12-00-spaceShooter/ver03/gameCode.js
/* global Phaser */

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* G L O B A L   C O N S T A N T S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

const ASTEROID_SCALE = [0.4, 0.6, 0.8, 1];
const ASTEROID_XVELO = [-20, -10, 0, 10, 20];
const ROTATE_ARRAY = [-0.05, -0.02, 0.02, 0.05];

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* G L O B A L   V A R I A B L E S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

var game = new Phaser.Game(960, 640, Phaser.AUTO, "", { preload: preload, create: create, update: update, render:render });
var gameState = "";

var playerShip;
var playerBulletGroup;

var asteroidGroup;

var mainTitleText, subTitleText;

var cursorKeys, fireKey;

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* P H A S E R   S T A T E   F U N C T I O N S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

function preload()
{
    game.load.image("ship", "../assets/CX16-X1.png");
    game.load.image("background", "../assets/background_02_parallax_01.jpg");
    game.load.image("playerbullets", "../assets/bullet_blaster_small_single.png");
    game.load.image("asteroid", "../assets/asteroid_07.png");
}

function create()
{
    /* enable ARCADE physics */
    game.physics.startSystem(Phaser.Physics.ARCADE);    
    
    /* background image */
    game.add.image(0, 0, "background");

	/* create the asteroid group */
	asteroidGroup = game.add.group();
	asteroidGroup.createMultiple(100, "asteroid");
	asteroidGroup.forEach(asteroidGroupInit);
	asteroidGroup.data = {};
	asteroidGroup.data.delay = 500;
	asteroidGroup.data.maxVelocity = 100;
	asteroidGroup.data.timer = false;

	/* create the player bullets group */
	playerBulletGroup = game.add.group();
	playerBulletGroup.createMultiple(20, "playerbullets");
	playerBulletGroup.forEach(playerBulletGroupInit);
	playerBulletGroup.data = {};
	playerBulletGroup.data.nextFire = 0;
    
    /* player SPRITE with Physics enabled (adds a BODY property to sprite) */
    playerShip = game.add.sprite(game.width/2,game.height-100, "ship");
    game.physics.arcade.enable(playerShip);
    playerShip.anchor.setTo(0.5,0.5);
	playerShip.body.drag.x = 3000;
	playerShip.body.maxVelocity.x = 800;

    /* add title text to be used for various texty reasons */
    mainTitleText = game.add.text(game.width/2, game.height/2, "Main Title", { font: '100px Impact', fill: '#ff6666' });
    mainTitleText.anchor.setTo(0.5);
    subTitleText = game.add.text(game.width/2, game.height/2+120, "Sub Title", { font: '40px Impact', fill: '#8888ff' });
    subTitleText.anchor.setTo(0.5);
    
    /* add the cursor keys and a fire key */
    cursorKeys = game.input.keyboard.createCursorKeys();
    fireKey = game.input.keyboard.addKey(Phaser.Keyboard.CONTROL);
    fireKey.onDown.add(fireKeyClick);

    startState("TITLE_SCREEN");
}

function update()
{
    switch (gameState) {
        case "TITLE_SCREEN":
            break;
        case "GET_READY":
            updatePlayer();
            break;
        case "PLAY_GAME":
            checkCollisions();
            updatePlayer();
            asteroidGroup.forEachAlive(rotateAsteroid);
            break;
        case "GAME_OVER":
            asteroidGroup.forEachAlive(rotateAsteroid);
            break;
    }
}

function render() 
{
}

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* S T A T E   F U N C T I O N S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

function startState(newState)
{
    switch (newState) {
        case "TITLE_SCREEN":
            /* kill off any sprites, groups or timers we don't want */
            playerShip.kill();
            asteroidGroup.killAll();
            /* restore any sprites we want to see */
            mainTitleText.reset(mainTitleText.x, mainTitleText.y);
            mainTitleText.text = "Space Shooter";
            subTitleText.reset(subTitleText.x, subTitleText.y);
            subTitleText.text = "Press 'CTRL' to Play";

            gameState = "TITLE_SCREEN";
            break;
        case "GET_READY":
            /* restore any sprites we want to see */
            mainTitleText.text = "GET READY";
            subTitleText.text = "";
            subTitleText.data.countDown = 3;
            playerShip.reset(game.width/2, game.height-100);
            game.time.events.add(1000, getReadyCountdown);

            gameState = "GET_READY";
            break;
        case "PLAY_GAME":
            /* kill off any sprites, groups or timers we don't want */
            mainTitleText.kill();
            subTitleText.kill();
            /* restore any sprites we want to see */
        	asteroidGroup.data.delay = 500;
        	asteroidGroup.data.maxVelocity = 100;
	        setAsteroidTimer(asteroidGroup.data.delay);

            gameState = "PLAY_GAME";
            break;
        case "GAME_OVER":
            /* kill off any sprites, groups or timers we don't want */
            clearAsteroidTimer();
            /* restore any sprites we want to see */
            mainTitleText.reset(mainTitleText.x, mainTitleText.y);
            mainTitleText.text = "GAME OVER";
            subTitleText.reset(subTitleText.x, subTitleText.y);
            subTitleText.text = "Press 'CTRL' to Restart";

            gameState = "GAME_OVER";
            break;
    }
}

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* U P D A T E   F U N C T I O N S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

