我正在做一个小游戏。这不是动作游戏,而是益智游戏,因此性能并不那么重要。现在,我有了主要的游戏区域,一个背景图像。在某些情况下,我想在部分背景图像上绘制其他图像。我的问题是背景图像和叠加图像都可以是动画 gif,帧数未知(基本上,用户选择)。
现在,我要做的基本上是:绘制背景图像并使其动画化(如果它是 gif),然后在其上绘制 0-n 个较小的动画 gif,相对于背景图像的位置,以像素坐标给出。此外,它应该是可调整大小的,以便图像相应地缩放/移动。
最终结果如何:http: //i.stack.imgur.com/PxdDt.png(想象一下它是动画的)
我找到了一个解决方案,它通过将布局管理器设置为 null 并使用绝对定位的带有图标的 JLabels 来使它们动画化,使用一个作为背景,另一个作为前景添加到其中:
background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight());
foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight());
background.setLocation(0, 0);
foreground.setLocation(30, 30);
background.setLayout(null);
background.add(foreground);
frame.setLayout(null);
frame.add(background);
(下面的完整代码)
正如我所听到的,将布局管理器设置为 null 是有问题的(尤其是因为我想稍后在图像中添加一些文本,尽管我会在背景中使用另一个标签,而不是背景标签本身或其他东西(帧之间的延迟等等)。此外,由于位置应该是像素完美的,因此即使可能调整大小也可能由于舍入误差而出现问题。
现在,有没有更好的方法来做到这一点?我可以以某种方式加载动画 gif 并手动合并它们(即使它们可能有不同数量的层),所以我只需要绘制一个图像?是否有一个布局管理器,我可以在其中手动设置组件位置,但如果您调整窗口/面板的大小,它会自动缩放它?是否有第三方图形项目可以做我想做的事?
理想情况下,如果它们不是动画,我会做一些类似的事情,比如构建一个合并的图像,然后调整大小并显示该图像。
完整代码:
import java.awt.Dimension;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public final class Tester extends JFrame {
public static void main(String[] args) throws MalformedURLException {
new Tester();
}
private Tester() throws MalformedURLException {
setTitle("Tester");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Icon backgroundIcon = new ImageIcon(new URL("http://s5.favim.com/orig/51/animated-gif-gif-hands-sign-language-Favim.com-542945.gif"));
Icon foregroundIcon = new ImageIcon(new URL("http://i.imgur.com/89HANHg.gif"));
JLabel background = new JLabel(backgroundIcon);
JLabel foreground = new JLabel(foregroundIcon);
// ugly
background.setSize(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight());
foreground.setSize(foregroundIcon.getIconWidth(), foregroundIcon.getIconHeight());
background.setLocation(0, 0);
foreground.setLocation(30, 30);
background.setLayout(null);
background.add(foreground);
setLayout(null);
add(background);
// set size of frame to size of content
setResizable(false);
getContentPane().setPreferredSize(new Dimension(backgroundIcon.getIconWidth(), backgroundIcon.getIconHeight()));
pack();
setLocationRelativeTo(null);
setVisible(true);
}
}