Subversion Repositories AndroidProjects

Rev

Rev 886 | Rev 888 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.burutaru.game.entities;

import com.badlogic.gdx.Gdx;
import com.gebauz.bauzoid.graphics.sprite.AtlasSprite;
import com.gebauz.bauzoid.graphics.sprite.AtlasSpriteInstance;
import com.gebauz.bauzoid.math.MathUtil;
import com.gebauz.bauzoid.math.Vector2;
import com.gebauz.burutaru.GameConsts;
import com.gebauz.burutaru.game.GameLogic;

public class PowerUpMissile extends Entity
{

        // Constants========================================================================================
       
        public static final int MAX_MISSILES = 2;
       
        public static final int UPPER_MISSILE = 0;
        public static final int LOWER_MISSILE = 1;
       
        public static final float MISSILE_WIDTH = 40;
        public static final float MISSILE_HEIGHT = MISSILE_WIDTH/2;
       
        public static final float MISSILE_ROTATION_DURATION = 0.5f;
       
        public static final float MISSILE_SPEED = 400.0f;
       
        public static final float LAUNCH_TIME = 0.4f;
        public static final float LAUNCH_SPEED =  100.0f;
       
        public static final int NUM_MISSILE_FRAMES = 4;
        public static final int ROCKET_FIRE_FRAME = 4;
       
        public static final float ROCKET_FIRE_SIZE = 20;
        public static final float ROCKET_FIRE_SIZE_VARIANCE = 10;
        public static final float ROCKET_FIRE_OFFSET = 5;
       
        public static final float MAX_ANGLE = 60.0f;

        // Embedded Types===================================================================================
       
        public enum MissilePhase
        {
                PHASE_LAUNCHING,
                PHASE_HOAMING
        }
       
        public class Missile
        {
                public float x = 0;
                public float y = 0;
                public int type = -1;
                public boolean isAlive = false;
                public float lifeTime = 0.0f;
               
                public float angle = 0.0f;
               
                private MissilePhase mPhase;
                private float currentAngle = 0.0f;
               
                public Missile(int _type)
                {
                        type = _type;
                }
               
                public void launch(float _x, float _y)
                {
                        isAlive = true;
                        x = _x; y = _y;
                        lifeTime = 0.0f;
                        angle = 0.0f;                  
                        currentAngle = 0.0f;
                        mPhase = MissilePhase.PHASE_LAUNCHING;
                }
               
                public void update(float deltaTime)
                {
                        // search nearest enemy and adjust heading towards it
                        lifeTime += deltaTime;
                       
                        switch(mPhase)
                        {
                        case PHASE_LAUNCHING:
                                //float t = MathUtil.clamp((lifeTime / LAUNCH_TIME), 0.0f, 1.0f);
                               
                                if (type == UPPER_MISSILE)
                                {
                                        y -= LAUNCH_SPEED * deltaTime;
                                }
                                else if (type == LOWER_MISSILE)
                                {
                                        y += LAUNCH_SPEED * deltaTime;                                 
                                }
                               
                                if (lifeTime > LAUNCH_TIME)
                                {
                                        mPhase = MissilePhase.PHASE_HOAMING;
                                }                              
                                break;
                        case PHASE_HOAMING:
                                //x += MISSILE_SPEED * deltaTime;
                               
                                // default target: just ahead
                                Vector2 target = new Vector2(x + 100.0f, y);
                                getGameLogic().getNearestEnemyPosition(x, y, target);
                               
                                // get heading
                                Vector2 heading = new Vector2(target.x - x, target.y - y);
                                heading.normalize();
                               
                                angle = MathUtil.radToDeg((float)Math.atan2(-heading.y, heading.x));
                               
                                if (((float)Math.abs(angle - currentAngle)) > MAX_ANGLE)
                                {
                                        if (angle < currentAngle)
                                                angle -= MAX_ANGLE;
                                        else
                                                angle += MAX_ANGLE;
                                        heading.x = (float)Math.sin(Math.toRadians(angle));
                                        heading.y = (float)Math.cos(Math.toRadians(angle));
                                }
                               
                                x += MISSILE_SPEED * deltaTime * heading.x;
                                y += MISSILE_SPEED * deltaTime * heading.y;
                               
                                break;
                        }
                       
                        float angleDiff = angle - currentAngle;
                        currentAngle = angleDiff * deltaTime * 11;
                       
                        if ((x > (GameConsts.VIRTUAL_SCREEN_WIDTH + MISSILE_WIDTH)) ||
                                (x < (-MISSILE_WIDTH)) ||
                                (y > (GameConsts.VIRTUAL_SCREEN_HEIGHT+ MISSILE_HEIGHT)) ||
                                (y < (-MISSILE_HEIGHT)))
                        {
                                // out of screen -> make un alive
                                isAlive = false;
                        }
                }
               
