AnalogListener's onAnalog(String name, float value, float tpf)

Hi Monkeys,



I have been looking into using the AnalogListener for my project and so I have been running a few tests. I must admit that it is not so easy to understand. I have taken my base knowledge of this from Tutorial #5 - Hello Input.



The onAnalog method takes three parameters like so …



public void onAnalog(String name, float value, float tpf){}



One of my problems is that I cannot trace where the float ‘value’ comes from. I have looked through the jME3 code (classes and interfaces) and can’t find it. The other problem is that it is always the same value as the float tpf.



The way I understand the reasoning for using the AnalogListener is to have a ramp-up control (not just off and on), and it would seem that this ramp would vary between zero and one. But I can’t see this working at all.



Here is an output of the values …



Speed: 1.0 Value: 5.75506E-4 tpf: 5.75506E-4

Speed: 1.0 Value: 0.001221459 tpf: 0.001221459

Speed: 1.0 Value: 7.8915496E-4 tpf: 7.8915496E-4

Speed: 1.0 Value: 7.4796495E-4 tpf: 7.4796495E-4

Speed: 1.0 Value: 7.2063395E-4 tpf: 7.2063395E-4

Speed: 1.0 Value: 5.3624E-4 tpf: 5.3624E-4

Speed: 1.0 Value: 0.00109019 tpf: 0.00109019

Speed: 1.0 Value: 0.001149087 tpf: 0.001149087

Speed: 1.0 Value: 0.001223768 tpf: 0.001223768

Speed: 1.0 Value: 0.001100198 tpf: 0.001100198

Speed: 1.0 Value: 8.4150897E-4 tpf: 8.4150897E-4

Speed: 1.0 Value: 7.41806E-4 tpf: 7.41806E-4

Speed: 1.0 Value: 7.12934E-4 tpf: 7.12934E-4

Speed: 1.0 Value: 5.78971E-4 tpf: 5.78971E-4

Speed: 1.0 Value: 7.98009E-4 tpf: 7.98009E-4

Speed: 1.0 Value: 8.57292E-4 tpf: 8.57292E-4

Speed: 1.0 Value: 6.99461E-4 tpf: 6.99461E-4

Speed: 1.0 Value: 0.001089419 tpf: 0.001089419

Speed: 1.0 Value: 0.0010386059 tpf: 0.0010386059



… when running a code snippet:



