diff --git a/skmfv0tk0w.js b/skmfv0tk0w.js new file mode 100644 index 0000000..c47dc3f --- /dev/null +++ b/skmfv0tk0w.js @@ -0,0 +1,347 @@ + +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 < GameLib.CustomCode.TETRIS_GRID_HEIGHT; y++) { + this.grid[y] = []; + for (var x = 0; x < GameLib.CustomCode.TETRIS_GRID_WIDTH; x++) { + this.grid[y][x] = { + value: GameLib.CustomCode.TETRIS_GRID_NOT_TAKEN, + mesh: null + }; + } + } + + if (this.block && this.block.center) { + + this.animation.removeMesh(this.block.center); + + GameLib.Event.Emit( + GameLib.Event.REMOVE_COMPONENT, + { + component: this.block.center + } + ); + } + + if (this.block && this.block.meshes) { + this.block.meshes.map( + function (mesh) { + GameLib.Event.Emit( + GameLib.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'); + + GameLib.Event.Emit( + GameLib.Event.REMOVE_COMPONENT, + { + component: animationObject.glow + } + ); + + GameLib.Event.Emit( + GameLib.Event.REMOVE_COMPONENT, + { + component: animationObject.flames + } + ); + + + /** + * Remove the meshes + */ + for (var x = 0; x < GameLib.CustomCode.TETRIS_GRID_WIDTH; x++) { + + if (!this.grid[animationObject.rowNumber][x].mesh) { + throw new Error('mesh should exist but does not'); + } + + GameLib.Event.Emit( + GameLib.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 < GameLib.CustomCode.TETRIS_GRID_WIDTH; x++) { + row.push( + { + value: GameLib.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 < GameLib.CustomCode.TETRIS_GRID_HEIGHT - 1; y++) { + for (var x = 0; x < GameLib.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: GameLib.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); + + GameLib.Event.Emit( + GameLib.Event.REMOVE_COMPONENT, + { + component: this.block.center + } + ); + + this.removeLines(); + + //this.visualizeGrid(0xff0000); + + for (var x = 0; x < GameLib.CustomCode.TETRIS_GRID_WIDTH; x++) { + if ( + this.grid[19][x].value === GameLib.CustomCode.TETRIS_GRID_TAKEN || + this.grid[20][x].value === GameLib.CustomCode.TETRIS_GRID_TAKEN || + this.grid[21][x].value === GameLib.CustomCode.TETRIS_GRID_TAKEN || + this.grid[22][x].value === GameLib.CustomCode.TETRIS_GRID_TAKEN || + this.grid[23][x].value === GameLib.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; + + GameLib.Event.Emit( + GameLib.Event.GAME_OVER, + { + score: this.entityLoaded.score, + level: this.entityLoaded.level, + rows: this.entityLoaded.rows + } + ); + + //this.visualizeGrid(0xff0000); + + } else { + this.getNextBlock(); + } +} + +//@ sourceURL=beforeRender.js