Sign in to follow this  
Maxamor

Object vs World and Object vs Object: How have you solved this?

Recommended Posts

Maxamor    361
I’m aware that this topic has been discussed over and over again but I’m still hitting a wall when it comes to implementing it myself. First, background on what my project is. “Simple” 2d (tile-based) platform/action Mario game. To be more specific a complete Megaman (NES) game rip-off. Horizontal running, jumping, shooting, sliding, etc. The problem I’m having is with correct decoupling between the game objects and the world in which they exist. How should my hero ask the world if and where he is colliding? Should he keep a pointer or reference to the map he’s on? Should that just be passed in to the collision function or at the construction of the object? How should objects ask the world if they are colliding with each other? I know that probably a good answer to this is a messaging system. And even with that said, how have you guys don this in your games? I’m more confused by the concept than the code. If I can understand the concept of how these interactions typically take place—I can code it. Any help is appreciated! Edit: With regard to a message-passing system or "events" system, where does the message pump live in your design? is it at the engine level? Is it within each state of the game? Is it a *gasp* singleton?

Share this post


Link to post
Share on other sites
Telastyn    3777
Quote:
Original post by Maxamor
How should my hero ask the world if and where he is colliding?


He doesn't.

Quote:

Should he keep a pointer or reference to the map he’s on?


Maybe, but probably not.

Quote:

How should objects ask the world if they are colliding with each other?


They don't. At worst, the world tells its children (the objects) if they collide.


You don't necessarily need an event or messaging system to keep things de-coupled. Just keep a good hierarchal design. An object doesn't know about other objects or its container, but the container knows and can act upon its contents.

Sorry if that's not very clear. I shall try to post more later if it doesn't help.

Share this post


Link to post
Share on other sites
Barius    325
Quote:
Original post by Telastyn
You don't necessarily need an event or messaging system to keep things de-coupled. Just keep a good hierarchal design. An object doesn't know about other objects or its container, but the container knows and can act upon its contents.


Yes, a message system is probably overkill. But I think a strict hierarchy is too restrictive. Not every object in a container is 'interested' in the same things, but the container can't know that. For example, a flying monster does not need to be informed every tick that it's not standing on solid ground, but a ground-based monster does (so it can start falling). If you follow the strict hierarchy, you'll end up with a "void stuffHappened(GiantDataPacket)"-method, or a dozen methods called unneededly every tick.

The contained object should not be able to "mess up" the container. But if access to the container is restricted to a narrow interface (abstract base class) that just contains the methods the game object needs to use, this is not possible (unless you cast it down, but then it's "Your Own Damn Fault".

Still, certain things *should* sometimes be enforced by the container, for example that objects can't go outside the map.


Share this post


Link to post
Share on other sites
Maxamor    361
Thank you both for your replies. I totally understand what you are saying. I think my problem is that I am trying to design objects that know nothing about each other but have to work together--it's where I put the glue that I struggle with.

I agree that a message system is overkill. At least, I feel that it is for this scale of a project.

Share this post


Link to post
Share on other sites
Telastyn    3777
And even a ground based monster only needs to know if it's not standing on solid ground when it moves. And in that method, you already know if you're moving a flying or non-flying monster.... But yes, situations like that are where event and/or message systems or even some fudging of the rules is good. You don't need such systems, and I think they're becoming over used/recommended. They are however options; good options at that.

As for Maxamor's 'glue': Generally, if you have two objects that need to work together, but need not know about one another, you make a class 'above' them. Just because two things can't know about each other doesn't mean you can't have something else that knows of both.

Share this post


Link to post
Share on other sites
umbrae    308
My first impression is that each item in the world implements an interface or is a subclass of a common interface for performing collisions. The 'collision space' has a reference to all these objects so it can tell them when they collided.

Or each object in the world has a 'physics' object that represents what they are in the world. This object interacts with the 'collision space' like above but it tells the owning object what happens.

By de-coupling the physics object from the actual behaviour we don't have to tie the interaction code to the physics system, so we can test these interactions independently by pretending to be it's physics object and calling the right methods.

Anyway, that's my 5 minutes.

Share this post


Link to post
Share on other sites
coaster    122
I've had some success by including a separate physics object in each game entity. I also used a separate object to provide a graphical representation and reduced the game entity object to a simple connection between the two.

Share this post


Link to post
Share on other sites
bzroom    647
In my engine, the collision function determines all possible collisions between objects. Then for each potential collision, a collision callback is called on both colliding objects providing the collision location, velocity, and the other body's reference. Either of the objects can choose to reject the collision, remain passive, or fully collide (this is returned to the collision function via an enumeration).

Internally, each object can choose to handle the collision as necessary, updating sound, animation, etc. For instance, the character class receives collisions from a ray cast into the terrain, this collision is ignored, but internally the character updates the current height. If any other object collides with the character, the force is evaluated. If the force is great enough the character enters ragdoll mode. Regardless of the force size, a collision with a general object will result in a full collision (either between the character's upright capsule or the ragdoll).

Share this post


Link to post
Share on other sites
catch    192
You can either be really complex with this, or really simple.

I had a 2d shooter game where the only thing in the world was the stuff on screen (other than being offscreen momentarily upon creation). So I basically just collided the entire screen against all objects. Speed wasn't an issue, and there were often only 10 or 15 things on the screen at any given time.

I used 2 layers for collision. The player layer, and the enemy layer. The player layer included the player unit itself, along with its bullets and what not. Same thing for the enemy layer.

Basically, i'd just check the layers against each other, per frame, and flag if a collision occurred or not to the object, and upon update, the object would take the collision into account.

This method doesn't scale very well... if I wanted to add like 10 more types of objects for collision, it might get hairy. Though, it's likely for how simply my game was I'd only need maybe 1 or 2 more layers.

At the end of the day though, the real performance boundaries are the number of objects you have to collide per frame.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this