Advertisement

compoenent base system for XNA.

Started by April 25, 2015 02:55 PM
4 comments, last by LetsDoThis 9 years, 8 months ago

I just found the article here about the component base system. Sadly I cant find any example of component base system implemented in XNA so i decided to make my own. Im not really sure if this is the correct implementation of component base system but it will help me improve if someone can point what are my mistakes. Here is my diagram (note this is just a simple diagram)

Untitled.jpg

Here is my simple code for pong

The input class


 class InputHandler : IKeyInputhandler
    {
       
        Dictionary<Keys,Vector2> keyDictionary = new Dictionary<Keys, Vector2>();
        private bool left, right;
        public InputHandler()
        {
            keyDictionary.Add(Keys.Space, new Vector2(-1,0));
            keyDictionary.Add(Keys.Right, new Vector2(1, 0));
       
        }

        public bool moveLeft
        {
            get { return left; }
        }

        public bool moveRight
        {
            get { return right; }
        }

        public void Update()
        {

            KeyboardState state = Keyboard.GetState();
      
            foreach (KeyValuePair<Keys, Vector2> keyValuePair in keyDictionary)
            {

                if (state.IsKeyDown(keyValuePair.Key))
                {

                    if (keyValuePair.Key == Keys.Space)
                    {

                        left = true;

                    }
                    if (keyValuePair.Key == Keys.D)
                    {
                        right = true;

                    }
                }
                else
                {
                    if (keyValuePair.Key == Keys.Space)
                    {
                        left = false;
                    }
                }

            }

        }
    }

The interface for input


public interface IKeyInputhandler
    {
        bool moveLeft { get; }
        bool moveRight { get; }
        void Update();

    }

Player class


 public class Player
    {
        private readonly IKeyInputhandler keyInputhandler;

        public Player(IKeyInputhandler keyInputhandler)
        {
            this.keyInputhandler = keyInputhandler;
            
        }

        public void Update(GameTime gameTime)
        {
            keyInputhandler.Update();
            if (keyInputhandler.moveLeft)
            {
                Debug.WriteLine("moving left");
            }
        }
    }

The implementation in game class


player = new Player(new InputHandler());

In this tutorial I decided just to send messages via boolean variable property from InputHandler

Is this good? Am i doing this right?

ooookkkkkaaaayyy

In general, entities (i assume Player is an entity?) should not know about its concrete components and there are should be no specializations of entities.

Entity class is a moniker using which you can find all the components related to the real entity in your game. There are two common implementations: one in which Entity class contains a list of components (or components ids) and second in which Entity is just an id and you search for component in appropriate subsystem using entity's id.

That would be all if components were completely independent. But usually there is some binding between different component types. That is why before desinging component system it is better to assess requirements of your game to understand what functionality you'll need and how it will all interact. Usually, there are two types of interaction between components: message passing (usually Component::OnMessage(MessageStructWithGenericParams event); and some functionality to send messages to all components of concrete entity or to send messages to all components of the same type, etc. depending on your needs) and direct access from one component to another. In a pure form there should only be message passing, but it is rarely practical.

I want to stress that designing a component system can be quite complicated. Regarding the link you've provided, HealthSystem plays "boom.wav" when health drops to 0. Then we might think that it would be good to play different audio effects and we add AudioFileName to our HealthComponent. Then we decide it will be good to play animation in some cases and we add DeathEffectComponent. But how will it interact with HealthComponent? It can check HealthComponent.curHp and play effect once it reaches 0. But what if we want some entities without HealthComponent to play death effect too? Well, DeathEffect component might then listen to "OnKill" message. And so on...

Another thing why Components are so important are cache coherency. It is probably the biggest benefit of Entity-Components approach. You pack data of each component type and process it sequentially.

Advertisement

Here's an article I wrote with a Bomberman type game written with an entity component system in XNA:

http://www.gamedev.net/page/resources/_/technical/game-programming/case-study-bomberman-mechanics-in-an-entity-component-system-r3159

Hopefully that will be some of use.

Here's an article I wrote with a Bomberman type game written with an entity component system in XNA:

http://www.gamedev.net/page/resources/_/technical/game-programming/case-study-bomberman-mechanics-in-an-entity-component-system-r3159

Hopefully that will be some of use.

Hi. I read your article. Downloaded the source. And uh I really cant understand it( not literraly I cant understand it, what i mean by this is that its just too many class involve that it makes it too complicated for me) . From what I saw you built an engine on top of XNA.

I kept reading your article and this article. I somehow understand the concept but the implementation is not clear for me. The thing that I dont understand the most is combing the components to form an entity. Im just trying to this on a pong clone game so that i cant understand it

Lets say I have this

Component


   public class Sprite : IComponentInterface
    {
        public Texture2D texture { get; set; }
        public float Width { get { return texture.Width; } }
        public float Height { get { return texture.Height; } }
    }

public class Position : IComponentInterface
    {
        public Vector2 position { get; set; }
    }

Combining them is what gets me.

If I am going to create an empty Entity it will look like this


    public class Entity
    {
        public List<IComponentInterface> listComponent { get; set; }
    }

Then create an Entity Manager class


 public List<Entity> listEntity = new List<Entity>();
        public Entity GetEntity { get { return entity; } }
        Entity entity = new Entity();

        public void createEntity(IComponentInterface componentInterface)
        {
            entity.listComponent.Add(componentInterface);
            listEntity.Add(entity);
            
        }
    }

But then the problem is the calling in the draw method is the problem.

ooookkkkkaaaayyy

You need to have code that can answer the question "give me component X on this entity".

So in its simplest form, if your draw code needs the Sprite and Position components to draw something, then the pseudo-code would look something like:


foreach(Entity e in listEntity)
{
    Sprite sprite = e.GetComponent<Sprite>();
    Position position = e.GetComponent<Position>();
    if ((sprite != null) && (position != null))
    {
        DrawSprite(sprite, position);
    }
}

Does that make more sense?

I would say, though, that an entity-component system is probably overkill for a simple game like Pong. While it might be an interesting exercise, Pong might not have complex enough requirements that make the benefit of an entity-component system clear. So you might get Pong working with an ECS, and think to yourself "all it did was make things more complex". And you'd probably be right.


I would say, though, that an entity-component system is probably overkill for a simple game like Pong.

I think you are right. Maybe its just an overkill. Like using 3d game engine to build 2d pong. I think I should move on and do another game. I really need more real life experience in coding to better understand this concept I think.

ooookkkkkaaaayyy

This topic is closed to new replies.

Advertisement