Problems with analog listener

Hi.
Quite old topic, but i don’t see any solution to the problem. Google search also ended up in failure.
I figured a workaround to the problem. It does work, however I’m not happy with it at all - it’s just awful:

public class GameListener implements ActionListener, AnalogListener {
private int accelerate;
@Override
	public void onAction(String binding, boolean value, float tpf) {
		switch (binding) {
			case up:
				if (!value) {
					car.setAccelerating(false);
					accelerate = 0;
				}
				break;
		}
	}

	@Override
	public void onAnalog(String binding, float arg1, float arg2) {
		switch (binding) {
			case up:
				if (accelerate++ > 1) {
					car.setAccelerating(true);
				}
				break;
		}
	}
}

Anyone has a better idea?

[java]
public void onAction(String binding, boolean value, float tpf) {
switch (binding) {
case up:
car.setAccelerating(value);
break;
}
}
[/java]

What’s the problem exactly?

This is quite simple solution, however it does not cover all the cases - i need to constantly invoke the ‘setAccelerating’ method: when your car reaches max speed (player still holds the ‘up’ button) and either a collision occurs or just some steering (turning left) the car looses some speed, but wont accelerate any more. Player is required to release, and press again the acceleration button to reinvoke the method - that is why AnalogListener is required.

edit: I might have been slightly unprecise

@mystere said:

I tried your suggestion. SOMETIMES it works, but SOMETIMES i got the situation like this
accelerate (i keep pressing UP key)
accelerate
accelerate (i release the key here)
stop accelerate (actionListener is triggered)
accelerate (the analogListener gets executed once more)


the int value is used to bypass the last execution of analogListener

Well, it also bypasses the first.

If all you want is for the car to accelerate on every update then set a flag and set accelerate to that flag on update.

1 Like

Missing one update loop is totally unnoticeable.
I wanted to avoid having code responsible for one action in two places and also overusing the updateLoop. However, the solution i’ve found seems even worse.

Ok, thank you very much;)

So, I still don’t understand what’s so hard but this is kind of the last time I feel like writing code for you. You might be in over your head so far.

[java]
private boolean accelerate;

public void onAction( String binding, boolean value, float tpf ) {
switch (binding) {
case up:
this.accelerate = value;
break;
}
}

public void onAnalog( String binding, float value, float tpf ) {
switch (binding) {
case up:
car.setAccelerating(accelerate);
break;
}
}
[/java]

And if this is the only thing you are using this listener for then you could simplify it even further by only adding it to the ‘up’ binding in the first place:

[java]
private boolean accelerate;

public void onAction( String binding, boolean value, float tpf ) {
this.accelerate = value;
}

public void onAnalog( String binding, float value, float tpf ) {
car.setAccelerating(accelerate);
}
[/java]

No it’s not. I’ve omitted quite a few mappings to shorten the code.
The code you suggested is simply the same i created with int with this slight difference that it does not bypass a single invocation of analogListener and thus does not work (we do NOT have the certainty of invocation of the onAnalog method after the boolean has changed). In such case the accelerating method should be placed in the update loop, and that is what i have already done.

[java]
public void onAction( String binding, boolean value, float tpf ) {
this.accelerate = value;
car.setAccelerating(accelerate);
}

public void onAnalog( String binding, float value, float tpf ) {
car.setAccelerating(value == 0 ? false : accelerate);
}
[/java]

Why there is a comparison of value to 0? As far as i know the value will always differ from 0 so i can simply write ‘car.setAccelerating(accelerate);’
Or am i wrong?

I have checked

public void onAction( String binding, boolean value, float tpf ) {
    this.accelerate = value;
    car.setAccelerating(accelerate);
}

public void onAnalog( String binding, float value, float tpf ) {
    car.setAccelerating(accelerate);
}

And it works fine, thanks. However, I’m not fully happy with it - it leaves me with double invocation of a method in a code (imo such things should be avoided…) that is why i used int and decided to loose first invocation of listener.
Putting the accelerating method into the update loop is bad also but from performance reasons only.

Would it be possible to determine in what order the listeners are invoked?
This will fix such cases - or am i too dumb to understand your point?