为啥我在 paintComponent 中的 gif 动画不起作用?
Posted
技术标签:
【中文标题】为啥我在 paintComponent 中的 gif 动画不起作用?【英文标题】:Why is my gif animation in paintComponent not working?为什么我在 paintComponent 中的 gif 动画不起作用? 【发布时间】:2021-07-15 04:14:49 【问题描述】:我正在创建一个 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");
虽然“绘制”正在控制台上打印出来,但爆炸 gif 不会加载。我检查了文件名,它是正确的。但是,我确实在我的代码中的其他地方使用了相同的 gif,并且它在那里工作,那么有什么东西可以防止在 Java 中使用两次 gif 吗?
这是我的整个 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。
如果我应该添加任何其他内容,请告诉我,并提前感谢您!
【问题讨论】:
不在您的环境中进行编码,但如果复制的作品听起来像是只需要重新启动动画,可能与此 Animated gif only loops once in Chrome and Firefox 相关...如果没有扩展,请尝试使用带有扩展名的 GIF复制。 【参考方案1】:您应该始终在绘画方法中将this
作为最后一个参数传递给drawImage
。如果一个图像有多个帧,或者图像是在后台加载的,这会告诉组件在更多图像可用时再次绘制自己。
组件的绘制经常发生。它由系统控制,而不仅仅是通过调用组件的 repaint
方法的代码。事实上,绘画每秒发生多次是很常见的。许多超出程序员控制的系统事件都可以触发绘画,例如用户移动一个窗口,或另一个窗口移动,甚至是用户移动鼠标。
因此,绘画不应执行加载文件等缓慢的操作。将图像的加载从绘画方法中移出,并移到类的构造函数中。将 Image 对象存储在私有字段中,paintComponent 可以在其中一次又一次地使用它们,而无需在每次绘制运行时重新加载它们。
由于绘制的时间超出了您的控制范围,因此切勿在绘制方法中更改组件的状态,这一点很重要。将setFocusable
和requestFocus
移出您的paintComponent 方法。这些调用应该在构建组件并将其添加到窗口的代码中。
最后,请注意,如果您将应用程序打包成 .jar 文件,则无法从文件中加载图像。 .jar 文件是单个压缩存档;其中的条目不再是文件,它们只是存档中的字节序列。使用 getResource
加载所有文件将解决这个问题,因为 getResource 会查看类路径中的每个 .jar 文件。
【讨论】:
【参考方案2】:没关系,我必须复制“explosion.gif”。它现在工作正常! 但是,请让我知道是否有另一种方法可以更快、更有效地执行此操作。谢谢!
【讨论】:
以上是关于为啥我在 paintComponent 中的 gif 动画不起作用?的主要内容,如果未能解决你的问题,请参考以下文章