java - 如何修复不良的双缓冲

标签 java graphics awt flicker double-buffering

我尝试遵循双缓冲教程,但我真的不知道我做错了什么。在我完成教程之前它就可以工作,但仍然偶尔会出现闪烁。我有两个文件 Game 和 gameLoop

游戏:

import java.awt.Graphics;
public class Game extends gameLoop
{
    public void init()
    {
        setSize(854,480);
        Thread th = new Thread(this);
        th.start();
        offscreen = createImage(854,480);
        d = offscreen.getGraphics();
    }
    public void paint(Graphics g)
    {
        d.clearRect(0, 0, 854, 480);
        d.drawImage(disk, x, y, this);
        g.drawImage(offscreen , 0, 0, this);
    }
    public void Update(Graphics gfx)
    {
        paint(gfx);
    }
}

游戏循环

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

public class gameLoop extends Applet implements Runnable, MouseListener, MouseMotionListener 
{
    public int x, y, counter, mouseX, mouseY;
    public Image offscreen;
    public Graphics d;
    public boolean up, down, left, right, pressed;
    public BufferedImage disk1, disk2, disk3, disk4, disk;
    public int ballSpeedX = -6;
    public int ballSpeedY = -3;

    public void run() 
    {
        x = 400;
        y = 200;
        try {
            disk1 = ImageIO.read(new File("disk1.png"));
            disk2 = ImageIO.read(new File("disk2.png"));
            disk3 = ImageIO.read(new File("disk3.png"));
            disk4 = ImageIO.read(new File("disk4.png"));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        while(true)
        {
            if(x >= (854 - 150))
            {
                    ballSpeedX = ballSpeedX * -1;
            }
            if(y >= (480 - 140))
            {
                    ballSpeedY = ballSpeedY * -1;
            }
            if(y < (0 - 10))
            {
                    ballSpeedY = ballSpeedY * -1;
            }
            if(x < (0- 10))
            {
                    ballSpeedX = ballSpeedX * -1;
            }

            x = x + ballSpeedX;
            y = y + ballSpeedY;

            counter ++;
            if(counter >= 4)
                counter = 0;

            if(counter == 0)
                disk = disk1;
            if(counter == 1)
                disk = disk2;
            if(counter == 2)
                disk = disk3;
            if(counter == 3)
                disk = disk4;

            System.out.println(counter);

            repaint();

            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }



    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseMoved(MouseEvent m) {}

    public void mousePressed(MouseEvent m) 
    {

    }

    public void mouseReleased(MouseEvent m) 
    {
        pressed = false;
    }

    public void mouseDragged(MouseEvent e) {
        PointerInfo a = MouseInfo.getPointerInfo();
        Point b  = a.getLocation();
        mouseX = (int)b.getX();
        mouseY = (int)b.getY();
        ballSpeedX = mouseX;
        ballSpeedY = mouseY;
    }
}

最佳答案

public void Update(Graphics gfx)
{
    paint(gfx);
}

应为小写,因为您尝试重写 Applet 中的 update(Graphics g) 方法。

应该是这样

@Override
public void update(Graphics gfx)
{
    paint(gfx);
}

至于更改背景,背景只是一个覆盖屏幕并使其具有某种颜色的大矩形。在 paint 中,您正在执行 clearRect,这会清除屏幕。相反,只需在设置颜色后将其切换为 fillRect 即可。

它可能看起来像

public void paint(Graphics g)
{
    //setColor to whatever you want
    //fillRect to cover the screen
}

当你这样做时,你必须记住的一件事是不要混淆你的两个图形对象。作为一个概念,双缓冲的工作原理是首先绘制到内存(将其绘制在屏幕外图像上),然后绘制到屏幕。您希望始终在该屏幕外图像上进行绘制,因为它的速度要快得多(并且我们不会出现闪烁)。

因此,请确保您执行的是 imageGraphicsObject.setColor 而不是 screenGraphicsObject.setColor 或 imageGraphicsObject.fillRect而不是screenGraphicsObject.fillRect`。否则你就不再是双缓冲了。

关于java - 如何修复不良的双缓冲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15891698/

相关文章:

java - 如何在 Hibernate 的 XML 文件中声明一对多映射?

java - 启动 Web 应用程序时出现 IllegalStateException - Spring + Wicket

android - OpenGL 二维水模拟

php - 使用 PHP 的图形用法(使用数据库中的数据创建条形图)

iphone - 通过贝塞尔曲线绘制路径

java - 用Java从一个角度画线

java - 使用java获取System32文件夹位置

java - IntelliJ 快捷方式将对象重构为对象列表

Java在设置组件大小时重用Dimension对象

java - JFileChooser 在 Linux 下不是模态的