Home | History | Annotate | Download | only in replicaisland
      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 import com.replica.replicaisland.SoundSystem.Sound;
     20 
     21 /**
     22  * This component allows objects to die and be deleted when their life is reduced to zero or they
     23  * meet other configurable criteria.
     24  */
     25 public class LifetimeComponent extends GameComponent {
     26     private boolean mDieWhenInvisible;
     27     private float mTimeUntilDeath;
     28     private GameObjectFactory.GameObjectType mSpawnOnDeathType;
     29     private LaunchProjectileComponent mTrackingSpawner;
     30     private Vector2 mHotSpotTestPoint;
     31     private boolean mReleaseGhostOnDeath;
     32     private boolean mVulnerableToDeathTiles;
     33     private boolean mDieOnHitBackground;
     34     private Sound mDeathSound;
     35     private boolean mIncrementEventCounter;
     36     private int mEventCounter;
     37 
     38     public LifetimeComponent() {
     39         super();
     40         mHotSpotTestPoint = new Vector2();
     41         reset();
     42         setPhase(ComponentPhases.THINK.ordinal());
     43     }
     44 
     45     @Override
     46     public void reset() {
     47         mDieWhenInvisible = false;
     48         mTimeUntilDeath = -1;
     49         mSpawnOnDeathType = GameObjectFactory.GameObjectType.INVALID;
     50         mTrackingSpawner = null;
     51         mHotSpotTestPoint.zero();
     52         mReleaseGhostOnDeath = true;
     53         mVulnerableToDeathTiles = false;
     54         mDieOnHitBackground = false;
     55         mDeathSound = null;
     56         mIncrementEventCounter = false;
     57         mEventCounter = -1;
     58     }
     59 
     60     public void setDieWhenInvisible(boolean die) {
     61         mDieWhenInvisible = die;
     62     }
     63 
     64     public void setTimeUntilDeath(float time) {
     65         mTimeUntilDeath = time;
     66     }
     67 
     68     public void setObjectToSpawnOnDeath(GameObjectFactory.GameObjectType type) {
     69         mSpawnOnDeathType = type;
     70     }
     71 
     72     public void setIncrementEventCounter(int event) {
     73     	mIncrementEventCounter = true;
     74     	mEventCounter = event;
     75     }
     76 
     77     @Override
     78     public void update(float timeDelta, BaseObject parent) {
     79         GameObject parentObject = (GameObject)parent;
     80         if (mTimeUntilDeath > 0) {
     81             mTimeUntilDeath -= timeDelta;
     82             if (mTimeUntilDeath <= 0) {
     83                 die(parentObject);
     84                 return;
     85             }
     86         }
     87 
     88         if (mDieWhenInvisible) {
     89             CameraSystem camera = sSystemRegistry.cameraSystem;
     90             ContextParameters context = sSystemRegistry.contextParameters;
     91             final float dx =
     92                 Math.abs(parentObject.getPosition().x - camera.getFocusPositionX());
     93             final float dy =
     94                 Math.abs(parentObject.getPosition().y - camera.getFocusPositionY());
     95             if (dx > context.gameWidth || dy > context.gameHeight) {
     96                 // the position of this object is off the screen, destroy!
     97                 // TODO: this is a pretty dumb test.  We should have a bounding volume instead.
     98                 die(parentObject);
     99                 return;
    100             }
    101         }
    102 
    103         if (parentObject.life > 0 && mVulnerableToDeathTiles) {
    104             HotSpotSystem hotSpot = sSystemRegistry.hotSpotSystem;
    105             if (hotSpot != null) {
    106                 // TODO: HACK!  Unify all this code.
    107                 if (hotSpot.getHotSpot(parentObject.getCenteredPositionX(),
    108                         parentObject.getPosition().y + 10.0f) == HotSpotSystem.HotSpotType.DIE) {
    109                     parentObject.life = 0;
    110                 }
    111             }
    112         }
    113 
    114         if (parentObject.life > 0 && mDieOnHitBackground) {
    115         	if (parentObject.getBackgroundCollisionNormal().length2() > 0.0f) {
    116         		parentObject.life = 0;
    117         	}
    118         }
    119 
    120         if (parentObject.life <= 0) {
    121             die(parentObject);
    122             return;
    123         }
    124     }
    125 
    126     private void die(GameObject parentObject) {
    127         GameObjectFactory factory = sSystemRegistry.gameObjectFactory;
    128         GameObjectManager manager = sSystemRegistry.gameObjectManager;
    129 
    130         if (mReleaseGhostOnDeath) {
    131             // TODO: This is sort of a hack.  Find a better way to do this without introducing a
    132             // dependency between these two.  Generic on-death event or something.
    133             GhostComponent ghost = parentObject.findByClass(GhostComponent.class);
    134             if (ghost != null) {
    135                 ghost.releaseControl(parentObject);
    136             }
    137         }
    138 
    139         if (mIncrementEventCounter) {
    140         	EventRecorder recorder = sSystemRegistry.eventRecorder;
    141         	recorder.incrementEventCounter(mEventCounter);
    142         }
    143 
    144         if (mSpawnOnDeathType != GameObjectFactory.GameObjectType.INVALID) {
    145             GameObject object = factory.spawn(mSpawnOnDeathType, parentObject.getPosition().x,
    146                     parentObject.getPosition().y, parentObject.facingDirection.x < 0.0f);
    147 
    148             if (object != null && manager != null) {
    149                 manager.add(object);
    150             }
    151 
    152         }
    153 
    154         if (mTrackingSpawner != null) {
    155             mTrackingSpawner.trackedProjectileDestroyed();
    156         }
    157 
    158 
    159         if (manager != null) {
    160             manager.destroy(parentObject);
    161         }
    162 
    163         if (mDeathSound != null) {
    164         	SoundSystem sound = sSystemRegistry.soundSystem;
    165         	if (sound != null) {
    166         		sound.play(mDeathSound, false, SoundSystem.PRIORITY_NORMAL);
    167         	}
    168         }
    169 
    170     }
    171 
    172     public final void setTrackingSpawner(LaunchProjectileComponent spawner) {
    173         mTrackingSpawner = spawner;
    174     }
    175 
    176     public final void setReleaseGhostOnDeath(boolean release) {
    177         mReleaseGhostOnDeath = release;
    178     }
    179 
    180     public final void setVulnerableToDeathTiles(boolean vulnerable) {
    181         mVulnerableToDeathTiles = vulnerable;
    182     }
    183 
    184     public final void setDieOnHitBackground(boolean die) {
    185     	mDieOnHitBackground = die;
    186     }
    187 
    188     public final void setDeathSound(Sound deathSound) {
    189     	mDeathSound = deathSound;
    190     }
    191 }
    192