hard drop trail

This commit is contained in:
Adrien MALINGREY 2019-10-27 12:27:24 +01:00
parent b054401625
commit e4dce4c2f4
2 changed files with 51 additions and 33 deletions

View File

@ -54,7 +54,7 @@ canvas {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
margin: 10% 0; margin: 10% 0;
font-size: 3vw; font-size: 2.5vw;
} }
.stats-names { .stats-names {

View File

@ -19,22 +19,23 @@ Array.prototype.pick = function() {
} }
const MINO_SIZE = 20 const MINO_SIZE = 20
const NEXT_PIECES = 5 const NEXT_PIECES = 5
const HOLD_ROWS = 6 const HOLD_ROWS = 6
const HOLD_COLUMNS = 6 const HOLD_COLUMNS = 6
const MATRIX_ROWS = 20 const MATRIX_ROWS = 20
const MATRIX_COLUMNS = 10 const MATRIX_COLUMNS = 10
const NEXT_ROWS = 20 const NEXT_ROWS = 20
const NEXT_COLUMNS = 6 const NEXT_COLUMNS = 6
const HELD_PIECE_POSITION = [2, 2] const HELD_PIECE_POSITION = [2, 2]
const FALLING_PIECE_POSITION = [4, 0] const FALLING_PIECE_POSITION = [4, 0]
const NEXT_PIECES_POSITIONS = Array.from({length: NEXT_PIECES}, (v, k) => [2, k*4+2]) const NEXT_PIECES_POSITIONS = Array.from({length: NEXT_PIECES}, (v, k) => [2, k*4+2])
const LOCK_DELAY = 500 const LOCK_DELAY = 500
const FALL_DELAY = 1000 const FALL_DELAY = 1000
const AUTOREPEAT_DELAY = 250 const AUTOREPEAT_DELAY = 250
const AUTOREPEAT_PERIOD = 10 const AUTOREPEAT_PERIOD = 10
const TEMP_TEXTS_DELAY = 700 const ANIMATION_DELAY = 67
const TEMP_TEXTS_DELAY = 700
const MOVEMENT = { const MOVEMENT = {
LEFT: [-1, 0], LEFT: [-1, 0],
RIGHT: [ 1, 0], RIGHT: [ 1, 0],
@ -335,16 +336,11 @@ class Stats {
if (pattern_score) if (pattern_score)
printTempTexts([pattern_name, pattern_score]) printTempTexts([pattern_name, pattern_score])
if (combo_score) if (combo_score)
printTempTexts(["COMBO x" + this.combo, combo_score]) printTempTexts([`COMBO x${this.combo}`, combo_score])
} }
print() { print() {
this.div.innerHTML = this.score + "<br/>" this.div.innerHTML = `${this.score}<br/>${this.highScore}<br/>${this.level}<br/>${this.goal}<br/>${this.linesCleared}<br/>${timeFormat(Date.now() - this.startTime)}`
+ this.highScore + "<br/>"
+ this.level + "<br/>"
+ this.goal + "<br/>"
+ this.linesCleared + "<br/>"
+ timeFormat(Date.now() - this.startTime)
} }
} }
@ -361,6 +357,8 @@ class Matrix {
this.centerX = this.width / 2 this.centerX = this.width / 2
this.centerY = this.height / 2 this.centerY = this.height / 2
this.piece = null this.piece = null
this.trail_length = 0
this.trailStartPos = []
} }
cellIsOccupied(x, y) { cellIsOccupied(x, y) {
@ -397,6 +395,18 @@ class Matrix {
this.cells.slice(3).forEach((row, y) => row.forEach((colors, x) => { this.cells.slice(3).forEach((row, y) => row.forEach((colors, x) => {
if (colors) drawMino(this.context, [x, y], ...colors, ghost_pos) if (colors) drawMino(this.context, [x, y], ...colors, ghost_pos)
})) }))
// trail
if (this.trail_length) {
var height = this.trail_length * MINO_SIZE
var gradient = this.context.createLinearGradient(0, 0, 0, height)
gradient.addColorStop(0,"rgba(255, 255, 255, 0)")
gradient.addColorStop(1, this.piece.ghostColor )
this.context.fillStyle = gradient
this.trailStartPos.forEach(topLeft => {
this.context.fillRect(...topLeft, MINO_SIZE, height)
})
}
// falling piece // falling piece
if (this.piece) if (this.piece)
@ -478,12 +488,15 @@ function fallingPhase() {
} }
function lockPhase() { function lockPhase() {
if (!move(MOVEMENT.DOWN)) if (!move(MOVEMENT.DOWN)) {
locksDown() matrix.piece.locked = true
if (!scheduler.timeoutTasks.has(locksDown))
scheduler.setTimeout(locksDown, stats.lockDelay)
}
requestAnimationFrame(draw) requestAnimationFrame(draw)
} }
function move(movement, lock=true, testMinoesPos=matrix.piece.minoesPos) { function move(movement, testMinoesPos=matrix.piece.minoesPos) {
const testPos = matrix.piece.pos.add(movement) const testPos = matrix.piece.pos.add(movement)
if (matrix.spaceToMove(testMinoesPos.translate(testPos))) { if (matrix.spaceToMove(testMinoesPos.translate(testPos))) {
matrix.piece.pos = testPos matrix.piece.pos = testPos
@ -493,11 +506,9 @@ function move(movement, lock=true, testMinoesPos=matrix.piece.minoesPos) {
if (matrix.spaceToMove(matrix.piece.minoesPos.translate(matrix.piece.pos.add(MOVEMENT.DOWN)))) if (matrix.spaceToMove(matrix.piece.minoesPos.translate(matrix.piece.pos.add(MOVEMENT.DOWN))))
fallingPhase() fallingPhase()
else { else {
matrix.piece.locked = true
scheduler.clearTimeout(locksDown) scheduler.clearTimeout(locksDown)
if (lock) { scheduler.setTimeout(locksDown, stats.lockDelay)
matrix.piece.locked = true
scheduler.setTimeout(locksDown, stats.lockDelay)
}
} }
return true return true
} }
@ -510,7 +521,7 @@ function rotate(spin) {
const test_minoes_pos = matrix.piece.minoesPos.map(pos => pos.rotate(spin)) const test_minoes_pos = matrix.piece.minoesPos.map(pos => pos.rotate(spin))
rotationPoint = 1 rotationPoint = 1
for (const movement of matrix.piece.srs[spin][matrix.piece.orientation]) { for (const movement of matrix.piece.srs[spin][matrix.piece.orientation]) {
if (move(movement, false, test_minoes_pos)) { if (move(movement, test_minoes_pos)) {
matrix.piece.orientation = (matrix.piece.orientation + spin + 4) % 4 matrix.piece.orientation = (matrix.piece.orientation + spin + 4) % 4
matrix.piece.rotatedLast = true matrix.piece.rotatedLast = true
if (rotationPoint == 5) if (rotationPoint == 5)
@ -544,16 +555,16 @@ function locksDown(){
} }
// Complete lines // Complete lines
var linesCleared = 0 var linesCleared = []
matrix.cells.forEach((row, y) => { matrix.cells.forEach((row, y) => {
if (row.filter(mino => mino.length).length == MATRIX_COLUMNS) { if (row.filter(mino => mino.length).length == MATRIX_COLUMNS) {
matrix.cells.splice(y, 1) matrix.cells.splice(y, 1)
matrix.cells.unshift(Array(MATRIX_COLUMNS)) matrix.cells.unshift(Array(MATRIX_COLUMNS))
linesCleared++ linesCleared.push(y * MINO_SIZE)
} }
}) })
stats.locksDown(tSpin, linesCleared) stats.locksDown(tSpin, linesCleared.length)
if (stats.goal <= 0) if (stats.goal <= 0)
newLevel() newLevel()
@ -635,10 +646,17 @@ function softDrop() {
function hardDrop() { function hardDrop() {
scheduler.clearTimeout(lockPhase) scheduler.clearTimeout(lockPhase)
scheduler.clearTimeout(locksDown) scheduler.clearTimeout(locksDown)
while(move(MOVEMENT.DOWN, false)) { matrix.trailStartPos = Array.from(matrix.piece.minoesAbsPos).map(pos => pos.mul(MINO_SIZE))
for (this.matrix.trail_length=0; move(MOVEMENT.DOWN); this.matrix.trail_length++) {
stats.score += 2 stats.score += 2
} }
locksDown() locksDown()
scheduler.setTimeout(clearTrail, ANIMATION_DELAY)
}
function clearTrail() {
matrix.trail_length = 0
requestAnimationFrame(draw)
} }
function rotateCW() { function rotateCW() {