BOSIG
BOSIG

Reputation: 13

Java graphics update stutters heavily (simple pong game)

Im new to more dynamic java swing programing. I have of course used the regular swing components before with Buttons, Panels and more.

So I'm trying to make a very basic pong game using Swing and Graphics2D. I previously made a painting program which i succeeded to do.

My issue is that the graphics stutters heavily when the program is running. So far I have only implemented the ball and its just choosing a random direction and starts to bounce around in the panel. Which works. But, I can only see the ball if I'm constantly resizing the frame all the time, otherwise it stutters so heavily that it looks blank. In the first second or so you can actually see the ball moving, but heavily stuttering, and then the panel start to seem blank.

Relevant code and structure:

Main parts of the program are the Controller and Frame class. Where the Controller implements runnable and contains a run method that does the game updating.

The Frame class extends JFrame and contains a private instance variable JPanel gamePanel where all the graphics are painted. JFrame also has a Overridden paint(); method

When the Controller updates the program it calls a class in Frame called updateGraphics() which previously called paint(getGraphics());

public class Frame extends JFrame {

    private JPanel gamePanel;

    ....

    public void paint(Graphics g) {
        super.paint(g);

        label.setText(Integer.toString(ball.getPos().x) + ", " +  Integer.toString(ball.getPos().y));
        Graphics2D g2 = (Graphics2D) gamePanel.getGraphics();
        g2.setStroke(new BasicStroke(2));
        //g2.drawRect(0, 0, gamePanel.getWidth(), gamePanel.getHeight());

        try{
            //Draws the ball
            g2.fillOval(ball.getPos().x, ball.getPos().y, 10, 10);

            //Draws the player1(left) shield
            g2.setStroke(new BasicStroke(2));
            g2.drawLine(playerShield.getNorthX(), playerShield.getNorthY(), playerShield.getSouthX(), playerShield.getSouthY());
            g2.drawLine(playerShield.getNorthX(), playerShield.getNorthY(), playerShield.getSouthX(), playerShield.getSouthY());

            //Draws the computer/Player2(right) Shield
            g2.drawLine(computerShield.getNorthX(), computerShield.getNorthY(), computerShield.getSouthX(), computerShield.getSouthY());
            g2.drawLine(computerShield.getNorthX(), computerShield.getNorthY(), computerShield.getSouthX(), computerShield.getSouthY());
        } catch(Exception e) {
            System.out.println(e);
        }
    }

    ...

    public void updateGraphics() {
          paint(getGraphics());
    }

    //Another version of the updateGraphics i have tried to use with as little success

    public void updateGrapgics() {
         gamePanel.validate();
         gamePanel.repaint();
    }

}

When searching I have found people that says that I should and shouldn't use the paint or repaint method.

Can someone explain to me why its stuttering and how I should do to make it stutter-free?

Upvotes: 0

Views: 1369

Answers (2)

akhikhl
akhikhl

Reputation: 2578

There's no need to implement double-buffering or other tricks. Just do the following:

public class SomeVisualObject extends JComponent {
  public void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D)g;  
    // paint things
  }
}

...
final SomeVisualObject obj = new SomeVisualObject()
frame.add(obj);
...

final Timer repaintTimer = new Timer(20, new ActionListener() {
  public void actionPerformed(ActionEvent evt) {
    // do some stuff here, for example calculate game physics.
    // repaint actually does not repaint anything, but enqueues repaint request
    obj.repaint();
  }
});
repaintTimer.start();

and it will run and paint smoothly, without glitches.

Just don't mess with the loops. Swing runs it's own event loop, which is vital for repaints and other stuff.

See a complete and working example of 2d game object (bouncing ball) here: https://gist.github.com/akhikhl/8199472

Upvotes: 1

Krystian Lieber
Krystian Lieber

Reputation: 481

I think that you should implement some kind of double buffering.

Your problem is simillar to this one Java Panel Double Buffering and this tutorial should help you a lot http://www.cokeandcode.com/info/tut2d.html.

Upvotes: 0

Related Questions