2012-02-07 5 views
2

Я использую таймерный цикл для реализации анимации на своем Java-приложении. На данный момент я использую статические переменные, относящиеся к анимации (время начала, откуда начинается элемент и где он собирается). Есть ли более простой способ сделать это? Могу ли я отправлять эти переменные в качестве аргументов, когда я запускаю таймер?Как лучше реализовать анимацию с помощью swing Timer в 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(); 
... 
+3

Я считаю, что использование javax.swing.Timer - лучший способ реализовать анимацию. – mre

+0

@mre да, это то, что я делаю уже. мой вопрос в том, как я могу использовать таймер качания лучше, чем более элегантно, например, избегая статических переменных вне цикла анимации для его настройки. –

+6

Вам не нужно использовать анонимный ActionListener. Создайте новый класс, который реализует ActionListener и настроит его со всеми связанными/необходимыми данными. – tenorsax

ответ

1

Благодаря комментарии @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(); 
     } 
    } 
} 

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

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

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

+0

+1 для реализации 'ActionListener'. См. Также [* Как использовать действия *] (http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html). – trashgod

Смежные вопросы