Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I know this question has been asked several times, but I'm still not sure how to implement input handling in a component based engine.

The component based design I used was based on T=Machine's blog series and on Artemis in which Entities are just ids.

There are three main ideas I have in implementing input handling:

  1. The input component will hold events it's interested. The input system will translate key and mouse events to game events and loop through the entities with the input component and if they are interested in the event an appropriate action will be taken by the input system. This action would be hard coded to the input system.
  2. No input component. You would register entities with specific events to the input system. The input system would then send messages (with the entity id and event type) to other systems so that these can take the appropriate action. Or as in the first case, the actions would be hard-coded to the input system.
  3. Similar to the first method, but instead of hard coding the action to the input system, the component would contain a map of events to functions (i.e. std::map<std::function>) which would be called by the input system. This has the added effect of being able to couple the same event to different actions.

Would you recommend any of the above methods or do you have any suggestions that would help me implement a flexible input handling system? Also, I'm not yet familiar with multi-threading but any suggestions that would make the implementation thread-friendly are also welcome.

Note: One added requirement I'd like the implementation to fulfill is that I'd be able to pass the same input to many entities, like for example moving a camera entity and the player at the same time.

share|improve this question
2  
Usually (when the camera follows the player) you don't want to receive input in the camera, instead you make the camera check the player position and follow it. –  Luke B. Feb 11 '13 at 3:43
1  
It doesn't really matter conceptually if the camera follows the player, or "itself". Nonetheless, I'm not sure how your suggestion would be implemented in a component based design without breaking the design principles. –  Grieverheart Feb 11 '13 at 4:11
1  
@Luke B.: After giving it some thought, I see that you could also make the camera as a separate class, taking a pointer to an entity to follow. –  Grieverheart Feb 11 '13 at 4:48
add comment

3 Answers

up vote 4 down vote accepted

I think that, just like my answer regarding materials in a component system, you're running in to a problem where you're trying to shove everything into a "component." You don't need to do this and in doing so you're probably creating a really cumbersome interface by trying to fit a bunch of square pegs into round holes.

It sounds like you already have a system that handles the acquisition of input from the player. I'd opt for an approach that then translates that input into actions ("move forward," or "move backwards") or events and dispatches those to interested parties. In the past, I've disallowed components from registering themselves for these events, preferring an approach where the higher-level system explicitly selected the "controlled entity." But it could work that other way if you prefer, especially if you're going to re-use the same messages for taking actions that were not stimulated directly by input.

I wouldn't necessarily suggest implementing camera-following behavior by having both the camera entity and the player entity respond to the "move forward" (et cetera) message, though. This creates an extremely rigid connection between the two objects that will likely not feel good to the player, and it also makes it a bit trickier to handle things like having the camera orbit the player when the player rotates left or right: you have an entity responding to "rotate left" by assuming it is slaved to the player, but that means it can't correctly respond if it were ever unslaved... unless you introduce that concept as some state you can check. And if you're going to do that, you may as well implement a proper system for slaving two physical objects together, complete with appropriate elasticity tweakables and so on.

Regarding multi-threading, I don't really see a need to employ it here as it would likely cause more complication than it's worth, and you're dealing with an inherently serial problem so you'd just need to involve a lot of thread synchronization primitives.

share|improve this answer
    
I game my question some thought and was about to answer it myself. I also came to the conclusion that I should be better of decoupling the input handling from the EC system so it nice to see a confirmation of this. How I thought of doing this is by the use of signals and the ability to associate several entities to an event type. I also decided to decouple the camera, although this is not really necessary and having it as an entity would be equally viable. I think when still being a newbie with ECs you really have to think what the benefits are of making something a component or entity. –  Grieverheart Feb 14 '13 at 0:44
add comment

My experience might be biased but in multi platform projects the input devices are not directly exposed to the entity system.

The input devices are handled by a lower level system which receives the events from the keys, buttons, axis, mouse, touch surfaces, accelerometers...

These events are then sent through a layer of context dependent intention generators.

Each generator register for sate changes from components, entities and systems that are relevant to its functions.

These generators then send messages/intentions for routing to the intention system where entities have a component or directly to the right components.

This way you can simply rely on "always" having the same input i.e. JUMP_INTENT(1), JUMP_INTENT(0), AIM_INTENT(1)...

And "all" the dirty platform dependent input work remains outside of your entity system.


Concerning the camera if you want to move it around the player it can register its own intent component and listen to intents you will send.

Otherwise when if follows the player it should never listen to inputs destined to the player. It should listen to the state changes emitted by the player (ENTITY_MOVED(transform))... and move accordingly. If you use a physics system you can even attach the camera to the player using one of the various joints.

share|improve this answer
    
Coyote, thanks for your answer. I have also read your other post here. My biggest concern is not how to abstract the input. I already have a lower level construct which handles key presses and such, and adding one more level of indirection wouldn't be difficult. My problem is in handling the events generated by for example your intent system. If I understand correctly, you have no input components at all in your method. How do you know which entities need input and how do you handle it? Could you give some more concrete examples? –  Grieverheart Feb 11 '13 at 15:41
add comment

What benefit does an InputComponent bring? Surely it is the prerogative of the input command to decide what entities it is performing an action on. The classic example is that of making the player jump. Instead of having an InputComponent on every entity listening for "Jump" events, why not have the jump command lookup the entity marked "player" and perform the necessary logic itself?

Action jump = () =>
{
    entities["player"].Transform.Velocity.Y += 5;
};

Another example, from the OP:

Action moveRight = () =>
{
    foreach (var entity in entities.Tagged("player", "camera"))
        entity.Transform.Position.X += 5;
};
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.