# Implementing 2D Physics

• (4 Pages)
• « First
• 2
• 3
• 4

## 51 Replies - 5644 Views - Last Post: 25 June 2012 - 09:56 PM

### #46 BBeck

Reputation: 208
• Posts: 563
• Joined: 24-April 12

## Re: Implementing 2D Physics

Posted 30 May 2012 - 08:16 AM

DanielLeone, on 29 May 2012 - 11:49 PM, said:

I don't think that I want line 13 to be an else if, because I want to be changing velocity every frame. It's also only going to be increasing velocity by Drag it it's

less than -drag,
grater than drag, and
less than drag.

Probably sounds a bit confusing, it does to me, so I drew a numberline . Just assume when I say velocity, it means either X or Y.

Test Velocity Drag.png

So now I'll look at the code relative to each colour test.

1 (Blue). the first 'if' says if velocity.X < Drag AND > -Drag. Well it IS.
So in this case we set velocity back to zero.

2 (Red). Again it's going to say if velocity.X < Drag AND > -Drag. Well it is less than Drag, but not > -Drag. SO it goes to the else. Now we know that it's out of the bounds of Drag and -Drag, found through the previous if statement. So now we just define which side it's on. If velocity > Drag (so on the right of the number line). Well it's not, so it goes to the else, and velocity += Drag. And that's it, for red. That SHOULD work, right?

3 (Aqua) Again the first if statement, which defines if it's inside the bounds of Drag and -Drag. It's not so it goes to the else again. Then the second if statement : if (velocity > drag). TRUE. So it goes velocity -= Drag. DONE.

4 (Purple) The first if statement should return true, velocity = 0;

The only other positions are velocity == Drag || velocity == -Drag || velocity = 0;
All 3 of theses though would return true for the first if statement. bringing it back to zero. (Because it is actually <= Drag).

Looking at that, I don't see why it wouldn't work?

It's confusing me.

So I do what Kilorn said and put some breakpoints. If your reading it now, I haven't got around to putting them in yer .

Your're probably also wondering what actually happens instead. Well nothing.

If just moves by force. I got rid of gravity to test it, and it just moves to what ever force is, like drag isn't involved at all.

I don't see a problem in the code. I'm going to guess that the problem is in another section of the code not shown. At first I thought it was because you aren't specifically checking against negative drag, but when I ran numbers through it, I saw that it still works even with a negative velocity. So, I can't find a problem with it.

Definately step through the execution line by line in the debugger and watch the values change. Sorry I can't be more helpful.

### #47 DanielLeone

Reputation: 22
• Posts: 177
• Joined: 04-February 12

## Re: Implementing 2D Physics

Posted 02 June 2012 - 09:58 PM

Okay, tried a number of things, without success.

Firstly a debugging question.
Is there a way I can stop the code when a value changes. Not like a breakpoint where you specify the line of code, but where it breaks, when a value actually changes. Note I'm only using Express, so I might not have access if there is.

I want this because I was trying this code.

```            if (force.X <= Drag && force.X >= -Drag)
{
force.X = 0;
}
else
{
//If velocity is larger that Drag, or smaller than -Drag.
if (force.X > Drag)
{
//If the velocity is bigger than Drag, decriment it by Drag.
force.X -= Drag;
}
else
{
//If the velocity is small than -Drag, increment it by Drag.
force.X += Drag;
}
}

```

This is just the same as before, except entirely for force, not velocity. I was thinking this, because I don't think I want to directly change velocity, but the force acting on it. So it will still have the same effect, but it reduces the force, which is probably what happens in real life (I think).

Now, the reason for the debugging question. This does not work (the code above). I have initially set force to (1,1). So, taking that, on the first run through, force should be set back to zero, note Drag is also 1.

So, I run the code, and sure enough, it breaks on that first line. (force.X = 0;), and then again (force.Y = 0;). That was the first run through.

Then I press play again, and it breaks at the same spot again?
I check the value of force, and it's (1,1) again.

If I remove the breakpoints, and play the game, the object just moves (1,1) as per force. It's as if this bit of code isn't taking effect. But it is, because I can see force change to (0,0), and then next run through is back at (1,1);

