diff --git a/src/js/index.js b/src/js/index.js index 38fcf88..26536b3 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -1,3 +1,4 @@ + class Controller { static #KEY_CODES = { ENTER: 13, @@ -20,7 +21,7 @@ class Controller { constructor(game, view) { this.#game = game; this.#view = view; - + this.#initializeEventListeners(); this.#view.renderStartScreen(); } @@ -90,7 +91,7 @@ class Controller { #handleKeyDown(event) { const gameState = this.#game.getState(); - + switch (event.keyCode) { case Controller.#KEY_CODES.SPACE: case Controller.#KEY_CODES.ENTER: @@ -235,7 +236,7 @@ class Game { getState() { const displayBoard = this.#createDisplayBoard(); - + return { score: this.#score, level: this.level, @@ -263,8 +264,12 @@ class Game { moveTetrominoDown() { if (this.#isGameOver) return; - this.#currentTetromino.y += 1; + let count = 0; + while (!this.#hasCollision() && count < 3) { + this.#currentTetromino.y += 1; + count += 1; + } if (this.#hasCollision()) { this.#currentTetromino.y -= 1; this.#lockTetromino(); @@ -296,7 +301,7 @@ class Game { #createDisplayBoard() { const displayBoard = []; - + for (let row = 0; row < this.#gameBoard.length; row++) { displayBoard[row] = [...this.#gameBoard[row]]; } @@ -328,26 +333,26 @@ class Game { #hasCollision() { const { y: tetrominoY, x: tetrominoX, blocks } = this.#currentTetromino; - + for (let row = 0; row < blocks.length; row++) { for (let col = 0; col < blocks[row].length; col++) { if (!blocks[row][col]) continue; - + const boardY = tetrominoY + row; const boardX = tetrominoX + col; - + if (boardY < 0) continue; - - const isOutOfBounds = - boardY >= Game.#BOARD_HEIGHT || - boardX < 0 || + + const isOutOfBounds = + boardY >= Game.#BOARD_HEIGHT || + boardX < 0 || boardX >= Game.#BOARD_WIDTH; - - const isOccupied = - boardY >= 0 && - this.#gameBoard[boardY] && + + const isOccupied = + boardY >= 0 && + this.#gameBoard[boardY] && this.#gameBoard[boardY][boardX]; - + if (isOutOfBounds || isOccupied) { return true; } @@ -359,7 +364,7 @@ class Game { #lockTetromino() { const { y: tetrominoY, x: tetrominoX, blocks } = this.#currentTetromino; - + for (let row = 0; row < blocks.length; row++) { for (let col = 0; col < blocks[row].length; col++) { if (blocks[row][col]) { @@ -429,14 +434,14 @@ class Game { class View { static #TETROMINO_COLORS = { - 1: "#00FFFF", - 2: "#5D2F77", - 3: "#00FF00", - 4: "#4682B4", - 5: "#8A2BE2", - 6: "#FECA57", - 7: "#FF6347", -}; + 1: "#00FFFF", + 2: "#5D2F77", + 3: "#00FF00", + 4: "#4682B4", + 5: "#8A2BE2", + 6: "#FECA57", + 7: "#FF6347", + }; static #FONT_FAMILY = "'Courier New'"; static #FONT_SIZE_LARGE = 18; @@ -486,7 +491,7 @@ class View { renderEndScreen({ score }) { this.#clearScreen(); - + const centerX = this.#width / 3; const centerY = this.#height / 2; const lineHeight = 48; @@ -495,7 +500,7 @@ class View { this.#context.font = `${View.#FONT_SIZE_LARGE}px ${View.#FONT_FAMILY}`; this.#context.textAlign = "center"; this.#context.textBaseline = "middle"; - + this.#context.fillText("GAME OVER", centerX, centerY - lineHeight); this.#context.fillText(`Score: ${score}`, centerX, centerY); this.#context.fillText("Press Enter to Restart", centerX, centerY + lineHeight); @@ -511,7 +516,7 @@ class View { #calculateDimensions(rows, columns) { const boardWidth = (this.#width * 2) / 3; const boardHeight = this.#height; - + this.#boardArea = { x: View.#BORDER_WIDTH, y: View.#BORDER_WIDTH,