Hi I have been stuck on this problem for a couple of days. In my Character class i haves some basic functions such as walk, idle, attack and die. All of the functions work perfectly fine except for the die function. When ever i kill an enemy in this example the bandit the animation just freezes on the first frame instead of playing all the way through.
I have tried using Boolean to check if its dying or if its dead but still it just freezes on the first frame and stays in that static pose.
I have fixed the problem before, but I cannot remember how. can someone please help me solve this.
Character.h
#include "DarkGDK.h"
#include "Windows.h"
#include "SC_Collision.h"
#include "Math.h"
#ifndef Character_H
#define Character_H
#define MAX_DAMAGE 25
class Character
{
public:
Character();
~Character();
int FindFree();//
int GetDist(int Object);//
int GetHealth();//
void SetHealth(int x);//
bool Alive();//
void SetDying(bool);//
bool GetDying();//
void Walk(int sFrame, int eFrame);
void Idle(int sFrame, int eFrame);
void Attack(int sFrame, int eFrame);
void Die(int sFrame, int eFrame);
void UpdatePhysics();
void TakeHit(int Object);
virtual void Update()
{
}
protected:
int m_Model;
int m_Object;
int m_Health;
bool dying;
int numSpheres;
float radius;
float littleRadius;
int rtimer;
int stimer;
int vtimer;
float gravity;
float slope;
int ground;
int jumptimer;
int syncmode;
int view;
int hide;
//player movement vector
float vx;
float vy;
float vz;
};
#endif
character.cpp
#include "Character.h"
Character::Character()
{
numSpheres = 5;
radius = 3.5f;
littleRadius = 2.0f;
rtimer = 0;
stimer = 0;
vtimer = 0;
gravity = -0.1f;
slope = 0.5f;
ground = 1;
jumptimer = 0;
syncmode = 60;
view = 1;
hide = 0;
Character::m_Object = Character::FindFree();
dbMakeObjectCube(Character::m_Object,10);
dbHideObject(Character::m_Object);
SC_SetupObject(Character::m_Object,1,2);
}
Character::~Character()
{
}
int Character::FindFree()
{
int Start = 6000;
while(dbObjectExist(Start)==1)
{
Start++;
}
return Start;
}
bool Character::Alive()
{
if(Character::m_Health>0 )
return true;
else if(Character::m_Health<=0 && Character::dying==false)
return false;
}
int Character::GetDist(int Object)
{
int xTotal = pow(dbObjectPositionX(Character::m_Object)-dbObjectPositionX(Object),2);
int yTotal = pow(dbObjectPositionY(Character::m_Object)-dbObjectPositionY(Object),2);
int zTotal = pow(dbObjectPositionZ(Character::m_Object)-dbObjectPositionZ(Object),2);
return (xTotal + yTotal + zTotal);
}
int Character::GetHealth()
{
return Character::m_Health;
}
void Character::SetHealth(int x)
{
Character::m_Health = x;
}
bool Character::GetDying()
{
return dying;
}
void Character::SetDying(bool x)
{
Character::dying = x;
}
void Character::TakeHit(int Object)
{
if(dbObjectHit(Object,Character::m_Object))
{
Character::m_Health-= dbRND(MAX_DAMAGE);
Character::vy += 1;
dbMoveObject(Character::m_Object,-5);
}
}
void Character::Walk(int sFrame, int eFrame)
{
dbPointObject(Character::m_Object,dbCameraPositionX(),dbObjectPositionY(Character::m_Object),dbCameraPositionZ());
dbMoveObject(Character::m_Object,1);
dbLoopObject(Character::m_Model,sFrame,eFrame);
}
void Character::Idle(int sFrame, int eFrame)
{
dbLoopObject(Character::m_Model,sFrame,eFrame);
//dbTurnObjectLeft(Character::m_Object,1);
}
void Character::Attack(int sFrame, int eFrame)
{
dbLoopObject(Character::m_Model,sFrame,eFrame);
//dbPitchObjectDown(Character::m_Object,1);
}
void Character::Die(int sFrame, int eFrame)
{
//
dbPlayObject(Character::m_Model,sFrame,eFrame);
}
void Character::UpdatePhysics()
{
/*dbYRotateObject( 13,dbObjectAngleY(13) + dbMouseMoveX()/3.0f );
dbXRotateObject( 13,dbObjectAngleX(13) + dbMouseMoveY()/3.0f );*/
float oldx = dbObjectPositionX(Character::m_Object);
float oldy = dbObjectPositionY(Character::m_Object);
float oldz = dbObjectPositionZ(Character::m_Object);
//apply gravity, and user changes to movement
float angy = dbObjectAngleY(Character::m_Object);
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 + 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
//dy = oldy - SC_GetStaticCollisionY()
//if ( dy < slope && dy > 0 && ground == 1 ) vy = 0.5;
}
//position the player
dbPositionObject( Character::m_Object,x,oldy,z );
SC_UpdateObject( Character::m_Object );
}
Bandit.h
#include "DarkGDK.h"
#include "Character.h"
#ifndef Bandit_H
#define Bandit_H
class Bandit : public Character
{
public:
Bandit(int x, int y, int z);
~Bandit();
virtual void Update();
private:
};
#endif
Bandit.cpp
#include "Bandit.h"
Bandit::Bandit(int x, int y, int z)
{
Character::m_Model = Character::FindFree();
dbLoadObject("media/npc/thief/knight.x",5);
if(dbObjectExist(5)==0) MessageBoxA(0,"Test","Missing",0);
dbCloneObject(Character::m_Model,5);
//dbSetObjectLight(Character::m_Model,0);
dbSetObjectSpeed(Character::m_Model,75);
dbScaleObject(Character::m_Model,30,30,30);
dbRotateObject(Character::m_Model,0,180,0);
dbFixObjectPivot(Character::m_Model);
dbPositionObject(Character::m_Object,x,y,z);
Character::SetHealth(100);
Character::SetDying(false);
dbSetCursor(50,50);
}
Bandit::~Bandit()
{
}
void Bandit::Update()
{
Character::UpdatePhysics();
Character::TakeHit(4);
dbPositionObject(Character::m_Model,dbObjectPositionX(Character::m_Object),
dbObjectPositionY(Character::m_Object)-4,
dbObjectPositionZ(Character::m_Object));
dbRotateObject(Character::m_Model,dbObjectAngleX(Character::m_Object),
dbObjectAngleY(Character::m_Object),
dbObjectAngleZ(Character::m_Object));
if(Character::Alive()==true && Character::GetDying()==false)
{
int Dist = Character::GetDist(13);
if(Dist > 15000) Character::Idle(0,129);
if(Dist <15000 && Dist >1000) Character::Walk(130,167);
if(Dist <=1000 ) Character::Attack(273,298);
//dbPrint(Character::m_Health*1.0);
}
if(Character::GetHealth() <= 0)
{
Character::SetHealth(0);
Character::SetDying(true);
}
if(Character::m_Health <=0 && Character::GetDying()==true)
{
dbText(10,10,"Dead");
Character::Die(350,365);
}
}