force is private, so I 2 methods to change it outside the class, both are never used as of yet.

And I've checked the current class, and it isn't changed as far as I can see.

That's why I was asking for the debugging feature.

I'll keep trying to figure this out, but once I do, it should work fine. How many times have we said that .

So any suggestions?

Edit : I also looked at all the references to force, every time it's used, and there isn't anything there that would change it. The only times are if the code above (which doesn't happen (I put breakpoints)), and in those 2 methods (aren't used).

Just before the lines of code where the gravity/acceleration and position come into play, I put force = Vector2.Zero; Now they don't move, whereas before they were moving (1,1) which is force. That proves that it's force causing this.

Thanks,
Daniel,

This post has been edited by DanielLeone: 02 June 2012 - 10:03 PM

### #48 BBeck

Reputation: 208
• Posts: 563
• Joined: 24-April 12

## Re: Implementing 2D Physics

Posted 03 June 2012 - 07:21 AM

DanielLeone, on 02 June 2012 - 09:58 PM, said:

Okay, tried a number of things, without success.

Firstly a debugging question.
Is there a way I can stop the code when a value changes. Not like a breakpoint where you specify the line of code, but where it breaks, when a value actually changes. Note I'm only using Express, so I might not have access if there is.

I want this because I was trying this code.

```            if (force.X <= Drag && force.X >= -Drag)
{
force.X = 0;
}
else
{
//If velocity is larger that Drag, or smaller than -Drag.
if (force.X > Drag)
{
//If the velocity is bigger than Drag, decriment it by Drag.
force.X -= Drag;
}
else
{
//If the velocity is small than -Drag, increment it by Drag.
force.X += Drag;
}
}

```

This is just the same as before, except entirely for force, not velocity. I was thinking this, because I don't think I want to directly change velocity, but the force acting on it. So it will still have the same effect, but it reduces the force, which is probably what happens in real life (I think).

Now, the reason for the debugging question. This does not work (the code above). I have initially set force to (1,1). So, taking that, on the first run through, force should be set back to zero, note Drag is also 1.

So, I run the code, and sure enough, it breaks on that first line. (force.X = 0;), and then again (force.Y = 0;). That was the first run through.

Then I press play again, and it breaks at the same spot again?
I check the value of force, and it's (1,1) again.

If I remove the breakpoints, and play the game, the object just moves (1,1) as per force. It's as if this bit of code isn't taking effect. But it is, because I can see force change to (0,0), and then next run through is back at (1,1);

force is private, so I 2 methods to change it outside the class, both are never used as of yet.

And I've checked the current class, and it isn't changed as far as I can see.

That's why I was asking for the debugging feature.

I'll keep trying to figure this out, but once I do, it should work fine. How many times have we said that .

So any suggestions?

Edit : I also looked at all the references to force, every time it's used, and there isn't anything there that would change it. The only times are if the code above (which doesn't happen (I put breakpoints)), and in those 2 methods (aren't used).

Just before the lines of code where the gravity/acceleration and position come into play, I put force = Vector2.Zero; Now they don't move, whereas before they were moving (1,1) which is force. That proves that it's force causing this.

Thanks,
Daniel,

Well, I figured out how to set a conditional break point. I'm glad that you asked the question. I used to know how to set a conditional break point, but I haven't done it in so long, and I've changed IDEs a couple times since then. This is something good for me to know. Anyway, I found this article explaining how to set a conditional break point.

That's the good news.

The bad news is that you can't set conditional break points in the Express edition, as you alluded to. I think it was you that was asking the question of "Why bother going to a paid version of Visual Studio". I think we just found the answer. I remember in my answer I said that if it didn't have good debugging tools, that would probably be a "show stopper" for me.

Assuming that you're not going to run out and buy a paid version of VS2010 today, I have an idea. In a lot of development environments you don't have good debugging tools, so you learn to get creative.

What you "could" do is put something like this in your code (if you wanted a conditional break when .X became less than 6.3 for example):

```
if(MyVector.X < 6.3f)
{
//This could be any statement. I don't want it to actually do this. I just want something to break on.
MyVector.X = 0f;
}

```

