Java程序  |  127行  |  4.57 KB

/*
 * 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;
    }
    
    
}