Subversion Repositories AndroidProjects

Rev

Rev 956 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
886 chris 1
package com.gebauz.burutaru.game.entities;
2
 
890 chris 3
import com.badlogic.gdx.audio.Sound;
886 chris 4
import com.gebauz.bauzoid.graphics.sprite.AtlasSprite;
915 chris 5
import com.gebauz.bauzoid.graphics.sprite.AtlasSpriteFrame;
945 chris 6
import com.gebauz.bauzoid.graphics.sprite.AtlasSpriteInstance;
886 chris 7
import com.gebauz.bauzoid.math.MathUtil;
945 chris 8
import com.gebauz.bauzoid.math.Matrix4;
887 chris 9
import com.gebauz.bauzoid.math.Vector2;
950 chris 10
import com.gebauz.bauzoid.math.collision.AABoundingBox;
945 chris 11
import com.gebauz.bauzoid.math.collision.Shape;
12
import com.gebauz.bauzoid.math.collision.ShapeUtil;
886 chris 13
import com.gebauz.burutaru.GameConsts;
14
import com.gebauz.burutaru.game.GameLogic;
15
 
16
public class PowerUpMissile extends Entity
17
{
18
 
19
        // Constants========================================================================================
20
 
945 chris 21
        public static final int MISSILE_DAMAGE = 10;
22
 
890 chris 23
        public static final int MAX_MISSILES = 2;
886 chris 24
 
25
        public static final int UPPER_MISSILE = 0;
26
        public static final int LOWER_MISSILE = 1;
27
 
28
        public static final float MISSILE_WIDTH = 40;
29
        public static final float MISSILE_HEIGHT = MISSILE_WIDTH/2;
30
 
31
        public static final float MISSILE_ROTATION_DURATION = 0.5f;
32
 
33
        public static final float MISSILE_SPEED = 400.0f;
34
 
887 chris 35
        public static final float LAUNCH_TIME = 0.4f;
886 chris 36
        public static final float LAUNCH_SPEED =  100.0f;
887 chris 37
 
38
        public static final int NUM_MISSILE_FRAMES = 4;
39
        public static final int ROCKET_FIRE_FRAME = 4;
40
 
41
        public static final float ROCKET_FIRE_SIZE = 20;
42
        public static final float ROCKET_FIRE_SIZE_VARIANCE = 10;
43
        public static final float ROCKET_FIRE_OFFSET = 5;
44
 
895 chris 45
        public static final float MAX_ANGLE = 20.0f;
896 chris 46
        public static final float ANGULAR_SPEED = 25.0f;
890 chris 47
 
896 chris 48
        public static final float HEADING_UPDATE_INTERVAL = 0.125f;
886 chris 49
 
50
        // Embedded Types===================================================================================
51
 
52
        public enum MissilePhase
53
        {
54
                PHASE_LAUNCHING,
55
                PHASE_HOAMING
56
        }
57
 
945 chris 58
        public class Missile extends Projectile
886 chris 59
        {
945 chris 60
                public AtlasSpriteInstance spriteInstance = null;
61
 
886 chris 62
                public int type = -1;
63
                public float lifeTime = 0.0f;
64
 
65
                private MissilePhase mPhase;
945 chris 66
                private float angle = 0.0f;
890 chris 67
                private float mCurrentAngle = 0.0f;
886 chris 68
 
890 chris 69
                private float mHeadingUpdateTimer = 0.0f;
70
 
886 chris 71
                public Missile(int _type)
72
                {
945 chris 73
                        super(MISSILE_DAMAGE);
886 chris 74
                        type = _type;
945 chris 75
 
76
                        spriteInstance = new AtlasSpriteInstance(getGraphics(), mMissileSprite, mMissileFrames, mMissileShape);
77
                        setAlive(false);
886 chris 78
                }
79
 
945 chris 80
                public void launch(float x, float y)
886 chris 81
                {
82
                        lifeTime = 0.0f;
945 chris 83
                        angle = 0.0f;
890 chris 84
                        mCurrentAngle = 0.0f;
886 chris 85
                        mPhase = MissilePhase.PHASE_LAUNCHING;
890 chris 86
                        mHeadingUpdateTimer = 0.0f;
945 chris 87
 
88
                        spriteInstance.param.x = x;
89
                        spriteInstance.param.y = y;
90
                        spriteInstance.param.w = MISSILE_WIDTH;
91
                        spriteInstance.param.h = MISSILE_HEIGHT;
92
                        spriteInstance.param.pivotX = spriteInstance.param.w;
93
                        spriteInstance.param.pivotY = spriteInstance.param.h / 2;
949 chris 94
                        spriteInstance.param.angle = 0.0f;
945 chris 95
 
96
                        setAlive(true);
886 chris 97
                }
98
 
99
                public void update(float deltaTime)
100
                {
101
                        // search nearest enemy and adjust heading towards it
102
                        lifeTime += deltaTime;
103
 
104
                        switch(mPhase)
105
                        {
106
                        case PHASE_LAUNCHING:
107
                                //float t = MathUtil.clamp((lifeTime / LAUNCH_TIME), 0.0f, 1.0f);
108
 
109
                                if (type == UPPER_MISSILE)
110
                                {
945 chris 111
                                        spriteInstance.param.y -= LAUNCH_SPEED * deltaTime;
886 chris 112
                                }
113
                                else if (type == LOWER_MISSILE)
114
                                {
945 chris 115
                                        spriteInstance.param.y += LAUNCH_SPEED * deltaTime;                                    
886 chris 116
                                }
117
 
118
                                if (lifeTime > LAUNCH_TIME)
119
                                {
120
                                        mPhase = MissilePhase.PHASE_HOAMING;
890 chris 121
                                        mRocketFireSfx.play(0.3f);
886 chris 122
                                }                              
123
                                break;
124
                        case PHASE_HOAMING:
887 chris 125
                                // default target: just ahead
945 chris 126
                                Vector2 target = new Vector2(spriteInstance.param.x + 100.0f, spriteInstance.param.y);
127
                                getGameLogic().getNearestEnemyPosition(spriteInstance.param.x, spriteInstance.param.y, target);
890 chris 128
 
945 chris 129
                                Vector2 heading = new Vector2(target.x - spriteInstance.param.x, target.y - spriteInstance.param.y);
887 chris 130
 
890 chris 131
                                mHeadingUpdateTimer += deltaTime;
132
                                if (mHeadingUpdateTimer > HEADING_UPDATE_INTERVAL)
133
                                {
134
                                        mHeadingUpdateTimer = 0.0f;
135
                                        angle = MathUtil.radToDeg((float)Math.atan2(-heading.y, heading.x));
136
                                }
888 chris 137
 
890 chris 138
                                float diff = MathUtil.turnDegrees(angle, mCurrentAngle);
139
                                if (diff > MAX_ANGLE)
140
                                        diff = MAX_ANGLE;
141
                                if (mCurrentAngle > angle)
142
                                {
143
                                        mCurrentAngle -= diff * deltaTime * ANGULAR_SPEED;
144
                                        if (mCurrentAngle < angle)
145
                                                mCurrentAngle = angle;
146
                                }
147
                                else if (mCurrentAngle < angle)
148
                                {
149
                                        mCurrentAngle += diff * deltaTime * ANGULAR_SPEED;
150
                                        if (mCurrentAngle > angle)
151
                                                mCurrentAngle = angle;
152
                                }
153
 
154
                                heading.x = (float)Math.cos(Math.toRadians(mCurrentAngle));
155
                                heading.y = -(float)Math.sin(Math.toRadians(mCurrentAngle));
156
                                heading.normalize();
157
 
945 chris 158
                                spriteInstance.param.x += MISSILE_SPEED * deltaTime * heading.x;
159
                                spriteInstance.param.y += MISSILE_SPEED * deltaTime * heading.y;
160
                                spriteInstance.param.angle = mCurrentAngle;
886 chris 161
                                break;
162
                        }
947 chris 163
 
945 chris 164
                        getGameLogic().checkProjectileHit(this);
165
 
956 chris 166
                        /*if ((spriteInstance.param.x > (GameConsts.VIRTUAL_SCREEN_WIDTH + MISSILE_WIDTH)) ||
945 chris 167
                                (spriteInstance.param.x < (-MISSILE_WIDTH)) ||
168
                                (spriteInstance.param.y > (GameConsts.VIRTUAL_SCREEN_HEIGHT+ MISSILE_HEIGHT)) ||
956 chris 169
                                (spriteInstance.param.y < (-MISSILE_HEIGHT)))*/
170
                        if (getGameLogic().isOutOfScreen(spriteInstance.param))
886 chris 171
                        {
172
                                // out of screen -> make un alive
945 chris 173
                                setAlive(false);
886 chris 174
                        }
175
                }
176
 
177
                public void render()
178
                {
887 chris 179
                        float t = (lifeTime % MISSILE_ROTATION_DURATION) / MISSILE_ROTATION_DURATION;
180
                        int frame = MathUtil.clamp((int)(t * NUM_MISSILE_FRAMES), 0, NUM_MISSILE_FRAMES-1);
945 chris 181
                        spriteInstance.renderFrame(frame);
947 chris 182
 
887 chris 183
                        float rocketPulse = MathUtil.sin(lifeTime * 2000.0f) * 0.3f;
184
 
890 chris 185
                        if (mPhase == MissilePhase.PHASE_HOAMING)
186
                        {
945 chris 187
                                mMissileFrames[ROCKET_FIRE_FRAME].param.x = spriteInstance.param.x;
188
                                mMissileFrames[ROCKET_FIRE_FRAME].param.y = spriteInstance.param.y;
899 chris 189
                                mMissileFrames[ROCKET_FIRE_FRAME].param.w = ROCKET_FIRE_SIZE + ROCKET_FIRE_SIZE_VARIANCE * rocketPulse;
190
                                mMissileFrames[ROCKET_FIRE_FRAME].param.h = ROCKET_FIRE_SIZE;
191
                                mMissileFrames[ROCKET_FIRE_FRAME].param.pivotX = MISSILE_WIDTH + mMissileFrames[ROCKET_FIRE_FRAME].param.w - ROCKET_FIRE_OFFSET;
192
                                mMissileFrames[ROCKET_FIRE_FRAME].param.pivotY = mMissileFrames[ROCKET_FIRE_FRAME].param.h/2;
193
                                mMissileFrames[ROCKET_FIRE_FRAME].param.angle = mCurrentAngle;                 
890 chris 194
                                mMissileFrames[ROCKET_FIRE_FRAME].render();
195
                        }
886 chris 196
                }
945 chris 197
 
198
                @Override
993 chris 199
                public void processHit(ICollidable hitObject)
945 chris 200
                {
201
                        // spawn impact effect
993 chris 202
                        hitObject.hit(getDamage());
945 chris 203
                        setAlive(false);
204
                }
205
 
206
                @Override
207
                public Shape getShape()
208
                {
209
                        return spriteInstance.getShape();
210
                }
211
 
212
                @Override
213
                public Matrix4 getShapeTransform()
214
                {
215
                        return spriteInstance.param.getTransform();
216
                }
950 chris 217
 
218
                @Override
219
                public AABoundingBox getBounds()
220
                {
221
                        return spriteInstance.param.getBoundingBox();
222
                }
886 chris 223
        }
224
 
225
 
226
        // Fields===========================================================================================
227
 
228
        private Missile mMissiles[] = new Missile[MAX_MISSILES];
229
 
230
        private AtlasSprite mMissileSprite = null;
915 chris 231
        private AtlasSpriteFrame mMissileFrames[] = null;
890 chris 232
 
945 chris 233
        private Shape mMissileShape = null;
234
 
890 chris 235
        private Sound mRocketFireSfx = null;
886 chris 236
 
237
        // Methods==========================================================================================
238
 
239
        public PowerUpMissile(GameLogic gameLogic)
240
        {
241
                super(gameLogic);
242
                mMissileSprite = new AtlasSprite(getGraphics(), "data/textures/missile.png", "data/textures/missile.txt");
243
        }
244
 
245
        @Override
246
        public void initAsync()
247
        {
248
                mMissileSprite.initAsync();
249
        }
250
 
251
        @Override
252
        public void init()
253
        {
945 chris 254
                mMissileShape = ShapeUtil.createShapeFromFile("data/textures/missile.shape");
255
 
890 chris 256
                mRocketFireSfx = getAudio().newManagedSound("data/sounds/fire_rocket.wav");
257
 
886 chris 258
                mMissileSprite.init();
259
                mMissileFrames = mMissileSprite.createSpriteInstances();
260
 
261
                for (int i = 0; i < MAX_MISSILES; i++)
262
                {
263
                        mMissiles[i] = new Missile(i);
264
                }
265
        }
266
 
267
        @Override
268
        public void exit()
269
        {
270
                mMissileFrames = null;
271
 
272
                if (mMissileSprite != null)
273
                {
274
                        mMissileSprite.dispose();
275
                        mMissileSprite = null;
276
                }
890 chris 277
 
278
                if (mRocketFireSfx != null)
279
                {
280
                        getAudio().removeManagedSound(mRocketFireSfx);
281
                        mRocketFireSfx = null;
282
                }
886 chris 283
        }
284
 
285
        @Override
286
        public void update(float deltaTime)
287
        {
288
                int i = 0;
289
                while (i < MAX_MISSILES)
290
                {
945 chris 291
                        if (mMissiles[i].isAlive())
886 chris 292
                                mMissiles[i].update(deltaTime);
293
                        i++;
294
                }
295
 
296
        }
297
 
298
        @Override
299
        public void render()
300
        {
301
                int i = 0;
302
                while (i < MAX_MISSILES)
303
                {
945 chris 304
                        if (mMissiles[i].isAlive())
886 chris 305
                                mMissiles[i].render();
306
                        i++;
307
                }
308
        }
309
 
310
        public void launch(float x, float y)
311
        {
312
                // launch one upper, one lower
313
 
314
                for (int i = 0; i < MAX_MISSILES; i++)
315
                {
945 chris 316
                        if (!mMissiles[i].isAlive())
886 chris 317
                        {
318
                                mMissiles[i].launch(x, y);
319
                        }
320
                }
321
        }
322
 
323
        // Getters/Setters==================================================================================
324
 
325
}
326
 
327