Communication between objects

Started by
5 comments, last by Ratman 22 years, 5 months ago
How do you guys handle communication between objects? Like, if Object A and object B collide, and then object C needs to be notified by Object A, whats the best way to do this? I realize this is a very broad question, but Im trying to settle in on a simple but effective design pattern. Ive been reading Game Architecture and Design, and they say dont let tokens directly talk to each other. Thats fine and makes sense. But Im having trouble settling on a way to avoid this. Lets take pong for example. When a Ball objects collides with a Goal-Zone object, the appropriate Score object needs to be notified (ok for something like pong, this is WAY to complicated, but this is just a simple example). Right now what I would do is have a ObjectManager class which has a linked list of every object (paddles, balls, walls, goals, scores, etc) and updates and draws them every frame. I also have a CGame class which does this every frame and checks input and basically handles the game logic. For collision detection I would loop through the link list of objects and see if either one is colliiding with another object, if so I notifty each object of the object it collided with and let it handle itself (for example, if a ball hits a paddle, the ball will ''bounce'' itself). But what if the ball hits the goal zone and we need to update the score object. The two ways I can think of doing it are: -Have the goal zone object notify the CGame class of what happened. The CGame class maintains pointers to the "main objects" (in pong, every object is static. But in a game where objects were constantly being created and destroyed, it obviosuly couldnt have a pointer to all objects, but would to the ''important'' ones that are always there [the player, etc]) and would figure out which Score object needed to be updated. -The goal zone is gonna maintain a pointer to the appropriate score object (CGame would have to initilize this at the begnining of the game). And would update it that way. The first way seems better in the long run, but Im wondering if you guys have any other suggestions. Again for pong is too much but I want to get a good base for future games. Ive written a lot of more complex games, but have never been satisfied with how I handled this. Thanks for any input Ratman --------------- Ratfest.org
Advertisement
I think it''s application-dependent: if the object''s actions affect the entire game environment (or at least more than one other game object) then the CGame object (the manager) should handle the notifications. OTOH, if the object''s actions only affect one other object (in a collision, for example), it might be prudent to allow the objects correspond directly. Of course, since the game at large still needs to be notified of changes to the involved objects due to their interaction (their new directions and velocities for instance).

In other words, the answer (as usual) is it depends.


I wanna work for Microsoft!
A idea that I had was this:

example:
class objectA;
class objectB;

then you have class ObjectMsgs; This would be a one time instance that is global

the objective would be that you pass messages to class ObjectMsgs when things happen anywhere in the game. YOu could create id''s for each message and such.

Then in every object, you would have an update function called whenever you want. This would then access ObjectMsgs and see if it has anything related to it''s self.

I guess this is similiar to windows messaging...It seems effective though...

Pactuul
-Pac "The thing I like about friends in my classes is that they can't access my private members directly." "When listening to some one tell about their problem (whether it's code or not), don't listen to what went right or wrong, but what they assumed....."
I think I know your problem, and I came across it with the RPG engine I was creating. I had several "entities" that needed to interact by triggering each other and sending messages to each other. The way I got around it afterwards was to use a single base object from which ALL other entities are derived, then create another object, a "LinkManager", to handle the links between the entities. It took a while for me to figure out, but all it really is is a linked list of pointers to this base class. The base class has various functions to carry out various operations. So, one function is "DoEvent( int event_id )", this is a pure virtual function, so that all entities created must overload it in some manner. Depending on the value of "event_id" depends on what it does, some entities don''t support some events, and so will return an error and/or not do anything. I also created an entity manager to manage all the linkage and stuff like that, but that was the easy bit. This would be overkill for a simple pong game, but for something that is likely to have a lot of objects that need to interact, I feel it''s a good solution.
If at first you don't succeed, redefine success.
Ok let me ask another question about the ObjectMsgs class. Say I was doing pacman and when pacman eats a power pelet, all the ghosts need to be notified. Now either the power pellet needs to know what object ID all the ghosts are, or I need some way of extracting objects based on certain typ from my ObjectManager. What do you think?

---------------
Ratfest.org
I like the sound of a global ObjectMsgs class because that puts all of the interaction into a single class.

Apart from making everything neater, it make it easier to expand in the future. For example if you want to add network support, the network layer can ''talk'' directly to the ObjectMsgs object and manipulate the game without having to hook into all the object.

I guess it''s kind of like the Document/View architecture in MFC, with the OnUpdate function. When a view needs to be updated, this function gets called with a ''hint'' (a symbolic constant basically) and each view handles the hint in their own way.

I suppose this is like what python was saying where everything derives from a base class. The base class definition can have a virtual function called BulletCollidesWithEnemy, or whatever, and those objects that wish to handle this event do. Those that don''t, don''t.

I get the feeling I''m starting to ramble now so I''ll leave it at that
"Absorb what is useful, reject what is useless, and add what is specifically your own." - Lee Jun Fan
quote:Original post by Ratman
Ok let me ask another question about the ObjectMsgs class. Say I was doing pacman and when pacman eats a power pelet, all the ghosts need to be notified. Now either the power pellet needs to know what object ID all the ghosts are, or I need some way of extracting objects based on certain typ from my ObjectManager. What do you think?

---------------
Ratfest.org

Well, I''d say that you have some sort of Controller object that handles moving the Pacman once it gets notification of the input. It can then do the following:

- Check to see if there''s a power pellet in Pacman''s new location
- If so, notify all ghosts that they now have to be edible

This might seem counterintuitive, and you might think that the Pacman object should be responsible for handling whatever it eats, but I think that delegating much of this to a higher entity helps to make the design cleaner.

The idea here is that:

a) Most of your dependencies are isolated in one class: the Controller class. Therefore your other objects are independent and therefore encapsulated, easily extended, can be added and removed without worrying about referential integrity, and so on;

b) Your links are nearly all one-way, from 1 Controller to many objects. This one-way link helps again with preserving referential integrity (removing an object from the system or adding one only has to happen in one place, with no extra checks needed) and means that you can change the Controller without the other objects really needing to know the details of how they are controlled.

Disadvantages: the controlling class can get large and unwieldy. For Pacman or Pong or something, this is unlikely to be an issue. For something bigger, you will probably want to split the details and delegate them out, so you end up with a class structure like so:
Input   <--\                /--> GhostsNetwork <--- GameController ---> PacmanAI      <--/                \--> Maze 

Thus: the controller class queries the classes on the left for behaviours to take, and performs said behaviours on the objects on the right. The stuff on both left and right needs know nothing about the controller or the stuff on the other side.

Does any of that make sense?

This topic is closed to new replies.

Advertisement