| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.replica.replicaisland; |
| |
| /** |
| * A general-purpose animation selection system for animating enemy characters. Most enemy |
| * characters behave similarly, so this code tries to decide which animation bets fits their current |
| * state. Other code (such as enemy AI) may move these characters around and change the current |
| * ActionType, which will result in this code figuring out which sequence of animations is best to |
| * play. |
| */ |
| public class EnemyAnimationComponent extends GameComponent { |
| |
| public enum EnemyAnimations { |
| IDLE, |
| MOVE, |
| ATTACK, |
| HIDDEN, |
| APPEAR, |
| } |
| |
| private enum AnimationState { |
| IDLING, |
| MOVING, |
| HIDING, |
| APPEARING, |
| ATTACKING |
| } |
| |
| private SpriteComponent mSprite; |
| private AnimationState mState; |
| private boolean mFacePlayer; |
| |
| public EnemyAnimationComponent() { |
| super(); |
| setPhase(ComponentPhases.ANIMATION.ordinal()); |
| reset(); |
| } |
| |
| @Override |
| public void reset() { |
| mState = AnimationState.IDLING; |
| mFacePlayer = false; |
| mSprite = null; |
| } |
| |
| @Override |
| public void update(float timeDelta, BaseObject parent) { |
| if (mSprite != null) { |
| GameObject parentObject = (GameObject) parent; |
| final float velocityX = parentObject.getVelocity().x; |
| |
| GameObject.ActionType currentAction = parentObject.getCurrentAction(); |
| |
| switch(mState) { |
| case IDLING: |
| mSprite.playAnimation(EnemyAnimations.IDLE.ordinal()); |
| if (mFacePlayer) { |
| facePlayer(parentObject); |
| } |
| |
| if (currentAction == GameObject.ActionType.ATTACK) { |
| mState = AnimationState.ATTACKING; |
| } else if (currentAction == GameObject.ActionType.HIDE) { |
| mState = AnimationState.HIDING; |
| } else if (Math.abs(velocityX) > 0.0f) { |
| mState = AnimationState.MOVING; |
| } |
| |
| break; |
| |
| case MOVING: |
| mSprite.playAnimation(EnemyAnimations.MOVE.ordinal()); |
| final float targetVelocityX = parentObject.getTargetVelocity().x; |
| |
| if (!Utils.close(velocityX, 0.0f)) { |
| if (velocityX < 0.0f && targetVelocityX < 0.0f) { |
| parentObject.facingDirection.x = -1.0f; |
| } else if (velocityX > 0.0f && targetVelocityX > 0.0f) { |
| parentObject.facingDirection.x = 1.0f; |
| } |
| } |
| if (currentAction == GameObject.ActionType.ATTACK) { |
| mState = AnimationState.ATTACKING; |
| } else if (currentAction == GameObject.ActionType.HIDE) { |
| mState = AnimationState.HIDING; |
| } else if (Math.abs(velocityX) == 0.0f) { |
| mState = AnimationState.IDLING; |
| } |
| break; |
| case ATTACKING: |
| mSprite.playAnimation(EnemyAnimations.ATTACK.ordinal()); |
| if (currentAction != GameObject.ActionType.ATTACK |
| && mSprite.animationFinished()) { |
| mState = AnimationState.IDLING; |
| } |
| break; |
| case HIDING: |
| mSprite.playAnimation(EnemyAnimations.HIDDEN.ordinal()); |
| if (currentAction != GameObject.ActionType.HIDE) { |
| mState = AnimationState.APPEARING; |
| } |
| break; |
| case APPEARING: |
| if (mFacePlayer) { |
| facePlayer(parentObject); |
| } |
| |
| mSprite.playAnimation(EnemyAnimations.APPEAR.ordinal()); |
| if (mSprite.animationFinished()) { |
| mState = AnimationState.IDLING; |
| } |
| break; |
| |
| } |
| |
| |
| } |
| } |
| |
| private void facePlayer(GameObject parentObject) { |
| GameObjectManager manager = sSystemRegistry.gameObjectManager; |
| if (manager != null) { |
| GameObject player = manager.getPlayer(); |
| if (player != null) { |
| if (player.getPosition().x < parentObject.getPosition().x) { |
| parentObject.facingDirection.x = -1.0f; |
| } else { |
| parentObject.facingDirection.x = 1.0f; |
| } |
| } |
| } |
| } |
| |
| public void setSprite(SpriteComponent sprite) { |
| mSprite = sprite; |
| } |
| |
| public void setFacePlayer(boolean facePlayer) { |
| mFacePlayer = facePlayer; |
| } |
| } |