Then set a normal break point on "MyVector.X = 0f;". So, if your condition evaluates to true it will break. Put this code fragment right in front of the code you want to check. You're basically hard-coding a conditional break point with that.

Anyway, glad to see all the nonsense in other posts isn't slowing you down any. I look forward to seeing your games.

This post has been edited by BBeck: 03 June 2012 - 07:23 AM

### #49 DanielLeone

Reputation: 22
• Posts: 177
• Joined: 04-February 12

## Re: Implementing 2D Physics

Posted 03 June 2012 - 11:08 PM

Thanks BBeck,

I did think of that, and it did work, but obviously it doesn't break where the code changes, so thanks for the idea, better than nothing.

I did however find the problem after some tinkering. I don't what happened to the force value thing, but I striped down some of my code, so I only had one object and stuff.

Then I realised, the formula for velocity is Velocity += (Gravity + Acceleration);

That's it. Force starts at (1,1), and I just set gravity to 0 for now. Then the Drag code runs and sets force to zero. (Strange, because it definitely said it was still (1,1) but whatever). So then next time Velocity is calculated, it is already (1,1) so then it += (0,0) making it (1,1).

And from then on, force remains at 0 as well as gravity, so Velocity basically starts at (1,1) and never changed from there.
Hope that made sense.

All I did then was remove the + so it was Velocity = (Gravity + Acceleration)
Expanded, that would look like:

Velocity = (gravity + force / mass).

Should I use that formula for my physics, or do you think there's something wrong with it? I personally like it .

Thanks for all the help,
Daniel,

This post has been edited by DanielLeone: 03 June 2012 - 11:29 PM

### #50 BBeck

Reputation: 208
• Posts: 563
• Joined: 24-April 12

## Re: Implementing 2D Physics

Posted 04 June 2012 - 12:00 PM

DanielLeone, on 03 June 2012 - 11:08 PM, said:

Thanks BBeck,

I did think of that, and it did work, but obviously it doesn't break where the code changes, so thanks for the idea, better than nothing.

I did however find the problem after some tinkering. I don't what happened to the force value thing, but I striped down some of my code, so I only had one object and stuff.

Then I realized, the formula for velocity is Velocity += (Gravity + Acceleration);

That's it. Force starts at (1,1), and I just set gravity to 0 for now. Then the Drag code runs and sets force to zero. (Strange, because it definitely said it was still (1,1) but whatever). So then next time Velocity is calculated, it is already (1,1) so then it += (0,0) making it (1,1).

And from then on, force remains at 0 as well as gravity, so Velocity basically starts at (1,1) and never changed from there.
Hope that made sense.

All I did then was remove the + so it was Velocity = (Gravity + Acceleration)
Expanded, that would look like:

Velocity = (gravity + force / mass).

Should I use that formula for my physics, or do you think there's something wrong with it? I personally like it .

Thanks for all the help,
Daniel,

What works, works. It's hard to argue with working code.

That being said velocity in the real world is speed. And it doesn't change unless something causes it to change. So, the correct formula for the real world is

Velocity = Velocity + (gravity + (force/mass))

What that says it the new velocity is the old velocity + the acceleration caused by gravity plus the acceleration force caused by an engine [or something that is pushing the object] which is (the force of the push divided by the mass of the object being pushed). In other words, the velocity only changes if something pushes and the resulting velocity is the current velocity plus the push.

In that formula gravity should never change unless you are in outer-space or something where gravity is different. And force should always be greater than drag if you are subtracting drag from it, because the force has to overcome drag in order to move the object. If force is zero then you are saying "don't push the object".

I think I was recommending something like this:

```  acceleration = (force / mass);
velocity += (gravity + acceleration);
velocity -= (Velocity * DragPercentage);
position += velocity;

```

Where acceleration is the push caused by an amount of force being applied divided by the mass of the object being pushed. Then that is added to the push of gravity towards the ground, and combined with the current velocity/movement rate and direction of the object. Then you subtract drag so that there's something causing it to slow down such as wind resistance or terminal velocity. Then you add that velocity to the current position of where the object is at because velocity is really movement per frame and you need to add the movement per frame to the current position to get the new position for the next frame.

