簡體   English   中英

使用Java Swing進行雙緩沖會留下痕跡

[英]Double Buffering with Java Swing leaving a trail

我正在從事的項目旨在顯示帶有背景的可移動.gif 目前,如果我使用super.paint(g); 然后角色和背景會閃爍。 如果我不這樣做,那么它會像所包含的圖像一樣留下痕跡。 我不知道為什么會這樣,需要幫助。

Java swing的圖像動畫

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JLabel;

public class keyboardinput extends JFrame implements ActionListener, KeyListener {
    private JPanel contentPane;

    private Image playerModelRight;
    private Image playerModelLeft;
    private Image playerModelAttackRight;
    private Image playerModelAttackLeft;
    private Image playerModelStandRight;
    private Image playerModelStandLeft;
    private Image background;
    private Image doubleBuffer;

    private int direction;

    private Timer timer;

    private boolean up;
    private boolean down;
    private boolean left;
    private boolean right;
    private boolean attack;

    private int x, y;
    private int speed = 4;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    keyboardinput frame = new keyboardinput();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public keyboardinput() {

        super("Keyboard input testing");

        x = 200;
        y = 200;

        ImageIcon playerModelIconRight = new    ImageIcon(keyboardinput.class.getResource("/images/bitdashright.gif"));
        playerModelRight = playerModelIconRight.getImage();

        ImageIcon playerModelIconLeft = new ImageIcon(keyboardinput.class.getResource("/images/bitdashleft.gif"));
        playerModelLeft = playerModelIconLeft.getImage();

        ImageIcon playerModelIconStandRight = new ImageIcon(keyboardinput.class.getResource("/images/bitdashstandright.gif"));
        playerModelStandRight = playerModelIconStandRight.getImage();

        ImageIcon playerModelIconStandLeft = new ImageIcon(keyboardinput.class.getResource("/images/bitdashstandleft.gif"));
        playerModelStandLeft = playerModelIconStandLeft.getImage();

        ImageIcon playerModelIconAttackRight = new ImageIcon(keyboardinput.class.getResource("/images/bitdashattackright.gif"));
        playerModelAttackRight = playerModelIconAttackRight.getImage();

        ImageIcon playerModelIconAttackLeft = new ImageIcon(keyboardinput.class.getResource("/images/bitdashattackleft.gif"));
        playerModelAttackLeft = playerModelIconAttackLeft.getImage();

        ImageIcon backgroundIcon = new ImageIcon(keyboardinput.class.getResource("/images/backgroundtest.png"));
        background = backgroundIcon.getImage();

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(50, 50, 800, 500);
        contentPane = new JPanel();

        addKeyListener(this);

        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        timer = new Timer(10, this);
        timer.start();
    }

    public void update(Graphics g) {
        Dimension size = getSize();
        if (doubleBuffer == null || doubleBuffer.getWidth(this) != size.width || doubleBuffer.getHeight(this) != size.height) {
            doubleBuffer = createImage(size.width, size.height);
        }

        if (doubleBuffer != null) {
            Graphics g2 = doubleBuffer.getGraphics();
            paint(g2);
            g2.dispose();

            g.drawImage(doubleBuffer, 0, 0, null);
        } else {
            paint(g);
        }
    }

    public void paint(Graphics g) {
        super.paintComponents(g);
        if (attack) {
            if (direction == 1)
                g.drawImage(playerModelAttackRight, x, y, this);
            if (direction == 0) {
                x -= 15;
                g.drawImage(playerModelAttackLeft, x, y, this);
                x += 15;
            }
        } else if (left && right)
            g.drawImage(playerModelStandRight, x, y, this);
        else if (right)
            g.drawImage(playerModelRight, x, y, this);
        else if (left)
            g.drawImage(playerModelLeft, x, y, this);
        else {
            if (direction == 1)
                g.drawImage(playerModelStandRight, x, y, this);
            if (direction == 0)
                g.drawImage(playerModelStandLeft, x, y, this);
        }
        // g.drawImage(background, 0, 0, this);

    }

    public void actionPerformed(ActionEvent arg0) {
        if (attack)
            return;
        if (up && y > 235)
            y -= speed;
        if (down && y < 430)
            y += speed;
        if (left && x > -10)
            x -= speed;
        if (right && x < 750)
            x += speed;
        repaint();
        System.out.println(x + ", " + y);
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            right = true;
            direction = 1;
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            left = true;
            direction = 0;
        }
        if (e.getKeyCode() == KeyEvent.VK_DOWN)
            down = true;
        if (e.getKeyCode() == KeyEvent.VK_UP)
            up = true;
        if (e.getKeyCode() == KeyEvent.VK_SPACE)
            attack = true;

    }

    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_RIGHT)
            right = false;
        if (e.getKeyCode() == KeyEvent.VK_LEFT)
            left = false;
        if (e.getKeyCode() == KeyEvent.VK_DOWN)
            down = false;
        if (e.getKeyCode() == KeyEvent.VK_UP)
            up = false;
        if (e.getKeyCode() == KeyEvent.VK_SPACE)
            attack = false;
    }

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

    }

}
public void paint(Graphics g) {
    super.paintComponents(g);
  1. 這肯定會帶來麻煩。 不要在覆蓋內調用錯誤的super方法。
  2. 不要直接在JFrame中繪制,而要在JPanel的paintComponent方法中繪制。
  3. 不要在Swing程序中覆蓋update

檢查出的教程:

  1. 您已經破壞了繪畫鏈,調用了super.paintComponents(g); paint內部。 這將不會導致奇怪和奇妙的繪畫問題
  2. 您應該避免覆蓋頂級容器的paint ,因為它們不是雙緩沖的,而是Swing組件,因此,您實際上應該使用JPanel並覆蓋它的paintComponent方法。 您還應該避免像這樣在JFrame類的頂級容器上繪制,因為它將允許您在框架邊框下繪制,永遠不會漂亮,並且JFrame上還有許多其他重疊的組件,這可能會導致問題當它們重新粉刷時(作為子組件,在重新粉刷時可能不會通知其父容器)
  3. 在繪制緩沖區之前,您沒有“重置”緩沖區,因此您將獲得累積更新

您可以“添加” g2.fillRect(0, 0, getWidth(), getHeight()); 在您使用update方法調用paint之前先將代碼添加到代碼中,但是正如我已經說過的,如果正確使用API​​,您將浪費大量時間和精力在API已完成和提供的操作上

詳細了解如何在AWT和Swing執行自定義繪畫繪畫

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM