So far, I've been giving each of my in-game objects a step() function, and calling that function each step. In each object's step() function lies the game logic. But what about when I only want to test for collision once. If I test for collision between A and B from A, I don't want to test B and A from B. Instead, I want both of those objects to have access to the same data.
Should I have a World class that has an array of objects, a list of which ones want collision detection, which ones have been tested, and then an array of results?
Should I do something different from using a step() function specific to each object?
Should I have a World class that has an array of objects, a list of which ones want collision detection, which ones have been tested, and then an array of results?
I do something similar to this. Each individual object should not need to know about other objects in the world. Instead, the world should know about all the objects and should do the appropriate collision checks.
how about if each object has a collide(float, float, float, float, float, float) function, which tells them by how much they collide with another object, and the rate at which that object is moving?
I'm not entirely sure what you mean by your step function, but I generally have a DoCollisions() function in my world class which loops through a vector of 'objects' checking for collisions, with the function which checks for a collision and a function which checks whether they need to be checked for collision both in the base 'object' class.
Something like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
void CWorld::DoCollisions()
{
for ( WorldObjectIterator it1 = worldObjects.begin(); it1 != worldObjects.end()-1; ++it1 )
{
for ( WorldObjectIterator it2 = it1 + 1; it2 != worldObjects.end(); ++it2 )
{
if ( it1->CanCollideWith(*it2) )
{
if ( it1->IsCollidingWith(*it2) )
// take action to resolve the collision
}
}
}
}
Does that answer your question?
EDIT - What Disch said is a good point, an object should only know about itself, the world should know about all objects
my step() function is a member of each object, is called each frame by the world object, and contains all logic and rendering for that object. That's why I've been having trouble defining a system that does collision detection outside of the objects.
I need a way to pass information about the collisions to those objects so they can handle the collision (or I need to put the logic outside the object's step() function, and replace step() with draw(), since that's all it would do).
The other thing is: how should I access each object's collision properties? I want some of my objects to have cylindrical collision areas, some spherical, and others rectangular, and then I need to get the dimensions of that collision box.
The step function deals with movements/actions of the object. This is all this function does.
In the main game loop, A collision is when two objects occupy the same space. In loose terms A = B in fuzzy logic. So where you test for collision could be handled in Each object, on an Operator overload of equality, which could be specific to each object.
// this is my base object for everything on my playing field.
Class Object
{
// object's location info
// other information of the object
// movement stuff is in step other control structures.
bool Step(); // the return if the step was successful.
bool CollisionTypeOne();
bool CollisionTypeTwo();
bool SpaceCheck(Object *inObject); // simple thought: do both object occupy the same screen space, what ever is relevent to my game design
}
Class World
{
Object Objects[10];
PlayerObject playerOb;
bool Step(); // manage my things I need
int Collision(int nInIndex); //
}
bool World::Step()
{
int nIndex = 0;
for(nIndex = 0; nIndex < 10; ++nIndex)
{
if(!Objects[nIndex].Step())
{
// why wasn't it successful....
// to me most games would be a test of spaces or location info
// each object defined would be unique to how it might handle the different states
// for example an object would be destroy or it might bounce of another.
int findIndex = Collision[nIndex];
if(!findIndex)
{
// something other than a collision happened.
}
else
{
// I collided with Object[findIndex]
// this is where I would decide what to do with the object.
}
}
}
}
int World::Collision(int nInIndex)
{
// we are scanning the other object to see what we hit.
int nIndex = 0;
for(nIndex = 0; nIndex < 10; ++nIndex)
{
if(Objects[nIndex].SpaceCheck(&Objects[nInIndex])
{
return nIndex; // we collided with this object.....
}
}
}
I hope this give you some idea how the game flow might work for what you are doing, it doesn't matter if its text, 2d, or 3d. The basic logic is the same.
The Other thoughts are make ever object do their, then scan to see if two object have the same locations.