Archived

This topic is now archived and is closed to further replies.

rileyriley

Specifying interactions between objects

Recommended Posts

Discuss! I''m planning how I''ll make my next game, and for this one I want to really nail handling interactions between objects that are not obviously related. For example, picture a Wall object, a CannonBall object, and a MagicCannonBall object floating around in space. I want a response system that will: 1: allow me to specify that the cannonball goes through the wall if it hits it at more than 100 mph but bounces off at less than that 2: allow me to specify that the cannonball itself explodes and demolishes the wall if it hits the wall at more than 200 mph 3: allow me to specify that the magic cannon ball not only instantly destroy the wall as soon as it touches it, but instantly destroys the wall as soon as it is within 10 yards of it. Of course my game has nothing to do with cannonballs - the general problem is that I need a mechanism to specify several different behaviors that should happen when one object triggers another (or when two objects trigger eachother). In previous games, I''ve resorted to simple enumerations of all the types of objects that could hit one another, and given the responsibility of reacting to the collision to the object that was hit. That sort of sucked in a lot of ways - the biggest problem was that I couldn''t easily add new kinds of objects to the environment and expect good things to happen. So before I start my next game I''m trying to think of a really good way to solve this problem. I have a couple of ideas so far - please tell me what you think of them, and if you have any of your own! 1: have a master "Reactor" that is responsible for knowing how everything should interact. This still means enumerating the different permutations of object interactions and writing code for each case, but at least the enumeration would be centralized. 2: have a list of "attributes" that every object has that things that have been hit (defenders) can check to determine how they should react to the things that hit them (attackers). This is again enumeration, but over a hopefully smaller set of permutations. 3: a mix of #1 and #2 - a giant table of attributes that the reactor can check and use to look up a reaction. Now, I don''t really like the idea of a master Reactor. It seems to me that objects should be responsible for their own reactions. On the other hand, if objects are responsible for their own reactions, they have to know about the other types of objects which could be in the environment. This is why I (so far) prefer the attribute list - it seems much more reasonable for objects to have an idea about the basic properties that make up all things than for them to have an idea about all things, if you see what I''m saying. So. Discuss! Thanks

Share this post


Link to post
Share on other sites
quote:
Original post by DaTroof
First of all, what language are you using? In an object-oriented language like C++, you can use inheritance to eliminate switches based on enumerations.


I am thinking in general in an object-oriented language (C++ to be specific). But inheritance is not an adequate solution for the problem. Take for example the following structure:


//main physics loop:

for (each pair of objects o and p in the environment)
{
if (areTouching(o, p))
{
o.collide(p); //this is where inheritance

p.collide(o); //is helpful and good

}
}

//the object definitions


class Object
{
virtual void collide(Object *) = 0;
};

class CannonBall : public Object
{
void collide(Object *)
{
//here, if I want to react differently to different kinds of

//Objects, I need to enumerate each different kind of reaction.

//inheritance can't help me here!

}
};

class MagicCannonBall : public Object //or maybe Cannonball, whatever, irrelevant

{
void collide(Object *)
{ /* etc */ }
};

class Wall : public Object
{
//etc

}


So this is where I keep getting stuck.

[edited by - rileyriley on October 6, 2003 8:39:52 PM]

Share this post


Link to post
Share on other sites
In your example, the Collide function makes no differentiation whether it''s the object causing the collision or the object being struck. It might help to check for a collision when an object moves, and if a collision occurred, call the Strike function for the moving object and the StruckBy function for the object being struck. Then you could override the Strike function for the different types of cannonballs.


// main physics loop:

for (each Object o) {
o.move();
}

// class definitions:

class Object {
move() {
// Move the object

for (each object o)
if (collision with o) {
strike(o);
o.struckby(this);
}
}
virtual strike(Object *);
struckby(Object *);
};

class CannonBall : public Object {
strike(Object *) {
// Normal cannonball damage

}
}

class MagicCannonBall : public Object {
strike(Object *) {
// Magic cannonball damage

}
}


Checking for collisions in the move() function might also increase performance, since you''re not wasting time checking collisions between immobile objects.

Share this post


Link to post
Share on other sites
I don''t make a distinction between the kinds of collision because in the general case it is impossible to make. When a flying magic cannon ball hits a flying normal cannon ball, which strike and which struckBy function gets called? In your scenario it would just depend on which one happened to be updated in the game loop first - and then what if the two objects disagree about what should happen? Obviously my algorithm has similar problems but I think they are slightly less severe.

My goal in this post is to find the most generic solution I can - there may not BE a more generic solution, but I''m looking for it anyway

PS - thanks for the optimizing advice, but in this thread I''m leaving stuff like that out to focus on the problem of choosing a reaction.

Share this post


Link to post
Share on other sites
quote:
Original post by rileyriley
I don''t make a distinction between the kinds of collision because in the general case it is impossible to make. When a flying magic cannon ball hits a flying normal cannon ball, which strike and which struckBy function gets called? In your scenario it would just depend on which one happened to be updated in the game loop first - and then what if the two objects disagree about what should happen? Obviously my algorithm has similar problems but I think they are slightly less severe.

My goal in this post is to find the most generic solution I can - there may not BE a more generic solution, but I''m looking for it anyway

PS - thanks for the optimizing advice, but in this thread I''m leaving stuff like that out to focus on the problem of choosing a reaction.


Good points. There''s probably no way to make the solution more generic using the methods I described. I think I''m using a hammer to turn a screw.

Another route would be to build a two-dimensional array of function pointers, and let the collide function call the appropriate function from the array based on what two types of objects are colliding. Seems like that would be easier to manage than a massive switch statement, and it might even be more efficient, but I''m just tossing pure conjecture at this point.

Share this post


Link to post
Share on other sites