[英]Double Buffering with Java Swing leaving a trail
我正在從事的項目旨在顯示帶有背景的可移動.gif
。 目前,如果我使用super.paint(g);
然后角色和背景會閃爍。 如果我不這樣做,那么它會像所包含的圖像一樣留下痕跡。 我不知道為什么會這樣,需要幫助。
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);
update
。 請檢查出的教程:
super.paintComponents(g);
從paint
內部。 這將不會導致奇怪和奇妙的繪畫問題 paint
,因為它們不是雙緩沖的,而是Swing組件,因此,您實際上應該使用JPanel
並覆蓋它的paintComponent
方法。 您還應該避免像這樣在JFrame
類的頂級容器上繪制,因為它將允許您在框架邊框下繪制,永遠不會漂亮,並且JFrame
上還有許多其他重疊的組件,這可能會導致問題當它們重新粉刷時(作為子組件,在重新粉刷時可能不會通知其父容器) 您可以“添加” g2.fillRect(0, 0, getWidth(), getHeight());
在您使用update方法調用paint
之前先將代碼添加到代碼中,但是正如我已經說過的,如果正確使用API,您將浪費大量時間和精力在API已完成和提供的操作上
詳細了解如何在AWT和Swing中執行自定義繪畫和繪畫
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.