I tend to kind of think of this stuff in 3D these days. I think most of what we've been talking about is 2D. But maybe it would help to look at the issue in 1D. Forget about left and right (side to side). Forget about 2D vectors. Just look at as the attempt to launch a rocket into space with Position being the altitude of the rocket and zero position being sitting on the ground.

You've got gravity attempting to pull the rocket to the center of the earth, but when it's on the ground the earth is solid and won't let it go to a negative position/altitude. So, the acceleration of gravity is applied every frame, but if it causes the rocket to try to go below ground it's forced to stay on the ground rather than below ground. So, we have

```  gravity = -0.1635;  //units per frame to move.
velocity += (gravity);
position += velocity;
if (position<0) position=0;

```

So, at this point, if you lifted the rocket off the ground and let it go it would fall until it hits the ground because it is now affected by gravity.

And so our rocket sits on the ground. Notice that the acceleration of gravity is always on. Every frame it's doing it's best to pull the rocket to the center of the earth. The only thing preventing it from moving is the "if (position<0)" which says that the earth is a solid object that it can't pass through (we're assuming that the ground is always right at zero and that positive is upward and negative downward). Also, if 1 "unit" is the same as 1 pixel on the screen than the force of gravity is "trying" to move the rocket towards the center of the earth at a rate of 9.81 pixels every second. Again, gravity gets applied every frame even though our rocket is just sitting there on the ground.

So, we want to launch our rocket. We need to apply an acceleration, every frame, in order to overcome gravity. (Notice that gravity would not be interfering if we were moving horizontally but drag/wind resistance might). Velocity is our movement rate per frame. Gravity is applied to it every frame and we can't make the rocket travel into the sky without applying a greater acceleration than gravity and in the exact opposite direction. So, we "could" have code like this:

```  gravity = -0.1635;  //units per frame to move.
engine_acceleration = +0.1635;
velocity += (gravity + engine_acceleration);
position += velocity;
if (position<0) position=0;

```

The end result doesn't change anything, because even though we canceled gravity, we haven't over come it. The rocket will remain on the ground. We need a greater acceleration pushing upwards to make the rocket fly. Let's say we want it to gain 1 unit of altitude (for our example that will be 1 pixel) per second. The acceleration of gravity is 9.81 m/sec, so we want an upward acceleration of 10.81 m/sec in order to make the rocket rise 1 meter/unit/pixel per second. Divide that by 60 frames per second and we want an upward acceleration of 0.1803 units per frame. Now our code would look like this:

```  gravity = -0.1635;  //units per frame to move.
engine_acceleration = +0.1803;  //units per frame.
velocity += (gravity + engine_acceleration);
position += velocity;
if (position<0) position=0;

```

Notice both accelerations are applied every frame. So, what you'll see is our rocket "take off" after 1 second. But, then you will see that it keeps speeding up. Why? Because we're applying the engine acceleration every frame. What you'll see is the rocket rise 1 pixel after a second. It's altitude will be 3 pixels after two seconds. It's altitude will be 6 pixels after three seconds. It's altitude will be 10 pixels after four seconds.

Seconds Altitude
1 = 1
2 = 3
3 = 6
4 = 10
5 = 15
6 = 21
7 = 28
8 = 36
9 = 45
10 = 55
11 = 66
12 = 78
13 = 91
14 = 105
15 = 120
16 = 136
17 = 153
18 = 171
19 = 190
20 = 210

You can see that it's moving faster and faster every second. In fact, the number of seconds in the chart above is the rocket's velocity in pixels at that point in time. So, after 20 seconds it will have a velocity of 20 pixels and it just keeps speeding up forever after that.

This is actually what happens in the real world other than the fact that we aren't taking the drag of wind resistance into account. If you ever watch a rocket take off you will see it move unbelievably slow at first and then within a short amount of time it will literally be moving over 1,000 miles per hour. They take off slow, but they build speed fast.

It might even be worthwhile to build this into an XNA program to see it work.

