Basic Game Object Communication

Started by
8 comments, last by lucky6969b 7 years, 9 months ago

D3DXVECTOR3 vpos = FindPosition(warehouse, Convert_Truck_ID_To_Name(this->m_truck_id));

The line is contained in the class called Truck,

It needs to retrieve where it's going to park in the warehouse.

In this case, The FindPosition requires a warehouse pointer/handle to

know where to start to look.

I've several options here.

1) Store a global pointer of the warehouse, so I can access it anywhere

2) Use a Singleton to do the similar stuff

3) Store a local pointer, so a warehouse is always passed into the truck object (Not quite modular in this case)

4) Make use of the state machine, and let the state machine store a vector/map of game objects pointers, so it starts to look up from there inside. And I just send a message to the Truck State Machine, the truck state machine fills up the warehouse information and Just put the FindPosition inside the state machine. And it will handle the rest

Should I use option 4? it seems to be the preferred way to go? Not sure, so want to ask your opinion?

Advertisement

3 - KISS

The question is - when does that value change?

The idea that you could use a global or singleton implies that it doesn't change at all, or maybe just at the start of the level, or something like that. In which case, passing it in to be stored as a member of the Truck is reasonable. (Option 3.)

However, the fact that you mention option 4 at all implies that there's something else going on, which you've not fully explained.

What I would bear in mind is that this situation can't be reduced down to a "basic game object communication" - different types of object require different approaches, based on their scope, lifetime, mutability, etc.

3) Store a local pointer, so a warehouse is always passed into the truck object (Not quite modular in this case)

It's just as modular as your options 1 and 2, and except Truck's dependency on warehouse is called out explicitly instead of hidden (which is a good thing).

Or, move the "I need to find a parking spot for this truck in this warehouse" logic into a different piece of code that knows about both Truck and warehouse. It may not really belong in truck anyway. Do other vehicles need to find parking in a warehouse? Or parking in other structures? We don't really know how complex your game is.

4) Make use of the state machine,

Not sure what a state machine has to do with any of this, or why it would be responsible to find the warehouse and a parking spot in it.

Isn't this something that should be handled by your AI/path planning system? I would just place goal points (just a transform) within the warehouse and then assign the goals to the relevant truck(s) at load time and let the A* handle the rest. If you have some kind of AICharacterController for the trucks, it can just be passed one or more goal points that it could go to depending on the current game state. I doubt you want to hard-code the concept of a "warehouse", a warehouse is just a 3D geometry with other semantic data that are used by game objects to perform tasks like going to the correct spot in the warehouse.

Reading it over a few times, especially with the comments about the state machines, I think the question you are trying to ask is:

I've got a game object with it's ID, a truck. And I've got another game object called a warehouse. I want to create an interaction that lets the truck figure out a parking spot in a warehouse. I want to figure out where the truck is supposed to park in the warehouse.

Is that a good restatement?

For your options:

Option 1, a global pointer, does not work well in the general case. Global anything is generally a bad idea in games.

Option 2, a Singleton, is even worse in the general case.

Option 3, a local pointer, is probably close to what you want.

Option 4, "make use of the state machine", gives more information that makes it more clear what you are trying to do.

Based on what I anticipate about your questions, I imagine this:

Have a component or interface, perhaps called IParkingLocation or ParkingLocationComponent

Have your warehouse use that component/interface.

Now in your interaction to park your truck, you can get that interface. Depending on implementation maybe:

ParkingLocationComponent parkingLocation = warehouse->GetComponent( typeid(ParkingLocationComponent) );

or

IParkingLocation parkingLocation = dynamic_cast<IParkingLocation*>(warehouse);

Then you can use a function you build in your interface or component:

position = OutOfWorld;

if( parkingLocation ) {

position = parkingLocation->FindNearestParkingLocation( truck );

}

Your ParkingLocation component or type could have some extra functions to mark the spot as reserved (and also to un-reserve spots), or maybe other functionality as well.

The variables could all be part of your interaction, which seems to be a state machine in your description.

Thanks, buddies, It's all good.

But one thing to mention is, if the truck depends on many other stuff in my game.

Do I have a long parameter list to deal with? It's not the problem of the amount of typing.

The problem is if I extend the number of dependencies in the future, then would that become unmanagable?

Maybe I am wrong, please correct me if I am.

like this.

Truck::Truck(Warehouse* warehouse, Good* goods...)

If I understand you guys' concepts correctly

do it like that?

Truck::Truck(const std::vector<GameObject*>& depends....)

The first one is better, since it's more clear what the dependencies are. If you just stick them in an array, how are you going to know which game object is which?

But... I think you need to rethink what a Truck is. Again, we don't know all the scenarios your game needs to support, but it smells like you're putting way too much functionality into the Truck class.

If like phil_t said, completely decoupled?

Maybe just like phil_t said,
 
[code]
D3DXVECTOR3 FindParkingSpot(const std::shared_ptr<GameObject>& pParkingPlace)
{
    D3DMATRIX matPark = pParkPlace->FindFrame("ParkingPlace")->matCombined;
    return D3DXVECTOR3(matPark._41, matPark._42, matPark._43);
}
 
void Parking(const std::shared_ptr<GameObject>& pParkingPlace, const std::shared_ptr<GameObject>& pParkingVehicle)
{
     D3DXVECTOR3 vParkSpot = FindParkingSpot(pParkingPlace);
     pParkingVehcle->setPosition(vParkSpot);
}

Sorry, a couple of typos....

D3DXVECTOR3 FindParkingSpot(const std::shared_ptr<GameObject>& pParkingPlace)
{
    D3DMATRIX matPark = pParkingPlace->FindFrame("ParkingPlace")->matCombined;
    return D3DXVECTOR3(matPark._41, matPark._42, matPark._43);
}
 
void Parking(const std::shared_ptr<GameObject>& pParkingPlace, const std::shared_ptr<GameObject>& pParkingVehicle) const
{
     D3DXVECTOR3 vParkSpot = FindParkingSpot(pParkingPlace);
     pParkingVehcle->setPosition(vParkSpot);
}

This topic is closed to new replies.

Advertisement