• Keeping track of game objects? [XNA]
    20 replies, posted
Most game objects have a position, although some don't. Most game objects draw to the screen, although some don't. It's convenient to loop through a bunch of game objects in a list that sits in your Game.cs class, for easy updating and drawing. You may need to have a game object create other game objects, like a spaceship firing lasers. Here's a base class that could TRY to do the above. [csharp] abstract class GameObject { private Dictionary<string, object> vars = new Dictionary<string,object>(); public object Get(string name) { return vars[name]; } public void Set(string name, object value) { if (vars.ContainsKey(name)) { vars[name] = value; return; } vars.Add(name, value); } public int ID; public abstract void Initialize(); public abstract void Update(KeyboardState state); public abstract void Draw(SpriteBatch sb); }[/csharp] The problem with this is it feels too bloaty and I get the impression that the use of a Dictionary would slow things down. Not only that, but having one game object access another would be silly and more complicated than it needs to be. ...I feel like there's some keyword that I haven't heard of yet that I can use to make all this shit come together like magic.
[QUOTE=Rocket;32690656]I don't get it...what's the problem with the usual way of doing it?[/QUOTE] What's the "usual way"?
[QUOTE=Rocket;32690774][csharp] class SpaceShip { List<Bullet> bullets; public SpaceShip() { bullets = new List<Bullet>(); } } class Bullet { //Whatever } [/csharp] You just make a class for every object that has unique properties.[/QUOTE] And if the bullets hit an enemy?
How I do it is I make all my game objects extend Entity and then on spawn they're added to a central list, so they can despawn themselves.
[QUOTE=Yogurt;32691187]How I do it is I make all my game objects extend Entity and then on spawn they're added to a central list, so they can despawn themselves.[/QUOTE] How do you define Entity so that you can have variables declared, some that won't fit it applied to another gameobject? Because if Bullet tried to access the list, he'd get a bunch of Entity, not Enemy. And Entity doesn't have a definition for "int TypeOfEnemy" or something.
I used reflection magic.
I don't see how that would require Reflection. [code]public class Entity { public Vector2 pos; } public class Enemy : Entity { public string enemyType; } List<Entity> entList = new List<Entity>(); entList.Add( new Entity() ); entList.Add( new Enemy() ); foreach( Entity e in entList ) { if( e.GetType() == typeof(Enemy) ) { Enemy enemy = (Enemy)e; System.Diagnostics.Debug.WriteLine("Enemy Type: "+enemy.enemyType); } }[/code]
Ah, right, I didn't have it on me at the time. That's how I did it.
[QUOTE=a203xi;32691432]I don't see how that would require Reflection. [code]...[/code][/QUOTE] [quote]if( e.GetType() == typeof(Enemy)) { Enemy enemy = (Enemy)e;[/quote] And I refer to the last sentence in the first post. Thanks, this works a ton.
NEVER USE REFLECTION IN A GAME!!!!!!!!!!!!!!!!!!!!!!!!!! (Unless at load time or having a really good reason (tools etc), reflection is very slow and having to fall back on it shows a clear lack of design forethought, your initial method isn't far from an optimal solution however the dictionary of game objects should be in your scene/game. In systems i've designed in the past i assign a UID string to an entity as its name unless it is changed by an external object of a level designer ;), you could alternatively store the dictionary statically)
You should either have 1 entity dictionary in a game scene or game container class or mask it static if you absolutely must have it stored in the base game object class.
(That was a REALLY long string in parentheses)
A couple of ways of doing things: 1) [cpp] class Entity { public virtual void Update(double frameTime) { // Do nothing } } class MovableEntity : Entity { public Vector2 Position { get; set; } public double Rotation { get; set; } } class RenderableEntity : MovableEntity { public Texture Texture { get; set; } public virtual void Render(Renderer renderer) { // Render Texture at the current Position / Rotation } } class SpaceshipEntity : RenderableEntity { public double Health { get; set; } } ... private IEnumerable<Entity> _entities; void Think(double frameTime, Renderer renderer) { foreach (Entity entity in _entities) { entity.Update(frameTime); RenderableEntity renderableEntity = entity as RenderableEntity; if (renderableEntity != null) { renderableEntity.Render(renderer); } } } [/cpp] 2) [cpp] class Entity { public virtual void Update(double frameTime) { // Do nothing } public virtual void Render(Renderer renderer) { // Do nothing } } class MovableEntity : Entity { public Vector2 Position { get; set; } public double Rotation { get; set; } } class RenderableEntity : MovableEntity { public Texture Texture { get; set; } public override void Render(Renderer renderer) { // Render Texture at the current Position / Rotation } } class SpaceshipEntity : RenderableEntity { public double Health { get; set; } } ... private IEnumerable<Entity> _entities; void Think(double frameTime, Renderer renderer) { foreach (Entity entity in _entities) { entity.Update(frameTime); entity.Render(renderer); } } [/cpp] You would create and destroy entities through a factory. (A method of your Entity Manager.) You add new properties through inheritance.
Check out component-based entity systems, very clean and effective way to handle game entities
[QUOTE=icantread49;32696731]Check out component-based entity systems, very clean and effective way to handle game entities[/QUOTE] This. One of the best decisions I made was moving my engine to a component-based system, all the problems I was having with the default inheritance model faded away.
Why not do it how source does it? Central Entity list, and all objects have a common base class (Or all inherit a class definition). They have a string classname so you can compare it at runtime quickly (without reflection), and the Entity class has static methods for finding all entities with a certain name, classname, etc. That's at least how i've always built my games, then entities can add themselves in the constructor, and then any entity can remove any other entity......
[QUOTE=CowsCanFly;32699346]Why not do it how source does it?[/QUOTE] Source doesn't quite do it like that. This is a really interesting problem with no direct answer, it really depends on your system. Architecting truly abstractable systems for entity management can be a very hard and taxing process even for industry pros. I tend to use inheritance based systems for entity management, with things such as physics and rendering abstracted into components which are added to the entity when it is loaded (Avoid doing stuff in the constructor if you can, It's considered bad design if you're using c++. If you're in c# it doesn't matter) I tend to use a system of buckets in hash-tables for quick retrieval of entities of type. things like being able to call m_sceneManager->GetAllEntitiesOfType("CPlayer"); and get the results without having to iterate through your entire entity list are invaluable :)
Sorry, you need to Log In to post a reply to this thread.