if (!this.entityLoaded) { return; } if (!this.initialized) { this.scene = this.entityLoaded.scene; this.block = this.entityLoaded.block; this.animation = this.entityLoaded.animation; this.drawStatus = this.entityLoaded.drawStatus; this.getNextBlock = this.entityLoaded.getNextBlock; this.animationObjects = this.entityLoaded.animationObjects; this.burnLight = this.entityLoaded.burnLight; this.glowMaterial = this.entityLoaded.glowMaterial; this.totalTime = 0; this.waiting = false; this.gameOver = false; this.moveQueue = []; if (this.grid instanceof Array) { this.grid.map( function(y) { if (this.grid[y] instanceof Array) { this.grid[y].map( function(x){ if (this.grid[y][x].mesh) { this.scene.removeObject(this.grid[y][x].mesh); } }.bind(this) ) } }.bind(this) ) } /** * Initialize the grid */ this.grid = []; for (var y = 0; y < R3.CustomCode.TETRIS_GRID_HEIGHT; y++) { this.grid[y] = []; for (var x = 0; x < R3.CustomCode.TETRIS_GRID_WIDTH; x++) { this.grid[y][x] = { value: R3.CustomCode.TETRIS_GRID_NOT_TAKEN, mesh: null }; } } if (this.block && this.block.center) { this.animation.removeMesh(this.block.center); R3.Event.Emit( R3.Event.REMOVE_COMPONENT, { component: this.block.center } ); } if (this.block && this.block.meshes) { this.block.meshes.map( function (mesh) { R3.Event.Emit( R3.Event.REMOVE_COMPONENT, { component: mesh } ); }.bind(this) ); } this.drawStatus(); this.getNextBlock(); this.initialized = true; } this.animationObjects.map( function(animationObject){ animationObject.time += data.delta * 4; this.burnLight.intensity = Math.sin(animationObject.time); this.burnLight.updateInstance('intensity'); this.glowMaterial.opacity = Math.sin(animationObject.time); this.glowMaterial.updateInstance('opacity'); /** * Ok this looks weird - we're simulating 3d since we're in orthographic and z-distance doesn't make sense */ animationObject.flames.position.y += data.delta * (Math.random() - 0.5); animationObject.flames.updateInstance('position'); animationObject.flames.scale.x += animationObject.time * 0.5; animationObject.flames.scale.y += animationObject.time * 0.5; animationObject.flames.updateInstance('scale'); if (animationObject.time > Math.PI) { /** * Done with animation */ this.burnLight.intensity = 0; this.burnLight.updateInstance('intensity'); R3.Event.Emit( R3.Event.REMOVE_COMPONENT, { component: animationObject.glow } ); R3.Event.Emit( R3.Event.REMOVE_COMPONENT, { component: animationObject.flames } ); /** * Remove the meshes */ for (var x = 0; x < R3.CustomCode.TETRIS_GRID_WIDTH; x++) { if (!this.grid[animationObject.rowNumber][x].mesh) { throw new Error('mesh should exist but does not'); } R3.Event.Emit( R3.Event.REMOVE_COMPONENT, { component: this.grid[animationObject.rowNumber][x].mesh } ); } /** * Add a new row to the top of the grid */ this.grid.splice(animationObject.rowNumber, 1); var row = []; for (var x = 0; x < R3.CustomCode.TETRIS_GRID_WIDTH; x++) { row.push( { value: R3.CustomCode.TETRIS_GRID_NOT_TAKEN, mesh: null } ) } this.grid.push(row); /** * Now - drop all blocks above the current index down one row */ for (var y = animationObject.rowNumber; y < R3.CustomCode.TETRIS_GRID_HEIGHT - 1; y++) { for (var x = 0; x < R3.CustomCode.TETRIS_GRID_WIDTH; x++) { if (this.grid[y][x].mesh) { this.grid[y][x].mesh.position.y = y; this.grid[y][x].mesh.updateInstance('position'); } } } /** * Find any animation objects with a line number greater than our current line number, decrease it */ this.animationObjects.map( function (_animationObject) { if (_animationObject.rowNumber > animationObject.rowNumber) { _animationObject.rowNumber -= 1; } } ) var objectIndex = this.animationObjects.indexOf(animationObject); /** * Remove ourselves from the animation objects */ this.animationObjects.splice(objectIndex, 1); } }.bind(this) ); if (this.gameOver) { return; } var moved = true; var fall = false; if (this.waiting) { fall = true; } else { this.totalTime += data.delta; } if (this.drop) { fall = true; if (this.moveQueue && this.moveQueue.length > 0) { var tryMove = function () { if (this.moveQueue.length > 0) { var move = this.moveQueue[0]; if (this.moveBlock(this.block, move, 1, true)) { this.moveQueue.splice(0, 1); tryMove(); } } }.bind(this); tryMove(); } } if (this.totalTime > this.entityLoaded.speed) { this.totalTime = 0; fall = true; } if (fall) { moved = this.moveBlock(this.block, {down: true}, 1, true); } if (moved === null) { this.waiting = true; } else { this.waiting = false; } if (moved === false) { /** * We reached the bottom - */ this.drop = false; this.moveQueue = []; var gridPositions = this.getBlockGridPositions(this.block); gridPositions.map( function (position) { /** * If there already is a mesh - remove it - */ if (this.grid[position.y][position.x].mesh) { this.scene.removeObject(this.grid[position.y][position.x].mesh); } this.grid[position.y][position.x] = { value: R3.CustomCode.TETRIS_GRID_TAKEN, mesh: position.mesh }; }.bind(this) ); this.block.center.instance.position.x = this.block.center.position.x; this.block.center.instance.position.y = this.block.center.position.y; this.block.center.instance.position.z = this.block.center.position.z; this.block.center.instance.rotation.x = this.block.center.rotation.x; this.block.center.instance.rotation.y = this.block.center.rotation.y; this.block.center.instance.rotation.z = this.block.center.rotation.z; this.block.center.instance.updateMatrixWorld(); this.block.meshes.map( function (mesh) { mesh.setParentMesh(null); //mesh.position.z = 0.1; mesh.updateInstancePosition(); }.bind(this) ); this.animation.removeMesh(this.block.center); R3.Event.Emit( R3.Event.REMOVE_COMPONENT, { component: this.block.center } ); this.removeLines(); //this.visualizeGrid(0xff0000); for (var x = 0; x < R3.CustomCode.TETRIS_GRID_WIDTH; x++) { if ( this.grid[19][x].value === R3.CustomCode.TETRIS_GRID_TAKEN || this.grid[20][x].value === R3.CustomCode.TETRIS_GRID_TAKEN || this.grid[21][x].value === R3.CustomCode.TETRIS_GRID_TAKEN || this.grid[22][x].value === R3.CustomCode.TETRIS_GRID_TAKEN || this.grid[23][x].value === R3.CustomCode.TETRIS_GRID_TAKEN ) { this.gameOver = true; } } if (this.gameOver) { this.block.meshes.map( function (mesh) { this.scene.removeObject(mesh); }.bind(this) ); delete this.block; R3.Event.Emit( R3.Event.GAME_OVER, { score: this.entityLoaded.score, level: this.entityLoaded.level, rows: this.entityLoaded.rows } ); //this.visualizeGrid(0xff0000); } else { this.getNextBlock(); } } //@ sourceURL=beforeRender.js