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