function updatePlayer()
{
    if (cursorKeys.left.isDown) {
        playerShip.body.acceleration.x = -2000;
    } else if (cursorKeys.right.isDown) {
        playerShip.body.acceleration.x = 2000;
    } else {
        playerShip.body.acceleration.x = 0;
    }
 
    game.world.wrap(playerShip);
    
    if (fireKey.isDown) {
        firePlayerBullet();
    }
}

function firePlayerBullet()
{
    if (game.time.now > playerBulletGroup.data.nextFire) {
        var bullet = playerBulletGroup.getFirstExists(false);
        if (bullet) {
            bullet.reset(playerShip.x, playerShip.y + 8);
            bullet.body.velocity.y = -400;
            playerBulletGroup.data.nextFire = game.time.now + 200;
        }
    }
}

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* G R O U P   I N I T   F U N C T I O N S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

function playerBulletGroupInit(bullet)
{
    /* 'bullet' is just an individual sprite from the group */
    bullet.outOfBoundsKill = true;
    bullet.checkWorldBounds = true;		
    bullet.anchor.setTo(0.5);
    game.physics.arcade.enable(bullet);
}

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* U T I L I T Y   F U N C T I O N S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

function fireKeyClick()
{
    if (gameState == "TITLE_SCREEN") {
        startState("GET_READY");
    } else if (gameState == "GAME_OVER") {
        startState("TITLE_SCREEN");
    }
}

function getReadyCountdown() 
{
    if (subTitleText.data.countDown == 0) {
        startState("PLAY_GAME");
    } else {
        subTitleText.text = subTitleText.data.countDown;
        game.time.events.add(1000, getReadyCountdown);
    }
    subTitleText.data.countDown--;
}

function checkCollisions() 
{
    game.physics.arcade.overlap(asteroidGroup, playerBulletGroup, destroyAsteroid);
    game.physics.arcade.overlap(playerShip, asteroidGroup, destroyPlayer);
}

function destroyAsteroid(asteroid, bullet)
{
    asteroid.kill();
    bullet.kill();
	asteroidGroup.data.maxVelocity += 5;
}

function destroyPlayer(player, enemy) 
{
    playerShip.kill();
    enemy.kill();
    
    startState("GAME_OVER");
}

/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* A S T E R O I D   F U N C T I O N S */
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */

function asteroidGroupInit(asteroid)
{
    asteroid.outOfBoundsKill = true;
    asteroid.checkWorldBounds = true;
    asteroid.anchor.setTo(0.5);
    game.physics.arcade.enable(asteroid);
}

function clearAsteroidTimer()
{
    if (asteroidGroup.data.timer) {
        game.time.events.remove(asteroidGroup.data.timer);
    }    
    asteroidGroup.data.timer = false;
}

function setAsteroidTimer(delayTime)
{
    clearAsteroidTimer();
    asteroidGroup.data.timer = game.time.events.add(delayTime,deployAsteroid);
}

function deployAsteroid()
{
    var asteroid = asteroidGroup.getFirstExists(false);
    if (asteroid)
    {
        var scale = ASTEROID_SCALE[game.rnd.integerInRange(0,ASTEROID_SCALE.length-1)];
        asteroid.scale.setTo(scale);
        asteroid.data.rotate = ROTATE_ARRAY[game.rnd.integerInRange(0,ROTATE_ARRAY.length-1)];
        asteroid.reset(game.rnd.integerInRange(asteroid.width/2, game.width-asteroid.width/2), 4-asteroid.height/2);
        asteroid.body.velocity.y = game.rnd.integerInRange(50, asteroidGroup.data.maxVelocity);
        asteroid.body.velocity.x = ASTEROID_XVELO[game.rnd.integerInRange(0,ASTEROID_XVELO.length-1)];
    }
    setAsteroidTimer(asteroidGroup.data.delay);
}

function rotateAsteroid(asteroid)
{
    asteroid.rotation += asteroid.data.rotate;
}