Java Canvas repaint()正在闪烁

时间:2015-04-03 01:21:47

标签: java canvas repaint flicker

所以我终于让Canvas以我想要的方式工作,但它不断闪烁,repaint()每秒运行20次,当我每秒运行10次时轻弹就会减弱。

package pd.data;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;

import pd.areas.MainMenu;

@SuppressWarnings("serial")
public class Main extends JFrame implements Runnable {

    private JPanel contentPane = new JPanel();

    private Thread gameThread = new Thread(this);
    public boolean running = false;



    @SuppressWarnings("unused")
    private int current = PDU.PD_MAIN_MENU;
    private MainMenu mainmenu;

    public Main() {main.setTitle("PD");
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main.setLocation(SPU.screenWidth / 2 - SPU.windowSize.width / 2,
                SPU.screenHeight / 2 - SPU.windowSize.height / 2);
        main.setResizable(false);
        main.setVisible(true);
        contentPane.setLayout(new BorderLayout(0, 0));
        contentPane.setPreferredSize(SPU.windowSize);
        main.setContentPane(contentPane);
        main.pack();
        mainmenu = new MainMenu();

        contentPane.add(mainmenu, BorderLayout.CENTER);
        this.gameThread.start();
    }

    @Override
    public void run() {
        running = true;
        while (running) {
            {
                mainmenu.repaint();
            }
            try {
                Thread.sleep(SPU.TSU);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
    public static void main(String[] args) {
        new Main();
    }
}

以下是我的MainMenu课程:

package pd.areas;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

@SuppressWarnings("serial")
public class MainMenu extends Canvas{

    BufferedImage img = null;
    public MainMenu() {
        this.setBackground(Color.BLACK);

    }
    public void paint(Graphics graphics){

        try {
            img = ImageIO.read(this.getClass().getResource(
                    "/image.png"));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        graphics.drawImage(img, this.getWidth() / 2 - img.getWidth()/2, 50, null);
    }

}

虽然闪烁实际上是一个很好的效果,它会影响整个画布,而不仅仅是我猜的图像,我该如何修复闪烁?

2 个答案:

答案 0 :(得分:3)

  1. 不要使用java.awt.Canvas。改为使用JPanel。
  2. 在JPanel的paintComponent方法中绘制。
  3. 不要忘记给你的超级绘画方法打电话paintComponent super.paintComponent(graphics)
  4. 从不尝试从任何绘画方法中读取图像。这将减慢绘画速度,使你的程序看起来没有反应。为什么要一遍又一遍地读同一张图片呢?请在一次中阅读并将其保存到变量中。

答案 1 :(得分:0)

尽管这个帖子是在 5 年前打开的,但对于 Java SE 的新手来说仍然是一个问题。

我自己在使用 Canvas 时也遇到了同样的问题,但我没有足够的信心切换到 javax 组件,因为我想起了一个名为 JVLC 的 VLC 项目,该项目使用 Canvas 完美呈现视频(授予 jvlc 使用一些本机代码)。

提示 1:也许最好试试 JPanel。

提示 2:在游戏系统中,最好使用游戏引擎(它会为您节省大量时间)。

提示 3:在游戏系统中,实现 fps 机制,而不是在每次更改时调用 repaint()。

提示 4:如果您必须在您的paint() 实现中调用超过10 行的代码,那么您会减慢它的速度。最好为您需要对应用程序进行的每个图形更改绘制到 BufferedImage,然后让paint() 实现本身仅绘制图像本身。这应该可以很好地与 fps 机制配合使用,并且会减少任何闪烁的机会。