Archived

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

Game Data/Object Interaction...

This topic is 5377 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been programming lots of little simple demos in the past year and a half and other useless stuff with DirectDraw/Direct3D/OpenGL. I have created a few games and have come to a sort of barrier...AI and behavior that requires an object to know information about others constantly. The big question is how do you make it so that a game object (projectile/sprite) always knows the "world" it''s in and where things are without polling the game for it every frame or having the game tell it everything? One issue I have came up when I was trying to think of implementing homing missiles in a simple 2d game I am working on. I am not working on it right now but I was thinking that though the target''s(a sprite) the targets location is private, you could pass a pointer to the x and y location(the private member variables) and then have the missile have pointers to both pieces of data meaning that when it is updated, it is for the missile to and every frame it can change without any extra processing of the change in the missile. I was just wondering if this was possible(syntactically and philosphically), and is this what is done in real games? The same kind of information would apply if you want to have an AI sprite in a game. It would ideally need to know the position of every object in the gameworld every frame and process who to go after and where to move. I''m sure it would be stupid to have it poll and ask for every object''s location in the world everyframe so I would assume it should have direct access to the game world''s data structure and it can find out where everything is easily. On a similar topic, suppose something like a sprite fires at something else and you want to count the kill towards some player. Does the bullet have an associated ID of who shot it so the game informs the shooter of another kill? Does the bullet get associated/encapsulated within the sprite object so the sprite know''s when it got the kill? How do you do this kind of thing in your games?

Share this post


Link to post
Share on other sites
Any links to articles regarding this issue are very welcome. In fact, even if someone posts one - please post others. I''m willing to spend hours reading on how I should do this and keep my code clean and efficient.

Share this post


Link to post
Share on other sites
In fact, I have the same problem right now. I just can''t figure out how to share data between entities and the rest of the game world and UI efficiently. Any answers to the original poster would be welcome. I don''t feel like passing loads of arguments into every function I call can solve the problem, neither I want to go with globals.

Share this post


Link to post
Share on other sites
quote:
Original post by EbonySeraph
I am not working on it right now but I was thinking that though the target's(a sprite) the targets location is private, you could pass a pointer to the x and y location(the private member variables) and then have the missile have pointers to both pieces of data meaning that when it is updated, it is for the missile to and every frame it can change without any extra processing of the change in the missile.


I think this kind of problems can be solved, by making one object to contain POINTERS to other objects.

For example missile can have a pointer to its target:

class Thing
{
public:
int getX()
{
return x;
}
int getY()
{
return y;
}
private:
int x;
int y;
};
//
//
class Missile : public Thing
{
public:
void setTarget(Thing *t)
{
target = t;
}
void update()
{
moveTowards(target.getX(), target.getY());
}
private:
Thing *target;
};

If you do it the OOP way, you also need to add PUBLIC ACCESSOR METHODS to make the private variables available to other object

[edited by - Advanced Bug on March 26, 2003 4:31:24 AM]

Share this post


Link to post
Share on other sites
If you use pointers you have to be very careful when deleting objects (e.g. that have been destroyed), you'll either need to make the object enter a 'zombie' state until all objects that refer to it have had a chance to remove their pointers, or use an ID system which means the object has to lookup the pointer to the object, or use some sort of 'reference' system where objects hold a list of the objects that reference them and can loop through when changes (e.g. deletion) take place.

quote:

On a similar topic, suppose something like a sprite fires at something else and you want to count the kill towards some player. Does the bullet have an associated ID of who shot it so the game informs the shooter of another kill? Does the bullet get associated/encapsulated within the sprite object so the sprite know's when it got the kill?



It makes sense to store the 'owner' id of every projectile, e.g. in my current game I have (heavily simplified):

class Projectile
{
EntityID owner;
EType type;
Vector3 vel;
...
etc.
};

