我正在使用线程来显示带有精灵的动画。
Explosion e2 = new Explosion(this, x2, y2, explosion);
new Thread(e2).start();
在爆炸课上我有:
public void run()
{
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
cursor++;
}
};
Timer timer = new Timer(50, taskPerformer);
while(cursor < (sprite.getNbSprite()-1))
{
timer.start();
drawExplosion();
}
timer.stop();
compteur--;
}
public void drawExplosion()
{
Graphics g = board.getGraphics();
board.repaint();
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(sprite.getSprite(cursor), x, y, this);
g.dispose();
}
但是在显示过程中我遇到了问题,在精灵的每个图像之间都有一个空白。 就像显示器闪烁一样。
我怎样才能展示液体? 感谢
编辑----------------------- 我还有一个问题。 在我的Board类中,我把我的爆炸放在了ArrayList中。 但是当爆炸线程结束时我要删除ArrayList中的对象。 我有一个ArrayList来存储我的所有爆炸线程吗?当一个线程结束时我删除了爆炸ArrayList中的对象。 公共类委员会延伸JPanel {
Mouse mouse;
ArrayList<Explosion> explosions;
Sprite explosion;
public Board()
{
mouse = new Mouse(this);
explosion = new Sprite(320,320,5,5,"files/explosion2.png");
explosions = new ArrayList();
setDoubleBuffered(true);
this.addMouseListener(mouse);
}
public void addExplosion(int x, int y)
{
for(int i=0; i<100; i++)
{
int x2 = (int)(Math.random() * 450);
int y2 = (int)(Math.random() * 450);
Explosion e2 = new Explosion(this, x2, y2, explosion);
explosions.add(e2);
new Thread(e2).start();
}
}
public void removeExplosion(Explosion e)
{
explosions.remove(e);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
for(int i=0; i<explosions.size(); i++)
{
g2d.drawImage(explosion.getSprite(explosions.get(i).getCursorI()), explosions.get(i).getX(), explosions.get(i).getY(), this);
}
g.dispose();
}
}
答案 0 :(得分:2)
你似乎做了很多错事,包括
getGraphics()
获取图形对象,但没有获得持久的Graphics对象。相反,
如果您仍然遇到困难,请考虑创建并发布展示您问题的sscce。
答案 1 :(得分:1)
在Swing中,你必须在EDT中完成与Swing相关的所有事情。
// This actually calls paint() in the Swing EDT
board.repaint();
// This runs on your main thread
// (Never paint anything outside of the EDT!)
g2d.drawImage(sprite.getSprite(cursor), x, y, this);
你看到一些眨眼,因为board
在两个不同的线程中完成了一些绘画并绘制了两个不同的东西。
您需要做的是创建class BoardWithSprite extend JPanel
它会覆盖其paintComponent(g)
方法,以便绘制精灵。
然后你可以打电话给boardWithSprite.repaint()
,它会在Swing EDT上正确地进行绘画。
答案 2 :(得分:1)
Timer.start()
方法用于启动计时器,只应调用一次。它导致ActionListener
对象以Timer
构造函数中指定的间隔调用。在您的情况下,它将每50毫秒递增一次cursor
变量。
您可能希望研究一种名为双缓冲的技术。这涉及使用两个图像缓冲区来渲染屏幕上的图像。它的工作原理如下:不是将图像直接绘制到屏幕上,而是将其绘制到内存缓冲区中。只有在完成渲染整个框架时,才会在屏幕上显示框架。这有助于消除闪烁。
对于第二帧,您执行相同的操作,只有您绘制到第二个缓冲区,因为当前正在使用第一个缓冲区在屏幕上显示图像。完成绘制第二帧后,然后将第二个缓冲区发送到屏幕并使用 first 缓冲区渲染下一帧,依此类推。
在屏幕上显示每个帧之前渲染每个帧应该有助于消除闪烁。