fix lock
This commit is contained in:
		
							
								
								
									
										117
									
								
								app.js
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								app.js
									
									
									
									
									
								
							| @ -51,7 +51,7 @@ const TRANSLATION = { | |||||||
|  |  | ||||||
| const ROTATION = { | const ROTATION = { | ||||||
|     CW: 1,  // ClockWise |     CW: 1,  // ClockWise | ||||||
|     CCW: -1,  // CounterClockWise |     CCW: 3,  // CounterClockWise | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -73,10 +73,10 @@ class Matrix extends THREE.Group { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     lock() { |     lock() { | ||||||
|         this.piece.locked = false |  | ||||||
|         let minoes = Array.from(this.piece.children) |         let minoes = Array.from(this.piece.children) | ||||||
|         minoes.forEach(mino => { |         minoes.forEach(mino => { | ||||||
|             mino.position.add(this.piece.position) |             mino.position.add(this.piece.position) | ||||||
|  |             mino.material = this.piece.material | ||||||
|             this.add(mino) |             this.add(mino) | ||||||
|             if (this.cellIsEmpty(mino.position)) { |             if (this.cellIsEmpty(mino.position)) { | ||||||
|                 this.cells[mino.position.y][mino.position.x] = mino |                 this.cells[mino.position.y][mino.position.x] = mino | ||||||
| @ -206,23 +206,12 @@ class GhostMaterial extends THREE.MeshBasicMaterial { | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| class Tetromino extends THREE.Group { | class AbstractTetromino extends THREE.Group { | ||||||
|     static randomBag = [] |  | ||||||
|     static get random() { |  | ||||||
|         if (!this.randomBag.length) this.randomBag = [I, J, L, O, S, T, Z] |  | ||||||
|         return this.randomBag.pick() |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     constructor() { |     constructor() { | ||||||
|         super() |         super() | ||||||
|         this.rotatedLast = false |  | ||||||
|         this.rotationPoint4Used = false |  | ||||||
|         this.holdEnabled = true |  | ||||||
|         for (let i = 0; i < 4; i++) { |         for (let i = 0; i < 4; i++) { | ||||||
|             this.add(new Mino()) |             this.add(new Mino()) | ||||||
|         } |         } | ||||||
|         this.facing = 0 |  | ||||||
|         this.locked = false |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     set facing(facing) { |     set facing(facing) { | ||||||
| @ -236,12 +225,43 @@ class Tetromino extends THREE.Group { | |||||||
|         return this._facing |         return this._facing | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     canMove(translation, facing = this.facing) { | ||||||
|  |         let testPosition = this.position.clone().add(translation) | ||||||
|  |         return this.minoesPosition[facing].every(minoPosition => matrix.cellIsEmpty(minoPosition.clone().add(testPosition))) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class Ghost extends AbstractTetromino {} | ||||||
|  | Ghost.prototype.minoesPosition = [ | ||||||
|  |     [P(0, 0, 0), P(0, 0, 0), P(0, 0, 0), P(0, 0, 0)], | ||||||
|  | ] | ||||||
|  |  | ||||||
|  | class Tetromino extends AbstractTetromino { | ||||||
|  |     static randomBag = [] | ||||||
|  |     static get random() { | ||||||
|  |         if (!this.randomBag.length) this.randomBag = [I, J, L, O, S, T, Z] | ||||||
|  |         return this.randomBag.pick() | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     constructor() { | ||||||
|  |         super() | ||||||
|  |         this.rotatedLast = false | ||||||
|  |         this.rotationPoint4Used = false | ||||||
|  |         this.holdEnabled = true | ||||||
|  |         this.facing = 0 | ||||||
|  |         this.locked = false | ||||||
|  |     } | ||||||
|  |  | ||||||
|     set locked(locked) { |     set locked(locked) { | ||||||
|         this._locked = locked |         this._locked = locked | ||||||
|         if (locked) { |         if (locked) { | ||||||
|             this.children.forEach(mino => mino.material = this.lockedMaterial) |             this.children.forEach(mino => mino.material = this.lockedMaterial) | ||||||
|  |             scene.remove(this.ghost) | ||||||
|  |             scheduler.resetTimeout(game.lockDown, stats.lockDelay) | ||||||
|         } else { |         } else { | ||||||
|             this.children.forEach(mino => mino.material = this.material) |             //this.children.forEach(mino => mino.material = this.material) | ||||||
|  |             scene.add(this.ghost) | ||||||
|  |             scheduler.clearTimeout(game.lockDown, stats.lockDelay) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -249,57 +269,35 @@ class Tetromino extends THREE.Group { | |||||||
|         return this._locked |         return this._locked | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     canMove(translation, facing = this.facing) { |     move(translation, rotatedFacing, rotationPoint) { | ||||||
|         let testPosition = this.position.clone().add(translation) |         if (this.canMove(translation, rotatedFacing)) { | ||||||
|         return this.minoesPosition[facing].every(minoPosition => matrix.cellIsEmpty(minoPosition.clone().add(testPosition))) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     move(translation, testFacing) { |  | ||||||
|         if (this.canMove(translation, testFacing)) { |  | ||||||
|             scheduler.clearTimeout(game.lockDown) |             scheduler.clearTimeout(game.lockDown) | ||||||
|             this.position.add(translation) |             this.position.add(translation) | ||||||
|             if (!testFacing) { |             this.rotatedLast = rotatedFacing | ||||||
|                 this.rotatedLast = false |             if (rotatedFacing != undefined) { | ||||||
|                 this.moveGhost() |                 this.facing = rotatedFacing | ||||||
|             } |                 if (rotationPoint == 4) this.rotationPoint4Used = true | ||||||
|             if (this.canMove(TRANSLATION.DOWN)) { |  | ||||||
|                 this.locked = false |  | ||||||
|                 scene.add(this.ghost) |  | ||||||
|             } else { |  | ||||||
|                 this.locked = true |  | ||||||
|                 scene.remove(this.ghost) |  | ||||||
|                 scheduler.setTimeout(game.lockDown, stats.lockDelay) |  | ||||||
|             } |             } | ||||||
|  |             this.locked = !this.canMove(TRANSLATION.DOWN) | ||||||
|  |             this.updateGhost() | ||||||
|             return true |             return true | ||||||
|         } else if (translation == TRANSLATION.DOWN) { |         } else if (translation == TRANSLATION.DOWN) { | ||||||
|             this.locked = true |             this.locked = true | ||||||
|             if (!scheduler.timeoutTasks.has(game.lockDown)) |             scheduler.setTimeout(game.lockDown, stats.lockDelay) | ||||||
|                 scheduler.setTimeout(game.lockDown, stats.lockDelay) |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     rotate(rotation) { |     rotate(rotation) { | ||||||
|         let testFacing = (this.facing + rotation + 4) % 4 |         let testFacing = (this.facing + rotation) % 4 | ||||||
|         return this.srs[this.facing][rotation].some((translation, rotationPoint) => { |         return this.srs[this.facing][rotation].some( | ||||||
|             if (this.move(translation, testFacing)) { |             (translation, rotationPoint) => this.move(translation, testFacing, rotationPoint) | ||||||
|                 this.facing = testFacing |         ) | ||||||
|                 this.rotatedLast = true |  | ||||||
|                 if (rotationPoint == 4) this.rotationPoint4Used = true |  | ||||||
|                 //favicon.href = this.favicon_href |  | ||||||
|                 this.moveGhost() |  | ||||||
|                 return true |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     moveGhost() { |     updateGhost() { | ||||||
|         this.ghost.position.copy(this.position) |         this.ghost.position.copy(this.position) | ||||||
|         this.ghost.facing = this.facing |  | ||||||
|         this.ghost.minoesPosition = this.minoesPosition |         this.ghost.minoesPosition = this.minoesPosition | ||||||
|         this.children.forEach((mino, i) => { |         this.ghost.facing = this.facing | ||||||
|             this.ghost.children[i].position.copy(mino.position) |  | ||||||
|             this.ghost.children[i].material = this.ghostMaterial |  | ||||||
|         }) |  | ||||||
|         while (this.ghost.canMove(TRANSLATION.DOWN)) this.ghost.position.y-- |         while (this.ghost.canMove(TRANSLATION.DOWN)) this.ghost.position.y-- | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -317,11 +315,6 @@ Tetromino.prototype.srs = [ | |||||||
| ] | ] | ||||||
| Tetromino.prototype.lockedMaterial = new MinoMaterial(0xffffff) | Tetromino.prototype.lockedMaterial = new MinoMaterial(0xffffff) | ||||||
|  |  | ||||||
| class Ghost extends Tetromino {} |  | ||||||
| Ghost.prototype.minoesPosition = [ |  | ||||||
|     [P(0, 0, 0), P(0, 0, 0), P(0, 0, 0), P(0, 0, 0)], |  | ||||||
| ] |  | ||||||
|  |  | ||||||
| class I extends Tetromino { } | class I extends Tetromino { } | ||||||
| I.prototype.minoesPosition = [ | I.prototype.minoesPosition = [ | ||||||
|     [P(-1, 0), P(0, 0), P(1, 0), P(2, 0)], |     [P(-1, 0), P(0, 0), P(1, 0), P(2, 0)], | ||||||
| @ -653,7 +646,10 @@ let game = { | |||||||
|         matrix.piece = nextPiece |         matrix.piece = nextPiece | ||||||
|         matrix.piece.position.set(4, SKYLINE) |         matrix.piece.position.set(4, SKYLINE) | ||||||
|         scene.add(matrix.piece) |         scene.add(matrix.piece) | ||||||
|         matrix.piece.moveGhost() |         matrix.piece.updateGhost() | ||||||
|  |         matrix.piece.ghost.children.forEach((mino) => { | ||||||
|  |             mino.material = matrix.piece.ghostMaterial | ||||||
|  |         }) | ||||||
|         scene.add(matrix.piece.ghost) |         scene.add(matrix.piece.ghost) | ||||||
|      |      | ||||||
|         if (matrix.piece.canMove(TRANSLATION.NONE)) { |         if (matrix.piece.canMove(TRANSLATION.NONE)) { | ||||||
| @ -668,6 +664,11 @@ let game = { | |||||||
|     }, |     }, | ||||||
|      |      | ||||||
|     lockDown: function() { |     lockDown: function() { | ||||||
|  |         if (matrix.piece.canMove(TRANSLATION.DOWN)) { | ||||||
|  |             scheduler.resetTimeout(game.lockDown) | ||||||
|  |             return | ||||||
|  |         } | ||||||
|  |  | ||||||
|         scheduler.clearTimeout(game.lockDown) |         scheduler.clearTimeout(game.lockDown) | ||||||
|         scheduler.clearInterval(game.fall) |         scheduler.clearInterval(game.fall) | ||||||
|      |      | ||||||
|  | |||||||
							
								
								
									
										46
									
								
								jsm/utils.js
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								jsm/utils.js
									
									
									
									
									
								
							| @ -1,28 +1,34 @@ | |||||||
| class Scheduler { | class Scheduler { | ||||||
|   constructor() { |     constructor() { | ||||||
|       this.intervalTasks = new Map() |         this.intervalTasks = new Map() | ||||||
|       this.timeoutTasks = new Map() |         this.timeoutTasks = new Map() | ||||||
|   } |     } | ||||||
|  |  | ||||||
|   setInterval(func, delay, ...args) { |     setInterval(func, delay, ...args) { | ||||||
|       this.intervalTasks.set(func, window.setInterval(func, delay, ...args)) |         this.intervalTasks.set(func, window.setInterval(func, delay, ...args)) | ||||||
|   } |     } | ||||||
|  |  | ||||||
|   setTimeout(func, delay, ...args) { |     clearInterval(func) { | ||||||
|       this.timeoutTasks.set(func, window.setTimeout(func, delay, ...args)) |         if (this.intervalTasks.has(func)) | ||||||
|   } |             window.clearInterval(this.intervalTasks.get(func)) | ||||||
|  |         this.intervalTasks.delete(func) | ||||||
|  |     } | ||||||
|  |  | ||||||
|   clearInterval(func) { |     setTimeout(func, delay, ...args) { | ||||||
|       if (this.intervalTasks.has(func)) |         if (!this.timeoutTasks.has(func)) | ||||||
|           window.clearInterval(this.intervalTasks.get(func)) |             this.timeoutTasks.set(func, window.setTimeout(func, delay, ...args)) | ||||||
|       this.intervalTasks.delete(func) |     } | ||||||
|   } |  | ||||||
|  |  | ||||||
|   clearTimeout(func) { |     clearTimeout(func) { | ||||||
|       if (this.timeoutTasks.has(func)) |         if (this.timeoutTasks.has(func)) | ||||||
|           window.clearTimeout(this.timeoutTasks.get(func)) |             window.clearTimeout(this.timeoutTasks.get(func)) | ||||||
|       this.timeoutTasks.delete(func) |         this.timeoutTasks.delete(func) | ||||||
|   } |     } | ||||||
|  |  | ||||||
|  |     resetTimeout(func, delay, ...args) { | ||||||
|  |         this.clearTimeout(func) | ||||||
|  |         this.timeoutTasks.set(func, window.setTimeout(func, delay, ...args)) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user