我正在为邪恶的天才阅读编程视频游戏,我正在使用它的代码。 它编译得很好,但问题是我的图形闪烁。
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();
}
}
答案 0 :(得分:4)
1)远离Swing应用中的Thread.sleep()s
和while(true)s
。使用Swing Timer
。见How to Use Swing Timers。另请参阅示例here和here以及here和here以及here
2)不要在像JFrame
这样的顶级容器上绘画,因为它们已经完成了绘画组件的繁重工作,并且没有双缓冲。而是在JPanel/JComponent
上绘制并覆盖paintComponent
并调用super.paintComponent
,而不是paint
3)从Event Dispatch Thread(EDT)运行Swing应用程序。您可以将new MyGame()
包裹在SwingUtilities.invokeLater...
中。有关详细信息,请参阅Initial Threads。
4)对于你想要绘制的多个对象/形状,你应该采用OOP方法,如this example和上面大多数使用定时器的例子所示。
答案 1 :(得分:1)
您需要double buffer您的JFrame,将以下内容插入到paint方法中:
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);