Jozef Brudnicki
Jozef Brudnicki

Reputation: 21

Java Timer and drawing animations

I have no idea how to fix this problem. What I am doing is trying to break up a monster class I have into different things, like one class for player, one for fireball, etc. I had everything working before I tried to break up the class but now I am getting an error. I was wondering if anyone could help me solve it and explain to me how not to repeat this error again. Thank you in advance. EDIT: The error is on: animationTimer = new Timer(animationDelay, this);

EDIT:1 error found: File: C:\Users\jozef\Java\Dragon Ball Z\Player.java [line: 45] Error: incompatible types: Player cannot be converted to java.awt.event.ActionListener Also, I do format properly but when i try to copy and paste my code into the box to post here it doesn't count it as code so i have to indent every line to get it to appear as code and no normal text.

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();
    }
}

Upvotes: 0

Views: 1917

Answers (2)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

Here:

animationTimer = new Timer(animationDelay, this);

Since the Player class does not implement ActionListener this can not be passed in to the Timer constructor as a valid parameter. A possible solution is to have your Player class implement ActionListener giving it an appropriate actionPerformed method:

public class Player implements ActionListener {

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

     // .... rest of your code

or better still, use a different ActionListener such as an anonymous inner class.

e.g.,

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
}

Side recommendations:

  • You've got code within your painting method that changes your Player object's state, something that you'll want to avoid. Understand that you can only partially control when or even if an object will be painted, and so it would be best to keep these separate.
  • Myself, I'd get the Timer out of the Player class and instead use a Timer as your game loop or animation controller in a more general overall control class, perhaps the Game class (or whatever your "universe" class is called), the class that holds and controls all of your logical entities such as your Player objects.

Upvotes: 2

user6904265
user6904265

Reputation: 1938

This is the signature of javax.swing.Timer constructor:

public Timer(int delay, ActionListener listener)

You are providing an int and a Player.. You should create an ActionListener as well and provide it to the constructor or you could pass this but Player class should implements ActionListener inteface (you should write actionPerformed method in the Player class).

Read more info about Timer Here (official java doc).

Upvotes: 1

Related Questions