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 * A component that implements the "pop-out" AI behavior. Pop-out characters alternate between 21 * hiding and appearing based on their distance from the player. They do not move or normally 22 * attack. 23 */ 24 public class PopOutComponent extends GameComponent { 25 private static final int DEFAULT_APPEAR_DISTANCE = 120; 26 private static final int DEFAULT_HIDE_DISTANCE = 190; 27 private static final int DEFAULT_ATTACK_DISTANCE = 0; // No attacking by default. 28 private float mAppearDistance; 29 private float mHideDistance; 30 private float mAttackDistance; 31 private float mAttackDelay; 32 private float mAttackLength; 33 private float mAttackStartTime; 34 private Vector2 mDistance; 35 private int mState; 36 private float mLastAttackCompletedTime; 37 38 private final static int STATE_HIDDEN = 0; 39 private final static int STATE_VISIBLE = 1; 40 private final static int STATE_ATTACKING = 2; 41 PopOutComponent()42 public PopOutComponent() { 43 super(); 44 setPhase(GameComponent.ComponentPhases.THINK.ordinal()); 45 mDistance = new Vector2(); 46 reset(); 47 } 48 49 @Override reset()50 public void reset() { 51 mAttackDelay = 0; 52 mAttackLength = 0; 53 mAttackDistance = DEFAULT_ATTACK_DISTANCE; 54 mAppearDistance = DEFAULT_APPEAR_DISTANCE; 55 mHideDistance = DEFAULT_HIDE_DISTANCE; 56 mState = STATE_HIDDEN; 57 mLastAttackCompletedTime = 0.0f; 58 } 59 60 @Override update(float timeDelta, BaseObject parent)61 public void update(float timeDelta, BaseObject parent) { 62 GameObject parentObject = (GameObject) parent; 63 64 GameObjectManager manager = sSystemRegistry.gameObjectManager; 65 if (manager != null) { 66 GameObject player = manager.getPlayer(); 67 if (player != null) { 68 mDistance.set(player.getPosition()); 69 mDistance.subtract(parentObject.getPosition()); 70 71 TimeSystem time = sSystemRegistry.timeSystem; 72 final float currentTime = time.getGameTime(); 73 74 switch(mState) { 75 case STATE_HIDDEN: 76 parentObject.setCurrentAction(GameObject.ActionType.HIDE); 77 if (mDistance.length2() < (mAppearDistance * mAppearDistance)) { 78 mState = STATE_VISIBLE; 79 mLastAttackCompletedTime = currentTime; 80 } 81 break; 82 case STATE_VISIBLE: 83 parentObject.setCurrentAction(GameObject.ActionType.IDLE); 84 if (mDistance.length2() > (mHideDistance * mHideDistance)) { 85 mState = STATE_HIDDEN; 86 } else if (mDistance.length2() < (mAttackDistance * mAttackDistance) 87 && currentTime > mLastAttackCompletedTime + mAttackDelay) { 88 mAttackStartTime = currentTime; 89 mState = STATE_ATTACKING; 90 } 91 break; 92 case STATE_ATTACKING: 93 parentObject.setCurrentAction(GameObject.ActionType.ATTACK); 94 if (currentTime > mAttackStartTime + mAttackLength) { 95 mState = STATE_VISIBLE; 96 mLastAttackCompletedTime = currentTime; 97 } 98 break; 99 default: 100 assert false; 101 break; 102 } 103 104 } 105 } 106 107 } 108 setupAttack(float distance, float delay, float duration)109 public void setupAttack(float distance, float delay, float duration) { 110 mAttackDistance = distance; 111 mAttackDelay = delay; 112 mAttackLength = duration; 113 } 114 setAppearDistance(float appearDistance)115 public void setAppearDistance(float appearDistance) { 116 mAppearDistance = appearDistance; 117 } 118 setHideDistance(float hideDistance)119 public void setHideDistance(float hideDistance) { 120 mHideDistance = hideDistance; 121 } 122 123 124 } 125 126 127