EntityID is just a unique id for every entity (I've got projectiles as separate from the entity system to avoid them taking part in queries). I actually store the entities in a std::map keyed off the ID, that way I can delete objects without worrying about invalid pointers at the slight expense of an extra lookup everytime. I've yet to decide whether this is the 'best' system for what I want but it works fine.

quote:

The same kind of information would apply if you want to have an AI sprite in a game. It would ideally need to know the position ... >>>snip<<<



Similar principle to above really. I'm also using a set of queries (Level encapsulates the currently running game state):

class Level
{
public:

std::vector<Entity*> QueryEntitiesInBox(Vector3& bmin,Vector3& bmax, int filtermask );

private:
std::map<EntityID,Entity*> entities;
};

The Level stores the game state in a hierarchical manner (in fact a quadtree) which makes the box query very fast for fairly small boxes. There are a bunch of Query... methods which return a list of entities within various volumes, point containment and line traces. filtermask just allows me to filter out certain categories of entities. Obviously this is for a 3D game but the ideas map pretty straightforwardly to sprite based systems.


[edited by - JuNC on March 26, 2003 5:00:54 AM]

[edited by - JuNC on March 26, 2003 5:01:34 AM]

Share this post


Link to post
Share on other sites
JuNC is right, you can consider my code example only as the most simple way to solve this problem, not the way it should be solved in real programs.

[edited by - Advanced Bug on March 26, 2003 6:01:14 AM]

Share this post


Link to post
Share on other sites
I''m still not too sure about what all of the ideas that you guys posted mean.

Starting from the top. The missile/target example. If I wasn''t mistaken it looks as if the projectile type inherits members from the target''s class. Why would you do this? Wouldn''t it(Missile class) now hold two private members (int y, int x) that it doesn''t even use? Basically the missile doesn''t have an "is-a" relationship to it''s target to why inherit it?

The second reply(with an actual idea) I''m even more confused/not understating exactly. I get the Projectile class definition above what what exactly the members mean and should be used for. But the Level class. I''m not sure if I have this right...but calling QueryEntitiesInBox seems to be a function that you call with two corners of a RECT(?) and it will return all entities in the level, in that box? Next question is, when you talk of a single entity - what does that mean? Is an entity a projectile? Or is it an instance of a projectile? So far is seems like the latter, and the type is represented by Etype. Am I right?

Share this post


Link to post
Share on other sites
quote:
Original post by EbonySeraph
Wouldn''t it(Missile class) now hold two private members (int y, int x) that it doesn''t even use?


Yes, the Missile-Thing inheritance is NOT REQUIRED for this example.

On the other hand, now missile can be a target for another missile.


Share this post


Link to post
Share on other sites
The problem with storing pointers is the issue with saving and loading games. Maybe storing an index into a global entities'' vector is a better idea? Anyhow I''d still have to pass the pointer to the vector to any entity member functions using data from other entities.

Share this post


Link to post
Share on other sites
quote:

The second reply(with an actual idea) I'm even more confused/not understating exactly.



Sorry it was a brain dump so probably made little sense hehe.

In my system an entity is pretty much anything except projectiles. My game has two main types of visible entities, Buildings and Vehicles and various types of invisible entities like triggers and spawn points (a spawn point is just somewhere that can produce new entities during the level). At level load time the starting entities are constructed from the level file.

Each game tick (ie once through the game loop) a method is called on Level (called unsurprisingly Level::DoUpdate() ) which advances the state of all the entities.

quote:

But the Level class. I'm not sure if I have this right...but calling QueryEntitiesInBox seems to be a function that you call with two corners of a RECT(?) and it will return all entities in the level, in that box?



Exactly. The method performs a query on all of the entities currently in the level. bmin and bmax are the corners of a (3D) axis-aligned-box so they could be a RECT or whatever in 2D. There are other query methods too:

QueryEntitiesInSphere(Vector3& centre,float radius, int filtermask);
QueryEntitiesInCircle(Vector2& centre,float radius, int filtermask);
QueryEntitiesLineTrace(Vector3& start,Vector3& end, int filtermask);

Entities use these functions when doing collision detection and AI to obtain other nearby entities.

quote:

Next question is, when you talk of a single entity - what does that mean? Is an entity a projectile? Or is it an instance of a projectile? So far is seems like the latter, and the type is represented by Etype.



OK, in my particular system projectiles are not entities, however they could quite easily be considered so, it's just that for my particular purposes it is more efficient this way round:


class Entity
{
enum ECategory
{
CAT_VEHICLE,
CAT_BUILDING,
CAT_TRIGGER,
}

ECategory category;

Vector3 pos;
Vector3 vel;
int health;
...
etc.
};


The actual behaviour of an entity is described in separate EntityType classes but it could just as well be done by more fine-grained entity categories (e.g. CAT_PLAYERVEHICLE, CAT_DRONEVEHICLE etc.).


class Projectile
{
enum EType
{
TYPE_AP, // Armour piercing
TYPE_PULSE_CANNON, // projectiles from the pulse cannon
TYPE_MININUKE,
};

EntityID owner;
EType type;
Vector3 vel;
...
etc.
};


It's probably just as confusing now

quote:

The problem with storing pointers is the issue with saving and loading games. Maybe storing an index into a global entities' vector is a better idea? Anyhow I'd still have to pass the pointer to the vector to any entity member functions using data from other entities.



That's a good point too and depends heavily on where-abouts you can save and what state is actually saved. For instance my game doesn't allow saving in-mission so it isn't an issue. Even if it did the EntityID's allow direct reconstruction of the entity structure. The method of Level which adds entities to the level looks like:

Entity* SpawnEntity(const char* type,EntityID id,const Table& params);

The id passed in is obtained via another Level method:

EntityID AssignID();

But it would be possible to allow Level to directly use id's from a savegame file to Spawn the current set of entities.

[edited by - JuNC on March 26, 2003 6:53:00 AM]

[edited by - JuNC on March 26, 2003 6:56:59 AM]

Share this post


Link to post
Share on other sites