Java计时器和绘图动画

时间:2016-11-24 17:31:05

标签: java image swing animation timer

我不知道如何解决这个问题。我正在做的是试图将我所拥有的怪物分解成不同的东西,比如一个玩家类,一个玩火球等等。在尝试打破课程之前我已经完成了所有工作,但现在我遇到了错误。我想知道是否有人可以帮助我解决它并向我解释如何不再重复此错误。先感谢您。 编辑:错误是:animationTimer = new Timer(animationDelay,this);

编辑:找到1个错误: 文件:C:\ Users \ jozef \ Java \ Dragon Ball Z \ Player.java [line:45] 错误:不兼容的类型:Player无法转换为java.awt.event.ActionListener 此外,我做了正确的格式,但是当我尝试将我的代码复制并粘贴到框中以便在此处发布时,它不会将其计为代码,因此我必须缩进每一行以使其显示为代码而不是正常文本

import java.awt.Graphics;
import java.awt.MediaTracker;
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.event.ActionEvent;
import javax.swing.Timer;

public class Player {
    int x;
    int y;
    ImageIcon pictures[];
    int total;
    int current;
    boolean sideMove;
    int move;
    Timer animationTimer;
    int animationDelay = 80;

    public Player(int startX, int startY, ImageIcon image[], boolean sideMove, int move) {
        x = startX;
        y = startY;
        pictures = image;
        total = pictures.length;
        this.sideMove = sideMove;
        this.move = move;
        startAnimation();
    }

    public void draw(Graphics g) {
        if (pictures[current].getImageLoadStatus() == MediaTracker.COMPLETE) {
            Image img = pictures[current].getImage();
            g.drawImage(img, x, y, null);
            current = (current + 1) % total;
        }
        update();
    }

    public void update() {
        if (sideMove == true) {
            x += move;
        } else {
            y += move;
        }
    }

    public void startAnimation() {
        if (animationTimer == null) {
            current = 0;
            animationTimer = new Timer(animationDelay, this); // *** error ***
            animationTimer.start();
        } else if (!animationTimer.isRunning())
            animationTimer.restart();
    }

    public void stopAnimation() {
        animationTimer.stop();
    }
}

2 个答案:

答案 0 :(得分:2)

下面:

animationTimer = new Timer(animationDelay, this);

由于Player类没有实现ActionListener this,因此无法作为有效参数传递给Timer构造函数。一种可能的解决方案是让您的Player类实现ActionListener,为其提供适当的actionPerformed方法:

public class Player implements ActionListener {

     @Override
     protected void actionPerformed(ActionEvent e) {
         // your coded here
     }

     // .... rest of your code

或者更好的是,使用不同的ActionListener,例如匿名内部类。

如,

public void startAnimation() {
    if (animationTimer == null) {
        current = 0;
        animationTimer = new Timer(animationDelay, e -> timerActionPerformed(e));
        animationTimer.start();
    } else if (!animationTimer.isRunning()) {
        animationTimer.restart();
    }
}

private void timerActionPerformed(ActionEvent e) {
    // TODO repeated code goes here
}

侧面建议:

  • 您的绘画方法中的代码会更改您的播放器对象的状态,这是您希望避免的。了解您只能部分控制何时或甚至是否要绘制对象,因此最好将这些对象分开。
  • 我自己,我将Timer从Player类中取出,而是在一个更通用的整体控制类中使用Timer作为你的游戏循环或动画控制器,也许是游戏类(或任何你的" Universe"类被调用),该类保存并控制所有逻辑实体,例如您的Player对象。

答案 1 :(得分:1)

这是javax.swing.Timer构造函数的签名:

public Timer(int delay, ActionListener listener)

你提供的是一个int和一个玩家.. 您还应该创建一个ActionListener并将其提供给构造函数,或者您可以传递this但Player类应该实现ActionListener inteface(您应该在Player类中编写actionPerformed方法)。 / p>

阅读有关计时器Here(官方java doc)的更多信息。