Best design practice for accessing objects in another class?

I am working on a video game that is based on a tutorial I found online and I ran into an issue associated with accessing an object's method inside another class object's function without making the object global which seems bad.

Here is basically how the tutorial set things up in the game:
The game has a base class called GameObject then there are other child classes that inherit from this class. The GameObject class has all the basic information an object would have that needs rendered on the screen (x/y position, size of bitmap, bitmap, whether or not it is collidable, etc).

One of the child classes SpaceShip, which is the player so it has attributes and methods associated with managing # of lives and points scored.

There are other child classes of GameObjects in the game that need to take life and add points from the SpaceShip object if they collide with the spaceship or other objects.

In the collision handling routine I basically call a function "void Collided(int objectID)" when a game object collides with another. Within the Collided() routine, there is logic that executes code or other functions based on the objectID it collided with. Some of the collisions require taking life from the spaceship or adding points. The way this was accomplished in the tutorial was with function pointers (see Bullet class constructor and collided method for example). Is this really the best way to handle this sort of thing? It seems like there has to be a simpler way than to keep referencing function pointers in any new class I want to add to the game. I realized this when I went to add a method for the spaceship to fire bullets rather than inside my game class.

My Project Source found here:
https://www.dropbox.com/sh/zxoa1icyzjj6e0t/AAAZlXfFier09uG5gcQdCK8ba?dl=0
The GameObject class has all the basic information an object would have that needs rendered on the screen
That's kind of lousy, since a game object might not have any graphical sense, or it might translate to several on-screen objects.

The way this was accomplished in the tutorial was with function pointers (see Bullet class constructor and collided method for example). Is this really the best way to handle this sort of thing?
Function pointers being used in a OOP context is highly suspect. From what I see there, objectID actually holds a type ID that's used to decide when happens when the bullet hits; another red flag.
The canonical OOP way to do this would be
1
2
3
4
5
6
7
8
9
10
11
class GameObject{
    //...
	virtual void HitBy(Bullet &) = 0;
	//...
};

//...

void Bullet::Hits(GameObject &obj){
    obj.HitBy(*this);
}
Now the logic of what to do when a bullet hits is where it belongs.
To prevent friendly fire, a "faction" member should be added to GameObject, and Bullet::Hits() should be updated like so:
1
2
3
4
5
void Bullet::Hits(GameObject &obj){
    if (obj.faction == this->faction)
        return; //no friendly fire
    obj.HitBy(*this);
}
helios - thanks for the response

What exactly is kind of lousy regarding the GameObject class?

For the HitBy/Hits function architecture, point taken. I was thinking something like you suggested but this is my first game I'm trying implement and want to make sure I don't learn too many bad behaviors that will end up in other games.

Could you please explain a little more regarding using the objectID as logic to drive behavior being a red flag? i have this in other areas of my code and find it useful but if there is something I should be doing differently I would be grateful for the advice. Here is an example where I use the objectID to drive behavior in the game:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//clean up dead objects (frees up memory for new objects!)
//==========================
for(iter = objects.begin(); iter != objects.end();)
{
	if(! (*iter)->GetAlive())
	{
		if((*iter)->GetID() == BOSS)
		{
			//flag end of level if BOSS is dead
			lvl->SetStatus(END_STAGE);
		}
			
		delete (*iter);
		iter = objects.erase(iter);

	}
	else
	{
		iter++;
	}
}
What exactly is kind of lousy regarding the GameObject class?
I explained what is lousy about that in the sentence following that one.

Could you please explain a little more regarding using the objectID as logic to drive behavior being a red flag?
In OOP code, you should almost never have to write
1
2
3
4
5
if (object is of type A)
   foo();
else if (object is of type B)
   bar();
//etc. 
That's what polymorphism is for.
thanks again.
I switched things up in the code to pass objects rather than IDs as you suggested above and still run into the same problem of accessing the player's life/points for a few different scenarios where 2 things collide that aren't the player:

1. When a comet gets hit by a bullet, the player SpaceShip object scores a point. What is a better way besides function pointers to add a point to the player object?

2. When a comet hits the boarder of the screen, the player loses a life.

thoughts?
1. Then the bullet should know who fired it.
1
2
3
void Comet::HitBy(Bullet &bullet){
    bullet.GetOwner().IncreaseScore();
}


2. Same thing, but in Border::HitBy(), and should call GetOwner().Die().
Topic archived. No new replies allowed.