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 17package com.replica.replicaisland; 18 19/** 20 * A general-purpose animation selection system for animating enemy characters. Most enemy 21 * characters behave similarly, so this code tries to decide which animation bets fits their current 22 * state. Other code (such as enemy AI) may move these characters around and change the current 23 * ActionType, which will result in this code figuring out which sequence of animations is best to 24 * play. 25 */ 26public class EnemyAnimationComponent extends GameComponent { 27 28 public enum EnemyAnimations { 29 IDLE, 30 MOVE, 31 ATTACK, 32 HIDDEN, 33 APPEAR, 34 } 35 36 private enum AnimationState { 37 IDLING, 38 MOVING, 39 HIDING, 40 APPEARING, 41 ATTACKING 42 } 43 44 private SpriteComponent mSprite; 45 private AnimationState mState; 46 private boolean mFacePlayer; 47 48 public EnemyAnimationComponent() { 49 super(); 50 setPhase(ComponentPhases.ANIMATION.ordinal()); 51 reset(); 52 } 53 54 @Override 55 public void reset() { 56 mState = AnimationState.IDLING; 57 mFacePlayer = false; 58 mSprite = null; 59 } 60 61 @Override 62 public void update(float timeDelta, BaseObject parent) { 63 if (mSprite != null) { 64 GameObject parentObject = (GameObject) parent; 65 final float velocityX = parentObject.getVelocity().x; 66 67 GameObject.ActionType currentAction = parentObject.getCurrentAction(); 68 69 switch(mState) { 70 case IDLING: 71 mSprite.playAnimation(EnemyAnimations.IDLE.ordinal()); 72 if (mFacePlayer) { 73 facePlayer(parentObject); 74 } 75 76 if (currentAction == GameObject.ActionType.ATTACK) { 77 mState = AnimationState.ATTACKING; 78 } else if (currentAction == GameObject.ActionType.HIDE) { 79 mState = AnimationState.HIDING; 80 } else if (Math.abs(velocityX) > 0.0f) { 81 mState = AnimationState.MOVING; 82 } 83 84 break; 85 86 case MOVING: 87 mSprite.playAnimation(EnemyAnimations.MOVE.ordinal()); 88 final float targetVelocityX = parentObject.getTargetVelocity().x; 89 90 if (!Utils.close(velocityX, 0.0f)) { 91 if (velocityX < 0.0f && targetVelocityX < 0.0f) { 92 parentObject.facingDirection.x = -1.0f; 93 } else if (velocityX > 0.0f && targetVelocityX > 0.0f) { 94 parentObject.facingDirection.x = 1.0f; 95 } 96 } 97 if (currentAction == GameObject.ActionType.ATTACK) { 98 mState = AnimationState.ATTACKING; 99 } else if (currentAction == GameObject.ActionType.HIDE) { 100 mState = AnimationState.HIDING; 101 } else if (Math.abs(velocityX) == 0.0f) { 102 mState = AnimationState.IDLING; 103 } 104 break; 105 case ATTACKING: 106 mSprite.playAnimation(EnemyAnimations.ATTACK.ordinal()); 107 if (currentAction != GameObject.ActionType.ATTACK 108 && mSprite.animationFinished()) { 109 mState = AnimationState.IDLING; 110 } 111 break; 112 case HIDING: 113 mSprite.playAnimation(EnemyAnimations.HIDDEN.ordinal()); 114 if (currentAction != GameObject.ActionType.HIDE) { 115 mState = AnimationState.APPEARING; 116 } 117 break; 118 case APPEARING: 119 if (mFacePlayer) { 120 facePlayer(parentObject); 121 } 122 123 mSprite.playAnimation(EnemyAnimations.APPEAR.ordinal()); 124 if (mSprite.animationFinished()) { 125 mState = AnimationState.IDLING; 126 } 127 break; 128 129 } 130 131 132 } 133 } 134 135 private void facePlayer(GameObject parentObject) { 136 GameObjectManager manager = sSystemRegistry.gameObjectManager; 137 if (manager != null) { 138 GameObject player = manager.getPlayer(); 139 if (player != null) { 140 if (player.getPosition().x < parentObject.getPosition().x) { 141 parentObject.facingDirection.x = -1.0f; 142 } else { 143 parentObject.facingDirection.x = 1.0f; 144 } 145 } 146 } 147 } 148 149 public void setSprite(SpriteComponent sprite) { 150 mSprite = sprite; 151 } 152 153 public void setFacePlayer(boolean facePlayer) { 154 mFacePlayer = facePlayer; 155 } 156} 157