Reputation: 44
I have two classes:
class CEnemy : CObject
{
protected:
int hitPoints;
};
class COgro : public CEnemy
{
COgro::COgro() {hitPoints = 100}
};
and in other file I have class 'CRocket', which can collide with COgro, there is it function:
void CRocket::OnCollision(CObject *collisionObject)
{
if (typeid(*collisionObject) == typeid(COgro))
{
//collisionObject->hitPoints -= 10; ?? or what?
}
}
I want to shoot 10 times to ogro before it dies. How to do this? I've already tried:
collisionObject->hitPoints -= 10;
(CEnemy)collisionObject->hitPoints -= 10;
but I can't compile it...how to edit this hitPoints value, but without changing '(CObject *collisionObject)'? Thx
EDIT:
//===============================================================
//------------------------------------CLASS CRocket-----------------------
class CRocket : public CObject
{
protected:
void OnAnimate(scalar_t deltaTime);
void OnCollision(CObject *collisionObject);
void OnDraw(CCamera *camera);
public:
float pitch;
float distanceTravel;
CVector forward;
bool isExplosion;
CTexture *explosionTex;
CExplosion *explosion;
CRocket();
~CRocket();
void Load();
void Unload();
};
void CRocket::OnCollision(CObject *collisionObject)
{
if (typeid(*collisionObject) == typeid(COgroEnemy))
{
isExplosion = true;
velocity = CVector(0.0, 0.0, 0.0);
explosion = new CExplosion(500, position, 8.0, explosionTex->texID);
PlaySound();
}
}
//-----------------------------------------class CObject
class CObject : public CNode
{
protected:
virtual void OnAnimate(scalar_t deltaTime)
{
position += velocity * deltaTime;
velocity += acceleration * deltaTime;
}
virtual void OnDraw(CCamera *camera) {}
virtual void OnCollision(CObject *collisionObject) {}
virtual void OnPrepare()
{
ProcessCollisions(FindRoot());
}
public:
CVector position;
CVector velocity;
CVector acceleration;
scalar_t size;
bool isDead;
CObject() {isDead = false;}
~CObject() {}
...
...
...
}
//---------------------------------------class CEnemy
class CEnemy : public CObject
{
public:
int hitPoints;
protected:
float distFromPlayer;
float runSpeed;
AIState_t aiState;
virtual void OnProcessAI() {}
void OnCollision(CObject *collisionObject)
{
// if this enemy collides with another enemy
if (typeid(*collisionObject) == typeid(CEnemy))
{
modelState = MODEL_IDLE;
velocity = CVector(0.0, 0.0, 0.0);
}
// if this enemy collides with the terrain (always)
else if (typeid(*collisionObject) == typeid(CTerrain))
{
position.y = ((CTerrain*)collisionObject)->GetHeight(position.x, position.z) + size;
}
else
{
}
}
public:
CPlayer *player;
...
...
//----------------------------------class COgro-------------------------
class COgroEnemy : public CEnemy
{
protected:
void OnProcessAI();
void OnCollision(CObject *collisionObject);
void OnPrepare();
public:
COgroEnemy() { Load(); }
COgroEnemy(float x, float z) { position.x = x; position.z = z; Load(); }
~COgroEnemy() {}
void Load();
};
Upvotes: 0
Views: 91
Reputation: 254431
You'll need to cast the pointer to a pointer type CEnemy*
(or a subclass), or the dereferenced pointer to a reference type CEnemy&
. For maximum safety, I'd suggest dynamic_cast
, rather than an evil C-style cast; although that's slightly paranoid since you're checking the type before casting.
// no checks, undefined behaviour if type is wrong
((CEnemy*)collisionObject)->hitPoints -= 10;
static_cast<CEnemy*>(collisionObject)->hitPoints -= 10;
// throws if type is wrong
dynamic_cast<CEnemy&>(*collisionObject).hitPoints -= 10;
// does nothing if type is wrong
if (CEnemy* enemy = dynamic_cast<CEnemy*>(collisionObject)) {
enemy->hitPoints -= 10;
}
You might combine that with the type check, rather than using typeid
:
if (COgro * ogro = dynamic_cast<COgro*>(collisionObject)) {
ogro->hitPoints -= 10;
}
Note that this isn't exactly the same as your test: it will pass if the object is a subtype of COgro
, while your test checks for an exact match.
Upvotes: 3
Reputation: 57678
You code is not compiling because you are trying to access a class's protected data member from an external source.
The collisionObject
parameter is an instance of CObject
, which does not have a hitPoints
data member.
Also, when you pass around pointers to base classes to functions, the functions should assume that they can only access the interface or features of the base class.
You should write another overloaded method:
void CRocket::OnCollision(CEnemy& enemy);
Or move the hitPoints
data member to the CObject
class.
Upvotes: 0