4
\$\begingroup\$

I am currently having problems from finding my way into the component-oriented XNA design.

I read an overview over the general design pattern and googled a lot of XNA examples. However, they seem to be right on the opposite site. In the general design pattern, an object (my current player) is passed to InputComponent::update(Player). This means the class will know what to do and how this will affect the game (e.g. move person vs. scroll text in a menu).

Yet, in XNA GameComponent::update(GameTime) is called automatically without a reference to the current player.

The only XNA examples I found built some sort of higher-level Keyboard engine into the game component like this:

class InputComponent: GameComponent
{
    public void keyReleased(Keys);
    public void keyPressed(Keys);
    public bool keyDown(Keys);

    public void override update(GameTime gameTime)
    {
        // compare previous state with current state and
        // determine if released, pressed, down or nothing
    }
 }

Some others went a bit further making it possible to use a Service Locator by a design like this:

interface IInputComponent
{
    public void downwardsMovement(Keys);
    public void upwardsMovement(Keys);
    public bool pausedGame(Keys);

    // determine which keys pressed and what that means
    // can be done for different inputs in different implementations
    public void override update(GameTime);
 }

Yet, then I am wondering if it is possible to design an input class to resolve all possible situations. Like in a menu a mouse click can mean "click that button", but in game play it can mean "shoot that weapon".

So if I am using such a modular design with game components for input, how much logic is to be put into the InputComponent / KeyboardComponent / GamepadComponent and where is the rest handled?

What I had in mind, when I heard about Game Components and Service Locator in XNA was something like this:

  • use Game Components to run the InputHandler automatically in the loop
  • use Service Locator to be able to switch input at runtime (i.e. let player choose if he wants to use a gamepad or a keyboard; or which shall be player 1 and which player 2).

However, now I cannot see how this can be done.

  • First code example does not seem flexible enough, as on a game pad you could require some combination of buttons for something that is possible on keyboard with only one button or with the mouse)
  • The second code example seems really hard to implement, because the InputComponent has to know in which context we are currently. Moreover, you could imagine your application to be multi-layered and let the key-stroke go through all layers to the bottom-layer which requires a different behaviour than the InputComponent would have guessed from the top-layer.
  • The general design pattern with passing the Player to update() does not have a representation in XNA and I also cannot see how and where to decide which class should be passed to update(). At most time of course the player, but sometimes there could be menu items you have to or can click

I see that the question in general is already dealt with here, but probably from a more elobate point-of-view. At least, I am not smart enough in game development to understand it. I am searching for a rather code-based example directly for XNA.

And the answer there leaves (a noob like) me still alone in how the object that should receive the detected event is chosen. Like if I have a key-up event, should it go to the text box or to the player?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ It's rather important to point out that XNA's GameComponent implements a completely different pattern to the component-matrix design described in the article you linked (and this one). You should implement your own base class and component collection(s) to meet your needs. See also: here (especially my comment reply to BlueRaja) and here. \$\endgroup\$ Dec 3, 2012 at 7:08

1 Answer 1

1
\$\begingroup\$

I just wrestled with this myself -- how to create a simple component/entity framework for XNA. Here's what I did; my goals were:

  • Create reusable components (reusable within and across games) that are generic
  • Create game-specific entities that encapsulate "business domain" logic of my game

I ended up creating a basic Entity class (behind an interface):

public interface IEntity
    {
        void Update(double elapsedSeconds);        
        bool HasComponent<T>() where T : IComponent;
        T GetComponent<T>() where T : IComponent;
    }

My Player class, enemies, etc. all subclass from this. My components also live behind an interface with a simple Update method. Most of them expose specific functionality (eg. for input, events for when keys/mouse are pressed).

Creating the player was simple:

public class Player : Entity {
  public Player() {
    var input = new InputComponent();
    input.OnPress += (key) => {
      if (key == Keys.Space) { this.Jump(); }
    }
    this.addComponent(input);
  }
}

My input component reads keyboard input only. I personally created a different component for handling mouse input, although it could be the same. Tomorrow, I can always extend my input component to expose an event for when a gamepad button is pressed.

In this way, components really encapsulate only their specific piece of functionality, and I can easily reuse them across games; while entities are game-specific, and probably won't be reused; at the same time, it's easy to see where the "game logic" lives.

As for service locators, I think that amount of indirection is probably overkill for a small or medium-sized project. I would start with something a bit simpler first.

\$\endgroup\$
2
  • \$\begingroup\$ What are HasComponent and GetComponent used for? It does not seem they are needed for functionality; but you mentioned them, so I guess they are important? \$\endgroup\$ Dec 1, 2012 at 19:55
  • \$\begingroup\$ @Aufziehvogel it's up to you how you implement that. My entities all have a generic list of components, but you could as easily keep references in your entities to the components they have. You can find more general stuff in this awesome article: gameprogrammingpatterns.com/component.html ("How does the object get its components?") \$\endgroup\$
    – ashes999
    Dec 1, 2012 at 22:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .