1cfd74d65d832137e20e193c960802afba73b5d38sm/* 23c1e67e433728684b5f228c5d4f3e5b1457bb271sm * Copyright (C) 2010 The Android Open Source Project 3cfd74d65d832137e20e193c960802afba73b5d38sm * 4cfd74d65d832137e20e193c960802afba73b5d38sm * Licensed under the Apache License, Version 2.0 (the "License"); 5cfd74d65d832137e20e193c960802afba73b5d38sm * you may not use this file except in compliance with the License. 6cfd74d65d832137e20e193c960802afba73b5d38sm * You may obtain a copy of the License at 7cfd74d65d832137e20e193c960802afba73b5d38sm * 8cfd74d65d832137e20e193c960802afba73b5d38sm * http://www.apache.org/licenses/LICENSE-2.0 9cfd74d65d832137e20e193c960802afba73b5d38sm * 10cfd74d65d832137e20e193c960802afba73b5d38sm * Unless required by applicable law or agreed to in writing, software 11cfd74d65d832137e20e193c960802afba73b5d38sm * distributed under the License is distributed on an "AS IS" BASIS, 12cfd74d65d832137e20e193c960802afba73b5d38sm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cfd74d65d832137e20e193c960802afba73b5d38sm * See the License for the specific language governing permissions and 14cfd74d65d832137e20e193c960802afba73b5d38sm * limitations under the License. 15cfd74d65d832137e20e193c960802afba73b5d38sm */ 16cfd74d65d832137e20e193c960802afba73b5d38sm 17cfd74d65d832137e20e193c960802afba73b5d38smpackage com.replica.replicaisland; 18cfd74d65d832137e20e193c960802afba73b5d38sm 19cfd74d65d832137e20e193c960802afba73b5d38sm/** 20cfd74d65d832137e20e193c960802afba73b5d38sm * A general-purpose animation selection system for animating enemy characters. Most enemy 21cfd74d65d832137e20e193c960802afba73b5d38sm * characters behave similarly, so this code tries to decide which animation bets fits their current 22cfd74d65d832137e20e193c960802afba73b5d38sm * state. Other code (such as enemy AI) may move these characters around and change the current 23cfd74d65d832137e20e193c960802afba73b5d38sm * ActionType, which will result in this code figuring out which sequence of animations is best to 24cfd74d65d832137e20e193c960802afba73b5d38sm * play. 25cfd74d65d832137e20e193c960802afba73b5d38sm */ 26cfd74d65d832137e20e193c960802afba73b5d38smpublic class EnemyAnimationComponent extends GameComponent { 27cfd74d65d832137e20e193c960802afba73b5d38sm 28cfd74d65d832137e20e193c960802afba73b5d38sm public enum EnemyAnimations { 29cfd74d65d832137e20e193c960802afba73b5d38sm IDLE, 30cfd74d65d832137e20e193c960802afba73b5d38sm MOVE, 31cfd74d65d832137e20e193c960802afba73b5d38sm ATTACK, 32cfd74d65d832137e20e193c960802afba73b5d38sm HIDDEN, 33cfd74d65d832137e20e193c960802afba73b5d38sm APPEAR, 34cfd74d65d832137e20e193c960802afba73b5d38sm } 35cfd74d65d832137e20e193c960802afba73b5d38sm 36cfd74d65d832137e20e193c960802afba73b5d38sm private enum AnimationState { 37cfd74d65d832137e20e193c960802afba73b5d38sm IDLING, 38cfd74d65d832137e20e193c960802afba73b5d38sm MOVING, 39cfd74d65d832137e20e193c960802afba73b5d38sm HIDING, 40cfd74d65d832137e20e193c960802afba73b5d38sm APPEARING, 41cfd74d65d832137e20e193c960802afba73b5d38sm ATTACKING 42cfd74d65d832137e20e193c960802afba73b5d38sm } 43cfd74d65d832137e20e193c960802afba73b5d38sm 44cfd74d65d832137e20e193c960802afba73b5d38sm private SpriteComponent mSprite; 45cfd74d65d832137e20e193c960802afba73b5d38sm private AnimationState mState; 46cfd74d65d832137e20e193c960802afba73b5d38sm private boolean mFacePlayer; 47cfd74d65d832137e20e193c960802afba73b5d38sm 48cfd74d65d832137e20e193c960802afba73b5d38sm public EnemyAnimationComponent() { 49cfd74d65d832137e20e193c960802afba73b5d38sm super(); 50cfd74d65d832137e20e193c960802afba73b5d38sm setPhase(ComponentPhases.ANIMATION.ordinal()); 51cfd74d65d832137e20e193c960802afba73b5d38sm reset(); 52cfd74d65d832137e20e193c960802afba73b5d38sm } 53cfd74d65d832137e20e193c960802afba73b5d38sm 54cfd74d65d832137e20e193c960802afba73b5d38sm @Override 55cfd74d65d832137e20e193c960802afba73b5d38sm public void reset() { 56cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.IDLING; 57cfd74d65d832137e20e193c960802afba73b5d38sm mFacePlayer = false; 58cfd74d65d832137e20e193c960802afba73b5d38sm mSprite = null; 59cfd74d65d832137e20e193c960802afba73b5d38sm } 60cfd74d65d832137e20e193c960802afba73b5d38sm 61cfd74d65d832137e20e193c960802afba73b5d38sm @Override 62cfd74d65d832137e20e193c960802afba73b5d38sm public void update(float timeDelta, BaseObject parent) { 63cfd74d65d832137e20e193c960802afba73b5d38sm if (mSprite != null) { 64cfd74d65d832137e20e193c960802afba73b5d38sm GameObject parentObject = (GameObject) parent; 65cfd74d65d832137e20e193c960802afba73b5d38sm final float velocityX = parentObject.getVelocity().x; 66cfd74d65d832137e20e193c960802afba73b5d38sm 67cfd74d65d832137e20e193c960802afba73b5d38sm GameObject.ActionType currentAction = parentObject.getCurrentAction(); 68cfd74d65d832137e20e193c960802afba73b5d38sm 69cfd74d65d832137e20e193c960802afba73b5d38sm switch(mState) { 70cfd74d65d832137e20e193c960802afba73b5d38sm case IDLING: 71cfd74d65d832137e20e193c960802afba73b5d38sm mSprite.playAnimation(EnemyAnimations.IDLE.ordinal()); 72cfd74d65d832137e20e193c960802afba73b5d38sm if (mFacePlayer) { 73cfd74d65d832137e20e193c960802afba73b5d38sm facePlayer(parentObject); 74cfd74d65d832137e20e193c960802afba73b5d38sm } 75cfd74d65d832137e20e193c960802afba73b5d38sm 76cfd74d65d832137e20e193c960802afba73b5d38sm if (currentAction == GameObject.ActionType.ATTACK) { 77cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.ATTACKING; 78cfd74d65d832137e20e193c960802afba73b5d38sm } else if (currentAction == GameObject.ActionType.HIDE) { 79cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.HIDING; 80cfd74d65d832137e20e193c960802afba73b5d38sm } else if (Math.abs(velocityX) > 0.0f) { 81cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.MOVING; 82cfd74d65d832137e20e193c960802afba73b5d38sm } 83cfd74d65d832137e20e193c960802afba73b5d38sm 84cfd74d65d832137e20e193c960802afba73b5d38sm break; 85cfd74d65d832137e20e193c960802afba73b5d38sm 86cfd74d65d832137e20e193c960802afba73b5d38sm case MOVING: 87cfd74d65d832137e20e193c960802afba73b5d38sm mSprite.playAnimation(EnemyAnimations.MOVE.ordinal()); 88cfd74d65d832137e20e193c960802afba73b5d38sm final float targetVelocityX = parentObject.getTargetVelocity().x; 89cfd74d65d832137e20e193c960802afba73b5d38sm 90cfd74d65d832137e20e193c960802afba73b5d38sm if (!Utils.close(velocityX, 0.0f)) { 91cfd74d65d832137e20e193c960802afba73b5d38sm if (velocityX < 0.0f && targetVelocityX < 0.0f) { 92cfd74d65d832137e20e193c960802afba73b5d38sm parentObject.facingDirection.x = -1.0f; 93cfd74d65d832137e20e193c960802afba73b5d38sm } else if (velocityX > 0.0f && targetVelocityX > 0.0f) { 94cfd74d65d832137e20e193c960802afba73b5d38sm parentObject.facingDirection.x = 1.0f; 95cfd74d65d832137e20e193c960802afba73b5d38sm } 96cfd74d65d832137e20e193c960802afba73b5d38sm } 97cfd74d65d832137e20e193c960802afba73b5d38sm if (currentAction == GameObject.ActionType.ATTACK) { 98cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.ATTACKING; 99cfd74d65d832137e20e193c960802afba73b5d38sm } else if (currentAction == GameObject.ActionType.HIDE) { 100cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.HIDING; 101cfd74d65d832137e20e193c960802afba73b5d38sm } else if (Math.abs(velocityX) == 0.0f) { 102cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.IDLING; 103cfd74d65d832137e20e193c960802afba73b5d38sm } 104cfd74d65d832137e20e193c960802afba73b5d38sm break; 105cfd74d65d832137e20e193c960802afba73b5d38sm case ATTACKING: 106cfd74d65d832137e20e193c960802afba73b5d38sm mSprite.playAnimation(EnemyAnimations.ATTACK.ordinal()); 107cfd74d65d832137e20e193c960802afba73b5d38sm if (currentAction != GameObject.ActionType.ATTACK 108cfd74d65d832137e20e193c960802afba73b5d38sm && mSprite.animationFinished()) { 109cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.IDLING; 110cfd74d65d832137e20e193c960802afba73b5d38sm } 111cfd74d65d832137e20e193c960802afba73b5d38sm break; 112cfd74d65d832137e20e193c960802afba73b5d38sm case HIDING: 113cfd74d65d832137e20e193c960802afba73b5d38sm mSprite.playAnimation(EnemyAnimations.HIDDEN.ordinal()); 114cfd74d65d832137e20e193c960802afba73b5d38sm if (currentAction != GameObject.ActionType.HIDE) { 115cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.APPEARING; 116cfd74d65d832137e20e193c960802afba73b5d38sm } 117cfd74d65d832137e20e193c960802afba73b5d38sm break; 118cfd74d65d832137e20e193c960802afba73b5d38sm case APPEARING: 119cfd74d65d832137e20e193c960802afba73b5d38sm if (mFacePlayer) { 120cfd74d65d832137e20e193c960802afba73b5d38sm facePlayer(parentObject); 121cfd74d65d832137e20e193c960802afba73b5d38sm } 122cfd74d65d832137e20e193c960802afba73b5d38sm 123cfd74d65d832137e20e193c960802afba73b5d38sm mSprite.playAnimation(EnemyAnimations.APPEAR.ordinal()); 124cfd74d65d832137e20e193c960802afba73b5d38sm if (mSprite.animationFinished()) { 125cfd74d65d832137e20e193c960802afba73b5d38sm mState = AnimationState.IDLING; 126cfd74d65d832137e20e193c960802afba73b5d38sm } 127cfd74d65d832137e20e193c960802afba73b5d38sm break; 128cfd74d65d832137e20e193c960802afba73b5d38sm 129cfd74d65d832137e20e193c960802afba73b5d38sm } 130cfd74d65d832137e20e193c960802afba73b5d38sm 131cfd74d65d832137e20e193c960802afba73b5d38sm 132cfd74d65d832137e20e193c960802afba73b5d38sm } 133cfd74d65d832137e20e193c960802afba73b5d38sm } 134cfd74d65d832137e20e193c960802afba73b5d38sm 135cfd74d65d832137e20e193c960802afba73b5d38sm private void facePlayer(GameObject parentObject) { 136cfd74d65d832137e20e193c960802afba73b5d38sm GameObjectManager manager = sSystemRegistry.gameObjectManager; 137cfd74d65d832137e20e193c960802afba73b5d38sm if (manager != null) { 138cfd74d65d832137e20e193c960802afba73b5d38sm GameObject player = manager.getPlayer(); 139cfd74d65d832137e20e193c960802afba73b5d38sm if (player != null) { 140cfd74d65d832137e20e193c960802afba73b5d38sm if (player.getPosition().x < parentObject.getPosition().x) { 141cfd74d65d832137e20e193c960802afba73b5d38sm parentObject.facingDirection.x = -1.0f; 142cfd74d65d832137e20e193c960802afba73b5d38sm } else { 143cfd74d65d832137e20e193c960802afba73b5d38sm parentObject.facingDirection.x = 1.0f; 144cfd74d65d832137e20e193c960802afba73b5d38sm } 145cfd74d65d832137e20e193c960802afba73b5d38sm } 146cfd74d65d832137e20e193c960802afba73b5d38sm } 147cfd74d65d832137e20e193c960802afba73b5d38sm } 148cfd74d65d832137e20e193c960802afba73b5d38sm 149cfd74d65d832137e20e193c960802afba73b5d38sm public void setSprite(SpriteComponent sprite) { 150cfd74d65d832137e20e193c960802afba73b5d38sm mSprite = sprite; 151cfd74d65d832137e20e193c960802afba73b5d38sm } 152cfd74d65d832137e20e193c960802afba73b5d38sm 153cfd74d65d832137e20e193c960802afba73b5d38sm public void setFacePlayer(boolean facePlayer) { 154cfd74d65d832137e20e193c960802afba73b5d38sm mFacePlayer = facePlayer; 155cfd74d65d832137e20e193c960802afba73b5d38sm } 156cfd74d65d832137e20e193c960802afba73b5d38sm} 157