2012-08-31 54 views
0

我將位圖動畫添加到我的簡單2D安卓遊戲引擎中(如果您可以稱它爲一個,但是:D),我面臨以預先定義的FPS /速率循環幀的問題。Android位圖動畫

我現在所做的只是使用System來獲取currentTimeMillis並將其用作參考,但我確信這不是最好的決定..我想我可以將當​​前幀傳遞給繪圖方法並使用它來繪圖方法。

目前我有你得到繪製對象,我用它在渲染這樣的:

canvas.drawBitmap(animation.getDrawable(), (int)x, (int)y, null); 

和getDrawable()返回動畫的當前幀或只有框架,如果它的靜止圖像和繼承人代碼

 if(frames.size() > 1) { 
      long current = System.currentTimeMillis(); 
      if (currentFrame == frames.size() - 1 && frameDirection == 1) { 
       frameDirection = -1; 
      } else if (currentFrame == 0 && frameDirection == -1) { 
       frameDirection = 1; 
      } 
      if ((current - lastFrame) > delay) { 
       currentFrame += frameDirection; 
       lastFrame = current; 
      } 
     } 
     return frames.get(currentFrame); 

在我的眼中,只是看起來很糟糕,效率不高。我能做些什麼呢?是將當前幀傳遞給getDrawable的唯一方法,或者應該如何完成?

回答

1

如果我明白這個權利,你想爲你的遊戲引擎創建一個動畫類嗎?

在我的遊戲引擎中,我有一個名爲SpriteSheetAnimation的類,它在調用update方法時基本遍歷每個動畫幀 - 我相信你會理解它背後的邏輯,你會發現一種使用方法:

public class SpriteSheetAnimation extends GameObjectTemplate { 

    int animationSheetLength; 
    int animationSheetHeight; 
    int columns; 
    int rows; 
    Rect srcRect; 

    int left; 
    int bottom; 
    int lengthOfSpriteInSheet; 
    int heightOfSpriteInSheet; 

    boolean repeatAnimation; 
    boolean animationCompleted; 
    boolean animationStarted; 

    Bitmap bitmap; 

    /** 
    * You input a bitmap and the number of sprites (by defining the number of rows and columns), and this class will 
    * take care of animating the sheet. 
    * 
    */ 

    public SpriteSheetAnimation(WorldTemplate world, Bitmap animationSheet, int amountOfRows, int amountOfColumns) { 
     super(world); 
     this.animationSheetLength = animationSheet.getWidth(); 
     this.animationSheetHeight = animationSheet.getHeight(); 
     this.columns = amountOfColumns; 
     this.rows = amountOfRows; 
     this.lengthOfSpriteInSheet = this.animationSheetLength/this.columns; 
     this.heightOfSpriteInSheet = this.animationSheetHeight/this.rows; 
     srcRect = new Rect(); 

     left = 0; 
     bottom = this.heightOfSpriteInSheet; 

     repeatAnimation = false; 
     animationCompleted = false; 
     animationStarted = false; 

     this.bitmap = animationSheet; 
     this.drawShapesOfSprites = true; 

     this.gameObjectShape.addRectangle(new Rect(0, 0, 0 + this.heightOfSpriteInSheet, 0 + this.lengthOfSpriteInSheet)); 

    } 

    @Override 
    public void defineGameObjectPositionShape() { 
     this.gameObjectShape.addRectangle(new Rect()); 

    } 

    /** 
    * <b><i>public Rect getSrcRect()</i></b> 
    * <br> 
    * Since: API 1 
    * <br> 
    * <br> 
    * Retrieve the rect that will cover the current source of the sheet. 
    * 
    * @return 
    * The current rect that will cover the current source of the sheet. 
    * 
    */ 

    public Rect getSrcRect() { 
     return srcRect; 
    } 

    /** 
    * <b><i>public Rect getDstRect()</i></b> 
    * <br> 
    * Since: API 1 
    * <br> 
    * <br> 
    * Retrieve the rect where the bitmap will be scaled to fit into. 
    * 
    * @return 
    * The current rect where the bitmap will be scaled to fit into. 
    * 
    */ 

    public Rect getDstRect() { 
     return this.getGameObjectPositionRect(); 
    } 

    /** 
    * <b><i>public void repeatAnimation(boolean repetition)</i></b> 
    * <br> 
    * Since: API 1 
    * <br> 
    * <br> 
    * This method will set if the animation should be repeated or not. 
    * 
    * @param state 
    * <br><br> 
    * 1. True = The animation will repeat once completed and keep on doing so. 
    * <br><br> 
    * 2. False = The animation will play only once. 
    * 
    *  
    */ 

    public void repeatAnimation(boolean repetition) { 
     this.repeatAnimation = repetition; 
    } 

    /** 
    * <b><i>public boolean isAnimationFinished()</i></b> 
    * <br> 
    * Since: API 1 
    * <br> 
    * <br> 
    * Retrieve if the animation has finished. 
    * 
    * @return 
    * If the animation has finished. 
    * 
    */ 

    public boolean isAnimationFinished() { 
     return animationCompleted; 
    } 

    /** 
    * <b><i>public boolean hasBeenStarted()</i></b> 
    * <br> 
    * Since: API 1 
    * <br> 
    * <br> 
    * Retrieve if the animation has started. 
    * 
    * @return 
    * If the animation has started. 
    * 
    */ 

    public boolean hasBeenStarted() { 
     return animationStarted; 
    } 

    /** 
    * <b><i>public void render()</i></b> 
    * <br> 
    * Since: API 1 
    * <br> 
    * <br> 
    * This method will render the animation (the current picture of the sheet). 
    * 
    */ 

    public void render() { 
     world.game.getGraphics().getCanvasGameScreen().drawBitmap(this.bitmap, this.getSrcRect(), this.getGameObjectPositionRect(), null); 
    } 

    /** 
    * <b><i>public void update()</i></b> 
    * <br> 
    * Since: API 1 
    * <br> 
    * <br> 
    * This method will update the animation. 
    * 
    */ 

    @Override 
    public void update() { 
     // Every update will advance to the next frame of the animation 
     // Set if animation has started 
     if(!animationStarted) { 
      animationStarted = true; 
     } 

     // Set the frame 
     srcRect.set(left, (bottom - this.heightOfSpriteInSheet), (left + this.lengthOfSpriteInSheet), bottom); 
     // Change the location, so the next time the frame is set, it will be set accordingly 
     left = left + this.lengthOfSpriteInSheet; 

     if(left == this.animationSheetLength && bottom == this.animationSheetHeight) { 
      if(repeatAnimation == true) { 
       left = 0; 
       bottom = 0; 
      } 
      else { 
       animationCompleted = true; 
      } 
     } 

     if(left == this.animationSheetLength) { 
      bottom = bottom + this.heightOfSpriteInSheet; 
      left = 0; 
     } 

    } 


} 

我希望這可以幫助你,讓你開始。

+0

謝謝你,我幾乎忘記了使用精靈表。非常感謝你! – Ruuhkis