Handling a damage event

Started by
5 comments, last by JasonWelch 12 years, 8 months ago
[font="Verdana"]I'm trying to figure out the best way to handle damage events. I figured when dealing with localized damage such as the impact of a bullet, the bullet can generate a damage event and pass it to the entity's collision component, which may then pass it to the entity itself which in turn would pass it to the other components that care about it such as life, render, etc. This seems pretty logical to me but I'm open to suggestions, however my main question is with non localized damage events.[/font]
[font="Verdana"]
[/font]
[font="Verdana"]For example, a rocket explodes and should notify all nearby objects. This could be an ExplosionDamageEvent. Anyway, where would I broadcast the event? To the collision system? Eh.. to the life system? Maybe. What about AI? AI should be able to hear an explosion. I'm thinking maybe a global event system that all subsystems are registered with, will work. If the subsystems cares about the event type, they'll pass the event down to the registered components... but then, when the life system receives the event, how will it know if the explosion event affects it? If 300 entity's get the event and only 20 are within range of the explosion, there's still 300 distance checks being performed. The solution is obvious though: there needs to be a spatial division system such as a quadtree. However, what will query the quadtree and when will the affect entity list be created? The only thing I can think of is, the rocket could send the collision system the explosion damage event which would contain a collision volume. Based on the collision volume, the collision system would notify all registered collision components within range of the damage event. The collision components could then react to the explosion and could also send the event to their parent entities which in turn, the entities can pass the event to their other components such as life. This[/font][font=Verdana] sounds good to me, but I'm inexperienced still. What are your suggestions??[/font]
Advertisement
I'd just do a sphere collision check against the target objects for the explosion. if (explosionObject.sphereCollision(targetObject) == true)

If the target obect is within the blast radius of the sphere then perform the actions you want. You can even change the sphereColliders radius during the explosion if you want it to be missile command (the old game) like with the explosion growing and shrinking and all the time anything within the sphere is a hit.

Also 300 objects isn't that much and I wouldn't worry about running collision detection against this many objects. I mean say you wanted to create a system that avoided checking some of the collisions, that system has to have less overhead than the sphere collision detection which itself is very fast.
Thanks for the reply skuzzbag! (it feels like I'm insulting you haha). Now, would you say I should pass the damage event directly to the target object??

Edit:

Example:

target->eventCallback(damage_event);

Since damage being dealt is an event rather than a collision event.
It shouldn't matter if its a collision event or any other type of event, If something occurs in a scene, you should go over all the objects and if they are going to be affected, tell the objects about it.

Your world should be divided up into some kind of spacial division (usually some type of grid structure) so, if a rocket explodes in an area you know which grids are affected, then just go over the objects in the grid and tell each object what happened.
Wisdom is knowing when to shut up, so try it.
--Game Development http://nolimitsdesigns.com: Reliable UDP library, Threading library, Math Library, UI Library. Take a look, its all free.
Have you got code for the event or is this just theory?

With events generally you capture them. Ive never done this in a game myself as I've never needed to run threads. Going down that route though I'd say you'd need to implement a way of storing the events (like an event class) then you'd need your objects to check the class event list it holds.

I think anyway I could be wrong about that! With games especially solo coding keep it as simple as you can which is why I'd simply run a collision check on all the objects.
For an explosion I use a shpere overlap method from PhysX, it takes an object that has a callback of sorts that gets called for each actor thats intersected. In that call back I work out if its actually an Entity (SomeNxActors might not be) and just send an "EntityDamaaged" event into my event system. Anything can really listen for events if they want to, right now I have a HealthComponent that manages the health of things, it listens for EntityDamaged events and if they are for the entity it belongs to then it handles it. For now all it does is remove the health, sends out an "EntityHealthChanged" event and if appropriate kills the Entity. Other things can listen for EntityHealthChanged, my AI listens for it and starts retreating (or goes back into the fight), the GUI can listen for it and show the players health.

Its quite simple but its working well so far. I do have the concept of "internal only" events that are sent only to other components int he Entity which I would like to use for EntityHealthChanged but then I can no longer pick it up for GUI :(.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

[font="Verdana"]Thanks for all the replies..very helpful! Nanoha, an idea for you is, send the event twice..once to the entity only and once to the world / game listener..can't hurt. Anyway, the way my system works is, every type of component gets registered to an associated subsystem. Subsystems can be inherited, same as components. The entity itself gets managed by the GameWorld where as it's RenderComponent registers itself to the RenderSystem at startup/unregisters at shutdown. The game world and subsystems know nothing about each other. However, I was thinking of making a global "EventBoard" which subsystems can be registered to..for example, "PlayerDeath" maybe sent to the EventBoard so that the AISystem can react accordingly.[/font]

[font="Verdana"]Here's a small example of the system with a 2D "player" object:
[/font]

[font="Verdana"][/font]
[font="Verdana"]
protected GameObject createPlayer(float x, float y, RenderSystem renderer, PlayerInputSystem playerInput){
GameObject player = new GameObject();

Material mat = new Material();
mat.setTextureFile("zombie.png");

player.setMaterial(mat);
player.setPosition(new Vector2(x,y));
player.addComponent(new SpriteRenderComponent(renderer,player));
player.addComponent(new PlayerControllerComponent(playerInput,player));
player.addComponent(new MovementComponent(player));
return player;
}[/font]
[font="Verdana"]

[/font]

[font="Verdana"]Anyway, after reading all of your replies and doing a bit more thinking... The explosion will be a new entity that gets spawned during the explosion. Attached will be an ExplosionCollisionComponent which the collision system will handle just as any sphere collision. During the collision check, the component will send the damage event to all successful colliders. This even can then be passed down from the component to it's associated entity, which may in turn, send it to all of it's other components. [/font]

[font="Verdana"]But..[/font]

[font="Verdana"]I don't like that idea much. I don't like how it's being passed from one component, to the entity, then back out to all other components...So I'm thinking that the event will be given to the onCollision method of the targets, which will pass it directly to the parent entity and back out...so CollisionComponent::onCollision(other, Event event); Note that I do use type casting for events, but only for events...so the above would be:[/font]

[font="Verdana"]if(event instanceof DamageEvent) {[/font]
[font="Verdana"] DamageEvent damage = (DamageEvent)event;[/font]

[font="Verdana"] // do whatever here..[/font]

[font="Verdana"] this.getParent().eventCallback(damage);[/font]
[font="Verdana"]}[/font]

[font="Verdana"]In short: The rocket explodes creating an explosion entity. The explosion entity's collision component then get's access by the collision manager which performs the check based on some spatial data. All objects within the explosions node radius, get checked against for collisions. If a collision occurs, a new damage event is generated by the rocket's collision component, and passed to the collision event handler for the colliders. [/font]
[font="Verdana"]
Thoughts?[/font]

[font="Verdana"](ps..I'm literally falling asleep at my kb right now..hahaha)[/font]

This topic is closed to new replies.

Advertisement