Anyway, if you want the rocket to stop speeding up every second, you have to set that acceleration force of the engine to something that's below the acceleration force of gravity. If you set the acceleration of the engine equal to the acceleration of gravity the rocket will continue to rise at it's current velocity with that velocity not changing anymore. If you set it lower, the rocket will start slowing down because gravity has a stronger acceleration.

So, if we were going to write some code that said "turn off the engine when the altitude is greater than 100 units" it would look like this:

```  gravity = -0.1635f;  //units per frame to move.
if (engine_on)
{
engine_acceleration = +0.1803f;  //units per frame.
}
else
{
engine_acceleration = 0f; //units per frame.
}
velocity += (gravity + engine_acceleration);
position += velocity;
if (position<0f) position=0f;
if (position>100f) engine_on = false;

```

So, that gives us our basic movement. But what if we want to bring mass into the picture? Let's say this is a game and we want the rocket to carry a payload. The user can select how much cargo to put on board and we want that to have an affect on what it takes to get this rocket off the ground. The heavier it is, the harder it should be to get it off the ground. Now, we need to modify the engine acceleration to be a formula that includes mass.

I want the standard rocket weight/mass to give me the 1 unit per second acceleration that we got before. The acceleration that I had before was 0.1803 units per frame. So the formula is:

0.1803 = force / mass

I can either pick force to be a certain number here or mass. I'm going to pick mass. Let's say I want the rocket to weigh in at 10,000 kilograms without an additional payload/cargo. So algebra says:

0.1803 = force / 10000
force = 1803 Newtons.

So, the force of my rocket engine (how hard the engine can push at full throtle) is 1803 Newtons per frame. And that force is going to result in the 10,000 kg rocket accelerating by 0.1803 meters/units/pixels per frame.

So the code would look like:

```  gravity = -0.1635f;  //units per frame to move.
engine_force = 1803f;  //Newtons per frame
rocket_payload = 0f;   //kilograms
rocket_mass = 10000f + rocket_payload;  //kilograms
if (engine_on)
{
engine_acceleration = (engine_force/rocket_mass);  //units per frame.
}
else
{
engine_acceleration = 0f; //units per frame.
}
velocity += (gravity + engine_acceleration);
position += velocity;
if (position<0f) position=0f;
if (position>100f) engine_on = false;

```

So, that gives us the exact same thing, but taking the weight of the rocket into consideration. Now we can change the payload weight and the acceleration of our rocket will be affected.

So, going back to our formula:

engine_acceleration = force / (rocket_mass + rocket_payload)
0.1635 = 1803 / (10000 + rocket_payload)

Where 0.1635 pixels per frame is the acceleration of gravity, or the point where the rocket's acceleration is exactly equal to gravity.

Algebra says:
0.1635 * (10000 + rocket_payload) = 1803
10000 + rocket_payload = 1803/0.1635
10000 + rocket_payload = 1803/0.1635
10000 + rocket_payload = 11027.5
rocket_payload = 11027.5 - 10000

So, you should find that if you increase the payload above about 1027 the rocket won't be able to take off because it's overloaded.

This really shows the value of having solid algebra skill in game programming.

The primary problem with our program so far is it totally ignores wind resistance. It says that gravitational acceleration or the acceleration of the rocket can go on forever, which is not the case. At some point, the air that the rocket is pushing out of the way weighs more than the rocket itself regardless of whether it's moving up or down. That is going to set an absolute limit on the rocket's acceleration. To do it correctly, you would have to change that as the size of the acceleration changes. The acceleration of gravity never really changes when you're on earth, but the rocket engine's can if it's not full throttle.

I don't know if you even want to go deep enough into the simulation to worry about this air resistance. If you do, you will probably want to keep it simple and just say "the velocity can never be more than such and such amount".

Anyway, that's basically it. Dealing with this in 1D makes it a lot more intuitive, because that's what we're taught in school growing up. However, for game programming, you really need to deal with the problem in 2D or in 3D depending on the game. And for that you really need to look at it as a "vector" problem.

This is already a vector problem in 1D. It's just most people won't see it as a vector problem, and 1D vectors are so intuitive that we imagine that they don't exist. I mean you can imagine this whole problem without thinking about vectors at all in 1D. But they're there.

A vector is nothing more than an amount that has a direction. The direction and the fact that it cannot be separated from the amount is what makes it a vector.

