A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/AlmasB/FXGL/issues/1313 below:

Illegal keys are incorrectly released · Issue #1313 · AlmasB/FXGL · GitHub

Discussed in #1312

Originally posted by LegionaryCohort October 26, 2023
Hi,
First of all, great game engine, having a lot of fun playing around with it so far!

Context for my question:
I have a semi-static map (top-down view) and I'm trying to implement input handling that allows the player to move the viewport.
Nothing fancy, just WASD-keys to move the view around. This works great so far.
I'm now trying to add the ability to move the view around faster when pressing the Shift key as well.

So far I've tried the following:

  1. Add seperate UserActions for the keys with and without the Shift modifier.
    The UserActions simply set the viewport speed, which in turn is used in onUpdate to move the viewport around.
    This mostly works as expected, however with one caveat. When I press the A key, and then press the Shift key (while still holding the A key down), it does not switch to the fast movement. Vice versa, if I start with Shift-A and then release the Shift key (while still holding the A key), the movement stops entirely for a short moment, then resumes in slow mode.
    The cause appears to be that as long as the A-key remains pressed, the Shift key is not registered. Or in the second scenario, the Shift-A combination is registered and then stops and it takes the engine a short moment to register that the A-key is still being pressed.
private double speed = 0;

@Override
protected void initInput() {
	var moveLeft = new UserAction("Move Camera Left (Slow)") {
		@Override
		protected void onActionBegin() {
			speed = -600;
		}
		@Override
		protected void onActionEnd() {
			speed = 0;
		}
	};
	var moveLeftFast = new UserAction("Move Camera Left (Fast)") {
		@Override
		protected void onActionBegin() {
			speed = -1200;
		}
		@Override
		protected void onActionEnd() {
			speed = 0;
		}
	};
	FXGL.getInput().addAction(moveLeft, KeyCode.A);
	FXGL.getInput().addAction(moveLeftFast, KeyCode.A, InputModifier.SHIFT);
}

@Override
protected void onUpdate(double tpf) {
	FXGL.getGameScene().getViewport().setX(viewport.getX() + speed * tpf);
}
  1. Add separate UserActions for the WASD keys and the shift key.
    The WASD keys again set the speed, the shift key sets a factor. In onUpdate the viewport is moved according to speed*factor.
    This simply does not work, as the engine throws an IllegalArgumentException when trying to bind an action to the Shift key.
    If I bind toggleSpeed to a different (valid) key however, this gives me exactly the result I would like to achieve, just with the wrong key.
private double speed = 0;
private double factor = 1;

@Override
protected void initInput() {
	var toggleSpeed = new UserAction("Toggle Camera Speed") {
		@Override
		protected void onActionBegin() {
			factor = 2;
		}
		@Override
		protected void onActionEnd() {
			speed = 1;
		}
	};
	var moveLeft = new UserAction("Move Camera Left") {
		@Override
		protected void onActionBegin() {
			speed = -600;
		}
		@Override
		protected void onActionEnd() {
			speed = 0;
		}
	};
	FXGL.getInput().addAction(toggleSpeed, KeyCode.SHIFT);
	FXGL.getInput().addAction(moveLeft, KeyCode.A);
}

@Override
protected void onUpdate(double tpf) {
	FXGL.getGameScene().getViewport().setX(viewport.getX() + speed * factor * tpf);
}
  1. Add a TriggerListener that handles the Shift-logic internally
    The TriggerListener checks for the WASD-keys being pressed. If detected, it will check if the Shift-key is also pressed and set the viewport speed accordingly.
    This does not work, keyTrigger.getModifier() always returns NONE, regardless of whether the Shift key is pressed or not.
    The regular movement works just fine though, the Shift key just seems to never be registered.
    (On that note, this does feel like a bug, although I'm not entirely certain it isn't just me doing something wrong).
private double speed = 0;
private double factor = 1;

@Override
protected void initInput() {
	FXGL.getInput().addTriggerListener(
		new TriggerListener() {
			@Override
			protected void onAction(Trigger trigger) {
				if (trigger.isKey()) {
					var keyTrigger = (KeyTrigger) trigger;
					if (keyTrigger.getKey() == KeyCode.A) {
						speed = -600;
						factor = (keyTrigger.getModifier() == InputModifier.SHIFT) ? 2 : 1;
					}
				}
			}

			@Override
			protected void onActionEnd(Trigger trigger) {
				if (trigger.isKey()) {
					var keyTrigger = (KeyTrigger) trigger;
					if (keyTrigger.getKey() == KeyCode.A) {
						speed = 0;
						factor = 1;
					}
				}
			}
		}
	);
}

@Override
protected void onUpdate(double tpf) {
	FXGL.getGameScene().getViewport().setX(viewport.getX() + speed * factor * tpf);
}

So, my question:
How do I implement the behaviour that I want, i.e. smooth switching between regular and fast movement, without having to release the movement keys in between?
Note that I also tried using the onAction method, rather than the onActionBegin (figuring it might simply be that the single starting tick was the problem), but this made no difference.
I feel like I'm probably missing something obvious or I'm just misusing the API, so if you could give me any pointers on this, that would be great!
(And sorry for the long post, I'm hoping the code samples clarify what I'm doing, or trying to do)


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4