我正试图在X轴上移动船(没有键盘)。如何将移动/动画与boat.png
相关联而不与任何其他图像相关联?
public class Mama extends Applet implements Runnable {
int width, height;
int x = 200;
int y = 200;
int dx = 1;
Image img1, img2, img3, img4;
@Override
public void init(){
setSize(627, 373);
Thread t = new Thread(this);
img1 = getImage(getCodeBase(),"Background.png");
img2 = getImage(getCodeBase(), "boat.png");
img3 = getImage(getCodeBase(), "LeftPalm.png");
img4 = getImage(getCodeBase(), "RightPalm.png");
}
@Override
public void paint(Graphics g){
g.drawImage(img1, 0, 0, this);
g.drawImage(img2, 200, 200, this);
g.drawImage(img3, 40, 100, this);
g.drawImage(img4, 450, 130, this);
}
@Override
public void run() {
while(true){
x += dx;
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
System.out.println("Thread generates an error.");
}
}
}
}
答案 0 :(得分:11)
有一些事情很突出......
如前所述,您需要为图像绘制过程提供变量参数。 g.drawImage(img2, x, y, this);
,这将允许您定义图像的绘制位置。
虽然您已经实施了Runnable
,但实际上您并没有启动任何线程来调用它。这意味着,实际上没有任何改变变量。
在start
方法中,您应该调用类似new Thread(this).start()
的内容。
虽然您已将问题标记为Swing,但您使用的是AWT组件。这是不推荐的(实际上小程序通常不鼓励,因为它们很麻烦 - 恕我直言)。另一个问题,就像你很快就会发现的那样,它们不是双缓冲的,这通常会在执行动画时导致闪烁,这是不可取的。
作为旁注,我们也不鼓励覆盖paint
等顶层容器的Applet
方法。顶级容器往往包含许多其他组件,通过覆盖此类paint
方法,您可以销毁此设置。此外,顶级容器也不会被双重缓冲。
下面的示例使用JFrame
,但转换它以使用JApplet
(只需将AnimationPanel
放到其上就不会花费太多。这是另一个之所以不鼓励从顶级集装箱延伸;)
public class AnimatedBoat {
public static void main(String[] args) {
new AnimatedBoat();
}
public AnimatedBoat() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new AnimationPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class AnimationPane extends JPanel {
private BufferedImage boat;
private int xPos = 0;
private int direction = 1;
public AnimationPane() {
try {
boat = ImageIO.read(new File("boat.png"));
Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
xPos += direction;
if (xPos + boat.getWidth() > getWidth()) {
xPos = getWidth() - boat.getWidth();
direction *= -1;
} else if (xPos < 0) {
xPos = 0;
direction *= -1;
}
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return boat == null ? super.getPreferredSize() : new Dimension(boat.getWidth() * 4, boat.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = getHeight() - boat.getHeight();
g.drawImage(boat, xPos, y, this);
}
}
}
答案 1 :(得分:3)
您需要将g.drawImage(img2, 200, 200, this);
替换为g.drawImage(img2, x, y, this);