【问题标题】:Graphics flashing图形闪烁
【发布时间】:2011-10-21 21:32:33
【问题描述】:

当我运行程序时,一切正常,一切正常,但图形不断闪烁。我是做这种事情的新手,我不知道如何解决这个问题。

import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;


public class MovementTest extends Frame implements Runnable, MouseMotionListener, KeyListener {

    private static Thread thread;
    private int mouseX, mouseY;
    private boolean movingRight;
    private boolean movingLeft;
    private boolean movingUp;
    private boolean movingDown;

    private Rectangle player = new Rectangle(50, 50, 100, 100);
    private Rectangle wallOne = new Rectangle(400, 50, 100, 100);

    public MovementTest() {
        setSize(800, 600);
        setVisible(true);
        addKeyListener(this);
        addMouseMotionListener(this);
    }

    public static void main(String[] args) {
        thread = new Thread(new MovementTest());
        thread.start();
    }

    @Override
    public void run() {
        try {
            while(true) {
                if(player.intersects(wallOne)) {
                    thread.stop();
                    break;
                }
                if(movingRight) {
                    player.x++;
                } else if(movingLeft) {
                    player.x--;
                }
                if(movingUp) {
                    player.y--;
                } else if(movingDown) {
                    player.y++;
                }
                paint(getGraphics());
                Thread.sleep(5);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_D)
            movingRight = true;
        if (key == KeyEvent.VK_A)
            movingLeft = true;
        if (key == KeyEvent.VK_W)
            movingUp = true;
        if (key == KeyEvent.VK_S)
            movingDown = true;
    }

    @Override
    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_D)
            movingRight = false;
        if (key == KeyEvent.VK_A)
            movingLeft = false;
        if (key == KeyEvent.VK_W)
            movingUp = false;
        if (key == KeyEvent.VK_S)
            movingDown = false;
    }

    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub

    }

    public void paint(Graphics g) {
        g.drawString("x: " + mouseX + " y: " + mouseY, 5, 35);
        g.drawRect(player.x, player.y, 100, 100);
        g.drawRect(wallOne.x, wallOne.y, 100, 100);
        repaint();
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void mouseMoved(MouseEvent e) {
        mouseX = e.getX();
        mouseY = e.getY();
    }
}

【问题讨论】:

  • 我没听懂最后一句话。
  • 最后一句由 Stack Overflow 生成。我不知道他是如何在他的帖子中结束的,它应该只是一个消息。
  • 您不使用 Swing 有什么原因吗?你不应该直接打电话给paint()(而是打电话给repaint())。编写自己的更新循环是要求让自己发疯;查找Events/Listeners。尝试tutorial 可能对您有最大的帮助。

标签: java swing graphics2d keylistener


【解决方案1】:

您肯定想研究双缓冲。现在你正在做的是将所有内容直接绘制到屏幕上,并且用户会看到这一点。双缓冲的作用是首先在屏幕外缓冲区(图像)上绘制所有内容,一旦计算完所有内容并且图像准备就绪,您将屏幕外缓冲区绘制到可见缓冲区(因此用户只能看到最后一帧而不是中间帧)。

这与 OpenGL 或 Direct3D 应用程序最常用的功能类似。他们有两个缓冲区。一切都被绘制到屏幕外缓冲区,一旦完成,缓冲区就会被交换,现在屏幕外的缓冲区被清除,之后再次在其上绘制新图像。

正如glowcoder 还指出的那样,您的fps 非常高。尝试将其与显示器的刷新率同步,以避免浪费资源绘制的次数过多。

【讨论】:

    【解决方案2】:

    从你的绘画方法中去掉重绘。你真的不希望它在那里。这就是导致您的问题的原因。

    然后,添加它 - 从长远来看,它有助于保持事情的井井有条。

    public void update() {
        repaint();
    }
    

    然后,在你移动东西的地方添加重绘方法。您还需要为您的绘画方法添加一个清除。这实际上会让你的矩形移动。 更新:我注意到你已经有了一些东西可以重绘你的东西。出色的。虽然它真的很快(200 fps !!)所以你肯定想研究双缓冲。

    稍后我们可以讨论双缓冲 :) 但是你可以谷歌搜索一下。

    【讨论】:

    • @user 在编译完您的示例后,您似乎也无法移动矩形 :-) 我在您的绘制方法中添加了以下行:g.clearRect(0,0,800,600); - 这为您提供了一个清晰的工作屏幕每次。它会导致新的闪烁,您需要双缓冲才能摆脱它,但您至少现在可以看到您的 XY 坐标,而不是随着时间的推移它们变成一个巨大的黑匣子 :)
    • 我收回了。如果你使用正确的键,你会移动哈哈哈。我使用的是箭头键,而不是 WADS。 :-) 但清除仍然效果最好。
    猜你喜欢
    • 2011-02-06
    • 2013-01-09
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 2014-08-12
    • 2011-11-22
    • 1970-01-01
    相关资源
    最近更新 更多