C# XNA Box2d: ApplyImpulse() acts surprisingly - c#

I'm trying to move a body:
if (ks.IsKeyDown(Keys.Up)) {
rocket.ApplyImpulse(new Box2DX.Common.Vec2(0, 30f), rocket.GetPosition());
}
Oddly, the body only moves when the key is released. Why is this? I've been looking at the manual but can't figure it out.
When I remove the conditional, and just have the applyImpulse() call in Step(), the rocket continually has the animation of thrusters but never actually moves. (As if I had been holding down the Up key the entire time.)
Looks like what I really need to get this working is a better understanding of what the first argument to applyImpulse() does:
new Box2DX.Common.Vec2(0, 30f)
What is the significance of the two values in the vector?
UPDATE This works much better:
rocket.ApplyImpulse(new Box2DX.Common.Vec2(0, -1), rocket.GetPosition());
It looks like if the second value in the force vector is negative, the object rises on the screen. Before, the impulse applied was just slamming it into the floor. When I released the key, it would sometimes bounce back, if the impulse had been strong enough.

Regarding your update: In XNA, depending on how you've situated your camera, negative Y is up. If you want the rocket to go up, you have to apply a force in that direction.

That makes no sense as to why it only moves when it's released, is there nothing else interfering with it elsewhere such as another keyboard input hidden somewhere? I only ask as it could be that another keyboard input statement in conflicting with another and causing the problem.

Related

Creating AI in c# to work through a simple game

I want to try and get an AI to find a sequence of moves that wins in Marble Solitaire. I've completed the system which moves a random cylinder and also the system which undoes the previous move. All I need to do now is to work out how and when the AI undoes moves. I had no idea what to do so I sort of randomly tried things, and I had enough so I decided to ask here.
Here's the code I think you need to help me solve it - feel free to ask me for more snippets, I don't just want to overload you with meaningless code:
private int index; Increases when a move has been tried my the AI, and said move didn't work. I use it to stop the program from looping over the same move without checking others.
Below is the current code I use to determine whether the AI should undo a move or not, but it doesn't seem to work as I want:
if (possibleMove.Count < index)
{
index = 0;
undoMove();
}
else if (possibleMove.Count == 0)
{
undoMove();
} //possibleMove is a list of all possible Moves the AI has found
The code snippet above activates at the very end of findMove()
The general format of the code goes like this:
private void findEmpty()
{
findMove();
}
private void findMove()
{
makeMove();
}
private void makeMove()
{
}
private void undoMove()
{
}
Rules of Marble Solitaire
The player makes successive capturing moves, removing a single piece each turn until is it impossible to make any more capturing moves.
Each turn, the player captures a piece by jumping over that piece in any direction (not diagonally) from two spaces away a vacant point, making sure that there is a piece you can jump over.
Therefore, the first turn can be made only by jumping a piece into the middle hole from one of 4 possible points.
Image of marble solitaire:
You can do this with the BFS method of graph searching. What you can do is find a way to represent the board, it can be an array of booleans to represent marbles or gaps or anything you can think of, so long as it's easy for you to understand and manipulate.
Then you would have a queue that so far only holds the initial state of the board. You then set your current state to the first state in the queue and then remove it from the queue. You can now use findMoves(currentState) to return a list of states that you can access from this current move. Add each of those states to the end of the queue, and then once again set your current state to the first state in the queue and remove it and use findMoves repeatedly until your current state matches some sort of goal state. In your particular problem you can just run this until findMoves(currentState) returns an empty array since that would mean there are no more moves for you to be able to do.
That would get you to a solution, however it wouldn't keep track of the path for you. You can keep track of the path itself in any number of ways, for example instead of adding just the next state to the queue you can add an array of all of the states so far in that path and just use the last value when calculating the next states you can go to. But that's just an example.

How can i get the Direction where my Object is moving?

I have started to make Pacman and would like to know how can i write in my code the direction where the Ghost is going ? So if the transform.position.y is growing, its obvious Up Direction and so on....
This is for the Direction Change if they're hit the Wall.
Any suggestions?
It depends on how you've got your game set-up. One manual way you could go about it is by saving the position in a frame, and in the next frame you calculate the difference between the two positions (the previous frame and the actual frame), and divide that by the time that has passed (Time.deltaTime).
Another way you could go about it (and I would recommend if possible) is simply getting the Rigidbody component and checking the velocity attribute: https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html
Keep in mind, since this is a beginner's question, that the fact that an object is moving in a certain direction may not come from a ribidbody. As I said, this depends on your exact set-up.

finding magnitudes such that they produce the max resultant vector in a certain direction?

I'm working on a 2d spaceshooter game where the ship has boosters.
I want to determine how much force each booster needs to exert to move my ship with the maximum force in the direction it wants to go.
The ship may have any number of boosters but will probably be a small number like 2-10.
The rotations of the boosters are known but I can't determine their magnitudes.
The magnitudes can be from 0(min) to lets say 5(max).
I got to a point where I made this equation:
directionToGo = ForceB1*B1Direction + ForceB2*B2Direction
But now that I'm getting more boosters I'm just thinking, ok to find what I want I have to brute force in min/middle/max forces for each direction to find the others I don't know.
So how would I go about doing this?
Had to unanswer because I haven't figured out the answer.
This sounds to me like a constraint maximization problem. You want to maximize the force along a certain vector while applying exactly no force along the perpendicular vector.
If your thrusters aren't all pointing towards the center of mass, another constraint you need is that zero torque is applied. This makes sure the ship isn't rotated by an imbalance of forces. Some games ignore this for simplicity, though, and assume thrusters never apply torque.
One thing to note is that you only need to do the optimization when the orientation of thrusters changes: during gameplay you can just apply the ratio of thrusts to add that force vector. (Watch out, though, moving "diagonally" requires another solution: if you just try to apply forward + sideways, you will get > 100% power from a thruster, causing an imbalance.)
That is one way to go about it--there might be a simpler solution that I'm not aware of. If you can constrain your problem further, it's more likely that there's a simpler way.

