Welcome to part five of our Special Edition tutorials. In this tutorial we will learn how to apply gravity. We will also do our best to explain movement in general(across all three dimensions). You will find the code changes first, then a more detailed description at the end of our changes.
We first must change our rpg.h file. Add the following two lines to your rpg.h code:
geVec3d Up; //will contain the up/down vector for scale, it is the up/down counterpart
of In
float upspeed = -15.0f; //speed we are raising/lowering. For this example we will apply simple gravity with a constant
speed.
The rest of our changes will take place in rpg.c. Near the beginning of our file where we are defining our functions add the following line:
void ApplyGravity(void);
At approximately line 133(our source looks a bit different than yours) modify your code to look like the code below:
while (run) {
//Apply our gravity
ApplyGravity();
//gather mouse motion data, move camera
MoveCamera();
//Begin the engine frame, Engine, World, & Camera better all be valid pointers
//or its gonna hang.
if (GE_FALSE == geEngine_BeginFrame(Engine, World, Camera)) break;
All that remains to now is to actually create our ApplyGravity function. Someplace in your code(preferably at the
bottom) add the following code:
void ApplyGravity(void)
{
oldpos = Xform.Translation; //old position
newpos = Xform.Translation; //new position
geXForm3d_SetYRotation(&Xform,Angles.Y); //which way are we facing?
geXForm3d_GetUp(&Xform,&Up); //get our upward
vector
geVec3d_MA(&oldpos,upspeed,&Up,&newpos);//Move
Result=geWorld_Collision(World,&Mins,&Maxs,&oldpos,&newpos,GE_COLLIDE_MODELS,0xffffffff,&Collision);
//checks for collision
if(Result==1)//Your new position collides with something
newpos=Collision.Impact;//set new position to point of col.
Xform.Translation =newpos;
}
You may now run your code and gravity should be applied to your map. You may want to tinker with the values(by changing the upspeed value in rpg.h).
Okay, so what exactly does it do? You may notice that the gravity code is much the same as the move forward code(nearly identical). So let's examine the code in a little more detail.
oldpos = Xform.Translation; //old
position
newpos = Xform.Translation; //new position
All we are doing here is storing our position before gravity is applied and setting our new position to the same for the time being.
geXForm3d_SetYRotation(&Xform,Angles.Y); //which way are we facing?
This changes our view to reflect which direction in which the camera is facing.
geXForm3d_GetUp(&Xform,&Up);
//get our upward vector
geVec3d_MA(&oldpos,upspeed,&Up,&newpos);//Move
This is the interesting part that I wanted to discuss. There are three seperate Getx calls you can make. GetIn, GetLeft, and GetUp. GetIn is used for moving forward/backwards. GetLeft is used for moving left/right(for example sidestepping). GetUp is used for moving up/down. If you wanted to add sidestepping you would simply use a GetLeft and return that value to a geVec3d by the name of Le(or anything easy for you to remember). Then you would create a routine that looked identical to the ApplyGravity function other than using a GetLeft, replacing the Up areas to Le and by changing the upspeed to your sidestep speed. To step left you would set this to -x, and to step right it would be set to +x(for example geVec3d_MA(&oldpos,lespeed,&Le,&newpos); ).
Result=geWorld_Collision(World,&Mins,&Maxs,&oldpos,&newpos,GE_COLLIDE_MODELS,0xffffffff,&Collision);
//checks for collision
if(Result==1)//Your new position collides with something
newpos=Collision.Impact;//set new position to point of col.
Xform.Translation =newpos;
This routine simply checks to see if you have collided with anything. If you have then it change newpos to the
point of impact. Then it changes your XForm to your new location.
I hope this tutorial was useful. As always for comments, suggestions, bug reports, etc you can send your mail to jcsmith@gameznet.com.
[Hyperlinkleisten stehen in diesem Web nicht zur Verfügung]