How to do onHit event for collision

Started by
6 comments, last by oliii 14 years, 11 months ago
Well, it's not really for collision but when ammo (e.g. rocket, grenade) hits a player. I need to send an event like onHit() to that player but how can i tell if the object the ammo hits is a player? The event will be generated as a result of another event, onCollision(), and the ammo will then do it's thing like blow up or whatever and send onHit() to the player that was hit. Then in onHit(), there will be code to lower health and other things like play a "hurt" animation or something. But because ammo can hit any PhysicsObject or the ground, i can't know when to send onHit. I was thinking of a sort of hack where i would dynamic_cast the PhysicsObject to a Player and call onHit if it succeeded. I also though of using an event interface which any interested objects can inherit and override the onHit method of that interface. But then i would still have to know what objects have that interface. Any ideas? I hope i have explained clearly enough.
[Window Detective] - Windows UI spy utility for programmers
Advertisement
usually, a collision object has some form of information about his owner, so you can trace back to him for collision events. Either a pointer to the object (bad), a handle, a guid...


Everything is better with Metal.

Quote:Original post by oliii
usually, a collision object has some form of information about his owner, so you can trace back to him for collision events. Either a pointer to the object (bad), a handle, a guid...

Hmm, i just had a look at my collision code and realised that i don't actually send the collision "owner" in the event. I don't know why i didn't think of it before. But that still wouldn't tell me what type of object it is. I looked into using RTTI but i'm not sure how to do that*. Java has the instanceof keyword to get the class type but C++ doesn't.
And what do you mean when you say that object is bad? And what is a "handle" exactly, i though that would be the same thing as a pointer?

*btw i forgot to mention that i am using C++.
[Window Detective] - Windows UI spy utility for programmers
a handle / guid doesn't make assumptions on what type the owner is, whereas a pointer does. A collision object doesn't need to know anything about his owner.

I suppose 'bad' is a bit strong. Pointers are a bit more unsafe too, a handle / guid gives you a level of indirection that you can use for checks.

A handle is a way to reference an object indirectly. For example, you want to access object number '14', in the global object list, you handle / guid could be just '14', and let the object manager grab the owner for you. Handle and guids can contain more info about the object (such as a type enum and such).

As for types, I usually just use a enum and cast away. There's probably better solutions.

Everything is better with Metal.

Yes, i was also thinking of using a type enum where i just specify all class types i need. It would be an acceptable solution for me since i won't have a great many different types of collision object. But i would still have to cast in order to call onHit();
enum {    AMMO_TYPE,    PLAYER_TYPE,    etc};class PhysicsObject {    int type;    ...}// onCollision event in Ammo classif (collisionOwner.type == PLAYER_TYPE) {    collisionOwner.onHit(this);  // I would still have to cast here anyway...}


As far as a handle/guid goes, i still don't see the benefit. It seems kind of anti-OO. I prefer using an interface class that all objects inherit from. I don't see how using a handle would be any different since you still won't be able to determine the type.
[Window Detective] - Windows UI spy utility for programmers
ok then...

Quote:
class Player;class NPC;class Ammo;class Vehicle;class PhysicsObject{		virtual bool onCollide(PhysicsObject& collisionOwner)=0;	virtual bool onCollisionWithAmmo(Ammo* ammo)=0;	virtual bool onCollisionWithNPC(NPC* npc)=0;	virtual bool onCollisionWithPlayer(Player* player)=0;	virtual bool onCollisionWithVehicle(Vehicle* vehicle)=0;}class NPC: public PhysicsObject{	virtual bool onCollide(PhysicsObject& collisionOwner)	{		return collisionOwner.onCollisionWithNPC(this);  	}	virtual bool onCollisionWithAmmo(Ammo* ammo)			{ /*take damage*/ return true; }	virtual bool onCollisionWithNPC(NPC* npc)				{ /*collide with npc*/ return true; }	virtual bool onCollisionWithPlayer(Player* player)		{ return player->onCollisionWithNPC(this); }	virtual bool onCollisionWithVehicle(Vehicle* vehicle)	{ return /*collide with vehicle*/ return true; }};class Player: public PhysicsObject{	virtual bool onCollide(PhysicsObject& collisionOwner)	{		return collisionOwner.onCollisionWithPlayer(this);  	}	virtual bool onCollisionWithAmmo(Ammo* ammo)			{ /*take damage*/ return true; }	virtual bool onCollisionWithNPC(NPC* npc)				{ /*collide with npc*/ return true; }	virtual bool onCollisionWithPlayer(Player* player)		{ /*collide with player*/ return true; }	virtual bool onCollisionWithVehicle(Vehicle* vehicle)	{ /*collide with vehicle*/ return true; }};class Vehicle: public PhysicsObject{	virtual bool onCollide(PhysicsObject& collisionOwner)	{		return collisionOwner.onCollisionWithVehicle(this);  	}	virtual bool onCollisionWithAmmo(Ammo* ammo)			{ /*take damage*/ return true; }	virtual bool onCollisionWithNPC(NPC* npc)				{ npc->onCollisionWithVehicle(this); }	virtual bool onCollisionWithPlayer(Player* player)		{ player->onCollisionWithVehicle(this); }	virtual bool onCollisionWithVehicle(Vehicle* vehicle)	{ /*collide with vehicle*/ return true; }};class Ammo: public PhysicsObject{	virtual bool onCollide(PhysicsObject& collisionOwner)	{		return collisionOwner.onCollisionWithAmmo(this);  	}	virtual bool onCollisionWithAmmo(Ammo* ammo)			{ /* nothing to do*/ return false; }	virtual bool onCollisionWithNPC(NPC* npc)				{ return npc->onCollisionWithAmmo(this); }	virtual bool onCollisionWithPlayer(Player* player)		{ return player->onCollisionWithAmmo(this); }	virtual bool onCollisionWithVehicle(Vehicle* vehicle)	{ return vehicle->onCollisionWithAmmo(this); }};


You don't even need explicit type enums.

EDIT : this process is a 'design pattern', but I don't really know which one exactly.

[Edited by - oliii on May 22, 2009 5:55:30 AM]

Everything is better with Metal.

It's the visitor pattern, I believe.

What's wrong with using smart pointers rather than id/handle? A smart pointer is often faster to dereference, eliminates the need for a "object database" singleton class, and conveniently deallocate themselves as needed. Additionally, they're type safe.
you'd have to use a weak reference though.

Everything is better with Metal.

This topic is closed to new replies.

Advertisement