From 9f83ab70cfd5f2c41a23593f8ee5065b1015e242 Mon Sep 17 00:00:00 2001 From: Leonardo Bishop Date: Sat, 4 Nov 2023 15:25:06 +0000 Subject: Add frontend --- frontend/src/App.vue | 10 ++ frontend/src/assets/logo.svg | 1 + frontend/src/components/Board/TetrisBoard.vue | 162 ++++++++++++++++++ frontend/src/main.ts | 11 ++ frontend/src/model/board.ts | 1 + frontend/src/model/tetrominoes.ts | 230 ++++++++++++++++++++++++++ frontend/src/router/index.ts | 15 ++ frontend/src/util/tetris.ts | 40 +++++ frontend/src/views/HomeView.vue | 10 ++ 9 files changed, 480 insertions(+) create mode 100644 frontend/src/App.vue create mode 100644 frontend/src/assets/logo.svg create mode 100644 frontend/src/components/Board/TetrisBoard.vue create mode 100644 frontend/src/main.ts create mode 100644 frontend/src/model/board.ts create mode 100644 frontend/src/model/tetrominoes.ts create mode 100644 frontend/src/router/index.ts create mode 100644 frontend/src/util/tetris.ts create mode 100644 frontend/src/views/HomeView.vue (limited to 'frontend/src') diff --git a/frontend/src/App.vue b/frontend/src/App.vue new file mode 100644 index 0000000..e2ce8ee --- /dev/null +++ b/frontend/src/App.vue @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/assets/logo.svg b/frontend/src/assets/logo.svg new file mode 100644 index 0000000..7565660 --- /dev/null +++ b/frontend/src/assets/logo.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/components/Board/TetrisBoard.vue b/frontend/src/components/Board/TetrisBoard.vue new file mode 100644 index 0000000..d1f6557 --- /dev/null +++ b/frontend/src/components/Board/TetrisBoard.vue @@ -0,0 +1,162 @@ + + + + + \ No newline at end of file diff --git a/frontend/src/main.ts b/frontend/src/main.ts new file mode 100644 index 0000000..934b583 --- /dev/null +++ b/frontend/src/main.ts @@ -0,0 +1,11 @@ +import { createApp } from 'vue' +import App from './App.vue' +import router from './router' +import TetrisBoard from './components/Board/TetrisBoard.vue' + +const app = createApp(App) + +app.use(router) +app.component('TetrisBoard', TetrisBoard) + +app.mount('#app') diff --git a/frontend/src/model/board.ts b/frontend/src/model/board.ts new file mode 100644 index 0000000..c69befe --- /dev/null +++ b/frontend/src/model/board.ts @@ -0,0 +1 @@ +export type Board = Array>; \ No newline at end of file diff --git a/frontend/src/model/tetrominoes.ts b/frontend/src/model/tetrominoes.ts new file mode 100644 index 0000000..1d91c10 --- /dev/null +++ b/frontend/src/model/tetrominoes.ts @@ -0,0 +1,230 @@ +export type Tetromino = { + id: string; + shapes: Array>>; + color: string; + rotation: number; + col: number; + row: number; + width: number; + height: number; +}; + +export const Tetrominoes: { [key: string]: Tetromino } = { + I: { + id: "I", + shapes: [ + [ + [0, "I", 0, 0], + [0, "I", 0, 0], + [0, "I", 0, 0], + [0, "I", 0, 0], + ], + [ + [0, 0, 0, 0], + ["I", "I", "I", "I"], + [0, 0, 0, 0], + [0, 0, 0, 0], + ], + [ + [0, "I", 0, 0], + [0, "I", 0, 0], + [0, "I", 0, 0], + [0, "I", 0, 0], + ], + [ + [0, 0, 0, 0], + ["I", "I", "I", "I"], + [0, 0, 0, 0], + [0, 0, 0, 0], + ], + ], + color: "80, 227, 230", + rotation: 0, + col: 0, + row: 0, + width: 4, + height: 4, + }, + J: { + id: "J", + shapes: [ + [ + [0, "J", 0], + [0, "J", 0], + ["J", "J", 0], + ], + [ + ["J", 0, 0], + ["J", "J", "J"], + [0, 0, 0], + ], + [ + [0, "J", "J"], + [0, "J", 0], + [0, "J", 0], + ], + [ + [0, 0, 0], + ["J", "J", "J"], + [0, 0, "J"], + ], + ], + color: "36, 95, 223", + rotation: 0, + col: 0, + row: 0, + width: 3, + height: 3, + }, + L: { + id: "L", + shapes: [ + [ + [0, "L", 0], + [0, "L", 0], + [0, "L", "L"], + ], + [ + [0, 0, 0], + ["L", "L", "L"], + ["L", 0, 0], + ], + [ + ["L", "L", 0], + [0, "L", 0], + [0, "L", 0], + ], + [ + [0, 0, "L"], + ["L", "L", "L"], + [0, 0, 0], + ], + ], + color: "223, 173, 36", + rotation: 0, + col: 0, + row: 0, + width: 3, + height: 3, + }, + O: { + id: "O", + shapes: [ + [ + ["O", "O"], + ["O", "O"], + ], + [ + ["O", "O"], + ["O", "O"], + ], + [ + ["O", "O"], + ["O", "O"], + ], + [ + ["O", "O"], + ["O", "O"], + ], + ], + color: "223, 217, 36", + rotation: 0, + col: 0, + row: 0, + width: 2, + height: 2, + }, + S: { + id: "S", + shapes: [ + [ + [0, "S", "S"], + ["S", "S", 0], + [0, 0, 0], + ], + [ + [0, "S", 0], + [0, "S", "S"], + [0, 0, "S"], + ], + [ + [0, 0, 0], + [0, "S", "S"], + ["S", "S", 0], + ], + [ + ["S", 0, 0], + ["S", "S", 0], + [0, "S", 0], + ], + ], + color: "48, 211, 56", + rotation: 0, + col: 0, + row: 0, + width: 3, + height: 3, + }, + T: { + id: "T", + shapes: [ + [ + [0, 0, 0], + ["T", "T", "T"], + [0, "T", 0], + ], + [ + [0, "T", 0], + ["T", "T", 0], + [0, "T", 0], + ], + [ + [0, "T", 0], + ["T", "T", "T"], + [0, 0, 0], + ], + [ + [0, "T", 0], + [0, "T", "T"], + [0, "T", 0], + ], + ], + color: "132, 61, 198", + rotation: 0, + col: 0, + row: 0, + width: 3, + height: 3, + }, + Z: { + id: "Z", + shapes: [ + [ + ["Z", "Z", 0], + [0, "Z", "Z"], + [0, 0, 0], + ], + [ + [0, 0, "Z"], + [0, "Z", "Z"], + [0, "Z", 0], + ], + [ + [0, 0, 0], + ["Z", "Z", 0], + [0, "Z", "Z"], + ], + [ + [0, "Z", 0], + ["Z", "Z", 0], + ["Z", 0, 0], + ], + ], + color: "227, 78, 78", + rotation: 0, + col: 0, + row: 0, + width: 3, + height: 3, + }, +}; diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts new file mode 100644 index 0000000..e58491f --- /dev/null +++ b/frontend/src/router/index.ts @@ -0,0 +1,15 @@ +import { createRouter, createWebHistory } from 'vue-router' +import HomeView from '../views/HomeView.vue' + +const router = createRouter({ + history: createWebHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + name: 'home', + component: HomeView + } + ] +}) + +export default router diff --git a/frontend/src/util/tetris.ts b/frontend/src/util/tetris.ts new file mode 100644 index 0000000..3547108 --- /dev/null +++ b/frontend/src/util/tetris.ts @@ -0,0 +1,40 @@ +import type { Board } from "@/model/board"; +import type { Tetromino } from "@/model/tetrominoes"; + +export function mergeTetrominoWithBoard(board: Board, tetromino: Tetromino): Board { + return board.map((row, rowIndex) => { + if (rowIndex >= tetromino.row && rowIndex < tetromino.row + tetromino.shapes[tetromino.rotation].length) { + return row.map((col, colIndex) => { + if (colIndex >= tetromino.col && colIndex < tetromino.col + tetromino.shapes[tetromino.rotation][0].length) { + return tetromino.shapes[tetromino.rotation][rowIndex - tetromino.row][colIndex - tetromino.col] || col; + } + return col; + }); + } + return row; + }); +} + +export function tetrominoCollidesWithBoard(board: Board, tetromino: Tetromino): boolean { + return tetromino.shapes[tetromino.rotation].some((row, rowIndex) => { + return row.some((col, colIndex) => { + if (col) { + const boardRow = board[rowIndex + tetromino.row]; + if (!boardRow) { + return true; + } + const boardCol = boardRow[colIndex + tetromino.col]; + if (boardCol) { + return true; + } + if (colIndex + tetromino.col < 0 || colIndex + tetromino.col >= boardRow.length) { + return true; + } + if (rowIndex + tetromino.row < 0 || rowIndex + tetromino.row >= board.length) { + return true; + } + } + return false; + }); + }); +} diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue new file mode 100644 index 0000000..09d319e --- /dev/null +++ b/frontend/src/views/HomeView.vue @@ -0,0 +1,10 @@ + + + -- cgit v1.2.3-70-g09d2