Tuesday, July 21, 2015

entity system - Input handling in component based design


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) 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.



Answer



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.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...