• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.GameObject.ActionType;
20 
21 /**
22  * A component that allows an object to spawn other objects and apply velocity to them at
23  * specific intervals.  Can be used to launch projectiles, particle effects, or any other type
24  * of game object.
25  */
26 public class LaunchProjectileComponent extends GameComponent {
27     private GameObjectFactory.GameObjectType mObjectTypeToSpawn;
28     private float mOffsetX;
29     private float mOffsetY;
30     private float mVelocityX;
31     private float mVelocityY;
32     private float mThetaError;
33     private GameObject.ActionType mRequiredAction;
34     private float mDelayBetweenShots;
35     private int mProjectilesInSet;
36     private float mDelayBetweenSets;
37     private int mSetsPerActivation;
38     private float mDelayBeforeFirstSet;
39 
40     private float mLastProjectileTime;
41     private float mSetStartedTime;
42     private int mLaunchedCount;
43     private int mSetCount;
44 
45     private boolean mTrackProjectiles;
46     private int mMaxTrackedProjectiles;
47     private int mTrackedProjectileCount;
48 
49     private Vector2 mWorkingVector;
50 
51     private SoundSystem.Sound mShootSound;
52 
53 
LaunchProjectileComponent()54     public LaunchProjectileComponent() {
55         super();
56         setPhase(ComponentPhases.POST_COLLISION.ordinal());
57         mWorkingVector = new Vector2();
58         reset();
59     }
60 
61     @Override
reset()62     public void reset() {
63         mRequiredAction = ActionType.INVALID;
64         mObjectTypeToSpawn = GameObjectFactory.GameObjectType.INVALID;
65         mOffsetX = 0.0f;
66         mOffsetY = 0.0f;
67         mVelocityX = 0.0f;
68         mVelocityY = 0.0f;
69         mDelayBetweenShots = 0.0f;
70         mProjectilesInSet = 0;
71         mDelayBetweenSets = 0.0f;
72         mLastProjectileTime = 0.0f;
73         mSetStartedTime = -1.0f;
74         mLaunchedCount = 0;
75         mSetCount = 0;
76         mSetsPerActivation = -1;
77         mProjectilesInSet = 0;
78         mDelayBeforeFirstSet = 0.0f;
79         mTrackProjectiles = false;
80         mMaxTrackedProjectiles = 0;
81         mTrackedProjectileCount = 0;
82         mThetaError = 0.0f;
83         mShootSound = null;
84     }
85 
86     @Override
update(float timeDelta, BaseObject parent)87     public void update(float timeDelta, BaseObject parent) {
88         GameObject parentObject = (GameObject) parent;
89 
90         final TimeSystem time = sSystemRegistry.timeSystem;
91         final float gameTime = time.getGameTime();
92 
93         if (mTrackedProjectileCount < mMaxTrackedProjectiles || !mTrackProjectiles) {
94             if (parentObject.getCurrentAction() == mRequiredAction
95                     || mRequiredAction == ActionType.INVALID) {
96 
97                 if (mSetStartedTime == -1.0f) {
98                     mLaunchedCount = 0;
99                     mLastProjectileTime = 0.0f;
100                     mSetStartedTime = gameTime;
101                 }
102 
103                 final float setDelay = mSetCount > 0 ? mDelayBetweenSets : mDelayBeforeFirstSet;
104 
105                 if (gameTime - mSetStartedTime >= setDelay &&
106                         (mSetCount < mSetsPerActivation || mSetsPerActivation == -1)) {
107                     // We can start shooting.
108                     final float timeSinceLastShot = gameTime - mLastProjectileTime;
109 
110                     if (timeSinceLastShot >= mDelayBetweenShots) {
111 
112                         launch(parentObject);
113                         mLastProjectileTime = gameTime;
114 
115                         if (mLaunchedCount >= mProjectilesInSet && mProjectilesInSet > 0) {
116                             mSetStartedTime = -1.0f;
117                             mSetCount++;
118                         }
119                     }
120                 }
121             } else {
122                 // Force the timer to start counting when the right action is activated.
123                 mSetStartedTime = -1.0f;
124                 mSetCount = 0;
125             }
126         }
127     }
128 
launch(GameObject parentObject)129     private void launch(GameObject parentObject) {
130         mLaunchedCount++;
131         GameObjectFactory factory = sSystemRegistry.gameObjectFactory;
132         GameObjectManager manager = sSystemRegistry.gameObjectManager;
133         if (factory != null && manager != null) {
134             float offsetX = mOffsetX;
135             float offsetY = mOffsetY;
136             boolean flip = false;
137             if (parentObject.facingDirection.x < 0.0f) {
138                 offsetX = parentObject.width - mOffsetX;
139                 flip = true;
140             }
141 
142             if (parentObject.facingDirection.y < 0.0f) {
143                 offsetY = parentObject.height - mOffsetY;
144             }
145 
146             final float x = parentObject.getPosition().x + offsetX;
147             final float y = parentObject.getPosition().y + offsetY;
148             GameObject object = factory.spawn(mObjectTypeToSpawn, x, y, flip);
149             if (object != null) {
150 	            mWorkingVector.set(1.0f, 1.0f);
151 	            if (mThetaError > 0.0f) {
152 	                final float angle = (float)(Math.random() * mThetaError * Math.PI * 2.0f);
153 	                mWorkingVector.x = (float)Math.sin(angle);
154 	                mWorkingVector.y = (float)Math.cos(angle);
155 	                if (Utils.close(mWorkingVector.length2(), 0.0f)) {
156 	                    mWorkingVector.set(1.0f, 1.0f);
157 	                }
158 	            }
159 	            mWorkingVector.x *= flip ? -mVelocityX : mVelocityX;
160 	            mWorkingVector.y *= mVelocityY;
161 
162 	            object.getVelocity().set(mWorkingVector);
163 	            object.getTargetVelocity().set(mWorkingVector);
164 	            // Center the projectile on the spawn point.
165 	            object.getPosition().x -= object.width / 2.0f;
166 	            object.getPosition().y -= object.height / 2.0f;
167 
168 
169 	            if (mTrackProjectiles) {
170 	                object.commitUpdates();
171 	                LifetimeComponent projectileLife = object.findByClass(LifetimeComponent.class);
172 	                if (projectileLife != null) {
173 	                    projectileLife.setTrackingSpawner(this);
174 	                    mTrackedProjectileCount++;
175 	                }
176 	            }
177 	            manager.add(object);
178 
179 	            if (mShootSound != null) {
180 	            	SoundSystem sound = sSystemRegistry.soundSystem;
181 	            	if (sound != null) {
182 	            		sound.play(mShootSound, false, SoundSystem.PRIORITY_NORMAL);
183 	            	}
184 	            }
185             }
186         }
187 
188 
189     }
190 
setObjectTypeToSpawn(GameObjectFactory.GameObjectType objectTypeToSpawn)191     public final void setObjectTypeToSpawn(GameObjectFactory.GameObjectType objectTypeToSpawn) {
192         mObjectTypeToSpawn = objectTypeToSpawn;
193     }
194 
setOffsetX(float offsetX)195     public final void setOffsetX(float offsetX) {
196         mOffsetX = offsetX;
197     }
198 
setOffsetY(float offsetY)199     public final void setOffsetY(float offsetY) {
200         mOffsetY = offsetY;
201     }
202 
setVelocityX(float velocityX)203     public final void setVelocityX(float velocityX) {
204         mVelocityX = velocityX;
205     }
206 
setVelocityY(float velocityY)207     public final void setVelocityY(float velocityY) {
208         mVelocityY = velocityY;
209     }
210 
setRequiredAction(GameObject.ActionType requiredAction)211     public final void setRequiredAction(GameObject.ActionType requiredAction) {
212         mRequiredAction = requiredAction;
213     }
214 
setDelayBetweenShots(float launchDelay)215     public final void setDelayBetweenShots(float launchDelay) {
216         mDelayBetweenShots = launchDelay;
217     }
218 
setDelayBetweenSets(float delayBetweenSets)219     public final void setDelayBetweenSets(float delayBetweenSets) {
220         mDelayBetweenSets = delayBetweenSets;
221     }
222 
setDelayBeforeFirstSet(float delayBeforeFirstSet)223     public final void setDelayBeforeFirstSet(float delayBeforeFirstSet) {
224         mDelayBeforeFirstSet = delayBeforeFirstSet;
225     }
226 
setShotsPerSet(int shotCount)227     public final void setShotsPerSet(int shotCount) {
228         mProjectilesInSet = shotCount;
229     }
230 
setSetsPerActivation(int setCount)231     public final void setSetsPerActivation(int setCount) {
232         mSetsPerActivation = setCount;
233     }
234 
enableProjectileTracking(int max)235     public final void enableProjectileTracking(int max) {
236         mMaxTrackedProjectiles = max;
237         mTrackProjectiles = true;
238     }
239 
disableProjectileTracking()240     public final void disableProjectileTracking() {
241         mMaxTrackedProjectiles = 0;
242         mTrackProjectiles = false;
243     }
244 
trackedProjectileDestroyed()245     public final void trackedProjectileDestroyed() {
246         assert mTrackProjectiles;
247         if (mTrackedProjectileCount == mMaxTrackedProjectiles) {
248             // Let's restart the set.
249             mSetStartedTime = -1.0f;
250             mSetCount = 0;
251         }
252         mTrackedProjectileCount--;
253     }
254 
setThetaError(float error)255     public final void setThetaError(float error) {
256         mThetaError = error;
257     }
258 
setShootSound(SoundSystem.Sound shoot)259     public final void setShootSound(SoundSystem.Sound shoot) {
260     	mShootSound = shoot;
261     }
262 
263 }
264