| /* |
| * 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 component that implements the "pop-out" AI behavior. Pop-out characters alternate between |
| * hiding and appearing based on their distance from the player. They do not move or normally |
| * attack. |
| */ |
| public class PopOutComponent extends GameComponent { |
| private static final int DEFAULT_APPEAR_DISTANCE = 120; |
| private static final int DEFAULT_HIDE_DISTANCE = 190; |
| private static final int DEFAULT_ATTACK_DISTANCE = 0; // No attacking by default. |
| private float mAppearDistance; |
| private float mHideDistance; |
| private float mAttackDistance; |
| private float mAttackDelay; |
| private float mAttackLength; |
| private float mAttackStartTime; |
| private Vector2 mDistance; |
| private int mState; |
| private float mLastAttackCompletedTime; |
| |
| private final static int STATE_HIDDEN = 0; |
| private final static int STATE_VISIBLE = 1; |
| private final static int STATE_ATTACKING = 2; |
| |
| public PopOutComponent() { |
| super(); |
| setPhase(GameComponent.ComponentPhases.THINK.ordinal()); |
| mDistance = new Vector2(); |
| reset(); |
| } |
| |
| @Override |
| public void reset() { |
| mAttackDelay = 0; |
| mAttackLength = 0; |
| mAttackDistance = DEFAULT_ATTACK_DISTANCE; |
| mAppearDistance = DEFAULT_APPEAR_DISTANCE; |
| mHideDistance = DEFAULT_HIDE_DISTANCE; |
| mState = STATE_HIDDEN; |
| mLastAttackCompletedTime = 0.0f; |
| } |
| |
| @Override |
| public void update(float timeDelta, BaseObject parent) { |
| GameObject parentObject = (GameObject) parent; |
| |
| GameObjectManager manager = sSystemRegistry.gameObjectManager; |
| if (manager != null) { |
| GameObject player = manager.getPlayer(); |
| if (player != null) { |
| mDistance.set(player.getPosition()); |
| mDistance.subtract(parentObject.getPosition()); |
| |
| TimeSystem time = sSystemRegistry.timeSystem; |
| final float currentTime = time.getGameTime(); |
| |
| switch(mState) { |
| case STATE_HIDDEN: |
| parentObject.setCurrentAction(GameObject.ActionType.HIDE); |
| if (mDistance.length2() < (mAppearDistance * mAppearDistance)) { |
| mState = STATE_VISIBLE; |
| mLastAttackCompletedTime = currentTime; |
| } |
| break; |
| case STATE_VISIBLE: |
| parentObject.setCurrentAction(GameObject.ActionType.IDLE); |
| if (mDistance.length2() > (mHideDistance * mHideDistance)) { |
| mState = STATE_HIDDEN; |
| } else if (mDistance.length2() < (mAttackDistance * mAttackDistance) |
| && currentTime > mLastAttackCompletedTime + mAttackDelay) { |
| mAttackStartTime = currentTime; |
| mState = STATE_ATTACKING; |
| } |
| break; |
| case STATE_ATTACKING: |
| parentObject.setCurrentAction(GameObject.ActionType.ATTACK); |
| if (currentTime > mAttackStartTime + mAttackLength) { |
| mState = STATE_VISIBLE; |
| mLastAttackCompletedTime = currentTime; |
| } |
| break; |
| default: |
| assert false; |
| break; |
| } |
| |
| } |
| } |
| |
| } |
| |
| public void setupAttack(float distance, float delay, float duration) { |
| mAttackDistance = distance; |
| mAttackDelay = delay; |
| mAttackLength = duration; |
| } |
| |
| public void setAppearDistance(float appearDistance) { |
| mAppearDistance = appearDistance; |
| } |
| |
| public void setHideDistance(float hideDistance) { |
| mHideDistance = hideDistance; |
| } |
| |
| |
| } |
| |
| |