Implementing a Fast Forward and Rewind feature

I am trying to implement a fastForward() and rewind() methods to my application.



I need something like keep pressing a button to keep fast forwarding.



a sample code:

[java]

private void initInputs() {

inputManager.addMapping(“fastForward”, new KeyTrigger(keyInput.KEY_F));

inputManager.addMapping(“rewind”, new KeyTrigger(keyInput.KEY_R));





ActionListener acl = new ActionListener() {

public void onAction(String name, boolean keyPressed, float tpf) {

if (name.equals(“togglePause”) && keyPressed) {



else if (name.equals(“fastForward”) && keyPressed) {



while(keyPressed) <<<<<<<<<<<<< this will let it get stuck !

{

System.out.println(“Time fast forwarding”);

}





}



else if (name.equals(“rewind”) && keyPressed) {

System.out.println(“Time rewinding”);

}



}

};

inputManager.setCursorVisible(true);

inputManager.addListener(acl, “fastForward”);

inputManager.addListener(acl, “rewind”);

}

[/java]



the idea is to forward while key is pressed. Or if it’s easier, some loop when I press key once it forwards, and when I press it again it stops. The function of forwarding and rewinding is already written, the question is how to trigger it from pressing the buttons.

You should really consider the first suggestio of normen as you code is full of incoherences.



Now, listen to keyPress/keyRelease events. on key press, pout your local keyPressed boolean to true. On keyRelease, put it to false. Do not do anything else there. You should react to events as fast as possible.



In your game loop, if that boolean is set to true, play your game at 10x speed.



Concerning rewind, I hope you understand what the implications of such a feature are. You obviously can’t get back in time. You have to store all positions/velocities/whatever data might be needed of every entities in your game.

Obviously that while loop stops the code, it will forever hang in that while cause the instructions in the curly brackets cannot make it become anything else. The update loop is already a loop, you should re-read the first tutorials. Also maybe check http://www.javabeginner.com as you seem to have issues with java/coding in general if it doesn’t occur to you why that while blocks the code.

no no I definitely knew that, I put it out there to make a point of what I am trying to do. I am trying to write something WHILE KEY IS PRESSED do folowing events.

Add a listener, set a boolean if your key was pressed and the boolean-parameter was true, reset the boolean otherwise.



In your update Loop check wether your flag is true or false and react.

1 Like

Not sure that will do it, just to be clear I want something as simple as this:



pseudocode:

[java]

As long as F is pressed

System.out.println("Forwardinggggggg");



When F is released

System.out.println("Forwardinggggggg Stopped");

[/java]

@KuroSei said:
Add a listener, set a boolean if your key was pressed and the boolean-parameter was true, reset the boolean otherwise.
In your update Loop check wether your flag is true or false and react.

What am I doing wrong?



[java]

… boolean pressed = false;



else if (name.equals(“fastForward”) && keyPressed) {



pressed = true;



if(pressed == true)

{

System.out.println(“Forwardinggggggg”);

}

}



else if (!name.equals(“fastForward”) && !keyPressed) { pressed = false;

System.out.println(“Forwardinggggggg Stoppsss”);}

[/java]



if I keep pressing F I don’t see the System.out.println(“Forwardinggggggg”); repeating

Ok, I think you’re making one assumption that is killing you. Remember, onAction gets called when something happens. It passes a String, boolean and float. “keyPressed” is a boolean that is established as a local parameter when that method is called the moment something happens. It isn’t going to magically change when the person lets go of the key or presses another key, instead, when the key is let go another onAction will be called but keyPressed will be false.



What the others were saying to do is make a global boolean in your subclass, watch for keyPressed==true, and change the global boolean to true when it happens, then go into the while loop. That way when onAction is called again with keyPressed==false, your listener can change the global. Meanwhile, the while loop will watch the global to know when to stop. The local parameter keyPressed has no way of changing within that onAction method unless you do it on your own.

Yeah, you need onAnalog for it to be repeated.

I really advise you to start from scratch.

Forget what you thought you know. Its obviously wrong somehow.



Go through the tutorials, all Tutorials. Really. Do it. As Normen said.

Before you didnt do that you wont be able to write a Rewind-Function as you wish for. Pay special attention to CustomControls if i may say that, since you will really need this to create a nice and clean method to rewind your Entities.



DO THE TUTORIALS.

Really.

For your own sake.



If Normen sais so, just do it.

I never had Normen say a wrong thing, so you better listen. :wink:

Yeah, to be honest, I don’t see you implementing a rewind feature any time soon if you can’t work the basic actionListeners on your own.

That said, it’s good to be ambitious.

come on guys make give the guy a break :stuck_out_tongue:



here it is:



you need to implement both an analog listener (to recognize the button staying pressed) and also an action listener to change the boolean the guys were referring about from true to false. This tutorial covered it: https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:beginner:hello_input_system so normen and the guys were right, do the tutorials



So you need first to implement this:

[java]AnalogListener analogListener = new AnalogListener() {

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

if (pressed) {

if (name.equals("fastForward")) {

System.out.println("FastForwarding!");

}

} else {

System.out.println("FastForward STOP !!!");

}

}

};[/java]



Then also add this:

[java]

ActionListener acl = new ActionListener() {

public void onAction(String name, boolean keyPressed, float tpf) {

if (name.equals("fastForward") && keyPressed) {



pressed = true;

//System.out.println("Forwarding set to true");



}

}

};

[/java]



of course initially the boolean pressed must be set to false;



let me know if that works

1 Like

Great! you’re right garnaout…



Thanks and yes it works like a charm

you’re welcome! glad it worked.



and btw @cghislai7p you can go back in time (at least using Cinematics I can) here’s a snippet of my code, I did something pretty similar:



[java] // analog listeners

AnalogListener analogListener = new AnalogListener() {

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

if (pressed) {

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



System.out.println(“FastForwarding!”);

cinematic.setTime(cinematic.getTime() + 5);

System.out.println("Time "+cinematic.getTime());

}



else if (name.equals(“JumpTimeBackward”)) {



System.out.println(“Rewinding!”);

cinematic.setTime(cinematic.getTime() - 1);

System.out.println("Time "+cinematic.getTime());

}



}

}

};[/java]

Well. With cinematics its something different.



But if you have several entities which are physical animated and you want to rewind all those its recommended to add to all those rewindables a CustomControl which automaticly tracks the entities Position, Rotation and stuff in the needed intervall, and can interpolate back in the buffer, if needed.

You would need a buffer for that. With a custom control the hardest thing will be the interpolation and the gamelogic implementing the stuff, i guess.



Its not quite as simple as pointed out, since this would mess physics and effects and collisions and all that stuff. Much would look wierd.

This topic isnt as easy as ppl often think.



Try it with jBullet Physics and just a few Boxes and an interacting player who can throw little grenades which add forces. Its fascinating :wink:

Depends on the game mostly, a race game for example could probably be set back quite easily, if you just save a full gamestate every x seconds (Of course its more like resetting time than rewinding at that rough time resolution)