Hi there,
i am making a platformer game using box2d. My player have two ground sensors defined as small circle fixtures on feet level.
Now i want to let the player to jump, but only when on ground - i could achieve that by detecting if any one of my player ground sensors are touching another fixture - using an counter as a userdata reference for example in a contact listener for beginContact/endContact. This works fine, but...
... i may have more Entities in my game, like Jumppads, Spikes, Ladders, Enemies etc.
All these entities need a way to know which other fixtures does collide with it, so every entity can decide itself what it should do, maybe push the other enemy around, or kill it instantly.
What i dont like, is using beginContact, endContact and put the logic in there - thats a very nasty way. I dont want to put all the entity logic in one single contact listener!
The general idea was to let every entity have a list of other entities which are automatically handled by just the beginContact and endContact, but i couldnt´t figure out yet.
Or does someone have a better solution for that problem? There must be some state machine magic to solve this... i am pretty sure.
Thanks,
Final
In these types of high-level aspect, you can consider doing what you want basically. But using an reference counter for each collision mich be not a good way. Your game logic must be somekind related with the current game state.
What looks more reasonably for your problem is to let the entity handle not the collision itself but some kind of notification instead. Just create a virtual function, pass an enumerated value to this function with a number that the entity should know, and inherit this class. I did never used Box2D, but if there is a way to do this:
ContactListener::BeginContact( CONTACT* Contact ) {
Entity* EntityA = (Entity*) Contact.UserPointerA();
EntityA->Notify( JUMP );
EntityA->AddChildEntity( (Entity*) Contact.UserPointerB() );
}
I think that there is no problem with this.
You can also create an structure and pass to it:
ContactListener::BeginContact( CONTACT* Contact ) {
FILTERED_EVENT FilteredEvent;
FilteredEvent.CollisionTime = Contact.CollisionTime;
FilteredEvent.CollideWith = Contact.GetUserPointerA();
(Entity*)( Contact.UserPointerB() )->OnEvent( FilteredEvent );
}
This way your entity doesn't know what a contact is.
Also, you're talking about a parent-child entity relationship. Having this kind of thing it is not a bad problem, since you should propagate through the parent child nodes or notify the parent using an child node when something happens with one of them, etc. You can consider creating some kind of "CPhysicsEntity" that is an entity with physics attributes that can have child objects attached to it that are an "CPhysicsEntity" also. This "CPhysicsEntity" just have pointer or pointers to the rigid bodies, and since you're using an existing physics library, it is easy to implement.