diff options
| author | Leonardo Bishop <me@leonardobishop.com> | 2023-11-04 21:28:11 +0000 |
|---|---|---|
| committer | Leonardo Bishop <me@leonardobishop.com> | 2023-11-04 21:28:11 +0000 |
| commit | 7d8cca54e548d2a85287fd2325db88f2697be55a (patch) | |
| tree | 3daa82c6a709363f2f08d9f875d849e4babe1f8f /frontend/src/components/Board | |
| parent | e1633f3348ff7fc5e9131eeae2f2feba09f04838 (diff) | |
Add more shit
Diffstat (limited to 'frontend/src/components/Board')
| -rw-r--r-- | frontend/src/components/Board/TetrisBoard.vue | 270 |
1 files changed, 0 insertions, 270 deletions
diff --git a/frontend/src/components/Board/TetrisBoard.vue b/frontend/src/components/Board/TetrisBoard.vue deleted file mode 100644 index 7528ad7..0000000 --- a/frontend/src/components/Board/TetrisBoard.vue +++ /dev/null @@ -1,270 +0,0 @@ -<script setup lang="ts"> -import { ref, type Ref } from 'vue'; -import { mergeTetrominoWithBoard, randomiseNextTetrominoes, tetrominoCollidesWithBoard } from '@/util/tetris'; -import { type Tetromino, allTetrominoes } from '@/model/tetrominoes'; -import { type Board } from '@/model/board'; - -const renderBoard: Ref<Board> = ref([[]]); -let gameBoard: Board = [ - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], -] -let currentTetromino: Tetromino | null = null; -let nextTetrominoes: Ref<Array<Tetromino>> = ref([]); -let gameInterval: ReturnType<typeof setInterval>; -let gameSpeed = 1000; -let elapsedBlocks = 0; -let gameInProgress = false; -let points = ref(0); -let notificationMessage = ref('Press start to begin!'); -let notificationBg = ref('\#dfdfdf'); -let notificationFg = ref('black'); - -function updateRender() { - if (currentTetromino) { - renderBoard.value = mergeTetrominoWithBoard(gameBoard, currentTetromino); - } else { - renderBoard.value = gameBoard; - } -} - - -function rescheduleTickTimer() { - clearInterval(gameInterval); - gameInterval = setInterval(tick, gameSpeed); -} - -const tick = () => { - if (!currentTetromino) { - let next = nextTetrominoes.value.shift(); - currentTetromino = { ...next! }; - currentTetromino.col = 3; - if (tetrominoCollidesWithBoard(gameBoard, currentTetromino)) { - clearInterval(gameInterval); - notificationBg.value = '\#FF4136'; - notificationFg.value = 'white'; - notificationMessage.value = 'Game over!'; - return; - } - - - if (nextTetrominoes.value.length === 0) { - nextTetrominoes.value = randomiseNextTetrominoes(); - } - } - - updateRender(); - - if (tetrominoCollidesWithBoard(gameBoard, { ...currentTetromino, row: currentTetromino.row + 1 })) { - gameBoard = mergeTetrominoWithBoard(gameBoard, currentTetromino); - currentTetromino = null; - ++elapsedBlocks; - - let clears = 0; - for (let row = 0; row < gameBoard.length; ++row) { - if (gameBoard[row].every(cell => cell)) { - clears++; - gameBoard.splice(row, 1); - gameBoard.unshift([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - } - } - - switch (clears) { - case 1: - points.value += 40; - break; - case 2: - points.value += 100; - break; - case 3: - points.value += 300; - break; - case 4: - points.value += 1200; - break; - } - - if (gameSpeed > 150 && elapsedBlocks % 3 === 0) { - gameSpeed = Math.max(150, gameSpeed - (gameSpeed > 300 ? 75 : 10)); - rescheduleTickTimer(); - } - return; - } - - ++currentTetromino.row; - -}; - -function startGame() { - elapsedBlocks = 0; - gameSpeed = 1000; - nextTetrominoes.value = randomiseNextTetrominoes(); - gameInProgress = true; - notificationMessage.value = ''; - - updateRender(); - rescheduleTickTimer(); -} - -document.addEventListener('keydown', event => { - event.preventDefault(); - if (currentTetromino && event.key === 'r') { - if (!tetrominoCollidesWithBoard(gameBoard, { ...currentTetromino, rotation: (currentTetromino.rotation + 1) % 4 })) { - currentTetromino!.rotation = (currentTetromino!.rotation + 1) % 4; - } - - updateRender(); - } - if (currentTetromino && ['ArrowLeft', 'h'].includes(event.key)) { - if (!tetrominoCollidesWithBoard(gameBoard, { ...currentTetromino, col: currentTetromino.col - 1 })) { - --currentTetromino.col; - } - - updateRender(); - } - if (currentTetromino && ['ArrowRight', 'l'].includes(event.key)) { - if (!tetrominoCollidesWithBoard(gameBoard, { ...currentTetromino, col: currentTetromino.col + 1 })) { - ++currentTetromino.col; - } - - updateRender(); - } - if (currentTetromino && ['ArrowDown', 'j', 'z'].includes(event.key)) { - if (!tetrominoCollidesWithBoard(gameBoard, { ...currentTetromino, row: currentTetromino.row + 1 })) { - ++currentTetromino.row; - } - - updateRender(); - } - if (currentTetromino && ['ArrowUp', 'k', 'c'].includes(event.key)) { - let rowsDropped = 0; - while (!tetrominoCollidesWithBoard(gameBoard, { ...currentTetromino, row: currentTetromino.row + 1 })) { - ++currentTetromino.row; - ++rowsDropped; - } - - if (rowsDropped === 0) { - return; - } - - points.value += rowsDropped + 1; - - tick(); - } -}); -</script> - -<template> - <main> - <h1>Tetris</h1> - <div class="cols"> - <div> - <div v-if="notificationMessage" class="notification-banner" :style="{ 'background-color': notificationBg, 'color': notificationFg}"> - {{ notificationMessage }} - </div> - <div class="tetris-board"> - <div v-for="(row, rowIndex) of renderBoard" class="tetris-row"> - <div v-for="(col, colIndex) of row" class="tetris-cell" - :style="{ 'background-color': col ? `rgb(${allTetrominoes[col].color})` : 'white' }"> - - </div> - </div> - </div> - </div> - <div class="game-info"> - <button v-if="!gameInProgress" @click="startGame">Start game</button> - <h2>Next up</h2> - <div class="next-tetromino"> - <div v-for="(row, rowIndex) of nextTetrominoes[0]?.shapes[0]" class="tetris-row"> - <div v-for="(col, colIndex) of row" class="tetris-cell" - :style="{ 'background-color': col ? `rgb(${nextTetrominoes[0]?.color})` : 'white' }"> - - </div> - </div> - </div> - - <h2>Score</h2> - <h3> - {{ points }} - </h3> - - <h2>Controls</h2> - <p> - To move left and right, use the arrow keys or <kbd>H</kbd> and <kbd>L</kbd>. - </p> - - <p> - To rotate, use <kbd>R</kbd>. - </p> - - <p> - To do a soft drop, use the arrow down key or <kbd>J</kbd>. - </p> - - <p> - To do a hard drop, use the arrow up key or <kbd>K</kbd>. - </p> - </div> - </div> - - </main> -</template> - -<style scoped> -.cols { - display: flex; - flex-direction: row; - gap: 20px; -} - -.game-info { - max-width: 250px; -} - -.tetris-board { - width: calc(32px * 10); - height: calc(32px * 20); - border: 1px solid #dfdfdf; -} - -.notification-banner { - width: calc(32px * 10 + 2px); - height: 22px; - text-align: center; - position: absolute; -} - -.next-tetromino { - width: calc(32px * 4); - height: calc(32px * 4); -} - -.tetris-row { - display: grid; - grid-template-columns: repeat(10, 1fr); -} - -.tetris-cell { - width: 30px; - height: 30px; - border: 1px solid #dfdfdf; -} -</style>
\ No newline at end of file |
