画布中相同动画GIF的多个实例(Java)

画布中相同动画GIF的多个实例(Java),java,swing,gif,graphics2d,animated-gif,Java,Swing,Gif,Graphics2d,Animated Gif,所以我在做一个游戏,你可以把炸弹放在你角色的位置上。当炸弹显示并最终爆炸时,每个炸弹都与GIF图像关联(想想Bomberman) 问题是,当我试图在屏幕上绘制多个炸弹时,它是从GIF的最后一帧开始绘制的。通过调查,我找到了方法image.flush()来重置GIF循环,但现在的问题是,每次我在屏幕上绘制第二个炸弹时,屏幕上所有以前的炸弹的GIF循环都会重置 以下是我为每个炸弹设计的构造器: public Tnt(int x, int y){ this.x = x; this.y

所以我在做一个游戏,你可以把炸弹放在你角色的位置上。当炸弹显示并最终爆炸时,每个炸弹都与GIF图像关联(想想Bomberman)

问题是,当我试图在屏幕上绘制多个炸弹时,它是从GIF的最后一帧开始绘制的。通过调查,我找到了方法image.flush()来重置GIF循环,但现在的问题是,每次我在屏幕上绘制第二个炸弹时,屏幕上所有以前的炸弹的GIF循环都会重置

以下是我为每个炸弹设计的构造器:

public Tnt(int x, int y){
    this.x = x;
    this.y = y;
    ImageIcon ii = new ImageIcon("src/main/resources/modelObjects/tnt.gif");
    image = ii.getImage();
    image.flush();
}
我创建的每个炸弹都会进入一个ArrayList(listTnt)并在6秒后被移除,因此我只会绘制已经激活的炸弹

以下是我的绘图方法:

public void draw(Graphics2D g2d, JPanel board){
    for(Tnt tnt: listTnt){          
        g2d.drawImage(tnt.getImage(), tnt.getX(), tnt.getY(), board);
    }
}
编辑:问题似乎是ImageIcon,因为它使用Toolkit.getImage重用图像。相反,Toolkit.createImage会创建一个不可重用的映像

这是我的Tnt新构造函数,它工作得非常好:

public Tnt(int x, int y){
    this.x = x;
    this.y = y;
    Toolkit t = Toolkit.getDefaultToolkit ();
    image = t.createImage("src/main/resources/modelObjects/tnt.gif");
}

我现在甚至不需要
image.flush()
。谢谢大家

基础的
图像
在每个
图像图标
之间重复使用。 从图像中判断,这似乎是由于每个人都只是通过请求图像。 然而,这种方法有一个巧妙的警告,它解释了当前的问题:

底层工具包尝试将具有相同文件名的多个请求解析为相同的返回图像

相反,您应该完全跳过
ImageIcon
步骤(因为首先不必要地使用Swing类是不合适的),而是调用,文档中说明:

返回的图像是一个新对象,不会与此方法或其getImage变量的任何其他调用方共享


祝你好运。

由于我不知道如何解决这个问题,我尝试了@super_uu解决方案,效果非常好。我为任何想要示例的人共享代码+我向他道歉

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class TestAnimatedGif {

    private static final int IMAGE_COUNT = 9;

    protected void initUI() {
        JFrame frame = new JFrame(TestAnimatedGif.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JPanel panel = new JPanel();
        frame.add(panel);
        frame.setSize(600, 400);
        frame.setVisible(true);
        final Timer t = new Timer(1000, null);
        t.addActionListener(new ActionListener() {

            int count = 0;

            @Override
            public void actionPerformed(ActionEvent e) {
                if (count < IMAGE_COUNT) {
                    try {
                        JLabel image = new JLabel(new ImageIcon(Toolkit.getDefaultToolkit().createImage(
                                new URL("http://www.sitevip.net/gifs/bomba/BOMB-B_animado.gif"))));
                        panel.add(image);
                        count++;
                        panel.revalidate();
                        panel.repaint();
                        System.err.println("image added");
                    } catch (MalformedURLException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                } else {
                    t.stop();
                }
            }
        });
        t.start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestAnimatedGif().initUI();
            }
        });
    }

}
导入java.awt.Toolkit;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.net.MalformedURLException;
导入java.net.URL;
导入javax.swing.ImageIcon;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
导入javax.swing.Timer;
公共类TestAnimatedGif{
私有静态最终整数图像计数=9;
受保护的void initUI(){
JFrame=newJFrame(TestAnimatedGif.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
最终JPanel面板=新JPanel();
框架。添加(面板);
框架。设置尺寸(600400);
frame.setVisible(true);
最终定时器t=新定时器(1000,空);
t、 addActionListener(新ActionListener(){
整数计数=0;
@凌驾
已执行的公共无效操作(操作事件e){
如果(计数<图像计数){
试一试{
JLabel image=new JLabel(新图像图标(Toolkit.getDefaultToolkit().createImage(
新网址(“http://www.sitevip.net/gifs/bomba/BOMB-B_animado.gif"))));
面板。添加(图像);
计数++;
panel.revalidate();
panel.repaint();
System.err.println(“添加图像”);
}捕获(格式错误的异常e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}
}否则{
t、 停止();
}
}
});
t、 start();
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
newtestanimatedgif().initUI();
}
});
}
}

图像的范围是什么?在应用程序的主游戏状态中,我有一个炸弹列表。当我在游戏中投下炸弹时,一个新的Tnt被创建并添加到列表中,6秒后(炸弹生命周期),炸弹从列表中移除。
draw
方法仅从列表中绘制炸弹,
image
是Tnt中的一个变量。另请参见+1漂亮的解释和解决方案。我在尝试之前不知道的解决方案时添加了一个示例代码。