我有以下代码。我想在一段时间延迟之后在屏幕上的小鸡数组中显示图像。坐标必须移动 10px 图片已加载。我想知道我可以在此代码中添加哪些附加代码片段,以便在我的Frame上使用我拥有的两个图像制作动画.Below是我的代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
public class Chicken extends Frame implements Runnable{
Thread animation;
long frameDelay = 3000;
Image chick[] = new Image[2];
int numFrames = chick.length;
Toolkit tk = getToolkit();
public Chicken()
{
setSize(new Dimension(300,300));
setVisible(true);
setBackground(Color.BLACK);
animation = new Thread(this);
chick[0] = tk.createImage("stand.png");
chick[1] = tk.createImage("walk.png");
animation.start();
//setVisible(false);
}
public void paint(Graphics g)
{
g.drawImage(chick[0],100,100,null );
}
@Override
public void run() {
// TODO Auto-generated method stub
repaint();
try {
Thread.sleep(frameDelay);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[])
{
Chicken instance = new Chicken();
}
}
答案 0 :(得分:1)
所以,你遇到的第一个问题是资源问题。
存储在应用程序内部的资源(通常称为嵌入式资源)无法像外部资源一样加载。
chick[0] = tk.createImage("stand.png");
期望文件"./stand.png"
不存在。相反,您需要通过Class#getResource
API ...
chick[0] = tk.createImage(getClass().getResource("/stand.png"));
您将面临的第二个问题是您正在覆盖顶级容器的paint
。这真的不应该这样做。让我们从它不是双重缓冲的事实开始,并以框架具有位于可视区域内的装饰为结束。这意味着装饰将重叠你在表面上绘制的东西......不漂亮......
第三个问题是你没有告诉图像它应该移动到哪里。这是静态的。
您需要某种x / y值来告诉图像应该在哪里绘制。在调用repaint
...
您可能遇到的第四个问题是您正在使用AWT ...这有点过时了。 Swing会为你解决你的双缓冲问题...恕我直言,会做出更好的选择 - 现在有很多关于Swing铺设的文档和示例;)
当我在蹒跚骑马的时候...我个人会推荐ImageIO
超过Toolkit#createImage
或ImageIcon
,主要是因为它支持更多格式,但也因为它会当由于某种原因无法读取图像时抛出Exception
...
我有一个简单的例子,如果Swing,但我不会发布它,因为我会因为运行主题而遇到麻烦...如果你想看到它,请告诉我
已更新为Swing示例
这使用默认包中的嵌入图像...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ChickenDance {
public static void main(String[] args) {
new ChickenDance();
}
public ChickenDance() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage chicken;
private int xPos;
private int yPos;
private int xDelta = 4;
public TestPane() {
try {
chicken = ImageIO.read(getClass().getResource("/Chicken.png"));
} catch (IOException ex) {
Logger.getLogger(ChickenDance.class.getName()).log(Level.SEVERE, null, ex);
}
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
xPos += xDelta;
if (xPos + chicken.getWidth() > getWidth()) {
xPos = getWidth() - chicken.getWidth();
xDelta *= -1;
} else if (xPos < 0) {
xPos = 0;
xDelta *= -1;
}
yPos = (getHeight() - chicken.getHeight()) / 2;
repaint();
}
});
if (chicken != null) {
timer.start();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (chicken != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(chicken, xPos, yPos, this);
g2d.dispose();
}
}
}
}