here it is, I know it is pretty ugly, but i put it together in like 5 min.
#include "DarkGDK.h"
#include "SC_Collision.h"
float radius = 7.0f;
int rtimer = 0;
int stimer = 0;
int vtimer = 0;
float gravity = -0.1f;
float slope = 0.5f;
int ground = 1;
int jumptimer = 0;
float vx = 0;
float vy = 0;
float vz = 0;
void makePlayer()
{
dbMakeObjectSphere( 2,radius*2.0f );
dbPositionObject( 2,-80,15,-20 );
SC_SetupObject( 2,0,1 );
dbPositionObject(2,1000,700,1000);
//player has no group
}
void movePlayer()
{
//rotate player with mouse
dbYRotateObject( 2,dbObjectAngleY(2) + dbMouseMoveX()/3.0f );
dbXRotateObject( 2,dbObjectAngleX(2) + dbMouseMoveY()/3.0f );
float oldx = dbObjectPositionX(2);
float oldy = dbObjectPositionY(2);
float oldz = dbObjectPositionZ(2);
//apply gravity, and user changes to movement
float angy = dbObjectAngleY(2);
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 + 10*gravity;
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 ) { vx = vx + dbSin(angy); vz = vz + dbCos(angy); }
//only jump if on ground, and a certain time after last jump
if ( ground == 1 )
{
if ( dbSpaceKey() == 1 && jumptimer == 0 )
{
vy = vy + 4.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
//dy = oldy - SC_GetStaticCollisionY()
//if ( dy < slope && dy > 0 && ground == 1 ) vy = 0.5;
}
//position the player
dbPositionObject( 2,x,oldy,z );
SC_UpdateObject( 2 );
}
void positionCameraToObject( int obj)
{
dbPositionCamera( dbObjectPositionX(2),dbObjectPositionY(2),dbObjectPositionZ(2) );
dbRotateCamera( dbObjectAngleX(2),dbObjectAngleY(2),dbObjectAngleZ(2) );
dbPitchCameraDown( 10 );
dbMoveCamera( -60 );
}
void DarkGDK( )
{
dbSyncOn( );
dbSyncRate( 60 );
SC_Start( );
dbMakeObjectBox(1,5000,1,5000);
dbPositionObject(1,2500,0,2500);
dbColorObject(1,dbRGB(50,50,50));
SC_SetupComplexObject(1,1,2);
int obj = 3;
int Block = 1;
while (Block < 30)
{
dbMakeObjectBox(obj,500,100,500);
dbColorObject(obj,dbRGB(200,50,50));
dbPositionObject(obj,dbRND(5000),0,dbRND(5000));
SC_SetupComplexObject(obj,1,2);
obj++;
Block ++;
}
char info[256];
makePlayer();
while( LoopGDK( ) )
{
movePlayer();
positionCameraToObject( 2);
dbText ( 0, 30, info );
sprintf(info, "Use W A S D to move and SPACE to Jump");
dbSync ( );
}
}
I am not sure exactly how the moveplayer() function works, but it id easy enough to manipulate. What I did at first its that I snapped a 3d model of my character to the sphere's oriantation and then I hid the sphere, so it looks like your character is effected by gravity/level objects.
Later you can figure out how to replace the command int collide = SC_SphereCastGroup( 1, oldx,oldy,oldz, oldx,oldy+vy,oldz, radius,0 ); with something else that would help you to use this kinda function directly with any kind of 3d object.
also..
to setup a terrain you need to use SC_SetupTerrainObject (1,1,1000 ); er sumthing.
you can change the bits that say... if (dbKeyState(32) == 1 ) { vx = vx + dbCos(angy); vz = vz - dbSin(angy); }... to change the keys
I know it is not perfect but it is somwhere to start.
Sephnroth - thanks for the info. BTW..do u know if Newton is OpenGl based?