0

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(); }; 
5
  • 1
    but I can't compile it Why? Commented Jan 6, 2015 at 18:07
  • Why do you inherit from CObject? Are you porting from Java? Commented Jan 6, 2015 at 18:12
  • 1
    Please show more code around your assignment statements. Their location does matter. (For example, the hitPoints member can only be accessed inside a method from a class derived from CEnemy, due to the protected access.) Commented Jan 6, 2015 at 18:14
  • Does the type Cobject have a hitPoints attribute? Can you access that attribute from outside the class? Commented Jan 6, 2015 at 18:15
  • 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(); } } Commented Jan 6, 2015 at 18:19

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.