                public void render()
                {
                        float t = (lifeTime % MISSILE_ROTATION_DURATION) / MISSILE_ROTATION_DURATION;
                        int frame = MathUtil.clamp((int)(t * NUM_MISSILE_FRAMES), 0, NUM_MISSILE_FRAMES-1);
                       
                        mMissileFrames[frame].x = x;
                        mMissileFrames[frame].y = y;
                        mMissileFrames[frame].w = MISSILE_WIDTH;
                        mMissileFrames[frame].h = MISSILE_HEIGHT;
                        mMissileFrames[frame].pivotX = mMissileFrames[frame].w;
                        mMissileFrames[frame].pivotY = mMissileFrames[frame].h / 2;
                        mMissileFrames[frame].angle = currentAngle;
                        mMissileFrames[frame].render();
                       
                        float rocketPulse = MathUtil.sin(lifeTime * 2000.0f) * 0.3f;
                       
                        mMissileFrames[ROCKET_FIRE_FRAME].x = x;
                        mMissileFrames[ROCKET_FIRE_FRAME].y = y;
                        mMissileFrames[ROCKET_FIRE_FRAME].w = ROCKET_FIRE_SIZE + ROCKET_FIRE_SIZE_VARIANCE * rocketPulse;
                        mMissileFrames[ROCKET_FIRE_FRAME].h = ROCKET_FIRE_SIZE;
                        mMissileFrames[ROCKET_FIRE_FRAME].pivotX = MISSILE_WIDTH + mMissileFrames[ROCKET_FIRE_FRAME].w - ROCKET_FIRE_OFFSET;
                        mMissileFrames[ROCKET_FIRE_FRAME].pivotY = mMissileFrames[ROCKET_FIRE_FRAME].h/2;
                        mMissileFrames[ROCKET_FIRE_FRAME].angle = currentAngle;                
                        mMissileFrames[ROCKET_FIRE_FRAME].render();
                }
        }
       

        // Fields===========================================================================================
       
        private Missile mMissiles[] = new Missile[MAX_MISSILES];
       
        private AtlasSprite mMissileSprite = null;
        private AtlasSpriteInstance mMissileFrames[] = null;

        // Methods==========================================================================================

        public PowerUpMissile(GameLogic gameLogic)
        {
                super(gameLogic);
                mMissileSprite = new AtlasSprite(getGraphics(), "data/textures/missile.png", "data/textures/missile.txt");
        }
       
        @Override
        public void initAsync()
        {
                mMissileSprite.initAsync();
        }

        @Override
        public void init()
        {
                mMissileSprite.init();
                mMissileFrames = mMissileSprite.createSpriteInstances();
               
                for (int i = 0; i < MAX_MISSILES; i++)
                {
                        mMissiles[i] = new Missile(i);
                }
        }

        @Override
        public void exit()
        {
                mMissileFrames = null;
               
                if (mMissileSprite != null)
                {
                        mMissileSprite.dispose();
                        mMissileSprite = null;
                }
        }

        @Override
        public void update(float deltaTime)
        {
                int i = 0;
                while (i < MAX_MISSILES)
                {
                        if (mMissiles[i].isAlive)
                                mMissiles[i].update(deltaTime);
                        i++;
                }

        }

        @Override
        public void render()
        {
                int i = 0;
                while (i < MAX_MISSILES)
                {
                        if (mMissiles[i].isAlive)
                                mMissiles[i].render();
                        i++;
                }
        }
       
        public void launch(float x, float y)
        {
                // launch one upper, one lower
               
                for (int i = 0; i < MAX_MISSILES; i++)
                {
                        if (!mMissiles[i].isAlive)
                        {
                                mMissiles[i].launch(x, y);
                        }
                }
        }
       
        // Getters/Setters==================================================================================

}