This is my idea:
I know the players position and its angle. I take the height of 8 points arround this position:
Quote: "angle_temp[0]= dbObjectAngleY(3) ;
for (i=1;i<8;i++)
angle_temp[i]= angle_temp[i-1] + 45;"
I increase angle_temp[i] by 45 degree. With a hypotenuse ( Hyp) of 15 I calculate the positions of this 8 points and get the height.
Quote: "float x_delta = sin(angle_temp[i])*Hyp;
float z_delta = cos(angle_temp[i])*Hyp;
x_temp[i]= x_pos + x_delta;
z_temp[i]=z_pos + z_delta;
y_temp[i]= dbGetTerrainGroundHeight(1,x_temp[i], z_temp[i]);
}"
Than I sort it for min- and maxheight. The difference of these values decides wether movement is effected or not:
Quote: "if (HeightDifference > 25)
{
correction = HeightDifference * 0.33;
Forward_delta = dbCOS(CorrectionAngle)*correction;
Side_delta = dbSIN(CorrectionAngle)*correction;
MovementForward = MovementForward - Forward_delta;
MovementSide = MovementSide + Side_delta;
"
MovementForward an MovementSide usually have already values from W,A,S or D.
I move the player with dbMoveObject and dbMoveObjectRight:
Quote: "if (MovementForward != 0)
{
dbSetObjectSpeed ( 3,55 );
dbLoopObject ( 3, 300 , 318);
dbMoveObject (3,MovementForward);
x_pos = dbObjectPositionX ( 3 );
z_pos = dbObjectPositionZ ( 3 );
ObjWasLooped = true;
}
if (MovementSide != 0)
{
dbSetObjectSpeed ( 3,80 );
dbLoopObject ( 3, 260 , 279);
dbMoveObjectRight (3,MovementSide);
x_pos = dbObjectPositionX ( 3 );
z_pos = dbObjectPositionZ ( 3 );
ObjWasLooped = true;
}"
And here is the whole code:
// Dark GDK - The Game Creators - www.thegamecreators.com
// the wizard has created a very simple project that uses Dark GDK
// it contains the basic code for a GDK application
// whenever using Dark GDK you must ensure you include the header file
#include "DarkGDK.h"
#include "math.h"
#define W 17
#define A 30
#define D 32
#define S 31
void MovementCorrection();
bool ObjWasLooped;
bool WASD;
bool FPSView;
float MovementForward;
float MovementSide;
float PlayerAngleX;
float PlayerAngleY;
float GravityAngleXZ;
float x_pos;
float z_pos;
float x_delta;
float z_delta;
float objHeight;
float CorrectionAngle;
float HeightDifference;
float correction;
bool KeyStateWASD()
{
WASD = false;
if (dbKeyState(W))
WASD=true;
if (dbKeyState(A))
WASD=true;
if (dbKeyState(S))
WASD=true;
if (dbKeyState(D))
WASD=true;
return WASD;
}
void IsGroundSteep()
{
float x_temp[8];
float z_temp[8];
float y_temp[8];
float angle_temp[8];
float Hyp=10; //länge des Fühlers
float min =10000;
float max = 0;
int i, min_pos, max_pos;
angle_temp[0]= dbObjectAngleY(3) ;
for (i=1;i<8;i++)
angle_temp[i]= angle_temp[i-1] + 45;
for (i=0;i<8;i++)
{
x_delta = sin(angle_temp[i])*Hyp;
z_delta = cos(angle_temp[i])*Hyp;
x_temp[i]= x_pos + x_delta;
z_temp[i]=z_pos + z_delta;
y_temp[i]= dbGetTerrainGroundHeight(1,x_temp[i], z_temp[i]);
}
for (i=0;i<8;i++)
{
if (y_temp[i]<= min)
{
min= y_temp[i];
min_pos=i;
}
if (y_temp[i]>= max)
{
max = y_temp[i];
max_pos=i;
}
}
if (y_temp[min_pos] != y_temp[max_pos])
{
HeightDifference= y_temp[max_pos] - y_temp[min_pos];
CorrectionAngle = angle_temp[min_pos]-dbObjectAngleY(3) ;
//CorrectionAngle = PlayerAngleX + CorrectionAngle;
}
dbText(150,0,"Hoehendifferenz:" );
dbText(280,0,dbStr(HeightDifference));
dbText(150,20,"Korrekturwinkel" );
dbText(290,20,dbStr(CorrectionAngle));
dbText(150,10,"Playerwinkel" );
dbText(290,10,dbStr(PlayerAngleX));
}
void GravityPlayer()
{
float Forward_delta=0;
float Side_delta=0;
if (HeightDifference > 25)
{
correction = HeightDifference * 0.33;
Forward_delta = dbCOS(CorrectionAngle)*correction;
Side_delta = dbSIN(CorrectionAngle)*correction;
MovementForward = MovementForward - Forward_delta;
MovementSide = MovementSide + Side_delta;
}
else
{ x_pos = dbObjectPositionX ( 3 );
z_pos = dbObjectPositionZ ( 3 );
}
}
// the main entry point for the application is this function
void DarkGDK ( void )
{ //Variablen für Objekt-Position
dbSetDisplayMode ( 1024, 768, 32 );
x_pos = 1600.0f;
z_pos = 1100.0f;
ObjWasLooped = false;
FPSView=false;
// switch on sync rate and set to a maximum of 60 fps
dbSyncOn ( );
dbSyncRate ( 60 );
dbSetCameraRange ( 1.0f, 30000.0f );
SetCurrentDirectory ( "Map" );
dbLoadImage ( "aktuelltext.bmp", 1 );
dbLoadImage ( "detail.jpg", 2 );
dbSetupTerrain ( );
dbMakeObjectTerrain ( 1 );
dbSetTerrainHeightMap (1,"aktuell.bmp");
dbSetTerrainScale ( 1, 19.0f, 2.0f, 19.0f );
dbSetTerrainLight ( 1, 1.0f, -0.25f, 0.0f, 1.0f, 1.0f, 0.78f, 0.9f );
dbSetTerrainTexture ( 1, 1, 2 );
dbBuildTerrain ( 1 );
dbLoadObject ( "skybox2.x", 2 );
dbLoadObject ("Colonel-x.X",3);
dbSetObjectLight ( 2, 0 );
dbScaleObject ( 2, 30000, 30000, 30000 );
dbPositionCamera ( 385, 23, 100 );
dbSetObjectTexture ( 2, 3, 1 );
objHeight= dbGetTerrainGroundHeight ( 1, x_pos,z_pos);
dbPositionObject (3, x_pos, objHeight, z_pos);
while ( LoopGDK ( ) )
{
MovementForward=0;
MovementSide=0;
objHeight= dbGetTerrainGroundHeight ( 1, dbObjectPositionX(3),dbObjectPositionZ(3));
dbPositionObject (3, x_pos, objHeight, z_pos);
// find the ground height of the terrain
float fHeight = dbGetTerrainGroundHeight ( 1, dbCameraPositionX ( ), dbCameraPositionZ ( ) );
PlayerAngleX = dbWrapValue ( PlayerAngleX + dbMouseMoveX ( ) * 0.4 );
PlayerAngleY = dbWrapValue ( PlayerAngleY + dbMouseMoveY ( ) * 0.4);
dbYRotateObject (3,PlayerAngleX);
if (PlayerAngleY < 80)
dbXRotateCamera (PlayerAngleY);
if (PlayerAngleY>260)
dbXRotateCamera (PlayerAngleY);
dbText(0,0,dbStr(PlayerAngleY));
dbText (0,20,dbStr(dbScanCode()));
if (dbKeyState(W))
{
MovementForward = -10;
//ObjWasLooped = true;
}
/*if (dbKeyState(57))
{
float TempHeightNew;
TempHeightNew =dbGetTerrainGroundHeight ( 1, dbObjectPositionX(3),dbObjectPositionZ(3));
if (TempHeightNew > objHeight*0.99)
dbMoveObjectUp(3,50);
}*/
if (dbKeyState(A))
{
MovementSide=10;
//ObjWasLooped = true;
}
if (dbKeyState(D))
{
MovementSide = -10;
//ObjWasLooped = true;
}
if (dbKeyState(S))
{
MovementForward = 10;
//ObjWasLooped = true;
}
IsGroundSteep();
GravityPlayer();
if (MovementForward != 0)
{
dbSetObjectSpeed ( 3,55 );
dbLoopObject ( 3, 300 , 318);
dbMoveObject (3,MovementForward);
x_pos = dbObjectPositionX ( 3 );
z_pos = dbObjectPositionZ ( 3 );
ObjWasLooped = true;
}
if (MovementSide != 0)
{
dbSetObjectSpeed ( 3,80 );
dbLoopObject ( 3, 260 , 279);
dbMoveObjectRight (3,MovementSide);
x_pos = dbObjectPositionX ( 3 );
z_pos = dbObjectPositionZ ( 3 );
ObjWasLooped = true;
}
if (KeyStateWASD()==false)
if (ObjWasLooped == true)
{
dbLoopObject(3,210, 234);
dbStopObject(3);
ObjWasLooped = false;
}
// x_pos = dbObjectPositionX ( 3 );
//z_pos = dbObjectPositionZ ( 3 );
objHeight = dbGetTerrainGroundHeight (1,x_pos,z_pos);
float angle=dbObjectAngleY(3);
dbSetCameraToFollow( x_pos,objHeight+50,z_pos,angle+180,50,30,10,0);
// update the terrain
dbUpdateTerrain ( );
// update the screen
dbSync ( );
}
}