Java闪烁图形

时间:2014-03-08 15:24:50

标签: java swing graphics

我正在为邪恶的天才阅读编程视频游戏,我正在使用它的代码。 它编译得很好,但问题是我的图形闪烁。

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();
    }
}

2 个答案:

答案 0 :(得分:4)

1)远离Swing应用中的Thread.sleep()swhile(true)s。使用Swing Timer。见How to Use Swing Timers。另请参阅示例herehere以及herehere以及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);