Home | History | Annotate | Download | only in replicaisland
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.replica.replicaisland;
     18 
     19 /**
     20  * Provides an interface for controlling a sprite with animations.  Manages a list of animations
     21  * and provides a drawable surface with the correct animation frame to a render component each
     22  * frame.  Also manages horizontal and vertical flipping.
     23  */
     24 public class SpriteComponent extends GameComponent {
     25 
     26     private PhasedObjectManager mAnimations;
     27     private float mAnimationTime;
     28     private int mCurrentAnimationIndex;
     29     private int mWidth;
     30     private int mHeight;
     31     private float mOpacity;
     32     private RenderComponent mRenderComponent;
     33     private DynamicCollisionComponent mCollisionComponent;
     34     private boolean mVisible;
     35     private SpriteAnimation mCurrentAnimation;
     36     private boolean mAnimationsDirty;
     37 
     38     public SpriteComponent(int width, int height) {
     39         super();
     40         mAnimations = new PhasedObjectManager();
     41 
     42         reset();
     43         mWidth = width;
     44         mHeight = height;
     45         setPhase(ComponentPhases.PRE_DRAW.ordinal());
     46     }
     47 
     48     public SpriteComponent() {
     49         super();
     50         mAnimations = new PhasedObjectManager();
     51 
     52         reset();
     53 
     54         setPhase(ComponentPhases.PRE_DRAW.ordinal());
     55     }
     56 
     57     @Override
     58     public void reset() {
     59         mWidth = 0;
     60         mHeight = 0;
     61         mVisible = true;
     62         mCurrentAnimationIndex = -1;
     63         mAnimations.removeAll();
     64         mAnimations.commitUpdates();
     65         mAnimationTime = 0.0f;
     66         mRenderComponent = null;
     67         mCollisionComponent = null;
     68         mCurrentAnimation = null;
     69         mOpacity = 1.0f;
     70         mAnimationsDirty = false;
     71     }
     72 
     73     @Override
     74     public void update(float timeDelta, BaseObject parent) {
     75         mAnimationTime += timeDelta;
     76         final PhasedObjectManager animations = mAnimations;
     77         final int currentAnimIndex = mCurrentAnimationIndex;
     78 
     79         if (mAnimationsDirty) {
     80         	animations.commitUpdates();
     81         	mAnimationsDirty = false;
     82         }
     83         boolean validFrameAvailable = false;
     84         if (animations.getCount() > 0 && currentAnimIndex != -1) {
     85         	SpriteAnimation currentAnimation = mCurrentAnimation;
     86 
     87             if (currentAnimation == null && currentAnimIndex != -1) {
     88             	currentAnimation = findAnimation(currentAnimIndex);
     89                 if (currentAnimation == null) {
     90                     // We were asked to play an animation that doesn't exist.  Revert to our
     91                     // default animation.
     92                     // TODO: throw an assert here?
     93                     mCurrentAnimation = (SpriteAnimation)animations.get(0);
     94                     currentAnimation = mCurrentAnimation;
     95                 } else {
     96                 	mCurrentAnimation = currentAnimation;
     97                 }
     98             }
     99 
    100             GameObject parentObject = (GameObject)parent;
    101             AnimationFrame currentFrame = currentAnimation.getFrame(mAnimationTime);
    102             if (currentFrame != null) {
    103                 validFrameAvailable = true;
    104                 final RenderComponent render = mRenderComponent;
    105                 if (render != null) {
    106                     final DrawableFactory factory = sSystemRegistry.drawableFactory;
    107                     if (mVisible && currentFrame.texture != null && factory != null) {
    108                         // Fire and forget.  Allocate a new bitmap for this animation frame, set it up, and
    109                         // pass it off to the render component for drawing.
    110                         DrawableBitmap bitmap = factory.allocateDrawableBitmap();
    111                         bitmap.setWidth(mWidth);
    112                         bitmap.setHeight(mHeight);
    113                         bitmap.setOpacity(mOpacity);
    114                         updateFlip(bitmap, parentObject.facingDirection.x < 0.0f,
    115                                 parentObject.facingDirection.y < 0.0f);
    116                         bitmap.setTexture(currentFrame.texture);
    117                         render.setDrawable(bitmap);
    118                     } else {
    119                     	render.setDrawable(null);
    120                     }
    121                 }
    122 
    123                 if (mCollisionComponent != null) {
    124                     mCollisionComponent.setCollisionVolumes(currentFrame.attackVolumes,
    125                             currentFrame.vulnerabilityVolumes);
    126                 }
    127             }
    128         }
    129 
    130         if (!validFrameAvailable) {
    131             // No current frame = draw nothing!
    132             if (mRenderComponent != null) {
    133                 mRenderComponent.setDrawable(null);
    134             }
    135             if (mCollisionComponent != null) {
    136                 mCollisionComponent.setCollisionVolumes(null, null);
    137             }
    138         }
    139     }
    140 
    141     public final void playAnimation(int index) {
    142         if (mCurrentAnimationIndex != index) {
    143             mAnimationTime = 0;
    144             mCurrentAnimationIndex = index;
    145             mCurrentAnimation = null;
    146         }
    147     }
    148 
    149     public final SpriteAnimation findAnimation(int index) {
    150         return (SpriteAnimation)mAnimations.find(index);
    151     }
    152 
    153     public final void addAnimation(SpriteAnimation anim) {
    154         mAnimations.add(anim);
    155         mAnimationsDirty = true;
    156     }
    157 
    158     public final boolean animationFinished() {
    159         boolean result = false;
    160         if (mCurrentAnimation != null
    161                 && !mCurrentAnimation.getLoop()
    162                 && mAnimationTime > mCurrentAnimation.getLength()) {
    163             result = true;
    164         }
    165         return result;
    166     }
    167 
    168 
    169     public final float getWidth() {
    170         return mWidth;
    171     }
    172 
    173     public final float getHeight() {
    174         return mHeight;
    175     }
    176 
    177     public final void setSize(int width, int height) {
    178         mWidth = width;
    179         mHeight = height;
    180     }
    181 
    182     protected final void updateFlip(DrawableBitmap bitmap, boolean horzFlip, boolean vertFlip) {
    183         bitmap.setFlip(horzFlip, vertFlip);
    184     }
    185 
    186     public final void setRenderComponent(RenderComponent component) {
    187         mRenderComponent = component;
    188     }
    189 
    190     public final void setCollisionComponent(DynamicCollisionComponent component) {
    191         mCollisionComponent = component;
    192     }
    193 
    194     public final boolean getVisible() {
    195         return mVisible;
    196     }
    197 
    198     public final void setVisible(boolean visible) {
    199         mVisible = visible;
    200     }
    201 
    202     public final float getCurrentAnimationTime() {
    203         return mAnimationTime;
    204     }
    205 
    206     public final void setCurrentAnimationTime(float time) {
    207         mAnimationTime = time;
    208     }
    209 
    210     public final void setOpacity(float opacity) {
    211         mOpacity = opacity;
    212     }
    213 
    214     public final int getCurrentAnimation() {
    215         return mCurrentAnimationIndex;
    216     }
    217 
    218     public final int getAnimationCount() {
    219         return mAnimations.getConcreteCount();
    220     }
    221 }
    222