In the rocket example above, we assumed that the rocket engine always points up. What if the rocket spun around and the engine suddenly pointed straight down. Now, the acceleration of the rocket is helping gravity shove the rocket towards the earth. You still may not see this as a vector because it's almost obvious that you could flip the rocket around by making the rocket's acceleration negative. That's it. So, you might not think this is a vector problem. The reason that it is a vector problem is that you can't treat the rocket pointing upwards the same as pointing downwards. Accelerating by 0.1803 pixels per frame upwards is an entirely different movement from accelerating by 0.1803 pixels per frame downwards: the direction matters in determining the rocket's new position. You can't just ignore the direction the engine is pointing in. I mean, you can and we did by just assuming that it always points up. But what I'm trying to say is that if that acceleration for the engine goes negative the rocket is going to move down instead of up and you ignore that to your own detriment. To think of the problem properly you need to realize that the engine_acceleration has a direction that matters. So, the amount of acceleration only has proper meaning when you tie it to the direction.

In 1D this is over kill. I mean the rocket can only point in one of two directions, either up or down. And that's simply positive or negative and we're done with it. And it turns out that that's one of the basic rules of vectors: that you can reverse the direction of the vector by multiplying it by negative one.

Now here's why you really need to understand vectors. In 1D the rocket can only point one of two directions with one negative and the other positive. But in 2D, it's a whole n'other matter.

In 2D we have to determine what our 2 dimensions are. For our example here the obvious choice would be the up-down dimension and the left-right dimension. (It could have been the north-south dimension and the east-west dimension for another program).

So, in two dimensions, the rocket engine can not only point up or down, but it can rotate through a "continuum" of 360 degrees. Now, changing directions isn't as simple as flipping positive for negative unless we want to change directions by exactly 180 degrees. If we want to change directions by rotating 12 degrees clockwise, that's a whole lot more complicated than just multiplying by negative one. In 1D we couldn't rotate, but in 2D we can. In 1D you can only do a 180 degree flip, but in 2D you can change direction by any number of degrees.

That's when you start seeing the value of a vector. Notice that it doesn't matter what direction the engine is facing in determining the amount of acceleration. The amount is the same no matter what direction the engine faces. But the new position it goes to is entirely depended on both the amount of acceleration and the direction that it gets applied in.

Rotating a 2D vector requires a knowledge of Trigonometry or at least a method that you can call that knows how to do it. It's a trig problem.

Anyway, I guess my point is that it's critical to understand vectors for movement in 2D. Without it, it's going to be difficult and maybe impossible to handle 2D movement correctly. I'm saying this in general because I have no idea how solid Daniel's understanding of vectors is. I'm just saying that anyone doing 2D needs a solid understanding of what 2D vectors are and how they work.

This post has been edited by BBeck: 04 June 2012 - 01:57 PM

### #51 BBeck

Reputation: 208
• Posts: 563
• Joined: 24-April 12

## Re: Implementing 2D Physics

Posted 04 June 2012 - 07:18 PM

Well, this talk got me inspired to start writing my tutorial on Vectors. I mean most 2D physics is just vector math. I had been planning on doing it later, but this talk got me to thinking in terms of vectors and got me inspired to bump up the vector tutorial on the priorities list.

So here's my tutorial on Vectors. It's not complete. I need to add Vector multiplication and 3D vectors to it. (It was "supposed" to be all about 3D vectors but it seems to only be about 2D vectors so far). I probably need to proof read it for a couple of days and figure out what needs to be added to it. But here's what's there for now:

http://xna-3d-101.co...ls/Vectors.html

It one of those subjects that's really "weird" for me because I just reached this point where I understood it and now it's obvious. So, it's hard for me to see where people are having a hard time understanding vectors.

Anyway, if you can help me find areas where I'm not explaining it well that would be appreciated.

### #52 jjames967

• New D.I.C Head

Reputation: 1
• Posts: 33
• Joined: 01-January 12

## Re: Implementing 2D Physics

Posted 25 June 2012 - 09:56 PM

http://www.dreaminco...0&#entry1651487 is my link for what I want to do... let me know!