Reputation: 13
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
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
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