Есть несколько вещей, которые выделяются ...
Как уже было сказано, вам нужно передать переменные аргументы в процесс рисования изображений. g.drawImage(img2, x, y, this);
, это позволит вам определить, где должно быть написано изображение.
Пока вы реализовали Runnable
, на самом деле вы не начали нить, чтобы вызвать его. Это означает, что на самом деле ничего не меняется.
В вашем методе start
вы должны называть что-то вроде new Thread(this).start()
.
вы отметили вопрос как Swing, вы используете компоненты AWT. Это не рекомендуется (на самом деле апплеты обычно обескуражены, поскольку они хлопотливы - IMHO). Другая проблема, как вы вскоре узнаете, - это не двойное буферирование, это обычно приводит к мерцанию при выполнении анимации, что нежелательно.
В качестве побочного примечания, это также не рекомендуется переопределять метод paint
для контейнеров верхнего уровня, таких как Applet
. Контейнеры верхнего уровня, как правило, содержат ряд дополнительных компонентов, путем переопределения метода paint
, подобного этому, вы уничтожаете эту настройку. Кроме того, контейнеры верхнего уровня не имеют двойной буферизации.
В приведенном ниже примере используется JFrame
, но для его преобразования не потребуется много времени, чтобы использовать JApplet
(просто нажмите AnimationPanel
. Это еще одна причина, по которой отказ от контейнеров верхнего уровня обычно обескуражен;)
[/g2]
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);
}
}
}