public void onAnalog(String name, float value, float tpf) {

if (name.equals(“Rotate”)) {

geoMesh5.rotate(0, value * speed, 0);



str1 = "Speed: " + String.valueOf(speed);

str2 = "Value: " + String.valueOf(value);

str3 = "tpf: " + String.valueOf(tpf);



As you can see from the data posted above, there seems to be no difference in value between value and tpf.



From looking at the Application.class, I can see that the float speed is probably used for setting the game speed. This is always one.



The following is a quote from the tutorial. But I cannot see this behaviour happening.



Mappings registered to the AnalogListener are triggered repeatedly and gradually.



Parameters:

JME gives you access to the name of the triggered action.

JME gives you access to a gradual value how long the key has been pressed.

Example: Navigational events (e.g. Left, Right, Rotate, Run, Strafe), situations where you interact continuously.







So here are my questions:


  1. Where does the float ‘value’ come from? And what is it for? (if not for ramping, i.e. gradual change.)


  2. Where does the ramp effect come in? How do I get the ramp effect to work?


  3. Can it be made to ramp faster or slower? (Since I’d prefer a slow ramp up to full noise)



    Thanks in advance.



    BTW … can’t see any HTML tags for text formatting when posting this new topic. So I’m sorry for the lack of formatting.

I felt robbed for not being able to format the first post. And since I spent a good part of the night formatting the output of the data above with StringBuffer, I’ll try to repost so that it is at least formatted and easier to read. Here goes …



[java]

Here is an output of the values …



Speed: 1.0 Value: 5.75506E-4 tpf: 5.75506E-4

Speed: 1.0 Value: 0.001221459 tpf: 0.001221459

Speed: 1.0 Value: 7.8915496E-4 tpf: 7.8915496E-4

Speed: 1.0 Value: 7.4796495E-4 tpf: 7.4796495E-4

Speed: 1.0 Value: 7.2063395E-4 tpf: 7.2063395E-4

Speed: 1.0 Value: 5.3624E-4 tpf: 5.3624E-4

Speed: 1.0 Value: 0.00109019 tpf: 0.00109019

Speed: 1.0 Value: 0.001149087 tpf: 0.001149087

Speed: 1.0 Value: 0.001223768 tpf: 0.001223768

Speed: 1.0 Value: 0.001100198 tpf: 0.001100198

Speed: 1.0 Value: 8.4150897E-4 tpf: 8.4150897E-4

Speed: 1.0 Value: 7.41806E-4 tpf: 7.41806E-4

Speed: 1.0 Value: 7.12934E-4 tpf: 7.12934E-4

Speed: 1.0 Value: 5.78971E-4 tpf: 5.78971E-4

Speed: 1.0 Value: 7.98009E-4 tpf: 7.98009E-4

Speed: 1.0 Value: 8.57292E-4 tpf: 8.57292E-4

Speed: 1.0 Value: 6.99461E-4 tpf: 6.99461E-4

Speed: 1.0 Value: 0.001089419 tpf: 0.001089419

Speed: 1.0 Value: 0.0010386059 tpf: 0.0010386059

[/java]

@alfinete



I never tried it myself but analog-inputs with gradual value are input devices like joypads, steeringwheels and joysticks I suppose.

When you use the keyboard or mouse buttons the value just represents the time the key has been pressed since the last frame, the same value tpf is.



For speed multipliers you always need to use tpf. you can use value for example the angle of steering for cars with an analog controller if one is used.



if you want to know the total time of a keypress you need a variable that starts at 0 on key down and keeps adding the tpf till you stop pressing the key. that way you have an up to date total-key-press time if you want to.

Yeah right … so I could use the ActionListener for that and not need the AnalogListener. But the AnalogListener (as far as I can see from the docs) is for giving an analog variation on a keypress.



If it is not for keypresses and is only for joysticks and the likes, then I stand to be corrected and I probably won’t need to use the analogListener right now.



It would make sense that the ‘value’ variable would perhaps come from a joystick listener. But it’s the keypress thingy that has got me stumped here.

OK, so I found the ‘value’ float. It is in the JoystickAxisEvent.java.



[java]

*/

public class JoyAxisEvent extends InputEvent {



private int joyIdx;

private int axisIdx;

private float value;



public JoyAxisEvent(int joyIdx, int axisIdx, float value) {

this.joyIdx = joyIdx;

this.axisIdx = axisIdx;

this.value = value;

}

[/java]



It would then appear that the AnalogListener is not for keypresses.



This should be reflected in the documentation, especially in Tutorial #5 - Hello Input.

@alfinete

I don’t know but maybe value can be smaller then tpf, when a keypress didn’t took as long as the last frame.

@alfinete said:
I felt robbed for not being able to format the first post. And since I spent a good part of the night formatting the output of the data above with StringBuffer, I'll try to repost so that it is at least formatted and easier to read. Here goes ...

[java]
Here is an output of the values ...

Speed: 1.0 Value: 5.75506E-4 tpf: 5.75506E-4
Speed: 1.0 Value: 0.001221459 tpf: 0.001221459
Speed: 1.0 Value: 7.8915496E-4 tpf: 7.8915496E-4
Speed: 1.0 Value: 7.4796495E-4 tpf: 7.4796495E-4
Speed: 1.0 Value: 7.2063395E-4 tpf: 7.2063395E-4
Speed: 1.0 Value: 5.3624E-4 tpf: 5.3624E-4
Speed: 1.0 Value: 0.00109019 tpf: 0.00109019
Speed: 1.0 Value: 0.001149087 tpf: 0.001149087
Speed: 1.0 Value: 0.001223768 tpf: 0.001223768
Speed: 1.0 Value: 0.001100198 tpf: 0.001100198
Speed: 1.0 Value: 8.4150897E-4 tpf: 8.4150897E-4
Speed: 1.0 Value: 7.41806E-4 tpf: 7.41806E-4
Speed: 1.0 Value: 7.12934E-4 tpf: 7.12934E-4
Speed: 1.0 Value: 5.78971E-4 tpf: 5.78971E-4
Speed: 1.0 Value: 7.98009E-4 tpf: 7.98009E-4
Speed: 1.0 Value: 8.57292E-4 tpf: 8.57292E-4
Speed: 1.0 Value: 6.99461E-4 tpf: 6.99461E-4
Speed: 1.0 Value: 0.001089419 tpf: 0.001089419
Speed: 1.0 Value: 0.0010386059 tpf: 0.0010386059
[/java]


What were you listening to here? My guess would be a key or a button. In which case, you only get notified when the button is down and value is "how long the button has been down since the last time you were notified"... ie: the same as tpf. Which is what another poster said.

You can use it for keys and buttons... but I find action listener fits better... though usually you end up duplicating in some way what analog listener is doing with value.

There is no ramping. You'd have to do that yourself since there are an infinite number of ways to ramp and it is super-simple-trivial:
acceleration += baseAcceleration * value;
velocity = min(0, max( maxVelocity, velocity + acceleration * tpf - drag * tpf ));
...or whatever.

There is one big reason why you may sometimes use analogue listener for keys as well as for analogue devices. It is a very easy way to get notified continuously while a key is pressed. For example movement code that keeps going until they release the key.the alternative of setting a flag and moving in update is morecumbersome

@zarch said:
There is one big reason why you may sometimes use analogue listener for keys as well as for analogue devices. It is a very easy way to get notified continuously while a key is pressed. For example movement code that keeps going until they release the key.the alternative of setting a flag and moving in update is morecumbersome


Yes, but frequently the key is actually setting some acceleration. The update loop just continually applies the acceleration to velocity... this gives the "ramp up" that the original poster was looking for.

Analog listener for keys can be nice for prototyping but my guess is most games will do something to soften the movement. And analog listener doesn't give you a way to ramp down again, regardless.