fix lock
This commit is contained in:
parent
f85ad3f3e7
commit
11675fa9a2
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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user