diff --git a/21g30t1e75.js b/21g30t1e75.js index 82210f8..d7ccb08 100644 --- a/21g30t1e75.js +++ b/21g30t1e75.js @@ -1,724 +1,729 @@ - if (this.parentEntity === data.entity) { - console.log('snake entity loaded'); +if (this.parentEntity === data.entity) { + console.log('snake entity loaded'); +} else { + return; +} + +/** + * Defines + */ +GameLib.CustomCode.BODY_TYPE_NORMAL = 0x1; +GameLib.CustomCode.BODY_TYPE_TAIL = 0x2; +GameLib.CustomCode.BODY_TYPE_CORNER = 0x3; + +GameLib.CustomCode.GRID_WIDTH = 11; +GameLib.CustomCode.GRID_HEIGHT = 10; + +GameLib.CustomCode.GRID_OFFSET_X = 1; +GameLib.CustomCode.GRID_OFFSET_Y = 8; + +GameLib.CustomCode.SPEED_INITIAL = 1; + +GameLib.CustomCode.ORIENTATION_UP = 0; +GameLib.CustomCode.ORIENTATION_LEFT = 1; +GameLib.CustomCode.ORIENTATION_DOWN = 2; +GameLib.CustomCode.ORIENTATION_RIGHT = 3; + +GameLib.CustomCode.FOOD_SPEED_INITIAL = 3; +GameLib.CustomCode.MAX_FOOD_ITEMS = 6; + +GameLib.CustomCode.POWERUP_WAIT_TIME_MIN = 5; +GameLib.CustomCode.POWERUP_WAIT_TIME_MAX = 10; +GameLib.CustomCode.POWERUP_DURATION = 7; +GameLib.CustomCode.POWERUP_SPEED = 0; +GameLib.CustomCode.POWERUP_LIFE = 1; +GameLib.CustomCode.POWERUP_SLOW = 2; +GameLib.CustomCode.MAX_POWERUP_ITEMS = 3; + +GameLib.CustomCode.FOOD_BACON = 0; +GameLib.CustomCode.FOOD_CHEESE = 1; +GameLib.CustomCode.FOOD_ONION = 2; +GameLib.CustomCode.FOOD_ONION_RING = 3; +GameLib.CustomCode.FOOD_PATTY = 4; +GameLib.CustomCode.FOOD_TOMATO = 5; + +GameLib.CustomCode.BODY_TYPE_BREAD_BACON = 0; +GameLib.CustomCode.BODY_TYPE_BREAD_CHEESE = 1; +GameLib.CustomCode.BODY_TYPE_BREAD_ONION = 2; +GameLib.CustomCode.BODY_TYPE_BREAD_ONION_RING = 3; +GameLib.CustomCode.BODY_TYPE_BREAD_PATTY = 4; +GameLib.CustomCode.BODY_TYPE_BREAD_TOMATO = 5; +GameLib.CustomCode.BODY_TYPE_BREAD_HEAD = 6; +GameLib.CustomCode.BODY_TYPE_BREAD_TAIL = 7; +GameLib.CustomCode.BODY_TYPE_BREAD_CORNER = 8; + +GameLib.CustomCode.OBJECT_TYPE_NONE = 0; +GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY = 1; +GameLib.CustomCode.OBJECT_TYPE_FOOD = 2; +GameLib.CustomCode.OBJECT_TYPE_POWERUP = 3; + +/** + * Get runtime + */ +this.runtime = GameLib.Utils.GetRuntime(); + +/** + * Custom Code Components + */ +this.beforeRender = GameLib.EntityManager.Instance.findComponentById('zjq6ach3jt'); +this.keyUp = GameLib.EntityManager.Instance.findComponentById('306204wy29'); + +/** + * Geometries + */ +this.geometryBody = GameLib.EntityManager.Instance.findComponentById('8f5q7k5ozp'); + +GameLib.CustomCode.BODY_SCALE_X = this.geometryBody.width; +GameLib.CustomCode.BODY_SCALE_Y = this.geometryBody.height; + +/** + * Materials + */ +this.materialTomato = GameLib.EntityManager.Instance.findComponentById('merwtvkm1t'); +this.materialBacon = GameLib.EntityManager.Instance.findComponentById('x5ffcl6ojc'); +this.materialCheese = GameLib.EntityManager.Instance.findComponentById('0rxqy5eddx'); +this.materialOnionRing = GameLib.EntityManager.Instance.findComponentById('gz8zex5xug'); +this.materialPatty = GameLib.EntityManager.Instance.findComponentById('f7y8nurbcv'); +this.materialOnion = GameLib.EntityManager.Instance.findComponentById('im3tsuzwrp'); +this.materialBreadBacon = GameLib.EntityManager.Instance.findComponentById('wn31yqi6lc'); +this.materialBreadCheese = GameLib.EntityManager.Instance.findComponentById('i22ixqizge'); +this.materialBreadOnion = GameLib.EntityManager.Instance.findComponentById('69sybcj08d'); +this.materialBreadOnionRing = GameLib.EntityManager.Instance.findComponentById('kvesyjtr2v'); +this.materialBreadPatty = GameLib.EntityManager.Instance.findComponentById('k6axym9bu5'); +this.materialBreadTomato = GameLib.EntityManager.Instance.findComponentById('9wxuzzz5co'); +this.materialBreadHead = GameLib.EntityManager.Instance.findComponentById('heu4f7zzuh'); +this.materialBreadTail = GameLib.EntityManager.Instance.findComponentById('mm2yq9rmpf'); +this.materialBreadCorner = GameLib.EntityManager.Instance.findComponentById('ju9r1bw6cb'); +this.materialPowerupSpeed = GameLib.EntityManager.Instance.findComponentById('fb32uutj9q'); +this.materialPowerupLife = GameLib.EntityManager.Instance.findComponentById('6tld70a6zu'); +this.materialPowerupSlow = GameLib.EntityManager.Instance.findComponentById('ulgntj8nta'); + +/** + * Other Objects (Scene) + */ +this.scene = GameLib.EntityManager.Instance.findComponentById('pllp034hsj'); +this.animation = GameLib.EntityManager.Instance.findComponentById('8kb7utb2fn'); +this.animationRotation = GameLib.EntityManager.Instance.findComponentById('z628kythyn'); + +/** + * Game objects + */ +this.snake = []; +this.grid = [[]]; + +this.speed = GameLib.CustomCode.SPEED_INITIAL; +this.advanceTime = 0; + +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 = []; + +/** + * Orientation is 0, 1, 2 or 3, (up, left, down, right) - + * This is also the amount we need to multiply with PI to get the mesh rotation + * @type {{direction: {x: number, y: number}, orientation: number}} + */ +this.state = { + orientation : 0, + turning : false, + flip : 0 +}; + +GameLib.CustomCode.prototype.visualizeGrid = function () { + + if (this.noneMesh) { + this.scene.instance.remove(this.noneMesh); + } + + if (this.foodMesh) { + this.scene.instance.remove(this.foodMesh); + } + + if (this.powerupMesh) { + this.scene.instance.remove(this.powerupMesh); + } + + if (this.snakeMesh) { + this.scene.instance.remove(this.snakeMesh); + } + + this.noneGeometry = new THREE.Geometry(); + this.foodGeometry = new THREE.Geometry(); + this.powerupGeometry = new THREE.Geometry(); + this.snakeGeometry = new THREE.Geometry(); + + this.grid.map( + function(x, xIndex) { + x.map( + function(object, yIndex) { + + if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_NONE) { + this.noneGeometry.vertices.push( + new THREE.Vector3( + (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, + (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, + 5 + ) + ); + } + + if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY) { + this.snakeGeometry.vertices.push( + new THREE.Vector3( + (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, + (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, + 5 + ) + ); + } + + if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { + this.foodGeometry.vertices.push( + new THREE.Vector3( + (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, + (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, + 5 + ) + ); + } + + if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP) { + this.powerupGeometry.vertices.push( + new THREE.Vector3( + (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, + (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, + 5 + ) + ); + } + + }.bind(this) + ) + }.bind(this) + ); + + var noneMaterial = new THREE.PointsMaterial({color: 0xffffff, size: 0.1}); + var foodMaterial = new THREE.PointsMaterial({color: 0x00ff00, size: 0.1}); + var snakeMaterial = new THREE.PointsMaterial({color: 0x0000ff, size: 0.1}); + var powerupMaterial = new THREE.PointsMaterial({color: 0xff0000, size: 0.1}); + + this.noneMesh = new THREE.Points(this.noneGeometry, noneMaterial); + this.foodMesh = new THREE.Points(this.foodGeometry, foodMaterial); + this.powerupMesh = new THREE.Points(this.powerupGeometry, powerupMaterial); + this.snakeMesh = new THREE.Points(this.snakeGeometry, snakeMaterial); + + this.scene.instance.add(this.noneMesh); + this.scene.instance.add(this.foodMesh); + this.scene.instance.add(this.powerupMesh); + this.scene.instance.add(this.snakeMesh); + +}.bind(this) + +GameLib.CustomCode.prototype.createGameMesh = function(material, visible) { + + if (GameLib.Utils.UndefinedOrNull(visible)) { + visible = true; + } + + var mesh = new GameLib.D3.Mesh( + this.runtime.graphics, + { + geometry : this.geometryBody, + materials : [material], + visible : visible, + useQuaternion : false + } + ) + + this.scene.addClone(mesh); + + return mesh; + +}.bind(this) + +/** + * GameLib.CustomCode.Object + * @param objectType + * @param type + * @param mesh + * @param position + * @constructor + */ +GameLib.CustomCode.GameObject = function( + objectType, + type, + mesh, + position +) { + if (GameLib.Utils.UndefinedOrNull(objectType)) { + objectType = GameLib.CustomCode.OBJECT_TYPE_NONE; + } + this.objectType = objectType; + + if (GameLib.Utils.UndefinedOrNull(type)) { + type = -1; + } + this.type = type; + + if (GameLib.Utils.UndefinedOrNull(mesh)) { + mesh = null; + } + this.mesh = mesh; + + if (GameLib.Utils.UndefinedOrNull(position)) { + position = null; + } + this.position = position; +} + +/** + * Disposes of the mesh object and resets this object to its defaults + */ +GameLib.CustomCode.GameObject.prototype.dispose = function(removeMesh) { + + if (GameLib.Utils.UndefinedOrNull(removeMesh)) { + removeMesh = true; + } + + if (this.mesh && removeMesh) { + this.mesh.geometry = null; + this.mesh.materials = null; + this.mesh.remove(); + this.mesh = null; + } + + this.objectType = GameLib.CustomCode.OBJECT_TYPE_NONE; + + this.type = -1; + + this.position = null; +}; + +/** + * Applies the object position to the mesh taking into account the offset and scale of the body + * @param updateInstance + */ +GameLib.CustomCode.GameObject.prototype.applyToMesh = function(updateInstance) { + if (this.mesh) { + + this.mesh.position.x = (this.position.x * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X; + this.mesh.position.y = (this.position.y * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y; + this.mesh.position.z = 0.1; + + if (updateInstance) { + this.mesh.updateInstance('position'); + } + } +}; + +/** + * Scans through the grid, gets all empty positions, and chooses a random one + * @type {function(this:snakeEntityLoaded)} + */ +GameLib.CustomCode.prototype.getFreeGridPosition = function() { + + var x = GameLib.Utils.GetRandomInt(0, GameLib.CustomCode.GRID_WIDTH); + var y = GameLib.Utils.GetRandomInt(0, GameLib.CustomCode.GRID_HEIGHT); + + return { + x : x, + y : y + }; + +}.bind(this); + +/** + * + * @type {function(this:snakeEntityLoaded)} + */ +GameLib.CustomCode.prototype.createGameObject = function( + objectType, + type, + position, + orientation +) { + + if (GameLib.Utils.UndefinedOrNull(type)) { + type = null; + } + + var mesh = null; + var array = null; + + if (objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP) { + type = GameLib.Utils.GetRandomIntInclusive(0, 2); + switch (type) { + case GameLib.CustomCode.POWERUP_SPEED : + mesh = this.createGameMesh(this.materialPowerupSpeed); + break; + case GameLib.CustomCode.POWERUP_LIFE : + mesh = this.createGameMesh(this.materialPowerupLife); + break; + case GameLib.CustomCode.POWERUP_SLOW : + mesh = this.createGameMesh(this.materialPowerupSlow); + break; + default: + throw new Error('unhandled power up type : ' + type) + } + + /** + * We apply a scale to the powerupss too - since they appear too big when normal + */ + mesh.scale.x = 0.8; + mesh.scale.y = 0.8; + mesh.updateInstance('scale'); + + array = this.powerups; + } + + if (objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { + type = GameLib.Utils.GetRandomIntInclusive(0, 5); + switch (type) { + case GameLib.CustomCode.FOOD_BACON : + mesh = this.createGameMesh(this.materialBacon); + break; + case GameLib.CustomCode.FOOD_CHEESE : + mesh = this.createGameMesh(this.materialCheese); + break; + case GameLib.CustomCode.FOOD_ONION : + mesh = this.createGameMesh(this.materialOnion); + break; + case GameLib.CustomCode.FOOD_ONION_RING : + mesh = this.createGameMesh(this.materialOnionRing); + break; + case GameLib.CustomCode.FOOD_PATTY : + mesh = this.createGameMesh(this.materialPatty); + break; + case GameLib.CustomCode.FOOD_TOMATO : + mesh = this.createGameMesh(this.materialTomato); + break; + default : + throw new Error('unhandled food type : ' + type) + } + + /** + * We apply a scale to the food meshes too - since they appear too big when normal + */ + mesh.scale.x = 0.8; + mesh.scale.y = 0.8; + mesh.updateInstance('scale'); + + array = this.food; + } + + if (objectType === GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY) { + + switch (type) { + case GameLib.CustomCode.BODY_TYPE_BREAD_BACON : + mesh = this.createGameMesh(this.materialBreadBacon); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_CHEESE : + mesh = this.createGameMesh(this.materialBreadCheese); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_ONION : + mesh = this.createGameMesh(this.materialBreadOnion); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_ONION_RING : + mesh = this.createGameMesh(this.materialBreadOnionRing); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_PATTY : + mesh = this.createGameMesh(this.materialBreadPatty); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_TOMATO : + mesh = this.createGameMesh(this.materialBreadTomato); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_HEAD : + mesh = this.createGameMesh(this.materialBreadHead); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_TAIL : + mesh = this.createGameMesh(this.materialBreadTail); + break; + case GameLib.CustomCode.BODY_TYPE_BREAD_CORNER : + mesh = this.createGameMesh(this.materialBreadCorner); + break; + default : + throw new Error('unhandled body type : ' + type) + } + + array = this.snake; + } + + var gameObject = null; + + switch (objectType) { + case GameLib.CustomCode.OBJECT_TYPE_FOOD: + case GameLib.CustomCode.OBJECT_TYPE_POWERUP: + gameObject = new GameLib.CustomCode.GameObject( + objectType, + type, + mesh, + position + ) + gameObject.applyToMesh(true); + break; + case GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY: + gameObject = new GameLib.CustomCode.SnakeBody( + type, + mesh, + position, + orientation + ) + gameObject.applyToMesh(true); + break; + default: + throw new Error('unhandled object type: ' + objectType); + } + + /** + * Update the grid with this object + */ + var currentGameObject = this.grid[gameObject.position.x][gameObject.position.y]; + + /** + * If there is a powerup at this position - remove it + */ + if (currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP) { + this.powerups.splice( + this.powerups.indexOf(currentGameObject), + 1 + ); + } + + /** + * If there is food at this position - remove it + */ + if (currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { + this.food.splice( + this.food.indexOf(currentGameObject), + 1 + ); + } + + /** + * If there is an existing snake body at this position - explode! + */ + if (currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY) { + console.warn('should not reach this code if collision detection is perfect'); + this.explode(currentGameObject.position); + return; + } + + this.grid[gameObject.position.x][gameObject.position.y].dispose(); + this.grid[gameObject.position.x][gameObject.position.y] = gameObject; + + /** + * Save a reference to this object to the specific object array + */ + + if ( + currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP || + currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD + ) { + /** + * Food and powerups automatically get added, snake bodys need careful insertion + */ + array.push(gameObject); + } + + /** + * If we have too many objects - dispose of the first on in the queue (fifo) + */ + if (this.food.length > GameLib.CustomCode.MAX_FOOD_ITEMS) { + gameObject = this.food.shift(); + this.grid[gameObject.position.x][gameObject.position.y].dispose(); + } + + if (this.powerups.length > GameLib.CustomCode.MAX_POWERUP_ITEMS_ITEMS) { + gameObject = this.powerups.shift(); + this.grid[gameObject.position.x][gameObject.position.y].dispose(); + } + + this.visualizeGrid(); + + return gameObject; + +}.bind(this); + +GameLib.CustomCode.prototype.createPowerup = function(delta) { + + this.powerupTime += delta; + + if (this.powerupTime > this.nextPowerupTime) { + this.powerupTime = 0; } else { return; } - /** - * Defines - */ - GameLib.CustomCode.BODY_TYPE_NORMAL = 0x1; - GameLib.CustomCode.BODY_TYPE_TAIL = 0x2; - GameLib.CustomCode.BODY_TYPE_CORNER = 0x3; - - GameLib.CustomCode.GRID_WIDTH = 11; - GameLib.CustomCode.GRID_HEIGHT = 10; - - GameLib.CustomCode.GRID_OFFSET_X = 1; - GameLib.CustomCode.GRID_OFFSET_Y = 8; - - GameLib.CustomCode.SPEED_INITIAL = 1; - - GameLib.CustomCode.ORIENTATION_UP = 0; - GameLib.CustomCode.ORIENTATION_LEFT = 1; - GameLib.CustomCode.ORIENTATION_DOWN = 2; - GameLib.CustomCode.ORIENTATION_RIGHT = 3; - - GameLib.CustomCode.FOOD_SPEED_INITIAL = 3; - GameLib.CustomCode.MAX_FOOD_ITEMS = 6; - - GameLib.CustomCode.POWERUP_WAIT_TIME_MIN = 5; - GameLib.CustomCode.POWERUP_WAIT_TIME_MAX = 10; - GameLib.CustomCode.POWERUP_DURATION = 7; - GameLib.CustomCode.POWERUP_SPEED = 0; - GameLib.CustomCode.POWERUP_LIFE = 1; - GameLib.CustomCode.POWERUP_SLOW = 2; - GameLib.CustomCode.MAX_POWERUP_ITEMS = 3; - - GameLib.CustomCode.FOOD_BACON = 0; - GameLib.CustomCode.FOOD_CHEESE = 1; - GameLib.CustomCode.FOOD_ONION = 2; - GameLib.CustomCode.FOOD_ONION_RING = 3; - GameLib.CustomCode.FOOD_PATTY = 4; - GameLib.CustomCode.FOOD_TOMATO = 5; - - GameLib.CustomCode.BODY_TYPE_BREAD_BACON = 0; - GameLib.CustomCode.BODY_TYPE_BREAD_CHEESE = 1; - GameLib.CustomCode.BODY_TYPE_BREAD_ONION = 2; - GameLib.CustomCode.BODY_TYPE_BREAD_ONION_RING = 3; - GameLib.CustomCode.BODY_TYPE_BREAD_PATTY = 4; - GameLib.CustomCode.BODY_TYPE_BREAD_HEAD = 5; - GameLib.CustomCode.BODY_TYPE_BREAD_TAIL = 6; - GameLib.CustomCode.BODY_TYPE_BREAD_CORNER = 7; - - GameLib.CustomCode.OBJECT_TYPE_NONE = 0; - GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY = 1; - GameLib.CustomCode.OBJECT_TYPE_FOOD = 2; - GameLib.CustomCode.OBJECT_TYPE_POWERUP = 3; - - /** - * Get runtime - */ - this.runtime = GameLib.Utils.GetRuntime(); - - /** - * Custom Code Components - */ - this.beforeRender = GameLib.EntityManager.Instance.findComponentById('zjq6ach3jt'); - this.keyUp = GameLib.EntityManager.Instance.findComponentById('306204wy29'); - - /** - * Geometries - */ - this.geometryBody = GameLib.EntityManager.Instance.findComponentById('8f5q7k5ozp'); - - GameLib.CustomCode.BODY_SCALE_X = this.geometryBody.width; - GameLib.CustomCode.BODY_SCALE_Y = this.geometryBody.height; - - /** - * Materials - */ - this.materialTomato = GameLib.EntityManager.Instance.findComponentById('merwtvkm1t'); - this.materialBacon = GameLib.EntityManager.Instance.findComponentById('x5ffcl6ojc'); - this.materialCheese = GameLib.EntityManager.Instance.findComponentById('0rxqy5eddx'); - this.materialOnionRing = GameLib.EntityManager.Instance.findComponentById('gz8zex5xug'); - this.materialPatty = GameLib.EntityManager.Instance.findComponentById('f7y8nurbcv'); - this.materialOnion = GameLib.EntityManager.Instance.findComponentById('im3tsuzwrp'); - this.materialBreadBacon = GameLib.EntityManager.Instance.findComponentById('wn31yqi6lc'); - this.materialBreadCheese = GameLib.EntityManager.Instance.findComponentById('i22ixqizge'); - this.materialBreadOnion = GameLib.EntityManager.Instance.findComponentById('69sybcj08d'); - this.materialBreadOnionRing = GameLib.EntityManager.Instance.findComponentById('kvesyjtr2v'); - this.materialBreadPatty = GameLib.EntityManager.Instance.findComponentById('k6axym9bu5'); - this.materialBreadHead = GameLib.EntityManager.Instance.findComponentById('heu4f7zzuh'); - this.materialBreadTail = GameLib.EntityManager.Instance.findComponentById('mm2yq9rmpf'); - this.materialBreadCorner = GameLib.EntityManager.Instance.findComponentById('ju9r1bw6cb'); - this.materialPowerupSpeed = GameLib.EntityManager.Instance.findComponentById('fb32uutj9q'); - this.materialPowerupLife = GameLib.EntityManager.Instance.findComponentById('6tld70a6zu'); - this.materialPowerupSlow = GameLib.EntityManager.Instance.findComponentById('ulgntj8nta'); - - /** - * Other Objects (Scene) - */ - this.scene = GameLib.EntityManager.Instance.findComponentById('pllp034hsj'); - this.animation = GameLib.EntityManager.Instance.findComponentById('8kb7utb2fn'); - this.animationRotation = GameLib.EntityManager.Instance.findComponentById('z628kythyn'); - - /** - * Game objects - */ - this.snake = []; - this.grid = [[]]; - - this.speed = GameLib.CustomCode.SPEED_INITIAL; - this.advanceTime = 0; - - 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.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_POWERUP, + null, + this.getFreeGridPosition() ); - this.powerups = []; - /** - * Orientation is 0, 1, 2 or 3, (up, left, down, right) - - * This is also the amount we need to multiply with PI to get the mesh rotation - * @type {{direction: {x: number, y: number}, orientation: number}} - */ - this.state = { - orientation : 0, - turning : false, - flip : 0 - }; +}.bind(this); - GameLib.CustomCode.prototype.visualizeGrid = function () { +GameLib.CustomCode.prototype.createFood = function(delta) { - if (this.noneMesh) { - this.scene.instance.remove(this.noneMesh); - } + this.foodTime += delta; - if (this.foodMesh) { - this.scene.instance.remove(this.foodMesh); - } + if (this.foodTime > this.foodSpeed) { + this.foodTime = 0; + } else { + return; + } - if (this.powerupMesh) { - this.scene.instance.remove(this.powerupMesh); - } + this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_FOOD, + null, + this.getFreeGridPosition() + ); - if (this.snakeMesh) { - this.scene.instance.remove(this.snakeMesh); - } +}.bind(this); - this.noneGeometry = new THREE.Geometry(); - this.foodGeometry = new THREE.Geometry(); - this.powerupGeometry = new THREE.Geometry(); - this.snakeGeometry = new THREE.Geometry(); - this.grid.map( - function(x, xIndex) { - x.map( - function(object, yIndex) { +/** + * GameLib.CustomCode.SnakeBody + * @param type + * @param mesh + * @param position + * @param orientation + * @param flip + * @param backupMesh + * @param isTail + * @property animation + * @constructor + */ +GameLib.CustomCode.SnakeBody = function( + type, + mesh, + position, + orientation, + flip, + backupMesh, + isTail +) { - if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_NONE) { - this.noneGeometry.vertices.push( - new THREE.Vector3( - (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, - (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, - 5 - ) - ); - } - - if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY) { - this.snakeGeometry.vertices.push( - new THREE.Vector3( - (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, - (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, - 5 - ) - ); - } - - if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { - this.foodGeometry.vertices.push( - new THREE.Vector3( - (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, - (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, - 5 - ) - ); - } - - if (object.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP) { - this.powerupGeometry.vertices.push( - new THREE.Vector3( - (xIndex * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X, - (yIndex * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y, - 5 - ) - ); - } - - }.bind(this) - ) - }.bind(this) - ); - - var noneMaterial = new THREE.PointsMaterial({color: 0xffffff, size: 0.1}); - var foodMaterial = new THREE.PointsMaterial({color: 0x00ff00, size: 0.1}); - var snakeMaterial = new THREE.PointsMaterial({color: 0x0000ff, size: 0.1}); - var powerupMaterial = new THREE.PointsMaterial({color: 0xff0000, size: 0.1}); - - this.noneMesh = new THREE.Points(this.noneGeometry, noneMaterial); - this.foodMesh = new THREE.Points(this.foodGeometry, foodMaterial); - this.powerupMesh = new THREE.Points(this.powerupGeometry, powerupMaterial); - this.snakeMesh = new THREE.Points(this.snakeGeometry, snakeMaterial); - - this.scene.instance.add(this.noneMesh); - this.scene.instance.add(this.foodMesh); - this.scene.instance.add(this.powerupMesh); - this.scene.instance.add(this.snakeMesh); - - }.bind(this) - - GameLib.CustomCode.prototype.createGameMesh = function(material, visible) { - - if (GameLib.Utils.UndefinedOrNull(visible)) { - visible = true; - } - - var mesh = new GameLib.D3.Mesh( - this.runtime.graphics, - { - geometry : this.geometryBody, - materials : [material], - visible : visible, - useQuaternion : false - } - ) - - this.scene.addClone(mesh); - - return mesh; - - }.bind(this) - - /** - * GameLib.CustomCode.Object - * @param objectType - * @param type - * @param mesh - * @param position - * @constructor - */ - GameLib.CustomCode.GameObject = function( - objectType, + GameLib.CustomCode.GameObject.call( + this, + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, type, mesh, position - ) { - if (GameLib.Utils.UndefinedOrNull(objectType)) { - objectType = GameLib.CustomCode.OBJECT_TYPE_NONE; - } - this.objectType = objectType; + ); - if (GameLib.Utils.UndefinedOrNull(type)) { - type = -1; - } - this.type = type; - - if (GameLib.Utils.UndefinedOrNull(mesh)) { - mesh = null; - } - this.mesh = mesh; - - if (GameLib.Utils.UndefinedOrNull(position)) { - position = null; - } - this.position = position; + if (GameLib.Utils.UndefinedOrNull(orientation)) { + orientation = GameLib.CustomCode.ORIENTATION_UP; } + this.orientation = orientation; - /** - * Disposes of the mesh object and resets this object to its defaults - */ - GameLib.CustomCode.GameObject.prototype.dispose = function(removeMesh) { + if (GameLib.Utils.UndefinedOrNull(flip)) { + flip = 0; + } + this.flip = flip; - if (GameLib.Utils.UndefinedOrNull(removeMesh)) { - removeMesh = true; - } + if (GameLib.Utils.UndefinedOrNull(backupMesh)) { + backupMesh = null; + } + this.backupMesh = backupMesh; - if (this.mesh && removeMesh) { - this.mesh.geometry = null; - this.mesh.materials = null; - this.mesh.remove(); - this.mesh = null; - } + if (GameLib.Utils.UndefinedOrNull(isTail)) { + isTail = false; + } + this.isTail = isTail; - this.objectType = GameLib.CustomCode.OBJECT_TYPE_NONE; + this.applyToMesh(); - this.type = -1; + var animation = GameLib.EntityManager.Instance.findComponentById('8kb7utb2fn'); - this.position = null; - }; + animation.meshes.push(this.mesh); +}; - /** - * Applies the object position to the mesh taking into account the offset and scale of the body - * @param updateInstance - */ - GameLib.CustomCode.GameObject.prototype.applyToMesh = function(updateInstance) { - if (this.mesh) { +GameLib.CustomCode.SnakeBody.prototype = Object.create(GameLib.CustomCode.GameObject.prototype); +GameLib.CustomCode.SnakeBody.prototype.constructor = GameLib.CustomCode.GameObject; - this.mesh.position.x = (this.position.x * GameLib.CustomCode.BODY_SCALE_X) + GameLib.CustomCode.GRID_OFFSET_X; - this.mesh.position.y = (this.position.y * GameLib.CustomCode.BODY_SCALE_Y) + GameLib.CustomCode.GRID_OFFSET_Y; - this.mesh.position.z = 0.1; +GameLib.CustomCode.SnakeBody.prototype.applyToMesh = function(updateInstance) { - if (updateInstance) { - this.mesh.updateInstance('position'); - } - } - }; + GameLib.CustomCode.GameObject.prototype.applyToMesh.call(this, updateInstance); - /** - * Scans through the grid, gets all empty positions, and chooses a random one - * @type {function(this:snakeEntityLoaded)} - */ - GameLib.CustomCode.prototype.getFreeGridPosition = function() { - - var x = GameLib.Utils.GetRandomInt(0, GameLib.CustomCode.GRID_WIDTH); - var y = GameLib.Utils.GetRandomInt(0, GameLib.CustomCode.GRID_HEIGHT); - - return { - x : x, - y : y - }; - - }.bind(this); - - /** - * - * @type {function(this:snakeEntityLoaded)} - */ - GameLib.CustomCode.prototype.createGameObject = function( - objectType, - type, - position, - orientation - ) { - - if (GameLib.Utils.UndefinedOrNull(type)) { - type = null; - } - - var mesh = null; - var array = null; - - if (objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP) { - type = GameLib.Utils.GetRandomIntInclusive(0, 2); - switch (type) { - case GameLib.CustomCode.POWERUP_SPEED : - mesh = this.createGameMesh(this.materialPowerupSpeed); - break; - case GameLib.CustomCode.POWERUP_LIFE : - mesh = this.createGameMesh(this.materialPowerupLife); - break; - case GameLib.CustomCode.POWERUP_SLOW : - mesh = this.createGameMesh(this.materialPowerupSlow); - break; - default: - throw new Error('unhandled power up type : ' + type) - } - - /** - * We apply a scale to the powerupss too - since they appear too big when normal - */ - mesh.scale.x = 0.8; - mesh.scale.y = 0.8; - mesh.updateInstance('scale'); - - array = this.powerups; - } - - if (objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { - type = GameLib.Utils.GetRandomIntInclusive(0, 5); - switch (type) { - case GameLib.CustomCode.FOOD_BACON : - mesh = this.createGameMesh(this.materialBacon); - break; - case GameLib.CustomCode.FOOD_CHEESE : - mesh = this.createGameMesh(this.materialCheese); - break; - case GameLib.CustomCode.FOOD_ONION : - mesh = this.createGameMesh(this.materialOnion); - break; - case GameLib.CustomCode.FOOD_ONION_RING : - mesh = this.createGameMesh(this.materialOnionRing); - break; - case GameLib.CustomCode.FOOD_PATTY : - mesh = this.createGameMesh(this.materialPatty); - break; - case GameLib.CustomCode.FOOD_TOMATO : - mesh = this.createGameMesh(this.materialTomato); - break; - default : - throw new Error('unhandled food type : ' + type) - } - - /** - * We apply a scale to the food meshes too - since they appear too big when normal - */ - mesh.scale.x = 0.8; - mesh.scale.y = 0.8; - mesh.updateInstance('scale'); - - array = this.food; - } - - if (objectType === GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY) { - - switch (type) { - case GameLib.CustomCode.BODY_TYPE_BREAD_BACON : - mesh = this.createGameMesh(this.materialBreadBacon); - break; - case GameLib.CustomCode.BODY_TYPE_BREAD_CHEESE : - mesh = this.createGameMesh(this.materialBreadCheese); - break; - case GameLib.CustomCode.BODY_TYPE_BREAD_ONION : - mesh = this.createGameMesh(this.materialBreadOnion); - break; - case GameLib.CustomCode.BODY_TYPE_BREAD_ONION_RING : - mesh = this.createGameMesh(this.materialBreadOnionRing); - break; - case GameLib.CustomCode.BODY_TYPE_BREAD_PATTY : - mesh = this.createGameMesh(this.materialBreadPatty); - break; - case GameLib.CustomCode.BODY_TYPE_BREAD_HEAD : - mesh = this.createGameMesh(this.materialBreadHead); - break; - case GameLib.CustomCode.BODY_TYPE_BREAD_TAIL : - mesh = this.createGameMesh(this.materialBreadTail); - break; - case GameLib.CustomCode.BODY_TYPE_BREAD_CORNER : - mesh = this.createGameMesh(this.materialBreadCorner); - break; - default : - throw new Error('unhandled body type : ' + type) - } - - array = this.snake; - } - - var gameObject = null; - - switch (objectType) { - case GameLib.CustomCode.OBJECT_TYPE_FOOD: - case GameLib.CustomCode.OBJECT_TYPE_POWERUP: - gameObject = new GameLib.CustomCode.GameObject( - objectType, - type, - mesh, - position - ) - gameObject.applyToMesh(true); - break; - case GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY: - gameObject = new GameLib.CustomCode.SnakeBody( - type, - mesh, - position, - orientation - ) - gameObject.applyToMesh(true); - break; - default: - throw new Error('unhandled object type: ' + objectType); - } - - /** - * Update the grid with this object - */ - var currentGameObject = this.grid[gameObject.position.x][gameObject.position.y]; - - /** - * If there is a powerup at this position - remove it - */ - if (currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP) { - this.powerups.splice( - this.powerups.indexOf(currentGameObject), - 1 - ); - } - - /** - * If there is food at this position - remove it - */ - if (currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { - this.food.splice( - this.food.indexOf(currentGameObject), - 1 - ); - } - - /** - * If there is an existing snake body at this position - explode! - */ - if (currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY) { - console.warn('should not reach this code if collision detection is perfect'); - this.explode(currentGameObject.position); - return; - } - - this.grid[gameObject.position.x][gameObject.position.y].dispose(); - this.grid[gameObject.position.x][gameObject.position.y] = gameObject; - - /** - * Save a reference to this object to the specific object array - */ - - if ( - currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP || - currentGameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD - ) { - /** - * Food and powerups automatically get added, snake bodys need careful insertion - */ - array.push(gameObject); - } - - /** - * If we have too many objects - dispose of the first on in the queue (fifo) - */ - if (this.food.length > GameLib.CustomCode.MAX_FOOD_ITEMS) { - gameObject = this.food.shift(); - this.grid[gameObject.position.x][gameObject.position.y].dispose(); - } - - if (this.powerups.length > GameLib.CustomCode.MAX_POWERUP_ITEMS_ITEMS) { - gameObject = this.powerups.shift(); - this.grid[gameObject.position.x][gameObject.position.y].dispose(); - } - - this.visualizeGrid(); - - return gameObject; - - }.bind(this); - - GameLib.CustomCode.prototype.createPowerup = function(delta) { - - this.powerupTime += delta; - - if (this.powerupTime > this.nextPowerupTime) { - this.powerupTime = 0; - } else { - return; - } - - this.createGameObject( - GameLib.CustomCode.OBJECT_TYPE_POWERUP, - null, - this.getFreeGridPosition() - ); - - }.bind(this); - - GameLib.CustomCode.prototype.createFood = function(delta) { - - this.foodTime += delta; - - if (this.foodTime > this.foodSpeed) { - this.foodTime = 0; - } else { - return; - } - - this.createGameObject( - GameLib.CustomCode.OBJECT_TYPE_FOOD, - null, - this.getFreeGridPosition() - ); - - }.bind(this); - - - /** - * GameLib.CustomCode.SnakeBody - * @param type - * @param mesh - * @param position - * @param orientation - * @param flip - * @param backupMesh - * @param isTail - * @property animation - * @constructor - */ - GameLib.CustomCode.SnakeBody = function( - type, - mesh, - position, - orientation, - flip, - backupMesh, - isTail - ) { - - GameLib.CustomCode.GameObject.call( - this, - GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, - type, - mesh, - position - ); - - if (GameLib.Utils.UndefinedOrNull(orientation)) { - orientation = GameLib.CustomCode.ORIENTATION_UP; - } - this.orientation = orientation; - - if (GameLib.Utils.UndefinedOrNull(flip)) { - flip = 0; - } - this.flip = flip; - - if (GameLib.Utils.UndefinedOrNull(backupMesh)) { - backupMesh = null; - } - this.backupMesh = backupMesh; - - if (GameLib.Utils.UndefinedOrNull(isTail)) { - isTail = false; - } - this.isTail = isTail; - - this.applyToMesh(); - - var animation = GameLib.EntityManager.Instance.findComponentById('8kb7utb2fn'); - - animation.meshes.push(this.mesh); - }; - - GameLib.CustomCode.SnakeBody.prototype = Object.create(GameLib.CustomCode.GameObject.prototype); - GameLib.CustomCode.SnakeBody.prototype.constructor = GameLib.CustomCode.GameObject; - - GameLib.CustomCode.SnakeBody.prototype.applyToMesh = function(updateInstance) { - - GameLib.CustomCode.GameObject.prototype.applyToMesh.call(this, updateInstance); - - this.mesh.rotation.z = this.orientation * Math.PI / 2; - - if (this.backupMesh) { - this.mesh.rotation.z += ((Math.PI / 2) * this.flip); - this.mesh.updateInstance('position'); - this.mesh.updateInstance('rotation'); - } + this.mesh.rotation.z = this.orientation * Math.PI / 2; + if (this.backupMesh) { + this.mesh.rotation.z += ((Math.PI / 2) * this.flip); + this.mesh.updateInstance('position'); this.mesh.updateInstance('rotation'); } - GameLib.CustomCode.SnakeBody.prototype.advance = function(orientation, flip) { + this.mesh.updateInstance('rotation'); +} - var crash = false; +GameLib.CustomCode.SnakeBody.prototype.advance = function(orientation, flip) { - switch (orientation) { - case GameLib.CustomCode.ORIENTATION_UP : - if ((this.position.y + 1) >= GameLib.CustomCode.GRID_HEIGHT) { - crash = true; - } else { - this.position.y += 1; - } - break; - case GameLib.CustomCode.ORIENTATION_DOWN : - if ((this.position.y - 1) < 0) { - crash = true; - } else { - this.position.y -= 1; - } - break; - case GameLib.CustomCode.ORIENTATION_LEFT : - if ((this.position.x - 1) < 0) { - crash = true; - } else { - this.position.x -= 1; - } - break; - case GameLib.CustomCode.ORIENTATION_RIGHT : - if ((this.position.x + 1) >= GameLib.CustomCode.GRID_WIDTH) { - crash = true; - } else { - this.position.x += 1; - } - break; - default : - console.warn('unknown orientation'); - break; - } + var crash = false; - if (crash) { - console.log('crashed!'); - } - - this.orientation = orientation; - - this.flip = flip; - - return !crash; + switch (orientation) { + case GameLib.CustomCode.ORIENTATION_UP : + if ((this.position.y + 1) >= GameLib.CustomCode.GRID_HEIGHT) { + crash = true; + } else { + this.position.y += 1; + } + break; + case GameLib.CustomCode.ORIENTATION_DOWN : + if ((this.position.y - 1) < 0) { + crash = true; + } else { + this.position.y -= 1; + } + break; + case GameLib.CustomCode.ORIENTATION_LEFT : + if ((this.position.x - 1) < 0) { + crash = true; + } else { + this.position.x -= 1; + } + break; + case GameLib.CustomCode.ORIENTATION_RIGHT : + if ((this.position.x + 1) >= GameLib.CustomCode.GRID_WIDTH) { + crash = true; + } else { + this.position.x += 1; + } + break; + default : + console.warn('unknown orientation'); + break; } - GameLib.CustomCode.prototype.initializeGrid = function() { + if (crash) { + console.log('crashed!'); + } - this.grid = []; + this.orientation = orientation; - for (var x = 0; x < GameLib.CustomCode.GRID_WIDTH; x++) { - this.grid[x] = []; - for (var y = 0; y < GameLib.CustomCode.GRID_HEIGHT; y++) { - this.grid[x][y] = new GameLib.CustomCode.GameObject(); - } + this.flip = flip; + + return !crash; +} + +GameLib.CustomCode.prototype.initializeGrid = function() { + + this.grid = []; + + for (var x = 0; x < GameLib.CustomCode.GRID_WIDTH; x++) { + this.grid[x] = []; + for (var y = 0; y < GameLib.CustomCode.GRID_HEIGHT; y++) { + this.grid[x][y] = new GameLib.CustomCode.GameObject(); } + } - }.bind(this); +}.bind(this); // GameLib.CustomCode.prototype.rebuildGrid = function() { // @@ -766,359 +771,405 @@ // }.bind(this); - /** - * Explode the snake - * @param position - */ - GameLib.CustomCode.prototype.explode = function(position) { - console.log('explode snake at position : ' + position.x + ', ' + position.y); +/** + * Explode the snake + * @param position + */ +GameLib.CustomCode.prototype.explode = function(position) { + console.log('explode snake at position : ' + position.x + ', ' + position.y); +} + +/** + * Extend the snake with information from gameObject + * @param gameObject + */ +GameLib.CustomCode.prototype.extend = function(gameObject, position, orientation) { + + if (gameObject.objectType !== GameLib.CustomCode.OBJECT_TYPE_FOOD) { + throw new Error('wrong type of game object'); } - /** - * Extend the snake with information from gameObject - * @param gameObject - */ - GameLib.CustomCode.prototype.extend = function(gameObject, position, orientation) { + var body = null; + GameLib.CustomCode.FOOD_BACON = 0; + GameLib.CustomCode.FOOD_CHEESE = 1; + GameLib.CustomCode.FOOD_ONION = 2; + GameLib.CustomCode.FOOD_ONION_RING = 3; + GameLib.CustomCode.FOOD_PATTY = 4; + GameLib.CustomCode.FOOD_TOMATO = 5; - if (gameObject.objectType !== GameLib.CustomCode.OBJECT_TYPE_FOOD) { - throw new Error('wrong type of game object'); - } + switch (gameObject.type) { + case GameLib.CustomCode.FOOD_BACON : + body = this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_BACON, + position, + orientation + ) + break; + case GameLib.CustomCode.FOOD_CHEESE : + body = this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_CHEESE, + position, + orientation + ) + break; + case GameLib.CustomCode.FOOD_ONION : + body = this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_ONION, + position, + orientation + ) + break; + case GameLib.CustomCode.FOOD_ONION_RING : + body = this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_ONION_RING, + position, + orientation + ) + break; + case GameLib.CustomCode.FOOD_PATTY : + body = this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_PATTY, + position, + orientation + ) + break; + case GameLib.CustomCode.FOOD_TOMATO : + body = this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_TOMATO, + position, + orientation + ) + break; + default : + throw new Error('unhandled food type: ' + gameObject.type); + } - var body = null; + this.state.eating = true; - switch (gameObject.type) { - case GameLib.CustomCode.FOOD_BACON : - body = this.createGameObject( - GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, - GameLib.CustomCode.BODY_TYPE_BREAD_BACON, - position, - orientation - ) - break; - default : - throw new Error('unhandled food type: ' + gameObject.type); - } + this.snake.splice(1, 0, body); - this.state.eating = true; +}.bind(this); - this.snake.splice(1, 0, body); - - }.bind(this); +/** + * Powerup the snake with information from gameObject + * @param gameObject + */ +GameLib.CustomCode.prototype.powerup = function(gameObject) { + console.log('powerup'); +}; - /** - * Powerup the snake with information from gameObject - * @param gameObject - */ - GameLib.CustomCode.prototype.powerup = function(gameObject) { - console.log('powerup'); - }; +/** + * Move the snake forward and do collision detection + * @type {function(this:snakeEntityLoaded)} + */ +GameLib.CustomCode.prototype.advanceSnake = function(delta) { - /** - * Move the snake forward and do collision detection - * @type {function(this:snakeEntityLoaded)} - */ - GameLib.CustomCode.prototype.advanceSnake = function(delta) { + this.advanceTime += delta; - this.advanceTime += delta; + if (this.advanceTime > this.speed) { + this.advanceTime = 0; + } else { + return; + } - if (this.advanceTime > this.speed) { - this.advanceTime = 0; - } else { - return; - } + var backup = null; + var temp = null; - var backup = null; - var temp = null; + this.snake.map( + function(body, index) { - this.snake.map( - function(body, index) { + if (index === 0) { - if (index === 0) { - - backup = { - position : { - x : body.position.x, - y : body.position.y - }, - orientation : body.orientation, - flip : body.flip - } - - var advanced = body.advance( - this.state.orientation, - this.state.flip, - this.grid - ); - - if (!advanced) { - - this.explode(body.position); - - } else { - - var gameObject = this.grid[body.position.x][body.position.y]; - - switch (gameObject.objectType) { - case GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY : - this.explode(body.position); - break; - case GameLib.CustomCode.OBJECT_TYPE_FOOD : - this.extend(gameObject); - break; - case GameLib.CustomCode.OBJECT_TYPE_POWERUP: - this.powerup(gameObject); - break; - default: - /** - * Update the grid with the body - */ - this.grid[body.position.x][body.position.y] = body; - break; - } - - /** - * Food or powerup objects need to be destroyed before being replaced with a body object - */ - if ( - gameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD || - gameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP - ) { - - if (gameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { - this.food.splice( - this.food.indexOf(gameObject), - 1 - ); - } else { - this.powerups.splice( - this.powerups.indexOf(gameObject), - 1 - ); - } - - gameObject.dispose(); - - this.grid[body.position.x][body.position.y] = body; - } - - } - - backup.orientation = body.orientation; - backup.flip = body.flip; + backup = { + position : { + x : body.position.x, + y : body.position.y + }, + orientation : body.orientation, + flip : body.flip } - if (index > 0) { + var advanced = body.advance( + this.state.orientation, + this.state.flip, + this.grid + ); - temp = { - position : { - x : body.position.x, - y : body.position.y - }, - orientation : body.orientation, - flip : body.flip + if (!advanced) { + + this.explode(body.position); + + } else { + + var gameObject = this.grid[body.position.x][body.position.y]; + + switch (gameObject.objectType) { + case GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY : + this.explode(body.position); + break; + case GameLib.CustomCode.OBJECT_TYPE_FOOD : + this.extend(gameObject, body.position, body.orientation); + break; + case GameLib.CustomCode.OBJECT_TYPE_POWERUP: + this.powerup(gameObject); + break; + default: + /** + * Update the grid with the body + */ + this.grid[body.position.x][body.position.y] = body; + break; } /** - * Create a new empty object at the current grid position (free it up) + * Food or powerup objects need to be destroyed before being replaced with a body object */ - this.grid[body.position.x][body.position.y] = new GameLib.CustomCode.GameObject(); + if ( + gameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD || + gameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_POWERUP + ) { + if (gameObject.objectType === GameLib.CustomCode.OBJECT_TYPE_FOOD) { + this.food.splice( + this.food.indexOf(gameObject), + 1 + ); + } else { + this.powerups.splice( + this.powerups.indexOf(gameObject), + 1 + ); + } + + gameObject.dispose(); + + this.grid[body.position.x][body.position.y] = body; + } + + } + + backup.orientation = body.orientation; + backup.flip = body.flip; + } + + if (index > 0) { + + temp = { + position : { + x : body.position.x, + y : body.position.y + }, + orientation : body.orientation, + flip : body.flip + } + + /** + * Create a new empty object at the current grid position (free it up) + */ + this.grid[body.position.x][body.position.y] = new GameLib.CustomCode.GameObject(); + + /** + * Assign the new location to the body + */ + body.position.x = backup.position.x; + body.position.y = backup.position.y; + body.orientation = backup.orientation; + body.flip = backup.flip; + + /** + * Update the grid with our new body + */ + this.grid[body.position.x][body.position.y] = body; + + if (body.backupMesh) { /** - * Assign the new location to the body + * We used to be a corner, change back + * @type {null} */ - body.position.x = backup.position.x; - body.position.y = backup.position.y; - body.orientation = backup.orientation; - body.flip = backup.flip; + body.mesh.geometry = null; - /** - * Update the grid with our new body - */ - this.grid[body.position.x][body.position.y] = body; + body.mesh.materials = null; - if (body.backupMesh) { + body.mesh.remove(); + + body.mesh = body.backupMesh; + + body.backupMesh = null; + + body.mesh.visible = true; + + body.mesh.updateInstance('visible'); + + body.mesh.updateInstance('position'); + } + + if (body.orientation !== temp.orientation) { + + if ((index ) < this.snake.length) { /** - * We used to be a corner, change back - * @type {null} + * Our orientation changed - we should make a corner */ - body.mesh.geometry = null; + body.orientation = temp.orientation; - body.mesh.materials = null; + body.applyToMesh(); - body.mesh.remove(); + body.orientation = backup.orientation; - body.mesh = body.backupMesh; + body.backupMesh = body.mesh; - body.backupMesh = null; + if (temp.orientation === GameLib.CustomCode.ORIENTATION_UP) { + body.backupMesh.position.y -= 0.5 * GameLib.CustomCode.BODY_SCALE_Y; + } + + if (temp.orientation === GameLib.CustomCode.ORIENTATION_DOWN) { + body.backupMesh.position.y += 0.5 * GameLib.CustomCode.BODY_SCALE_Y; + } + + if (temp.orientation === GameLib.CustomCode.ORIENTATION_LEFT) { + body.backupMesh.position.x += 0.5 * GameLib.CustomCode.BODY_SCALE_X; + } + + if (temp.orientation === GameLib.CustomCode.ORIENTATION_RIGHT) { + body.backupMesh.position.x -= 0.5 * GameLib.CustomCode.BODY_SCALE_X; + } + + //body.backupMesh.visible = false; + + //body.backupMesh.updateInstance('visible'); + + body.mesh = this.createGameMesh(this.materialBreadCorner); + + body.mesh.position.z = 5; + + body.mesh.updateInstance('position'); body.mesh.visible = true; body.mesh.updateInstance('visible'); - - body.mesh.updateInstance('position'); } - if (body.orientation !== temp.orientation) { - - if ((index ) < this.snake.length) { - /** - * Our orientation changed - we should make a corner - */ - body.orientation = temp.orientation; - - body.applyToMesh(); - - body.orientation = backup.orientation; - - body.backupMesh = body.mesh; - - if (temp.orientation === GameLib.CustomCode.ORIENTATION_UP) { - body.backupMesh.position.y -= 0.5 * GameLib.CustomCode.BODY_SCALE_Y; - } - - if (temp.orientation === GameLib.CustomCode.ORIENTATION_DOWN) { - body.backupMesh.position.y += 0.5 * GameLib.CustomCode.BODY_SCALE_Y; - } - - if (temp.orientation === GameLib.CustomCode.ORIENTATION_LEFT) { - body.backupMesh.position.x += 0.5 * GameLib.CustomCode.BODY_SCALE_X; - } - - if (temp.orientation === GameLib.CustomCode.ORIENTATION_RIGHT) { - body.backupMesh.position.x -= 0.5 * GameLib.CustomCode.BODY_SCALE_X; - } - - //body.backupMesh.visible = false; - - //body.backupMesh.updateInstance('visible'); - - body.mesh = this.createGameMesh(this.materialBreadCorner); - - body.mesh.position.z = 5; - - body.mesh.updateInstance('position'); - - body.mesh.visible = true; - - body.mesh.updateInstance('visible'); - } - - } - - backup = temp; } - //if (!body.isTail) { + backup = temp; + } - body.applyToMesh(); - //} + //if (!body.isTail) { - }.bind(this) - ) + body.applyToMesh(); + //} - this.state.turning = false; - - this.visualizeGrid(); - - }.bind(this); - - 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 : GameLib.CustomCode.ORIENTATION_UP - }; - - this.initializeGrid(); - this.visualizeGrid(); - - this.snake = [ - this.createGameObject( - GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, - GameLib.CustomCode.BODY_TYPE_BREAD_HEAD, - { - x : 4, - y : 4 - }, - GameLib.CustomCode.ORIENTATION_UP - ), - this.createGameObject( - GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, - GameLib.CustomCode.BODY_TYPE_BREAD_TAIL, - { - x : 4, - y : 3 - }, - GameLib.CustomCode.ORIENTATION_UP - ) - ] - - /** - * Other Settings - */ - this.advanceTime = 0; - this.speed = GameLib.CustomCode.SPEED_INITIAL; - - 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 = []; - - /** - * Re-initialize our other custom code components - */ - this.beforeRender.initialized = false; - this.beforeRender.entityLoaded = this; - - this.keyUp.initialized = false; - this.keyUp.entityLoaded = this; - - console.log('starting game snake'); - }.bind(this) - ); - - GameLib.Event.Subscribe( - GameLib.Event.GAME_OVER, - function() { - - this.keyUp.initialized = false; - this.keyUp.entityLoaded = null; - - this.beforeRender.initialized = false; - this.beforeRender.entityLoaded = null; - - console.log('starting game snake'); }.bind(this) ) - GameLib.Event.Emit(GameLib.Event.GAME_LOADED); + this.state.turning = false; + + this.visualizeGrid(); + +}.bind(this); + +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 : GameLib.CustomCode.ORIENTATION_UP + }; + + this.initializeGrid(); + this.visualizeGrid(); + + this.snake = [ + this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_HEAD, + { + x : 4, + y : 4 + }, + GameLib.CustomCode.ORIENTATION_UP + ), + this.createGameObject( + GameLib.CustomCode.OBJECT_TYPE_SNAKE_BODY, + GameLib.CustomCode.BODY_TYPE_BREAD_TAIL, + { + x : 4, + y : 3 + }, + GameLib.CustomCode.ORIENTATION_UP + ) + ] + + /** + * Other Settings + */ + this.advanceTime = 0; + this.speed = GameLib.CustomCode.SPEED_INITIAL; + + 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 = []; + + /** + * Re-initialize our other custom code components + */ + this.beforeRender.initialized = false; + this.beforeRender.entityLoaded = this; + + this.keyUp.initialized = false; + this.keyUp.entityLoaded = this; + + console.log('starting game snake'); + }.bind(this) +); + +GameLib.Event.Subscribe( + GameLib.Event.GAME_OVER, + function() { + + this.keyUp.initialized = false; + this.keyUp.entityLoaded = null; + + this.beforeRender.initialized = false; + this.beforeRender.entityLoaded = null; + + console.log('starting game snake'); + }.bind(this) +) + +GameLib.Event.Emit(GameLib.Event.GAME_LOADED); //@ sourceURL=entityLoaded.js \ No newline at end of file