what is the smoothest/fastest way of reacting to user keyboard input (in order to move the player) ?

Right now I'm doing it like this:- user presses a key: the key which is pressed is remembered (for example: Globals.isMovingForward = true )- a Thread which is always running in the backround checks the pressed keys and reacts by moving the player modell

But that approach is not smooth. It feels slow and its jerking (I tried different Thread priorities).

I would suggest not to seperate the input gathering and input reacting threads.

In my opinion you should handle input gathering and then input reacting immediately afterwards, in the same thread. That way input is processed as soon as it arrives, in the same frame that it arrives.

I would suggest not to seperate the input gathering and input reacting threads.

In my opinion you should handle input gathering and then input reacting immediately afterwards, in the same thread. That way input is processed as soon as it arrives, in the same frame that it arrives.

That doesnt work. Try the following: type "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA". If you hold down the "A" key, you'll notice that the first "A" is written immediately. Then there is a short pause before the other "A"'s are written.And thats the problem with handling the key input immediately. It doesnt behave natural then.

But I found the workaround:I'm saving the system time when the key was pressed. Then I'm computing the way which was left behind by multiplying the speed with the time since the key was pressed. That way I'm independent of when the Thread is called. And it works perfectly, the figur now moves smoothly as it should.

But is there any other way? I dont think that my method is the perfect solution. So again: How do you do it?

It's times like this that I wish I'd listened to what my dad used to tell me. Yeah? What was that?I don't know. I never listened. - Dr. Venkman and Mr. Zeddemore

You must not use Threads to do this in Java3D. To change the graph you must use behaviors.You can set the triggers for it to be time elapsed, frames elapsed, AWT Events (Key, mouse, others), ad others.Here is a behavior example :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

publicclassMoveBehaviorextendsBehavior{TransformGrouptarget;Transform3Dt3d;WakeupOnElapsedTimetrigger; //This time it will be triggered by timepublicMoveBehavior(TransformGrouptarget){this.target = target;t3d = newTransform3D();trigger = newWakeupOnElapsedTime(1000 / 60); }publicvoidinitialize() {this.wakeupOn(trigger); }publicvoidprocessStimulus(Enumerationcriteria) {//the enumeration has all the triggers that meet its condition,//In this case is only one, so no iteration to define the response//Do the transformst3d.rotX();//Set the transformtarget.setTransform(t3d);//Set the trigger for the nest timethis.wakeupOn(trigger); }}

To put the behavior in the scenegraph you use something like this:

1 2 3 4 5

//In the graph creationbranchGroup.addChild(groupToChange);MoveBahaviormv = newMoveBehavior(groupToChange); //The group you want to movemv.setSchedulingBounds(newBoundingSphere(newPoint3d(),100.0f));branchgroup.addChild(mv);

Java3D uses its own threads to run behaviors and rendering. It's not a good idea to change things in middle of their work.Example: Your player object is a Tank(with two shapes Body and Turret) The J3D Render Thread begins to draw your Tank, trasnforms the body and draw the polygons You change the Transform to move forward The J3D Render Thread continues to draw your Tank, trasnforms the turret and draw the polygons Now you have a mutant Tank with the turret moved forward!

Other cases could be to change the camera rotation in the middle of the rendering of your scene , etc.

Using behaviors you wil update the transform always in a synchronized way with the rendering.

I use a KeyBehavior which reacts on the user pressing or releasing a key. When he does this, the state of the key is safed along with the time of the action. But when the Behavioris called because a key is pressed which is already pressed then the time is not safed (because it was already safed).

Then I have a second Behaviorwhich uses WakeupOnElapsedTime in order to act like a thread. It checks if a key is pressed and then moves the player accordingly.

So, for example, when the user presses the key "w" in order to move forward these things happen:

- the KeyBehavior class is called and it sets the boolean isMoveForward to true and the long timeMoveForward to the current time- the KeyBehaviour class is called again, because the user did not yet release the "w" key: nothing happens- the ThreadBehavior awakes and checkes if isMoveForward is true- the ThreadBehavior gets timeMoveForward and moves the player. - the ThreadBehavior sets timeMoveForward to the current time- all this is repeated until the user releases the "w" key- the user releases the "w" key: KeyBehavior sets isMoveForward to false

It works as smoothly as my previous approach (It feels perfect).

Does that sound like the right way to do it now?

It's times like this that I wish I'd listened to what my dad used to tell me. Yeah? What was that?I don't know. I never listened. - Dr. Venkman and Mr. Zeddemore

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org