Hello everybody,
Sorry for my english, I'm french.
I'm using Sparky's DLL for collisions/simple gravity in my game. But, I want to use all the power of the player's graphic card, by using dbSyncRate(0);
But, the colision speed is also affected. I use timer to regulate X and Z speed, but I can't have anything working on Y fall speed (and for jump).
Here's my code :
#include "CameraPlayer.h"
// TIMER
typedef struct
{
int Temps;
int Temps_Precedent;
int FPS_Base;
double Coefficient;
} Info_Timer;
Info_Timer pChrono;
CameraPlayer::CameraPlayer(int PlayerObject)
{
mPlayerObjectID = PlayerObject;
ground = 1;
radius = dbObjectSizeY(PlayerObject)/2;
jumptimer = 10;
mPreviousMouseClick = dbMouseClick();
mCameraZoom = -30.0f;
mDestinationZoom = mCameraZoom;
pChrono.FPS_Base = 60;
Chrono_Update();
}
void CameraPlayer::Update()
{
float slope = 0.7f;
float gravity = -0.1f;
Chrono_Update();
int MouseMoveX = dbMouseMoveX();
int MouseMoveY = dbMouseMoveY();
bool ShowMouse = true;
if (mPreviousMouseClick == 0)
{
mOriginalMouseX = dbMouseX();
mOriginalMouseY = dbMouseY();
}
//rotate player with mouse
if (dbMouseClick() > 0 && mPreviousMouseClick != 0)
{
dbPositionMouse(mOriginalMouseX, mOriginalMouseY);
dbYRotateCamera( dbCameraAngleY() + MouseMoveX/3.0f );
dbXRotateCamera( dbCameraAngleX() + MouseMoveY/3.0f );
if (dbCameraAngleX() > 90)
dbXRotateCamera(90);
if (dbCameraAngleX() < -90)
dbXRotateCamera(-90);
ShowMouse = false;
}
if (dbMouseClick() >= 2 && mPreviousMouseClick != 0)
{
dbYRotateObject(mPlayerObjectID, dbCameraAngleY());
}
mPreviousMouseClick = dbMouseClick();
if (ShowMouse)
dbShowMouse();
else
dbHideMouse();
float oldx = dbObjectPositionX(mPlayerObjectID);
float oldy = dbObjectPositionY(mPlayerObjectID);
float oldz = dbObjectPositionZ(mPlayerObjectID);
//apply gravity, and user changes to movement
float angy = dbObjectAngleY(mPlayerObjectID);
vx = 0;
vz = 0;
//if player is jumping or falling then apply 'normal' gravity
//if not attempt to keep the player stuck to the floor
if ( vy == 0 && jumptimer == 0 )
{
vy = (vy + (gravity*10));
}
else
vy = (vy + (gravity));
if (dbKeyState(32) == 1) { vx = vx + dbCos(angy); vz = vz - dbSin(angy); }
if (dbKeyState(30) == 1 ) { vx = vx - dbCos(angy); vz = vz + dbSin(angy); }
if (dbKeyState(31) == 1 ) { vx = vx - dbSin(angy); vz = vz - dbCos(angy); }
if (dbKeyState(17) == 1 || dbMouseClick() >= 3) { vx = vx + dbSin(angy); vz = vz + dbCos(angy); }
// Timering / Speeding
vx = vx*Chrono_GetVal(1);
vz = vz*Chrono_GetVal(1);
//only jump if on ground, and a certain time after last jump
if ( ground == 1 )
{
if ( dbSpaceKey() == 1 && jumptimer == 0 )
{
vy = vy + 3.0f;
jumptimer = 20;
}
}
//this would be the player's final position without collision
float x = oldx + vx;
float y = oldy + vy;
float z = oldz + vz;
//first handle gravity - seperated from horizontal movement
//to achieve a more realistic effect
//Method: simple - cast a sphere vertically down, if it hits the level then
// position the object there (sticky collision) then move
// on to horizontal movement
// more complex - if we were to only use the simple method the player would be
// allowed to climb almost vertical slopes. Alternative is to
// get the normalY direction to work out how flat the gorund
// below the player is, 0-slope# is flatter, slope#-1 is steeper.
// if it's flat, use sticky collision, if it's steep slide the
// player down the slope. Changing slope# determines how steep the
// player can climb. NOTE: this also effects stairs.
int collide = SC_SphereCastGroup( 1, oldx,oldy,oldz, oldx,oldy+vy,oldz, radius,0 );
if ( collide > 0 )
{
//how flat is this ground
float ny = SC_GetCollisionNormalY();
if ( dbAbs(ny) > slope )
{
//FLAT, stick
oldy = SC_GetStaticCollisionY();
}
else
{
//STEEP, slide
x = x - oldx; z = z - oldz;
oldx = SC_GetCollisionSlideX();
oldy = SC_GetCollisionSlideY();
oldz = SC_GetCollisionSlideZ();
x = x + oldx; z = z + oldz;
}
//ny#<0 means the player has hit a ceiling rather than a floor
if ( ny > slope )
{
//only on ground if standing on flat ground
ground = 1;
vy = 0;
}
else
{
ground = 0;
//if player has hit a flat ceiling then stop vy# movement
if ( ny < -slope ) vy = (gravity);
}
}
else
{
//nothing below player, not on ground, add vertical speed to player
oldy = oldy + (vy);
ground = 0;
}
//jumptimer will decrease only when player is back on ground
//creates a pause between two successive jumps
if ( ground == 1 && jumptimer > 0 ) jumptimer--;
//handle horizontal movement as sliding
//player only collides with group 1 (level) objs and moves freely through others
collide = SC_SphereSlideGroup( 1, oldx,oldy,oldz, x,oldy,z, radius,0 );
if ( collide > 0 )
{
//if hit, reposition player, halt movement vector
x = SC_GetCollisionSlideX();
oldy = SC_GetCollisionSlideY();
z = SC_GetCollisionSlideZ();
vx = 0;
vz = 0;
//possible code for giving the player a jumping help up stairs...
//might be useful if slope# is set very high but stairs are still required
//int dy = oldy - SC_GetStaticCollisionY();
//if ( dy < slope && dy > 0 && ground == 1 ) vy = (0.5*Chrono_GetVal(0.1));
}
//position the player
dbPositionObject( mPlayerObjectID,x,oldy,z );
SC_UpdateObject( mPlayerObjectID );
// Zoom
mDestinationZoom += dbMouseMoveZ()/20;
mCameraZoom = dbCurveValue(mCameraZoom, mDestinationZoom, dbAbs(5-Chrono_GetVal(8)));
if (mCameraZoom > 0) mCameraZoom = 0;
dbPositionCamera( dbObjectPositionX(mPlayerObjectID),dbObjectPositionY(mPlayerObjectID),dbObjectPositionZ(mPlayerObjectID) );
//dbPitchCameraDown( 10 );
dbMoveCamera( mCameraZoom );
}
void Chrono_Update()
{
pChrono.Temps = dbTimer();
pChrono.Coefficient = pChrono.FPS_Base * ((pChrono.Temps - pChrono.Temps_Precedent) / 1000.0);
//pChrono.Coefficient = (pChrono.Temps - pChrono.Temps_Precedent);
pChrono.Temps_Precedent = pChrono.Temps;
//pChrono.FPS_Base
}
double Chrono_GetVal(float MVT)
{
double valeur = (MVT)*pChrono.Coefficient;
return valeur;
}
Basically, it's the Sliding Demo code in a class, with two functions to get a coefficient defined by a timer.
How to make that working with Y axis?
E-One Games Entertainement
Projects :
The War of Shattrith