diff --git a/app.js b/app.js index 19341a4..6ec9d6c 100644 --- a/app.js +++ b/app.js @@ -237,8 +237,6 @@ Ghost.prototype.minoesPosition = [ [P(0, 0, 0), P(0, 0, 0), P(0, 0, 0), P(0, 0, 0)], ] -const lockEvent = new Event("pieceLocked") - class Tetromino extends AbstractTetromino { static randomBag = [] static get random() { @@ -265,17 +263,13 @@ class Tetromino extends AbstractTetromino { } if (this.canMove(TRANSLATION.DOWN)) { this.locking = false - scheduler.clearTimeout(this.lock) + scheduler.clearTimeout(game.lockDown) } else { - scheduler.resetTimeout(this.lock, stats.lockDelay) + scheduler.resetTimeout(game.lockDown, this.lockDelay) this.locking = true } this.updateGhost() return true - } else if (translation == TRANSLATION.DOWN) { - this.locking = true - if (!scheduler.timeoutTasks.has(this.lock)) - scheduler.setTimeout(this.lock, stats.lockDelay) } } @@ -296,10 +290,6 @@ class Tetromino extends AbstractTetromino { } } - lock() { - this.dispatchEvent(lockEvent) - } - updateGhost() { this.ghost.position.copy(this.position) this.ghost.minoesPosition = this.minoesPosition @@ -320,6 +310,7 @@ Tetromino.prototype.srs = [ { [ROTATION.CW]: [P(0, 0), P(-1, 0), P(-1, -1), P(0, 2), P(-1, 2)], [ROTATION.CCW]: [P(0, 0), P(-1, 0), P(-1, -1), P(0, 2), P(-1, 2)] }, ] Tetromino.prototype.lockedMaterial = new MinoMaterial(0xffffff) +Tetromino.prototype.lockDelay = 500 class I extends Tetromino { } I.prototype.minoesPosition = [ @@ -597,13 +588,13 @@ window.addEventListener("resize", () => { world.camera.updateProjectionMatrix() }) - -/* Game logic */ - messagesSpan.onanimationend = function (event) { event.target.remove() } + +/* Game logic */ + let game = { playing: false, @@ -639,7 +630,10 @@ let game = { document.onkeydown = onkeydown document.onkeyup = onkeyup - pauseSpan.className = "" + document.body.classList.remove("pause") + gui.resumeButton.hide() + gui.pauseButton.show() + stats.clock.start() stats.clock.elapsedTime = stats.elapsedTime world.music.play() @@ -651,6 +645,7 @@ let game = { generate: function(nextPiece=nextQueue.shift()) { matrix.piece = nextPiece matrix.piece.position.set(4, SKYLINE) + matrix.piece.lockDelay = stats.lockDelay scene.add(matrix.piece) matrix.piece.updateGhost() matrix.piece.ghost.children.forEach((mino) => { @@ -670,7 +665,7 @@ let game = { }, lockDown: function() { - scheduler.clearTimeout(matrix.piece.lock) + scheduler.clearTimeout(game.lockDown) scheduler.clearInterval(game.fall) if (matrix.lock(matrix.piece)) { @@ -699,7 +694,7 @@ let game = { stats.clock.stop() scheduler.clearInterval(game.fall) - scheduler.clearTimeout(matrix.piece.lock) + scheduler.clearTimeout(game.lockDown) scheduler.clearTimeout(repeat) scheduler.clearInterval(autorepeat) @@ -707,7 +702,9 @@ let game = { document.onkeydown = null pauseSpan.onfocus = game.resume - pauseSpan.className = "pause" + document.body.classList.add("pause") + gui.pauseButton.hide() + gui.resumeButton.show() }, over: function() { @@ -722,6 +719,7 @@ let game = { localStorage["teTraHighScore"] = stats.highScore messagesSpan.addNewChild("div", { className: "show-level-animation", innerHTML: `

GAME
OVER

` }) + gui.pauseButton.hide() gui.startButton.name("Rejouer") gui.startButton.show() }, @@ -743,7 +741,7 @@ let playerActions = { }, hardDrop: function () { - scheduler.clearTimeout(matrix.piece.lock) + scheduler.clearTimeout(game.lockDown) world.hardDropSound.play() if (settings.sfxVolume) { world.hardDropSound.currentTime = 0 @@ -758,7 +756,7 @@ let playerActions = { hold: function () { if (matrix.piece.holdEnabled) { scheduler.clearInterval(game.fall) - scheduler.clearTimeout(matrix.piece.lock) + scheduler.clearTimeout(game.lockDown) let heldpiece = holdQueue.piece holdQueue.piece = matrix.piece @@ -774,41 +772,6 @@ let playerActions = { pause: game.pause, } -// Sounds -const listener = new THREE.AudioListener() -world.camera.add( listener ) -const audioLoader = new THREE.AudioLoader(loadingManager) -world.music = new THREE.Audio(listener) -audioLoader.load('audio/Tetris_CheDDer_OC_ReMix.mp3', function( buffer ) { - world.music.setBuffer(buffer) - world.music.setLoop(true) - world.music.setVolume(settings.musicVolume/100) - if (game.playing) world.music.play() -}) -world.lineClearSound = new THREE.Audio(listener) -audioLoader.load('audio/line-clear.ogg', function( buffer ) { - world.lineClearSound.setBuffer(buffer) - world.lineClearSound.setVolume(settings.sfxVolume/100) -}) -world.tetrisSound = new THREE.Audio(listener) -audioLoader.load('audio/tetris.ogg', function( buffer ) { - world.tetrisSound.setBuffer(buffer) - world.tetrisSound.setVolume(settings.sfxVolume/100) -}) -world.hardDropSound = new THREE.Audio(listener) -audioLoader.load('audio/hard-drop.wav', function( buffer ) { - world.hardDropSound.setBuffer(buffer) - world.hardDropSound.setVolume(settings.sfxVolume/100) -}) - -let scheduler = new Scheduler() -let stats = new Stats() -let settings = new Settings(playerActions) - -var gui = new TetraGUI(game, settings, stats, world) - -gui.load() - // Handle player inputs const REPEATABLE_ACTIONS = [ playerActions.moveLeft, @@ -868,6 +831,44 @@ function onkeyup(event) { } } + +/* Sounds */ + +const listener = new THREE.AudioListener() +world.camera.add( listener ) +const audioLoader = new THREE.AudioLoader(loadingManager) +world.music = new THREE.Audio(listener) +audioLoader.load('audio/Tetris_CheDDer_OC_ReMix.mp3', function( buffer ) { + world.music.setBuffer(buffer) + world.music.setLoop(true) + world.music.setVolume(settings.musicVolume/100) + if (game.playing) world.music.play() +}) +world.lineClearSound = new THREE.Audio(listener) +audioLoader.load('audio/line-clear.ogg', function( buffer ) { + world.lineClearSound.setBuffer(buffer) + world.lineClearSound.setVolume(settings.sfxVolume/100) +}) +world.tetrisSound = new THREE.Audio(listener) +audioLoader.load('audio/tetris.ogg', function( buffer ) { + world.tetrisSound.setBuffer(buffer) + world.tetrisSound.setVolume(settings.sfxVolume/100) +}) +world.hardDropSound = new THREE.Audio(listener) +audioLoader.load('audio/hard-drop.wav', function( buffer ) { + world.hardDropSound.setBuffer(buffer) + world.hardDropSound.setVolume(settings.sfxVolume/100) +}) + + +let scheduler = new Scheduler() +let stats = new Stats() +let settings = new Settings(playerActions) + +var gui = new TetraGUI(game, settings, stats, world) + +gui.load() + window.onbeforeunload = function (event) { gui.save() if (game.playing) return false diff --git a/jsm/gui.js b/jsm/gui.js index e3f8912..7a827e1 100644 --- a/jsm/gui.js +++ b/jsm/gui.js @@ -7,6 +7,8 @@ class TetraGUI extends GUI { super({title: "teTra"}) this.startButton = this.add(game, "start").name("Jouer").hide() + this.pauseButton = this.add(game, "pause").name("Pause").hide() + this.resumeButton = this.add(game, "resume").name("Reprendre").hide() this.stats = this.addFolder("Stats").hide() this.stats.add(stats, "time").name("Temps").disable().listen() diff --git a/style.css b/style.css index a05fe38..31cc99e 100644 --- a/style.css +++ b/style.css @@ -157,17 +157,21 @@ h1 { animation-duration: 2s; } +.pause canvas { + filter: blur(10px); +} + #pauseSpan { display: none; } -#pauseSpan.pause { +.pause #pauseSpan { display: flex; position:absolute; display: flex; top: 0; left: 0; - backdrop-filter: blur(10px); + filter: blur(2px); width: 100%; height: 100%; z-index: 10;