2011-10-08 88 views
1

我試圖在自定義視圖中設置ShapeDrawable的動畫效果。但我不確定完成此任務的最佳方法是什麼。在自定義視圖中爲Drawable設置動畫效果

我應該嘗試在路徑上畫一個棋子,然後撥打invalidate(),直到它到達目標廣場?或者有更好的方法使用AsyncTask或Handler?

這裏是我的代碼,我省略了很多方法和變量以使其可讀。

public class CheckerBoard extends View { 

    public enum State implements Parcelable { 
     EMPTY(0), WHITE(1), BLACK(2); 
    } 

     private final State[][] boardStates = new State[SIZE][SIZE]; 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawColor(bgColor); 
     for (int y = 0; y < SIZE; y++) { 
      for (int x = 0; x < SIZE; x++) { 
       if ((y % 2 == 0 && x % 2 != 0) || (y % 2 != 0 && x % 2 == 0)) { 
        drawRect(x, y, canvas); 
        drawPawn(x, y, canvas); 
       } 
      } 
     } 
    } 

    private void drawRect(int x, int y, Canvas c) { 
    } 

    private void drawPawn(int x, int y, Canvas c) { 
    } 

    private void init() { 
     setupBoard(); 
     pawnLinePaint.setStyle(Paint.Style.STROKE); 
     wPawnDrawable.getPaint().setColor(wColor); 
     wPawnDrawable.getPaint().setShadowLayer(tileSize + 2, 4, 4, Color.GRAY); 
     bPawnDrawable.getPaint().setColor(bColor); 
     bPawnDrawable.getPaint().setShadowLayer(tileSize + 2, 4, 4, Color.GRAY); 
     playerState = startState; 
    } 

    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       int x = (int) (event.getX()/tileSize); 
       int y = (int) (event.getY()/tileSize); 
       if (selection[0] >= 0) { // A tile is already selected 
        if (isValidMove(selection[0], selection[1], x, y)) { 
         makeMove(x, y); 
         clearSelection(); 
         switchPlayer(); 
         invalidate(); 
        } 

       } else { // New selection 
        if (isValidSelection(x, y)) { 
         selection[0] = x; 
         selection[1] = y; 
         invalidate(); 
        } 
       } 

       return true; 
      default: 
       return super.onTouchEvent(event); 
     } 
    } 

    private void makeMove(int x, int y) { 
     // Move the pawn to the new square 
     boardStates[y][x] = boardStates[selection[1]][selection[0]]; 
     // Old square is now empty 
     boardStates[selection[1]][selection[0]] = State.EMPTY; 
    } 

    private void switchPlayer() { 
     playerState = playerState == State.WHITE ? State.BLACK : State.WHITE; 
    } 

    public CheckerBoard(Context context) { 
     super(context); 
     init(); 
    } 

    public CheckerBoard(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    public CheckerBoard(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(); 
    } 


    private class Pawn extends ShapeDrawable { 
     public Pawn() { 
      super(new OvalShape()); 
     } 

     public void drawWithCircles(Canvas canvas, float x, float y){ 
      super.draw(canvas); 
      canvas.drawCircle(x * tileSize + pawnDiameter, y * tileSize + pawnDiameter, pawnDiameter - pawnPadding, 
        pawnLinePaint); 
      canvas.drawCircle(x * tileSize + pawnDiameter, y * tileSize + pawnDiameter, pawnDiameter - pawnPadding * 6, 
        pawnLinePaint); 
      canvas.drawCircle(x * tileSize + pawnDiameter, y * tileSize + pawnDiameter, pawnDiameter - pawnPadding * 8, 
        pawnLinePaint); 
     } 
    } 

} 

謝謝你的幫助。

Blight

+1

我這種掙扎也是如此。你可以在http://stackoverflow.com/questions/7644909/battery-consumption-with-custom-animated-drawable看到我的結果 – Phix

回答

1

您應該爲您的應用程序創建兩個線程。一個線程是僅以當前狀態繪製板的UI線程。另一個線程是移動棋盤上物品的遊戲引擎或動畫線程。

第一個線程運行在任何你想要的幀速率下,而第二個線程的運行速度要快得多。這樣,您實際上不必親自處理動畫,因爲UI線程只是像現在一樣繪製板。在引擎線程中,更新遊戲狀態,棋盤,棋子,線程的每個週期。

這樣做的事情有幾個好處。如果引擎線程陷入某種計算困境,首先你的遊戲幀率不會下降。其次,它允許您將繪圖從遊戲中抽象出來,從而使調試變得更容易。

以進度條爲例。假設您嘗試使用進度條創建文件上傳器,但只有一個線程。所以你啓動進度條,然後開始上傳文件。如果上傳過程被阻止,那麼您必須等待文件完成上傳,然後才能更新進度欄,從而使進度欄無用。但是如果你用兩個線程做了這個,那麼你可以設置它,以便一個線程根據一些公共變量更新進度條圖形。另一個步驟負責執行操作並更新進度變量。

查閱這些鏈接,瞭解更多信息:

http://obviam.net/index.php/the-android-game-loop/

http://www.rbgrn.net/content/54-getting-started-android-game-development

http://www.helloandroid.com/tutorials/using-threads-and-progressdialog

相關問題