Results 1 to 10 of 10
Like Tree2Likes
  • 1 Post By DarrylBurke
  • 1 Post By Marcz

Thread: 2D game animation not smooth

  1. #1
    Marcz is offline Member
    Join Date
    Apr 2012
    Posts
    5
    Rep Power
    0

    Question 2D game animation not smooth

    Hello!

    I'm new to programming and making first 2D game.

    In general my game works but not as smooth as I would like to.

    Here is the full code:

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.lang.*;
    
    public class GameField extends JPanel implements ActionListener  {
    
    	private int c;
    	private int level = 1;
    	private int addlvl = 0;
    
    	private static final int HEIGHT = 600;
    	private static final int WIDTH = 600;
    	private static final int ONE_SQUARE = 30;
        private static final int RAND = 19;
    	private static final int DELAY = 2;
    	private static final double SPEED_PER_MILI = 0.2;
    
    	private double x;
    	private double y;
    	private int dx = 1;
    	private int dy = 1;
        private int dotX;
        private int dotY;
        private long beforeTime, latestTime, timeDiff, sleep;
    
        private String rez;
        private String lvl;
        private String msg;
        private static final String s = "Lai sāktu spēli nospied ENTER";
        private static final String msgnew = "Nospied pogu 'R', lai sāktu jaunu spēli!";
        private static final Font ff = new Font("SansSerif",Font.BOLD,18);
        private static final Font small = new Font("Helvetica", Font.BOLD, 14);
    
    
        private Timer timer = null;
    
    	private boolean gameRunning = false;
    	private boolean startScreen = true;
    	private boolean gameOver = false;
    	private boolean right = true;
    	private boolean left = false;
    	private boolean up = false;
    	private boolean down = false;
    
        private Image redd;
        private Image bulletL;
        private Image bulletR;
        private Image bulletU;
        private Image bulletD;
        private Image brick2;
        private Image line;
        private Image line2;
        private Image line3;
        private Image line4;
    
    
    	 public GameField() {
            addKeyListener(new Keys());
    
            setBackground(Color.black);
    
            ImageIcon bulletLeft = new ImageIcon(this.getClass().getResource("bulletLEFT.png"));
            bulletL = bulletLeft.getImage();
    
            ImageIcon bulletRight = new ImageIcon(this.getClass().getResource("bulletRIGHT.png"));
            bulletR = bulletRight.getImage();
    
            ImageIcon bulletUP = new ImageIcon(this.getClass().getResource("bulletUP.png"));
            bulletU = bulletUP.getImage();
    
            ImageIcon bulletDown = new ImageIcon(this.getClass().getResource("bulletDOWN.png"));
            bulletD = bulletDown.getImage();
    
            ImageIcon redDOT = new ImageIcon(this.getClass().getResource("redDOT.png"));
            redd = redDOT.getImage();
    
            ImageIcon brick4Hor = new ImageIcon(this.getClass().getResource("4brickHor.png"));
            brick2 = brick4Hor.getImage();
    
            ImageIcon redline = new ImageIcon(this.getClass().getResource("redline.png"));
            line = redline.getImage();
            line2 = redline.getImage();
    
            ImageIcon redline2 = new ImageIcon(this.getClass().getResource("redlineVert.png"));
            line3 = redline2.getImage();
            line4 = redline2.getImage();
    
            setFocusable(true);
        }
    
           public void gameStart() {
         *****
     }
          latestTime = System.currentTimeMillis();
    
        }
    
        	public void startScreen(Graphics g) {
            *****
        }
    
        	public void fieldObjects(Graphics g){
           *****
        	}
    
        	public void bulletDirection(Graphics g){
           *****
        	}
    
    	    public void score(Graphics g) {
            *****
            }
    
            public void level(Graphics g){
            *****
            }
    
            public void gameOver(Graphics g) {
           *****
        }
    
        public void paintComponent(Graphics g) {
    
            super.paintComponent(g);
    
            if (startScreen) {
            	startScreen(g);
            }
    
            if (gameRunning) {
            	startScreen = false;
            	gameOver = true;
            	fieldObjects(g);
                g.drawImage(redd, dotX, dotY, this);
                bulletDirection(g);
                score(g);
                level(g);
            } else {
            	if (gameOver) {
                gameOver(g);
            	}
            }
    
          Toolkit.getDefaultToolkit().sync();
          g.dispose();
        }
    
    
    
    
    
        public void checkDot() {
    	*****
    	}
    
        private class Keys extends KeyAdapter {
    
            public void keyPressed(KeyEvent e) {
    
    
                int key = e.getKeyCode();
    
                if ((key == KeyEvent.VK_LEFT) && (!right)) {
                    left = true;
                    up = false;
                    down = false;
                }
    
                if ((key == KeyEvent.VK_RIGHT) && (!left)) {
                    right = true;
                    up = false;
                    down = false;
                }
    
                if ((key == KeyEvent.VK_UP) && (!down)) {
                    up = true;
                    right = false;
                    left = false;
                }
    
                if ((key == KeyEvent.VK_DOWN) && (!up)) {
                    down = true;
                    right = false;
                    left = false;
                }
    
                if (key == KeyEvent.VK_ENTER){
                	gameRunning = true;
                	gameStart();
                }
                if (key == 'r' || key == 'R'){
                	*****
                }
    
            }
        }
    
        public void move() {
    
            if (left) {
                dx = -Math.abs(dx);
            }
    
            if (right) {
                dx = Math.abs(dx);
            }
    
            if (up) {
                dy = -Math.abs(dy);
            }
    
            if (down) {
                dy = Math.abs(dy);
            }
    
        *****
    
        }
    
        public void impact() {
    
            if (y > (HEIGHT - 30)) {
                gameRunning = false;
            }
    
            if (y < 0) {
                gameRunning = false;
            }
    
            if (x > (WIDTH - 30)) {
                gameRunning = false;
            }
    
            if (x < 0) {
                gameRunning = false;
            }
    
        }
    
        public void placeDot() {
        	*****
            }
        }
    
    public void actionPerformed(ActionEvent e) {
    
            if (gameRunning) {
                checkDot();
                impact();
                move();
            }
            repaint();
        }
    
    }
    And this is the main class where game gets launched:

    Java Code:
    import javax.swing.JFrame;
    
    
    public class Game extends JFrame {
    
        public Game() {
    
            add(new GameField());
    		String s;
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(606, 653);
            setLocationRelativeTo(null);
            setTitle("Test game");
            setResizable(false);
            setVisible(true);
        }
    
        public static void main(String[] args) {
            new Game();
        }
    }
    At the beginning I used just Timer to move my main object of game, but I realized quite fast that it just doesn't work well. Then I found (in this forum) about Delta time for object moving and added it to my code (do not know if I did that 100% correctly..). Now I get constant speed of animation every moment but not smoothness. What I mean, this deltatime int deltaTime = (int) (newTime - latestTime); shoud be +- the same every moment for animation to be smooth, but it changes from like 3 to 20 and sometimes even more.
    I think problem is in all code construction, but I just can't figure out where exactly =/ I'm stuck on this for about 3 days already, so now I'am asking for help, please.

    Maybe someone can take a look on my code and see where is the main problems in it?

    Thank you already.
    Last edited by Marcz; 04-05-2012 at 04:59 PM. Reason: updated code

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    Eastern Florida
    Posts
    17,587
    Rep Power
    25

    Default Re: 2D game animation not smooth

    Try overriding the paintComponent() method instead of paint()
    If you don't understand my response, don't ignore it, ask a question.

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default Re: 2D game animation not smooth

    Cache the Font objects as instance fields. Constructing Fonts can be computationally expensive. And don't assign FontMetrics references that you never use.

    For a further, if relatively minor performance boost, also make the constant Strings class constants (static final). Although you won't actually be creating new String objects (they will be held in the constant pool) you are unnecessarily creating new references to them each time through the methods called from paint(...).

    There's probably more suboptimal stuff, but I'm finding some parts of your code difficult to read because you don't adhere to the Code Conventions for the Java Programming Language: Contents -- variable names should not start with an uppercase letter, and only static final constants and enums should be in all-uppercase.

    db
    Marcz likes this.
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  4. #4
    Marcz is offline Member
    Join Date
    Apr 2012
    Posts
    5
    Rep Power
    0

    Default Re: 2D game animation not smooth

    Okay, thanks, I will try to do those things mentioned and then tell if it helped!

    Edit: Can You please describe what is the difference between paint() and paintComponent()?

    There's probably more suboptimal stuff, but I'm finding some parts of your code difficult to read because you don't adhere to the Code Conventions for the Java Programming Language: Contents -- variable names should not start with an uppercase letter, and only static final constants and enums should be in all-uppercase.
    Sorry for that, to be honest I didn't knew much about code conventions. I'll be more accurate forward.
    Last edited by Marcz; 04-04-2012 at 10:30 PM.

  5. #5
    Marcz is offline Member
    Join Date
    Apr 2012
    Posts
    5
    Rep Power
    0

    Default Re: 2D game animation not smooth

    Still having problems.. I done things you mentioned, but still repaint() I guess is taking too long (just all loop is taking too long). DELAY is set to 2ms, but I measured that from one move() execution to next it takes like 15-16ms now and the interesting thing is that yesterday evening this same code was again working good (just +1to2 ms per cycle), so it is changing like randomly - it can work fine like 3 hours, then I turn off computer and come back later and it doesnt work fine anymore..
    Also tested on my other PC and there was unsmoothness too.

    Maybe you can suggest some other options? I really would like to get this working fine and I guess I start to seem annoying..

    I updated code at my first post

    Thanks.
    Last edited by Marcz; 04-05-2012 at 11:56 AM.

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default Re: 2D game animation not smooth

    DELAY is set to 2ms, but I measured that from one move() execution to next it takes like 15-16ms now and the interesting thing is that yesterday evening this same code was again working good (just +1to2 ms per cycle)
    On the same computer, with the same OS? or was there something different in the running environment?

    On some Windows versions, timer granularity is approximately in multiples of 16 ms. Run this test rig a few times and post the results here.
    Java Code:
    public class TimerGranularity implements ActionListener {
    
      JLabel label = new JLabel("a");
      int count = 1;
      Timer timer;
      long startTime;
    
      public static void main(String[] args) {
        System.out.println("Java " + System.getProperty("java.version"));
        SwingUtilities.invokeLater(new Runnable() {
    
          @Override
          public void run() {
            new TimerGranularity().startTest();
          }
        });
      }
    
      private void startTest() {
        timer = new Timer(1, this);
        startTime = System.currentTimeMillis();
        timer.start();
      }
    
      @Override
      public void actionPerformed(ActionEvent e) {
        if (count++ % 1000 == 0) {
          stepUpTimer();
        }
      }
    
      void stepUpTimer() {
        int delay = timer.getDelay();
        System.out.println("Set delay: " + delay
                + "  Average delay: " + ((double) (System.currentTimeMillis() - startTime)) / 1000);
        if (delay == 6) {
          System.exit(0);
        }
        timer.setDelay(delay + 1);
        startTime = System.currentTimeMillis();
      }
    }
    These are my results for three runs, Windows 7, tabulated for easy comparison:
    Java Code:
    Java 1.6.0_30
    Set delay: 1  Average delay: 1.954 1.954 1.955
    Set delay: 2  Average delay: 2.049 2.048 2.048
    Set delay: 3  Average delay: 3.945 3.946 3.946
    Set delay: 4  Average delay: 4.936 4.933 4.938
    Set delay: 5  Average delay: 5.951 5.948 5.948
    Set delay: 6  Average delay: 6.943 6.945 6.939
    I updated code at my first post
    Please don't do that again. It makes replies irrelevant, and denies a learning opportunity to those who read this thread later. Feel free to post the updated code as a new response.

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  7. #7
    Marcz is offline Member
    Join Date
    Apr 2012
    Posts
    5
    Rep Power
    0

    Default Re: 2D game animation not smooth

    Java Code:
    Java 1.7.0
    Set delay: 1  Average delay: 15.615	1.971 1.974 1.953
    Set delay: 2  Average delay: 15.6	2.921 2.946 2.927
    Set delay: 3  Average delay: 15.6	3.878 3.941 3.937
    Set delay: 4  Average delay: 14.135	4.911 4.936 4.935
    Set delay: 5  Average delay: 6.002	5.933 5.92	5.924
    Set delay: 6  Average delay: 6.941	6.918 6.938 6.94
    The first results are interesting =/ . And I didn't done everything between run1 and run2.
    I have Windows 7 Ultimate (on other PC which I mentioned also have the same OS)

    So maybe problem is not in my games code?


    edit 1: I just got it! When my browser Firefox is running then delay is fine (actually not if it is just running, but when I'm into webpage where is some of flash/video/ and Java objects too I guess), when I close it, it is again those 15ms. Hmm, whats the reason? Thats interesting.

    edit 2: I did some research on google and found one solution - adding this code at the start of the main method:
    Java Code:
     new Thread()
            {
     
                {
                    this.setDaemon(true);
                    this.start();
                }
     
                public void run()
                {
                    while (true)
                    {
                        try
                        {
                            Thread.sleep(Integer.MAX_VALUE);
                        } catch (InterruptedException ex)
                        {
                        }
                    }
                }
            };
    Still there are maybe some other way how to solve this, without adding this code?
    Last edited by Marcz; 04-05-2012 at 01:13 PM.
    DarrylBurke likes this.

  8. #8
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default Re: 2D game animation not smooth

    It's a fairly old issue. Difficult to say whether the root cause lies somewhere deep inside the JVM/JRE or in the OS itself, but the granularity on Linux even years ago has been reported to be closer to 1 ms.

    Your observation is interesting. I had 4 browsers running when I ran my test rig. I'll try it again, with all other windows closed, to see if there's a difference.

    db

    edit
    Java Code:
    Java 1.6.0_30
    Set delay: 1  Average delay: 15.625
    Set delay: 2  Average delay: 15.625
    Set delay: 3  Average delay: 15.625
    Set delay: 4  Average delay: 15.625
    Set delay: 5  Average delay: 15.625
    Set delay: 6  Average delay: 15.625
    Now to try the fix you posted.

    edit2
    With the daemon thread running:
    Java Code:
    Java 1.6.0_30
    Set delay: 1  Average delay: 1.953
    Set delay: 2  Average delay: 2.049
    Set delay: 3  Average delay: 3.945
    Set delay: 4  Average delay: 4.934
    Set delay: 5  Average delay: 5.952
    Set delay: 6  Average delay: 6.944
    Very interesting. Thanks for contributing your research.
    Last edited by DarrylBurke; 04-05-2012 at 03:08 PM.
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  9. #9
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,423
    Rep Power
    20

    Default Re: 2D game animation not smooth

    It's also interesting that a 2 ms delay is the only value where the observed delay isn't almost 1 ms too long. Wonder what could possibly cause that?

    db
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  10. #10
    Marcz is offline Member
    Join Date
    Apr 2012
    Posts
    5
    Rep Power
    0

    Default Re: 2D game animation not smooth

    Quote Originally Posted by DarrylBurke View Post
    It's also interesting that a 2 ms delay is the only value where the observed delay isn't almost 1 ms too long. Wonder what could possibly cause that?
    Yea thats quite strange. I guess it is something related to system features. For me all delay values are almost 1 ms too long.

    Anyway Thank You for guiding me to discover this "bug", don't know how many more times I would rebuild my code thinking that main problem is in it...

Similar Threads

  1. draw smooth dash-ed line
    By sarveshwar in forum Java 2D
    Replies: 3
    Last Post: 03-01-2011, 08:23 AM
  2. Smooth graphs of functions
    By Ypsilon IV in forum Java 2D
    Replies: 0
    Last Post: 12-04-2010, 06:11 AM
  3. Replies: 7
    Last Post: 04-18-2010, 08:09 AM
  4. smooth-scroll
    By designer in forum Java Applets
    Replies: 1
    Last Post: 07-21-2009, 08:10 PM
  5. How to draw a Smooth Curve using jfreechart
    By Manfizy in forum New To Java
    Replies: 1
    Last Post: 07-07-2009, 10:01 AM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •