Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (734)
Games in Android Showcase (222)
games submitted by our members
Games in WIP (811)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Why AnimationTimer and setTranslate on a ImageView node create jerky movement?  (Read 896 times)
0 Members and 1 Guest are viewing this topic.
Offline ManofYesterday

Junior Newbie





« Posted 2017-06-13 01:38:31 »

My goal is to create a basic 2D game using the Java Fx library. And my subgoal is to create responsive controls and smooth movement of the character. My issue is the player in my game (ImageView node) is a little jerky when I use setTranslate on it. It seems to jerk for every second of continuous movement. Included in this post is an example. I've done research and I've been given conflicting answers... For instance, one person told me to use a WritableImage(because he said it's like BufferedImage), but that didn't seem to solve the jerkyness issue(maybe I implemented it wrong). Any help would be most appreciated.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
package pleasehelp;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;

import javafx.stage.Stage;

public class PleaseHelp extends Application {

    ImageView imageView;

    public void start(Stage stage) {

        Pane root = new Pane();

        Scene scene = new Scene(root, 800, 200);

        stage.setTitle("Please Help!");

        stage.setScene(scene);

        Animation animation = new Animation(this);

        Image image = new Image("http://lessonpix.com/drawings/192/100x100/Gray+Square.png");
        imageView = new ImageView();
        imageView.setImage(image);
        root.getChildren().add(imageView);
        animation.start();

        stage.show();

    }

    public static void main(String[] args) {
        launch(args);
    }

}

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
package pleasehelp;

import javafx.animation.AnimationTimer;

public class Animation extends AnimationTimer {
   
    PleaseHelp please;
   
    Animation(PleaseHelp please) {
        this.please = please;
    }
   
    @Override
    public void handle(long now) {
        please.imageView.setTranslateX(please.imageView.getTranslateX() + 1);
    }
   
    public void start() {
        super.start();
    }
   
    public void stop() {
        super.stop();
    }
   
}
Offline bmanmcfly
« Reply #1 - Posted 2017-06-13 02:56:34 »

It might be a "fix the timestep" issue?
Offline cylab

JGO Kernel


Medals: 171



« Reply #2 - Posted 2017-06-13 09:37:27 »

I didn't use javafx, but having the 'now' parameter in the handle() callback method screams variable timestep to me.

You need to incorporate the now into your calculation. The javadoc says it is the timestamp of a frame in nanoseconds. You may need to save it at the first frame, so you are able to calculate the relative time to the start of the animation per frame...

Also this looks helpful: http://svanimpe.be/blog/game-loops-fx.html

Mathias - I Know What [you] Did Last Summer!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline princec

« JGO Spiffy Duke »


Medals: 936
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #3 - Posted 2017-06-13 10:45:14 »

Unfortunately the timestamp does not quite match up with monitor sync rate so it'll always be a teeny bit juddery. JavaFX still has a ways to go for games.

Cas Smiley

Offline philfrei
« Reply #4 - Posted 2017-06-13 17:40:53 »

In my limited experience, AnimationTimer does a pretty good job of maintaining 60fps. When I ran the code, it looked fine. I'm not clear what the problem is.

If the scan rate on the monitor is something more different from 60, like 75 say, maybe that would help? I couldn't test this because I can't find where Windows10 let's one set the monitor refresh rate.

You might find it interesting to store the highest and lowest deviations. Store the last "now" long and compare it to the current "now" argument from the handle method. Or to tally the range of timing differences that occur.

Here is a short JavaFX graphics test program I wrote that is similar to your code (object bouncing side to side), though I am not using an ImageView in this case. Use of ImageView shouldn't make a difference. As far as I know this animation is reasonably smooth. Does it work for your setup?

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class BasicGraphicsDemo2 extends Application{

   final int WIDTH = 600;
   final int HEIGHT = 400;
   
   double ballRadius = 40;
   double ballX = 100;
   double ballY = 200;  
   double xSpeed = 4;
   
   public static void main(String[] args) {
     
      launch(args);
   }
   
   @Override
   public void start(Stage stage) throws Exception {
   
      stage.setTitle("Basic JavaFX demo");
     
      Group root = new Group();
      Scene scene = new Scene(root, WIDTH, HEIGHT);
     
      Circle circle = new Circle();
   
      circle.setCenterX(ballX);
      circle.setCenterY(ballY);
      circle.setRadius(ballRadius);
      circle.setFill(Color.BLUE);
      root.getChildren().add(circle);
     
      stage.setScene(scene);      
      stage.show();

      AnimationTimer animator = new AnimationTimer()
      {
         @Override
         public void handle(long arg0)
         {
            ballX += xSpeed;
           
            if (ballX + ballRadius >= WIDTH)
            {
               ballX = WIDTH - ballRadius;
               xSpeed *= -1;
            } else if (ballX - ballRadius < 0) {
               ballX = 0 + ballRadius;
               xSpeed *= -1;
            }
   
            circle.setCenterX(ballX);
         }  
      };

      animator.start();

   }
}




music and music apps: http://adonax.com
Offline philfrei
« Reply #5 - Posted 2017-06-13 17:51:00 »

For responsive controls, what I recommend is to have asynchronous input (keyboard and mouse) be used to set volatile variables. Then, in the AnimationTimer (the game loop), consume those values and update the animations accordingly. This is working pretty well so far on the 2D game JavaFX game I work on intermittently.

music and music apps: http://adonax.com
Offline ManofYesterday

Junior Newbie





« Reply #6 - Posted 2017-06-14 02:16:04 »

Thank you for the responses. I found out what the issue was. I use a program called f.lux that automatically adjusts screen brightness based on the time of day and it was drastically affecting the game's performance for some reason.
Offline philfrei
« Reply #7 - Posted 2017-06-14 05:04:23 »

Thanks for letting us know the resolution.

music and music apps: http://adonax.com
Pages: [1]
  ignore  |  Print  
 
 

 
cybrmynd (44 views)
2017-08-02 12:28:51

cybrmynd (59 views)
2017-08-02 12:19:43

cybrmynd (67 views)
2017-08-02 12:18:09

Sralse (82 views)
2017-07-25 17:13:48

Archive (504 views)
2017-04-27 17:45:51

buddyBro (652 views)
2017-04-05 03:38:00

CopyableCougar4 (1143 views)
2017-03-24 15:39:42

theagentd (1144 views)
2017-03-24 15:32:08

Rule (1117 views)
2017-03-19 12:43:22

Rule (1093 views)
2017-03-19 12:42:17
List of Learning Resources
by elect
2017-03-13 14:05:44

List of Learning Resources
by elect
2017-03-13 14:04:45

SF/X Libraries
by philfrei
2017-03-02 08:45:19

SF/X Libraries
by philfrei
2017-03-02 08:44:05

SF/X Libraries
by SkyAphid
2017-03-02 06:38:56

SF/X Libraries
by SkyAphid
2017-03-02 06:38:32

SF/X Libraries
by SkyAphid
2017-03-02 06:38:05

SF/X Libraries
by SkyAphid
2017-03-02 06:37:51
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
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!