为什么我在 paintComponent 中的 gif 动画不工作?
Why is my gif animation in paintComponent not working?
我正在创建一个 Java 游戏,在这个游戏中,我有一个可以由用户四处移动的飞机,但是如果飞机撞到任何一侧,它应该爆炸 - 这意味着应该在那个位置发生爆炸。我使用了诸如 Why gif animation doesn't animate when using it in paintComponent()? 和其他链接来了解如何制作 gif 动画,但是,我的代码不起作用。
相关代码如下:
ImageIcon ii = new ImageIcon(this.getClass().getResource("explosion.gif"));
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(ii.getImage(), planeX, planeY, this);
System.out.println("drawn");
尽管控制台上正在打印“drawn”,但不会加载爆炸 gif。我检查了文件名,它是正确的。但是,我确实在我的代码中的其他地方使用了相同的 gif 并且它在那里工作,所以有什么东西可以防止 gif 在 Java?
中被使用两次
这是我的整个 paintComponent() 方法:
super.paintComponent(g);
setFocusable(true);
requestFocus();
background = new ImageIcon("bg.png").getImage();
g.drawImage(background, -6, 0, 700, 700, null); //background of JPanel
if (!hit) g.drawImage(plane, planeX, planeY, planeLen, planeHei, null); //only draw plane if not exploded
else if (count == 0)
{
ImageIcon ii = new ImageIcon(this.getClass().getResource("explosion.gif"));
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(ii.getImage(), planeX, planeY, this); //doesn't work
System.out.println("drawn"); //printed
}
title = new ImageIcon("title.png").getImage(); //transparent, is drawn
g.drawImage(title, -9, 20, 700, 218, null);
title2 = new ImageIcon("title2.png").getImage(); //transparent, is drawn
g.drawImage(title2, 10, 245, 670, 20, null);
我检查了title和title2,是透明的,意思是爆炸应该可以看到。我什至在那两张图片下方尝试过,但仍然看不到爆炸。我也在这个面板上使用 JButtons 和 KeyListeners。
如果我还需要补充什么,请告诉我,在此先感谢您!
没关系,我不得不复制“explosion.gif”。现在工作正常!
但是,如果有另一种更快更有效的方法,请告诉我。谢谢!
您应该始终将 this
作为绘画方法中 drawImage
的最终参数传递。如果图像有多个帧,或者图像在后台加载,这会告诉组件在更多图像可用时再次绘制自身。
组件的绘制经常发生。它由系统控制,而不仅仅是通过调用组件的 repaint
方法的代码。事实上,绘画每秒发生多次是很常见的。许多超出程序员控制的系统事件都可以触发绘制,例如用户移动 window,或另一个 window 移动,甚至用户移动鼠标。
因此,绘画不应执行加载文件等缓慢操作。将图像加载从绘画方法中移出,并移至 class 的构造函数中。将 Image 对象存储在私有字段中,paintComponent 可以在其中一次又一次地使用它们,而无需为每幅画重新加载它们 运行.
由于绘制的时间不受您的控制,因此切勿在绘制方法中更改组件的状态,这一点很重要。将 setFocusable
和 requestFocus
移出您的 paintComponent 方法。这些调用应该在构建组件并将其添加到 window.
的代码中
最后,请注意,如果您将应用程序打包在 .jar 文件中,则无法从文件加载图像。 .jar 文件是单个压缩档案;其中的条目不再是文件,它们只是存档中的字节序列。使用 getResource
加载所有文件将解决此问题,因为 getResource 会查看 class 路径中的每个 .jar 文件。
我正在创建一个 Java 游戏,在这个游戏中,我有一个可以由用户四处移动的飞机,但是如果飞机撞到任何一侧,它应该爆炸 - 这意味着应该在那个位置发生爆炸。我使用了诸如 Why gif animation doesn't animate when using it in paintComponent()? 和其他链接来了解如何制作 gif 动画,但是,我的代码不起作用。
相关代码如下:
ImageIcon ii = new ImageIcon(this.getClass().getResource("explosion.gif"));
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(ii.getImage(), planeX, planeY, this);
System.out.println("drawn");
尽管控制台上正在打印“drawn”,但不会加载爆炸 gif。我检查了文件名,它是正确的。但是,我确实在我的代码中的其他地方使用了相同的 gif 并且它在那里工作,所以有什么东西可以防止 gif 在 Java?
中被使用两次这是我的整个 paintComponent() 方法:
super.paintComponent(g);
setFocusable(true);
requestFocus();
background = new ImageIcon("bg.png").getImage();
g.drawImage(background, -6, 0, 700, 700, null); //background of JPanel
if (!hit) g.drawImage(plane, planeX, planeY, planeLen, planeHei, null); //only draw plane if not exploded
else if (count == 0)
{
ImageIcon ii = new ImageIcon(this.getClass().getResource("explosion.gif"));
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(ii.getImage(), planeX, planeY, this); //doesn't work
System.out.println("drawn"); //printed
}
title = new ImageIcon("title.png").getImage(); //transparent, is drawn
g.drawImage(title, -9, 20, 700, 218, null);
title2 = new ImageIcon("title2.png").getImage(); //transparent, is drawn
g.drawImage(title2, 10, 245, 670, 20, null);
我检查了title和title2,是透明的,意思是爆炸应该可以看到。我什至在那两张图片下方尝试过,但仍然看不到爆炸。我也在这个面板上使用 JButtons 和 KeyListeners。
如果我还需要补充什么,请告诉我,在此先感谢您!
没关系,我不得不复制“explosion.gif”。现在工作正常! 但是,如果有另一种更快更有效的方法,请告诉我。谢谢!
您应该始终将 this
作为绘画方法中 drawImage
的最终参数传递。如果图像有多个帧,或者图像在后台加载,这会告诉组件在更多图像可用时再次绘制自身。
组件的绘制经常发生。它由系统控制,而不仅仅是通过调用组件的 repaint
方法的代码。事实上,绘画每秒发生多次是很常见的。许多超出程序员控制的系统事件都可以触发绘制,例如用户移动 window,或另一个 window 移动,甚至用户移动鼠标。
因此,绘画不应执行加载文件等缓慢操作。将图像加载从绘画方法中移出,并移至 class 的构造函数中。将 Image 对象存储在私有字段中,paintComponent 可以在其中一次又一次地使用它们,而无需为每幅画重新加载它们 运行.
由于绘制的时间不受您的控制,因此切勿在绘制方法中更改组件的状态,这一点很重要。将 setFocusable
和 requestFocus
移出您的 paintComponent 方法。这些调用应该在构建组件并将其添加到 window.
最后,请注意,如果您将应用程序打包在 .jar 文件中,则无法从文件加载图像。 .jar 文件是单个压缩档案;其中的条目不再是文件,它们只是存档中的字节序列。使用 getResource
加载所有文件将解决此问题,因为 getResource 会查看 class 路径中的每个 .jar 文件。