diff --git a/21g30t1e75.js b/21g30t1e75.js index 8409bbe..718d6d4 100644 --- a/21g30t1e75.js +++ b/21g30t1e75.js @@ -155,51 +155,119 @@ this.state = { flip : 0, eating : false, exploding : false, - lives : 2 + lives : 3, + getReady : false, + message : null }; GameLib.CustomCode.prototype.displayHUD = function() { - this.canvasHUD.clear(); - - this.canvasHUD.line(50, 38, 462, 38, 2, "#000000"); + this.canvasHUD.clear(); - this.canvasHUD.text('hiscore', 50, 32, '25px sans-serif', '#ffffff'); - - this.canvasHUD.image(this.imageHeart.instance, 250, 5, 30, 30); - this.canvasHUD.image(this.imageHeart.instance, 285, 5, 30, 30); - this.canvasHUD.image(this.imageHeart.instance, 320, 5, 30, 30); - - this.canvasHUD.line(50, 456, 462, 456, 2, "#000000"); - - this.canvasHUD.text('xtra', 110, 480, '20px sans-serif', '#ffffff'); - this.canvasHUD.text('speed', 110, 500, '20px sans-serif', '#ffffff'); - - this.canvasHUD.text('xtra', 265, 480, '20px sans-serif', '#ffffff'); - this.canvasHUD.text('life', 265, 500, '20px sans-serif', '#ffffff'); + this.canvasHUD.line(50, 38, 462, 38, 2, "#000000"); - this.canvasHUD.text('xtra', 420, 480, '20px sans-serif', '#ffffff'); - this.canvasHUD.text('slow', 420, 500, '20px sans-serif', '#ffffff'); - - this.canvasHUD.image(this.imagePowerupSpeed.instance, 50, 460, 48, 48); - this.canvasHUD.image(this.imagePowerupLife.instance, 205, 460, 48, 48); - this.canvasHUD.image(this.imagePowerupSlow.instance, 360, 460, 48, 48); - - this.textureHUD.instance.needsUpdate = true; -} + this.canvasHUD.text('hiscore', 50, 32, '25px sans-serif', '#ffffff'); + + var images = []; + + if (this.state.lives === 3) { + images.push(this.imageHeart.instance); + images.push(this.imageHeart.instance); + images.push(this.imageHeart.instance); + } else if (this.state.lives === 2) { + images.push(this.imageHeart.instance); + images.push(this.imageHeart.instance); + images.push(this.imageHeartGrey.instance); + } else if (this.state.lives === 1) { + images.push(this.imageHeart.instance); + images.push(this.imageHeartGrey.instance); + images.push(this.imageHeartGrey.instance); + } else if (this.state.lives === 0) { + images.push(this.imageHeartGrey.instance); + images.push(this.imageHeartGrey.instance); + images.push(this.imageHeartGrey.instance); + } + + this.canvasHUD.image(images[0], 250, 5, 30, 30); + this.canvasHUD.image(images[1].instance, 285, 5, 30, 30); + this.canvasHUD.image(images[2].instance, 320, 5, 30, 30); + + this.canvasHUD.line(50, 456, 462, 456, 2, "#000000"); + + this.canvasHUD.text('xtra', 110, 480, '20px sans-serif', '#ffffff'); + this.canvasHUD.text('speed', 110, 500, '20px sans-serif', '#ffffff'); + + this.canvasHUD.text('xtra', 265, 480, '20px sans-serif', '#ffffff'); + this.canvasHUD.text('life', 265, 500, '20px sans-serif', '#ffffff'); + + this.canvasHUD.text('xtra', 420, 480, '20px sans-serif', '#ffffff'); + this.canvasHUD.text('slow', 420, 500, '20px sans-serif', '#ffffff'); + + this.canvasHUD.image(this.imagePowerupSpeed.instance, 50, 460, 48, 48); + this.canvasHUD.image(this.imagePowerupLife.instance, 205, 460, 48, 48); + this.canvasHUD.image(this.imagePowerupSlow.instance, 360, 460, 48, 48); + + this.textureHUD.instance.needsUpdate = true; + +}.bind(this) GameLib.CustomCode.prototype.waitReload = function(delta) { this.explodeTime += delta; - + if (this.explodeTime < GameLib.CustomCode.EXPLODE_LIFETIME) { return; } - /** + /** * We need to revert to a good state - */ - console.warn('revert to good state'); + */ + console.warn('reverting to good state'); + + this.displayHUD(); + + this.restore(); + + this.state.exploding = false; + + this.state.getReady = true; + + window.setTimeout( + function(){ + this.state.message = null; + this.displayHUD(); + this.state.getReady = false; + }.bind(this), + 4000 + ); + + window.setTimeout( + function(){ + this.state.message = "1"; + this.displayHUD(); + }.bind(this), + 3000 + ); + + window.setTimeout( + function(){ + this.state.message = "2"; + this.displayHUD(); + }.bind(this), + 2000 + ); + + + window.setTimeout( + function(){ + this.state.message = "3"; + this.displayHUD(); + }.bind(this), + 1000 + ); + + this.state.message = "READY?"; + this.displayHUD(); }.bind(this) @@ -350,6 +418,16 @@ GameLib.CustomCode.GameObject = function( this.position = position; } +/* GameLib.CustomCode.GameObject.prototype.clone = function() { + + return new GameLib.CustomCode.GameObject( + this.objectType, + this.type, + this.mesh, + this.position + ) +}; +*/ /** * Disposes of the mesh object and resets this object to its defaults */ @@ -500,11 +578,11 @@ GameLib.CustomCode.prototype.createGameObject = function( array = this.food; } - var isTail = false; - + var isTail = false; + if (objectType === GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY) { - switch (type) { + switch (type) { case GameLib.CustomCode.BODY_TYPE_BREAD_BACON : mesh = this.createGameMesh(this.materialBreadBacon); break; @@ -528,7 +606,7 @@ GameLib.CustomCode.prototype.createGameObject = function( break; case GameLib.CustomCode.BODY_TYPE_BREAD_TAIL : mesh = this.createGameMesh(this.materialBreadTail); - isTail = true; + isTail = true; break; case GameLib.CustomCode.BODY_TYPE_BREAD_CORNER : mesh = this.createGameMesh(this.materialBreadCorner); @@ -559,9 +637,9 @@ GameLib.CustomCode.prototype.createGameObject = function( mesh, position, orientation, - null, - null, - isTail + null, + null, + isTail ) gameObject.applyToMesh(true); break; @@ -744,6 +822,20 @@ GameLib.CustomCode.SnakeBody = function( GameLib.CustomCode.SnakeBody.prototype = Object.create(GameLib.CustomCode.GameObject.prototype); GameLib.CustomCode.SnakeBody.prototype.constructor = GameLib.CustomCode.GameObject; +/* +GameLib.CustomCode.SnakeBody.prototype.clone = function() { + return new GameLib.CustomCode.SnakeBody( + this.type, + this.mesh, + this.position, + this.orientation, + this.flip, + this.backupMesh, + this.isTail + ) +}; +*/ + GameLib.CustomCode.SnakeBody.prototype.applyToMesh = function(updateInstance) { GameLib.CustomCode.GameObject.prototype.applyToMesh.call(this, updateInstance); @@ -810,6 +902,22 @@ GameLib.CustomCode.SnakeBody.prototype.advance = function(orientation, flip) { GameLib.CustomCode.prototype.initializeGrid = function() { + this.grid.map( + function(x) { + x.map( + function(y) { + y.dispose(); + } + ); + } + ) + + this.food = []; + + this.powerups = []; + + this.snake = []; + this.grid = []; for (var x = 0; x < GameLib.CustomCode.GRID_WIDTH; x++) { @@ -1015,6 +1123,52 @@ GameLib.CustomCode.prototype.createCorner = function(body, temp) { }.bind(this); +GameLib.CustomCode.prototype.backup = function() { + this.backupSnake = this.snake.map( + function(body) { + return body; + } + ); +}.bind(this) + +GameLib.CustomCode.prototype.restore = function() { + + + this.snake.map( + function(body) { + + /** + * We remove all snake parts from the grid so they are not destroyed on initializeGrid() + * @type {null} + */ + this.grid[body.position.x][body.position.y] = null; + + /** + * If we have snake parts which have not been backed up - dispose of them + */ + if (this.backupSnake.indexOf(body) === -1) { + body.dispose(); + } + + }.bind(this) + ) + + /** + * Now initialize the grid + */ + this.initializeGrid(); + + /** + * Restore our backup snake + */ + this.snake = this.backupSnake.map( + function(body) { + return body.clone(); + } + ); + +}.bind(this) + /** * Move the snake forward and do collision detection * @type {function(this:snakeEntityLoaded)} @@ -1042,7 +1196,7 @@ GameLib.CustomCode.prototype.advanceSnake = function(delta) { if (index === 0) { - if (body.backupMesh) { + if (body.backupMesh) { /** * We used to be a corner, change back * @type {null} @@ -1063,7 +1217,7 @@ GameLib.CustomCode.prototype.advanceSnake = function(delta) { body.mesh.updateInstance('position'); } - + backup = { position : { x : body.position.x, @@ -1091,66 +1245,66 @@ GameLib.CustomCode.prototype.advanceSnake = function(delta) { switch (gameObject.objectType) { case GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY : - - //f (body.orientation !== backup.orientation) { - //body.orientation = backup.orientation; - //body.flip = backup.flip; - //backup.orientation = this.state.orientation; - //backup.flip = this.state.flip; - // this.createCorner(body, backup); - // body.applyToMesh(); - //} - if (!gameObject.isTail) { - - if (body.orientation !== backup.orientation) { - /** - * This head is bent - */ - body.applyToMesh(); - - body.backupMesh = body.mesh; - if (body.orientation === GameLib.CustomCode.ORIENTATION_UP) { - body.backupMesh.position.y -= 0.5 * GameLib.CustomCode.BODY_SCALE_Y; - } + //f (body.orientation !== backup.orientation) { + //body.orientation = backup.orientation; + //body.flip = backup.flip; + //backup.orientation = this.state.orientation; + //backup.flip = this.state.flip; + // this.createCorner(body, backup); + // body.applyToMesh(); + //} + if (!gameObject.isTail) { - if (body.orientation === GameLib.CustomCode.ORIENTATION_DOWN) { - body.backupMesh.position.y += 0.5 * GameLib.CustomCode.BODY_SCALE_Y; - } + if (body.orientation !== backup.orientation) { + /** + * This head is bent + */ + body.applyToMesh(); - if (body.orientation === GameLib.CustomCode.ORIENTATION_LEFT) { - body.backupMesh.position.x += 0.5 * GameLib.CustomCode.BODY_SCALE_X; - } + body.backupMesh = body.mesh; - if (body.orientation === GameLib.CustomCode.ORIENTATION_RIGHT) { - body.backupMesh.position.x -= 0.5 * GameLib.CustomCode.BODY_SCALE_X; - } + if (body.orientation === GameLib.CustomCode.ORIENTATION_UP) { + body.backupMesh.position.y -= 0.5 * GameLib.CustomCode.BODY_SCALE_Y; + } - body.mesh = this.createGameMesh(this.materialBreadCorner); + if (body.orientation === GameLib.CustomCode.ORIENTATION_DOWN) { + body.backupMesh.position.y += 0.5 * GameLib.CustomCode.BODY_SCALE_Y; + } - var tempPos = { - x : body.position.x, - y : body.position.y - } - - body.position.x = backup.position.x; - body.position.y = backup.position.y; - body.mesh.position.z = 5; + if (body.orientation === GameLib.CustomCode.ORIENTATION_LEFT) { + body.backupMesh.position.x += 0.5 * GameLib.CustomCode.BODY_SCALE_X; + } - body.mesh.updateInstance('position'); + if (body.orientation === GameLib.CustomCode.ORIENTATION_RIGHT) { + body.backupMesh.position.x -= 0.5 * GameLib.CustomCode.BODY_SCALE_X; + } - body.mesh.visible = true; + body.mesh = this.createGameMesh(this.materialBreadCorner); - body.mesh.updateInstance('visible'); - - body.applyToMesh(); - - this.explode(tempPos); - - } else { - this.explode(body.position); - } - } + var tempPos = { + x : body.position.x, + y : body.position.y + } + + body.position.x = backup.position.x; + body.position.y = backup.position.y; + body.mesh.position.z = 5; + + body.mesh.updateInstance('position'); + + body.mesh.visible = true; + + body.mesh.updateInstance('visible'); + + body.applyToMesh(); + + this.explode(tempPos); + + } else { + this.explode(body.position); + } + } break; case GameLib.CustomCode.OBJECT_TYPE_FOOD : this.extend(gameObject, backup.position, backup.orientation); @@ -1199,15 +1353,15 @@ GameLib.CustomCode.prototype.advanceSnake = function(delta) { /** * Create a new empty object at the current grid position (free it up) */ - if (this.grid[body.position.x][body.position.y] === this.snake[0]) { - /** - * Its possible that we just nearly missed the tail with the head - and avoid a - * collision - in this case - don't reset this position since it belongs to the head - */ - } else { - this.grid[body.position.x][body.position.y] = new GameLib.CustomCode.GameObject(); - } - + if (this.grid[body.position.x][body.position.y] === this.snake[0]) { + /** + * Its possible that we just nearly missed the tail with the head - and avoid a + * collision - in this case - don't reset this position since it belongs to the head + */ + } else { + this.grid[body.position.x][body.position.y] = new GameLib.CustomCode.GameObject(); + } + /** * Assign the new location to the body */ @@ -1256,14 +1410,14 @@ GameLib.CustomCode.prototype.advanceSnake = function(delta) { ) this.state.turning = false; - - if (this.state.eating) { - /** - * make a backup of the snake here - */ - console.log('snake just ate'); - } - + + if (this.state.eating) { + /** + * make a backup of the snake here + */ + this.backupSnake(); + } + this.state.eating = false; this.visualizeGrid(); @@ -1274,40 +1428,21 @@ GameLib.Event.Subscribe( GameLib.Event.GAME_START, function() { - /** - * Remove all existing snake parts - */ - this.snake.map( - function(body) { - body.dispose(); - } - ) - - this.food.map( - function(food) { - food.dispose(); - } - ) - - this.powerups.map( - function(powerup) { - powerup.dispose(); - } - ); - this.state = { orientation : 0, turning : false, flip : 0, eating : false, exploding : false, - lives : 2 + lives : 3, + getReady : false, + message : null }; this.initializeGrid(); this.visualizeGrid(); - this.displayHUD(); - + this.displayHUD(); + this.snake = [ this.createGameObject( GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, @@ -1318,7 +1453,7 @@ GameLib.Event.Subscribe( }, GameLib.CustomCode.ORIENTATION_UP ), - this.createGameObject( + this.createGameObject( GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, GameLib.CustomCode.BODY_TYPE_BREAD_PATTY, { @@ -1338,6 +1473,8 @@ GameLib.Event.Subscribe( ) ] + this.backupSnake(); + /** * Other Settings */ @@ -1346,14 +1483,12 @@ GameLib.Event.Subscribe( this.foodTime = 0; this.foodSpeed = GameLib.CustomCode.FOOD_SPEED_INITIAL; - this.food = []; this.powerupTime = 0; this.nextPowerupTime = GameLib.Utils.GetRandomIntInclusive( GameLib.CustomCode.POWERUP_WAIT_TIME_MIN, GameLib.CustomCode.POWERUP_WAIT_TIME_MAX ); - this.powerups = []; this.explodeTime = 0; @@ -1387,11 +1522,11 @@ GameLib.Event.Subscribe( GameLib.Event.Subscribe( GameLib.Event.ENGINE_FIRED_PARTICLES_ZERO, function(data) { - if (data.component === this.particleEnginePickle) { - this.particleEnginePickle.enabled = false; - this.particleEnginePickle.fired = false; - } - }.bind(this) + if (data.component === this.particleEnginePickle) { + this.particleEnginePickle.enabled = false; + this.particleEnginePickle.fired = false; + } + }.bind(this) ) this.displayHUD();