Как лучше реализовать анимацию с помощью Swing Timer в Java - PullRequest
2 голосов
/ 07 февраля 2012

Я использую цикл таймера для реализации анимации в моем приложении Java. На данный момент я использую статические переменные, которые относятся к анимации (время начала, откуда начинается элемент и куда он направляется). Есть ли более простой способ сделать это? Могу ли я отправить эти переменные в качестве аргументов при запуске таймера вместо этого?

...
import javax.swing.Timer;

public class SlidePuzz2 extends Applet implements MouseMotionListener, MouseListener {
...

    static Element animating;
    static PieceLoc blank;
    static int delta;
    static int orig_x;
    static int orig_y;
    static long timeStart;

    Timer aniTimer;

...
    public void init() {
...        
        aniTimer = new Timer(20, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                    int dx = (blank.x*piece-orig_x);
                    int dy = (blank.y*piece-orig_y);
                    int t = 200;
                    delta = (int)(System.currentTimeMillis()-timeStart);
                    if (delta>t) delta=t;
                    animating.x = orig_x + dx*delta/t;
                    animating.y = orig_y + dy*delta/t;
                    repaint();
                    if (delta==t) {
                        animating.updateCA();
                        board.checkCompleted();
                        aniTimer.stop();
                    }
               }
        });
...
            setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));

            blank = board.getBlankPl();
            animating = e;
            timeStart = System.currentTimeMillis();
            orig_x = animating.x;
            orig_y = animating.y;

            aniTimer.start();
...

1 Ответ

1 голос
/ 08 февраля 2012

Благодаря комментариям @Max я нашел решение моей собственной проблемы, создав внутренний класс внутри моего основного класса Applet, который расширяет ActionListener.

public class AniTimer implements ActionListener {
    Element animating;
    PieceLoc blank;
    int orig_x;
    int orig_y;
    long timeStart;
    int delta;

    public AniTimer(Element e, PieceLoc pl) {
        animating = e;
        blank = pl;
        orig_x = animating.x;
        orig_y = animating.y;
        timeStart = System.currentTimeMillis();
    }

        public void actionPerformed(ActionEvent evt) {
        int dx = (blank.x*piece-orig_x);
        int dy = (blank.y*piece-orig_y);
        int t = 200;
        delta = (int)(System.currentTimeMillis()-timeStart);
        if (delta>t) delta=t;
        animating.x = orig_x + dx*delta/t;
        animating.y = orig_y + dy*delta/t;
        repaint();
        if (delta==t) {
            aniTimer.stop();
            animating.updateCA();
            board.checkCompleted();
        }
    }
}

Затем, когда я хочу запустить анимацию, все, что я делаю, - это создаю новый Timer с новым экземпляром моего класса ActionListener в качестве второго аргумента, и я могу передать все жизненно важные аргументы, относящиеся только к этому конкретному этапу анимации, в конструктор .

aniTimer = new Timer(20, new AniTimer(e, board.getBlankPl()));
aniTimer.start();

Спасибо Макс, я начинаю любить Java сейчас!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...