Reputation: 1076
I am reading programming video games for the evil genius, and i am using its code. It compiles well, but the problem is that my graphic is flashing.
import java.awt.*;
import javax.swing.*;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author kaldren
*/
public class MyGame extends JFrame {
final int WIDTH = 900, HEIGHT = 650;
double p1Speed = .5, p2Speed = .5;
Rectangle left = new Rectangle(0, 0, WIDTH / 9, HEIGHT);
Rectangle right = new Rectangle((WIDTH / 9) * 9, 0, WIDTH / 9, HEIGHT);
Rectangle top = new Rectangle(0, 0, WIDTH, HEIGHT / 9);
Rectangle bottom = new Rectangle(0, (HEIGHT / 9) * 9, WIDTH, HEIGHT / 9);
Rectangle center = new Rectangle((int) ((WIDTH / 9) * 2.5), (int)
((HEIGHT / 9) * 2.5), (int) ((WIDTH / 9) * 5), (HEIGHT / 9) * 4);
Rectangle obstacle = new Rectangle(WIDTH / 2, (int) ((HEIGHT / 9) * 7), WIDTH / 10, HEIGHT / 9);
Rectangle obstacle2 = new Rectangle(WIDTH / 3, (int) ((HEIGHT / 9) * 5), WIDTH / 10, HEIGHT / 4);
Rectangle obstacle3 = new Rectangle(2 * (WIDTH / 3), (int) ((HEIGHT / 9) * 5), WIDTH / 10, HEIGHT / 4);
Rectangle obstacle4 = new Rectangle(WIDTH / 3, HEIGHT / 9, WIDTH / 30, HEIGHT / 9);
Rectangle obstacle5 = new Rectangle(WIDTH / 2, (int) ((HEIGHT / 9) * 1.5), WIDTH / 30, HEIGHT / 4);
Rectangle finish = new Rectangle(WIDTH / 9, (HEIGHT / 2) - HEIGHT / 9, (int) ((WIDTH / 9) * 1.5), HEIGHT / 70);
Rectangle p1 = new Rectangle(WIDTH / 9, HEIGHT / 2, WIDTH / 30, WIDTH / 30);
Rectangle p2 = new Rectangle(((WIDTH / 9) + ((int) ((WIDTH / 9) * 1.5) / 2)), (HEIGHT / 2) + (HEIGHT / 10),
WIDTH / 30, WIDTH / 30);
public MyGame() {
super("Radical Racing");
setSize(WIDTH, HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Move1 m1 = new Move1();
Move2 m2 = new Move2();
m1.start();
m2.start();
}
public void paint(Graphics g)
{
super.paint(g);
g.setColor(Color.DARK_GRAY);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.GREEN);
Rectangle line0 = new Rectangle(WIDTH / 9, HEIGHT / 2, (int) ((WIDTH / 9) * 1.5) / 2, HEIGHT / 140);
Rectangle line1 = new Rectangle(((WIDTH / 9) + ((int) ((WIDTH / 9) * 1.5) / 2)), (HEIGHT / 2) +
(HEIGHT / 10), (int) ((WIDTH / 9) * 1.5) / 2, HEIGHT / 140);
g.fillRect(left.x, left.y, left.width, left.height);
g.fillRect(right.x, right.y, right.width, right.height);
g.fillRect(top.x, top.y, top.width, top.height);
g.fillRect(bottom.x, bottom.y, bottom.width, bottom.height);
g.fillRect(center.x, center.y, center.width, center.height);
g.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
g.fillRect(obstacle2.x, obstacle2.y, obstacle2.width, obstacle2.height);
g.fillRect(obstacle3.x, obstacle3.y, obstacle3.width, obstacle3.height);
g.fillRect(obstacle4.x, obstacle4.y, obstacle4.width, obstacle4.height);
g.fillRect(obstacle5.x, obstacle5.y, obstacle5.width, obstacle5.height);
g.setColor(Color.WHITE);
g.fillRect(line0.x, line0.y, line0.width, line0.height);
g.fillRect(line1.x, line1.y, line1.width, line1.height);
g.setColor(Color.YELLOW);
g.fillRect(finish.x, finish.y, finish.width, finish.height);
g.setColor(Color.BLUE);
g.fill3DRect(p1.x, p1.y, p1.width, p1.height, true);
g.setColor(Color.RED);
g.fill3DRect(p2.x, p2.y, p2.width, p2.height, true);
}
public class Move1 extends Thread {
public void run() {
while (true) {
try {
repaint();
if (p1Speed <= 5)
p1Speed += .2;
p1.y -= p1Speed;
Thread.sleep(75);
} catch (Exception e) {
break;
}
}
}
}
public class Move2 extends Thread
{
public void run()
{
while(true)
{
try
{
repaint();
if(p2Speed <= 5)
p2Speed+=.2;
p2.y-=p2Speed;
Thread.sleep(75);
} catch (Exception e) {break;}
}
}
}
public static void main(String[] args) {
new MyGame();
}
}
Upvotes: 0
Views: 466
Reputation: 209102
1) Stay away from Thread.sleep()s
and while(true)s
in Swing apps. Use a Swing Timer
. See How to Use Swing Timers. Also see examples here and here and here and here and here
2) Don't paint on top-level containers like JFrame
cause they already do the heavy lifting of painting component and they aren't double buffered. Instead paint on JPanel/JComponent
and override paintComponent
and call super.paintComponent
, not paint
3) Run Swing apps from the Event Dispatch Thread (EDT). You can do so by wrapping your new MyGame()
in a SwingUtilities.invokeLater...
. See Initial Threads for more details.
4) For multiple objects/shapes you want to draw, you should take an OOP approach, as seen in this example and most the other example above using Timers.
Upvotes: 4
Reputation: 1878
You will need to double buffer your JFrame, insert the following into your paint method:
BufferedImage bufferedImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();
//Paint using g2d instead of g, example g2d.fillRect(0, 0, 1, 1);
Graphics2D g2dComponent = (Graphics2D) g;
g2dComponent.drawImage(bufferedImage, null, 0, 0);
Upvotes: 1