Part 2. Here is the next code with jumping. I removed comments again, so only the changes are commented. To introduce the jump I had to rearrange the main loop a bit because I needed the values of the variables earlier. So I moved the camera move and terrain height commands to the beginning of the loop.
In your original code, I guess you wanted to change the camera height with different amounts depending on how high it currently is. But you seem to confuse range checking with "for" loops, these two are not the same. Then you are repeating code many times which is bad practice. Finally, the usual method of implementing gravity is different: there is a vertical speed for the jump, which is initially high, then it is decreased every loop by a constant gravity value. The speed is then added to the vertical position. Thus, the vertical position is changing by different amounts.
You can play with the initial vertical speed and the gravity value to make the jump higher or smaller. If you want, you can also experiment with different methods to perform the jump but this is a good general starting point. In very advanced programs, they use physics engines anyway, making the behaviour closer to real life.
#include "DarkGDK.h"
#define DIK_W 0x11
#define DIK_S 0x1F
//
void DarkGDK ( void )
{
dbSyncOn ( );
dbSyncRate ( 60 );
dbSetCameraRange ( 1.0f, 30000.0f );
dbLoadImage ( "texture.jpg", 1 );
dbLoadImage ( "detail.jpg", 2 );
dbSetupTerrain ( );
dbMakeObjectTerrain ( 1 );
dbSetTerrainHeightMap ( 1, "map.bmp" );
dbSetTerrainScale ( 1, 3.0f, 0.6f, 3.0f );
dbSetTerrainLight ( 1, 1.0f, -0.25f, 0.0f, 1.0f, 1.0f, 0.78f, 0.5f );
dbSetTerrainTexture ( 1, 1, 2 );
dbBuildTerrain ( 1 );
dbLoadObject ( "skybox2.x", 2 );
dbSetObjectLight ( 2, 0 );
dbScaleObject ( 2, 30000, 30000, 30000 );
dbSetObjectTexture ( 2, 3, 1 );
float speed = 2.0;
float DefPosX = 496, DefPosY = 23, DefPosZ = 406;
char Buffer[30] = "";
int Key = 0;
float MinX = 0, MaxX = 768, MinZ = 0, MaxZ = 768;
// Jump status indicator.
bool Jumping = false;
// Gravity. This will be deducted from the vertical speed.
const float Gravity = 0.1;
// Current vertical speed, to be added to CamPosY.
// The starting value of VertSpeed is not important here,
// it is initialized when a jump is started.
float VertSpeed = 0;
// When not jumping, the camera is 10 units above the terrain.
// CamPosY will be changed during a jump.
float CamPosY = 10.0;
dbPositionCamera (DefPosX, DefPosY, DefPosZ);
while ( LoopGDK ( ) )
{
// Do not let the player move while jumping.
// Otherwise, make the horizontal move so that we can get the terrain height
// at the new position.
if (! Jumping) dbControlCameraUsingArrowKeys ( 0, speed, 2.0 );
// Store the current position of the camera and the terrain height.
float CamX_now = dbCameraPositionX();
float CamZ_now = dbCameraPositionZ();
float fHeight = dbGetTerrainGroundHeight (1, CamX_now, CamZ_now);
Key = dbScanCode();
switch (Key)
{
case DIK_W:
if (speed < 5.0) speed += 0.1;
break;
case DIK_S:
if (speed > 0) speed -= 0.1;
break;
}
// We could check the scan code of the space key in the switch above,
// like the other keys, but this works too.
// If space is pressed and we are not jumping yet, then start a jump,
// with an initial vertical speed value.
if (dbSpaceKey() && ! Jumping) {
Jumping = true;
VertSpeed = 3.0;
}
// During a jump: add the current vertical speed to the vertical position.
// Decrease the vertical speed with the gravity. (After a while, vertical
// speed will turn into negative and the player will start falling back
// to the ground.)
if (Jumping) {
dbText(0, 15, "jumping");
CamPosY += VertSpeed;
VertSpeed -= Gravity;
// Check if we have fallen back onto the terrain: if the current
// vertical position went below the desired height above terrain,
// then adjust the height to the default and stop the jump.
if (CamPosY < fHeight + 10.0) {
CamPosY = fHeight + 10.0;
Jumping = false;
}
} else {
// If not jumping: just set the vertical position to a constant height
// above terrain.
// Note: you should replace the value 10.0 with a named constant because now we have
// repeated the same number in four different places, that's not good style.
// I leave that change to you.
CamPosY = fHeight + 10.0;
}
// Now that we calculated the vertical position, we can reposition the camera
// to its new height.
dbPositionCamera(CamX_now, CamPosY, CamZ_now);
sprintf(Buffer, "speed: %.2f", speed);
dbText(0, 0, Buffer);
if (CamX_now < MinX || CamX_now > MaxX || CamZ_now < MinZ || CamZ_now > MaxZ) {
dbText(100, 100, "You fell off!");
dbSync();
dbWait(1000);
dbPositionCamera (DefPosX, DefPosY, DefPosZ);
CamX_now = DefPosX;
CamZ_now = DefPosZ;
}
dbUpdateTerrain ( );
dbSync ( );
}
}