Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Lets say I have a key and door. My third class (player) needs to pick up a key and open the doors. How should those objects communicate without making too much dependencies between them?

share|improve this question
    
what exactly do you mean by dependencies? You should be able to easily create an inventory system for the player (list that stores objects that extend an item interface) for holding objects like a key. As for a door, you will need someway to tell how far the player is from the door and then check the inventory for the proper key object that can open it. –  Benjamin Danger Johnson May 9 '13 at 23:21
    
I mean class dependencies. Like that it's not good when object(A) knows too much about the object(B). –  Tom May 9 '13 at 23:25
    
Well they are always going to have to know something about each other. For example when your player hits the action button while facing a door there needs to be someway to identify it can be used (even if it's just implementing an interface) the door will also need a way to check and see if the person using it has a key. So there really is no way to separate them completely. –  Benjamin Danger Johnson May 9 '13 at 23:34
add comment

2 Answers 2

up vote 6 down vote accepted

Precise answer usually (or always?) depends on the specific situation and circumstances but I think it's a good idea to try to model the real-world relations between objects.

Like in your example - the human is the only entity that actually does something (takes action). So probably this class should call key and door's methods. Key doesn't have to know or do anything. It only has to have some kind of ID (to check if that's the right one). The door has to know what key fits into its lock (have the key's ID). Nothing else. Well, it can also have some kind of Open() method (to allow player to pass through it, but that's a different thing, actually). The human takes the actions (take/produce a key, put it in the door's lock and try to open the door).

Modeling the real-world relations between objects is good... because it's proven to work! It works in real-life so it should work in your application, too (provided it's not too complex/impossible to implement).

Also, as always, try to keep things as simple as possible and use common sense - if your app or the situation your trying to implement is small/simple - it's sometimes just better to do it the easiest way you can think of without overthinking and overdesigning objects' relationships - because there's no point in it.

share|improve this answer
    
Would it be right to directly call those methods in user interface class? –  Tom May 10 '13 at 0:18
    
What user interface class? –  NPS May 10 '13 at 0:20
    
I have a class where I check what button player clicked, what keyboard or mouse button pressed. So would it be right to directly call entity methods from user interface class or I should have some kind of controller class for controlling user interaction with game logic? –  Tom May 10 '13 at 0:30
3  
-1 for "Modeling the real-world relations between objects is good" yikes. –  Sean Middleditch May 10 '13 at 7:24
1  
It's just very, very rarely even close to good advice. It might work sometimes, this being an example of it being okay, but usually the way good OOP design interacts and how real-life objects interact are quite dissimilar. Much of the bad code I've dealt with over the years is from junior developers trying to model objects in a computer program after their physical counterparts; think about data and logic flow, not how real-life works. If they come out being similar, cool coincidence. –  Sean Middleditch May 10 '13 at 17:08
show 2 more comments

The simplest way to enforce a relationship without strong coupling is to use a Mediator. There could be an Unlocker system that keeps track of the player's keys and listens to collision messages between the player and doors. By moving this dependent logic upwards, you keep the player, the key, and the door decoupled.

Here's some C# code to illustrate. If you need clarification just leave a comment.

class Unlocker
{
    public OnCollision(Entity a, Entity b)
    {
        TestCollision(a, b);
        TestCollision(b, a);
    }

    private void TestCollision(Entity a, Entity b)
    {
        if(a is Player)
        {
            if(b is Key)
            {
                b.Destroy();
                _keys++;
            }

            if(b is Door && _keys > 0)
            {
                b.Destroy();
                _keys--;
            }
        }
    }

    private int _keys;
}

In this example, OnCollision is registered to the collision system, which activates it (and the other collision handlers) when two entities collide.

As you can see, this simple Unlocker class added a new set of behaviors dependent on the player, keys, and doors without creating any coupling between the entities themselves. This is especially important for object models like composition where entities are not able to implement their own behaviors.

share|improve this answer
1  
I would probably rework this function, that OnCollision call at the end going to get called every time leading to a stack overflow. –  UnderscoreZero May 10 '13 at 16:33
    
You're right. I completely overlooked that. –  Boreal May 10 '13 at 19:01
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.