I have some difficulties to understand how input should work when using StandardGame. If two GameStates bind the same key to an action, and both are active, the GameState which was attached first to the GameStateManager gets the key event, right? I don't have an idea what to do when I have some key events that should be catched by all active GameStates.
So:
an "active" GameState doesn't get an key event, if it's "stolen" by another one
the order of GameStateManager.getInstance().attachChild() is important
if you need another order of GameStates (e.g. because of some rendering tricks, let's say a skybox GameState), you have a problem
Here is a little extension of TestStandardGame from the SimpleGame -> StandardGame tutorial, which illustrates that behavior (use some of the "debug" keys like B or L):
/**
* TestStandardGame is meant to be an example replacement of
* jmetest.base.TestSimpleGame using the StandardGame implementation
* instead of SimpleGame.
*
* @author Matthew D. Hicks
*/
public class TestStandardGame {
First of all, this is not really specific to StandardGame but to the InputHandler as a whole. I would say this should be considered a bug…the key event should propagate to all InputHandlers.
Not to throw out unnecessary propaganda, but this should not be an issue for GameControl as it doesn't rely on InputHandlers, but the same code that InputHandler relies on.
You can create a GameControlManager for your game (for the in-game actions) and then have a GameControlManager for in-game menus as well and if you use the controllers I've added they'll work just fine as long as the GameState it's attached to is still enabled.
Well, you don't have to use GameStates for GameControls either actually since the controllers I was speaking of just Controllers that can be added to any Node in jME.
The version in the repository HEAD does allow events to propagate to all subscribed handlers. I think you may be affected by a bug that was solved a week or two weeks ago. What version of jME are you using, Landei?
Also, I think there is no way to associate InputHandlers and GameStates. I've found that if I want to place input handling code in GameStates, it's easier to use a main input handler and route input events myself (which also gives me some more control on where I send input events).
Maybe all the InputHandlers and Listeners and GameControl stuff is great, but is too mixed and undocumented for me.
Example InputHandler using this aproach (it is dependent on my code, and I'm almost certain that I will try another solution for this, but maybe lets you make an idea):
/**
* The MainInputHandler intercepts all the input events.
*/
public class MainInputHandler extends InputHandler {
/**
* Class logger
*/
private static final Logger logger = Logger.getLogger(MainInputHandler.class.toString());
Well, if you hadn't mentioned GameControl as part of that I would agree with you. Since we're posting code, I'll show you the code I just wrote this evening replacing a mess of input handling crap for a prototype game I'm working on:
// Pitch Forward and Reverse
pitchForwardReverseController = new RotationController(ship, manager.getControl("Pitch Forward"), manager.getControl("Pitch Reverse"), 1.0f, Axis.X);
rootNode.addController(pitchForwardReverseController);
loader.setProgress(0.85f);
// Pitch Left and Right
pitchLeftRightController = new RotationController(ship, manager.getControl("Pitch Left"), manager.getControl("Pitch Right"), 1.0f, Axis.Y);
rootNode.addController(pitchLeftRightController);
loader.setProgress(0.875f);
// Rolling
rollController = new RotationController(ship, manager.getControl("Roll Left"), manager.getControl("Roll Right"), 1.0f, Axis.Z);
rootNode.addController(rollController);
loader.setProgress(0.9f);
// Toggle Menu
ActionRepeatController toggleMenuController = new ActionRepeatController(manager.getControl("Toggle Menu"), 5000, new MenuAction());
rootNode.addController(toggleMenuController);
loader.setProgress(0.95f);
Pretty simple and straight-forward in my opinion. ;) Also, it's got loader code in there as well, so forgive the added mess. :P
My entire control system is nearly finished in that block of code. This is just a prototype so much of that is currently hard-coded values, but you get the idea.
Landei, can you confirm your problem is solved in current CVS? All InputHandlers should trigger a subscribed action; no InputHandler should be able to 'steal' it.
What behaviour do you get with the test class from my first post? As I never had any problems with this in SimpleGame, I would also guess that it is a GameState thing.