C# Monogame & Farseer Physics: Collisions

I am a begginer. I am using Monogame and Farseer Physics Library in C#. (latest versions)
In my game, whenever my ball (circle) hits the corner of a rectangle, (or even another circle), it is supposed to only change direction on the Y-Axis.
However, it does not only change direction on the Y-Axis, (as intended), but it also moves a small amount to the right as well (or the left accordingly), depending on how you hit the corner (or another circle). It is as if some force is being put on the ball, making it move on X-Axis as well.
This movement is cool and all, and it makes a lot of sense, but in my game, it does not, therefore i want to get rid of it.
How is this possible ? I am guessing i have to change some default values.
This what my coding looks like:
BallBody.BodyType = BodyType.Dynamic;
BlockBody.BodyType = BodyType.Static;
Ball.LinearVelocity = new Vector(0,-1); // ball going up
BallBody.OnCollision += Ball_OnCollision;
public bool Ball_OnCollision(Fixture f1, Fixture f2, Contact contact)
{
// if the Ball (f1), collides with the Block (f2)
if (f2.Body == BlockBody)
// change the direction of the Ball on Y-Axis
Ball.LinearVelocity = new Vector(0,-1);
return true;
}
Also with high speeds, this occurs:
Even though the ball is never able to pass through the Block (tunneling), I want to know how could i possible fix that so that the ball never enters the Block area ?
Unfortunately, this is surprisingly difficult to do with Box2D. The best I could manage when I tried, was to record the velocity of the ball when the contact started, and then when the contact ends, manually set the velocity to what I wanted. That works fine when the ball only begins and end contact with one block at a time, but in some cases the ball can begin touching two blocks in the same time step. You would have to look at the arrangement of the blocks it touched, and calculate for yourself what angle you would expect it to bounce away at. Eventually I just gave up and did not bother to cover that case.

A* pathfinder obstacle collision problem

I am working on a project with a robot that has to find its way to an object and avoid some obstacles when going to that object it has to pick up.
The problem lies in that the robot and the object the robot needs to pick up are both one pixel wide in the pathfinder. In reality they are a lot bigger. Often the A* pathfinder chooses to place the route along the edges of the obstacles, sometimes making it collide with them, which we do not wish to have to do.
I have tried to add some more non-walkable fields to the obstacles, but it does not always work out very well. It still collides with the obstacles, also adding too many points where it is not allowed to walk, results in that there is no path it can run on.
Do you have any suggestions on what to do about this problem?
Edit:
So I did as Justin L suggested by adding a lot of cost around the obstacles which results in the folling:
Grid with no path http://sogaard.us/uploades/1_grid_no_path.png
Here you can see the cost around the obstacles, initially the middle two obstacles should look just like the ones in the corners, but after running our pathfinder it seems like the costs are overridden:
Grid with path http://sogaard.us/uploades/1_map_grid.png
Picture that shows things found on the picture http://sogaard.us/uploades/2_complete_map.png
Picture above shows what things are found on the picture.
Path found http://sogaard.us/uploades/3_path.png
This is the path found which as our problem also was before is hugging the obstacle.
The grid from before with the path on http://sogaard.us/uploades/4_mg_path.png
And another picture with the cost map with the path on.
So what I find strange is why the A* pathfinder is overriding these field costs, which are VERY high.
Would it be when it evaluates the nodes inside the open list with the current field to see whether the current fields path is shorter than the one inside the open list?
And here is the code I am using for the pathfinder:
Pathfinder.cs: http://pastebin.org/343774
Field.cs and Grid.cs: http://pastebin.org/343775
Have you considered adding a gradient cost to pixels near objects?
Perhaps one as simple as a linear gradient:
C = -mx + b
Where x is the distance to the nearest object, b is the cost right outside the boundary, and m is the rate at which the cost dies off. Of course, if C is negative, it should be set to 0.
Perhaps a simple hyperbolic decay
C = b/x
where b is the desired cost right outside the boundary, again. Have a cut-off to 0 once it reaches a certain low point.
Alternatively, you could use exponential decay
C = k e^(-hx)
Where k is a scaling constant, and h is the rate of decay. Again, having a cut-off is smart.
Second suggestion
I've never applied A* to a pixel-mapped map; nearly always, tiles.
You could try massively decreasing the "resolution" of your tiles? Maybe one tile per ten-by-ten or twenty-by-twenty set of pixels; the tile's cost being the highest cost of a pixel in the tile.
Also, you could try de-valuing the shortest-distance heuristic you are using for A*.
You might try to enlarge the obstacles taking size of the robot into account. You could round the corners of the obstacles to address the blocking problem. Then the gaps that are filled are too small for the robot to squeeze through anyway.
I've done one such physical robot. My solution was to move one step backward whenever there is a left and right turn to do.
The red line is as I understand your problem. The Black line is what I did to resolve the issue. The robot can move straight backward for a step then turn right.

Categories