331
Axe / Re: Velocity
« on: December 07, 2011, 10:32:20 am »
If you're referring to acceleration, deceleration, and gravity, those three are actually fairly easy to implement.
Say you have a sprite for your character in Pic1, and the characters position in two variables, X and Y. Every frame, to update the screen, you go like this:
Because you'll probably want to use 256x inflation, to insure smoothness and acuracy. Some say 256x is too much, but dividing by 256 is a highly optimized procedure (read: it's way fast)
So to do gravity, you need to implement constant acceleration along the Y-Axis. To do that, you need a variable to store the current velocity on the Y-Axis, and add to it every frame. I'm going to use the variable E.
Adding to our previous code:
If you run that code, you'll notice a problem - the character falls right off the bottom of the screen! You need to add some code to prevent that.
Now, we want to add the capability to fly. I'm going to add some code that adds the functionality to fly. If, when we want to fall, we just make E a bigger number, to fly, we just need to make E a negative number, thus subtracting from and making smaller the Y position variable.
Great! Now, we need to add acceleration on the X axis. We need a variable for X axis velocity. I'll use D. To do this, when the user presses right, we want to add to the X velocity, and when the user presses left, we want to subtract from it. Piece of cake!
You can already see the problem here - the character will go off the edges of the screen. We need to add boundary checking.
Now, we need one final feature - automatic deceleration. Right now the character never loses his energy, and that's not very practical for most games. (note that it's not practical for MOST games - you could still design some kind of a game around that concept)
The way we're going to do this is by checking to see if the user DIDN'T press right or left, decelerate. There are very efficient ways to do this, but for clarity purposes, I'm going to use a very simple method.
That should be everything! You now have a simple but working physics movement engine that supports boundary checking, gravity, and acceleration/deceleration.
Keep in mind, take all this code with a grain of salt. It's not perfect, it's not the best way, it doesn't have every little detail you want to add to make games great, but it works!
Say you have a sprite for your character in Pic1, and the characters position in two variables, X and Y. Every frame, to update the screen, you go like this:
Code: [Select]
.Initialize
0->X->Y
.Main Game Loop
Repeat getkey(15)
ClrDraw
Pt-On(X/256,Y/256,Pic1)
Dispgraph
.Just so it's not too fast...
Pause 75
End
Because you'll probably want to use 256x inflation, to insure smoothness and acuracy. Some say 256x is too much, but dividing by 256 is a highly optimized procedure (read: it's way fast)
So to do gravity, you need to implement constant acceleration along the Y-Axis. To do that, you need a variable to store the current velocity on the Y-Axis, and add to it every frame. I'm going to use the variable E.
Adding to our previous code:
Code: [Select]
0->X->Y->E
Repeat getkey(15)
.Add Y_Velocity to Y_Position
Y+E->Y
.Add a constant acceleration to Y_Velocity
E+100->E
ClrDraw
Pt-On(X/256,Y/256,Pic1)
Dispgraph
Pause 75
End
If you run that code, you'll notice a problem - the character falls right off the bottom of the screen! You need to add some code to prevent that.
Code: [Select]
0->X->Y->E
Repeat getkey(15)
Y+E->Y
E+100->E
.Make sure he doesn't fall off the bottom of the screen
If Y>>14336
.^^make sure it's >>, not >. >> works on negative numers, > doesn't.
.14336 = 56 (the lowest we want our character to be able to go) * 256 (256x inflation)
14336->Y
0->E
.there are other ways of stopping the character, like in Builderboy's Zedd physics library, objects bounce when they hit the ground and stuff like that.
End
ClrDraw
Pt-On(X/256,Y/256,Pic1)
Dispgraph
Pause 75
End
Now, we want to add the capability to fly. I'm going to add some code that adds the functionality to fly. If, when we want to fall, we just make E a bigger number, to fly, we just need to make E a negative number, thus subtracting from and making smaller the Y position variable.
Code: [Select]
0->X->Y->E
Repeat getkey(15)
Y+E->Y
E+100->E
If Y>>14336
14336->Y
0->E
End
.Press [2nd] to fly
If getkey(54)
E-150->E
.This number needs to be bigger than 100, to overcome gravity
End
.Make it so the character doesn't fly off the top of the screen
If Y<<0
0->Y->E
End
ClrDraw
Pt-On(X/256,Y/256,Pic1)
Dispgraph
Pause 75
End
Great! Now, we need to add acceleration on the X axis. We need a variable for X axis velocity. I'll use D. To do this, when the user presses right, we want to add to the X velocity, and when the user presses left, we want to subtract from it. Piece of cake!
Code: [Select]
0->X->Y->E
Repeat getkey(15)
.Every frame, add X_Velocity to X_position
X+D->X
Y+E->Y
E+100->E
If Y>>14336
14336->Y
0->E
End
If getkey(54)
E-150->E
End
If Y<<0
0->Y->E
End
.When the user presses right, add to X_Velocity
If getkey(3)
D+50->D
End
.When the user presses left, subtract from it
If getkey(2)
D-50->D
End
ClrDraw
Pt-On(X/256,Y/256,Pic1)
Dispgraph
Pause 75
End
You can already see the problem here - the character will go off the edges of the screen. We need to add boundary checking.
Code: [Select]
0->X->Y->E
Repeat getkey(15)
X+D->X
Y+E->Y
E+100->E
If Y>>14336
14336->Y
0->E
End
If getkey(54)
E-150->E
End
If Y<<0
0->Y->E
End
If getkey(3)
D+50->D
End
If getkey(2)
D-50->D
End
.If the character is off the right edge...
If X>>22528
.bring him back
22528->X
0->D
End
.If the character is off the left edge...
If X<<0
.we can take care of this
0->X->D
End
ClrDraw
Pt-On(X/256,Y/256,Pic1)
Dispgraph
Pause 75
End
Now, we need one final feature - automatic deceleration. Right now the character never loses his energy, and that's not very practical for most games. (note that it's not practical for MOST games - you could still design some kind of a game around that concept)
The way we're going to do this is by checking to see if the user DIDN'T press right or left, decelerate. There are very efficient ways to do this, but for clarity purposes, I'm going to use a very simple method.
Code: [Select]
0->X->Y->E
Repeat getkey(15)
X+D->X
Y+E->Y
E+100->E
If Y>>14336
14336->Y
0->E
End
If getkey(54)
E-150->E
End
If Y<<0
0->Y->E
End
If getkey(3)
D+50->D
End
If getkey(2)
D-50->D
End
If X>>22528
22528->X
0->D
End
If X<<0
0->X->D
End
.if the user isn't pressing right and the user isn't pressing left
If getkey(2)=0 and (getkey(3)=0)
.divide the acceleration value by 2
D//2->D
End
ClrDraw
Pt-On(X/256,Y/256,Pic1)
Dispgraph
Pause 75
End
That should be everything! You now have a simple but working physics movement engine that supports boundary checking, gravity, and acceleration/deceleration.
Keep in mind, take all this code with a grain of salt. It's not perfect, it's not the best way, it doesn't have every little detail you want to add to make games great, but it works!