」 feat(front): front mainly done, waiting for image api

This commit is contained in:
y-syo
2025-10-21 14:05:02 +02:00
parent a74848b9f4
commit b52b43b250
9 changed files with 235 additions and 63 deletions

View File

@ -26,10 +26,10 @@
<img src="./static/assets/tetrio.svg" width=32 height=32 />
<span class="text-white font-[Kubasta]">tetris_game.ts</span>
</a>
<a class="flex flex-col items-center" href="https://tetr.io/">
<!--a class="flex flex-col items-center" href="https://tetr.io/">
<img src="./static/assets/tetrio.svg" width=32 height=32 />
<span class="text-white font-[Kubasta]">tetr.io</span>
</a>
</a-->
</div>
<div id="app" class="flex-1 flex items-center justify-center">
@ -46,8 +46,7 @@
<a target="_blank" class="taskbar-button" href="https://rusty.42angouleme.fr/">rusty</a>
<a target="_blank" class="taskbar-button" href="https://dn720004.ca.archive.org/0/items/2009-tetris-variant-concepts_202201/2009%20Tetris%20Design%20Guideline.pdf">tetris-guideline.pdf</a>
</div>
<div class="flex px-4 items-center content-center space-x-2">
<button id="friends-btn" class="taskbar-button">friends</button>
<div id="taskbar-trail" class="flex px-4 items-center content-center space-x-2">
<div class="reverse-border m-1.5 h-8/10 content-center">
<span id="taskbar-clock" class="text-neutral-900 dark:text-white px-4">12:37</span>
</div>

View File

@ -12,11 +12,21 @@ export async function isLogged(): Promise<boolean> {
if (uuid_req.status === 200) {
let uuid = await uuid_req.json();
document.cookie = `uuid=${uuid.user};max-age=${60 * 60 * 24 * 7}`;
if (!document.getElementById("friends-btn"))
{
const btn: HTMLButtonElement = document.createElement("button") as HTMLButtonElement;
btn.id = "friends-btn";
btn?.classList.add("taskbar-button");
btn.innerText = "friends";
document.getElementById("taskbar-trail")?.prepend(btn);
}
return true;
}
else // 401
{
document.cookie = `uuid=;max-age=0`;
const btn = document.getElementById("friends-btn") as HTMLButtonElement;
if (btn) btn.remove();
return false;
}
}
@ -32,7 +42,7 @@ const routes = [
{ path: "/", view: () => import("./views/MainMenu.ts") },
{ path: "/pong", view: () => import("./views/PongMenu.ts") },
{ path: "/pong/local", view: () => import("./views/Game.ts") },
{ path: "/pong/local", view: () => import("./views/Pong.ts") },
{ path: "/pong/tournament", view: () => import("./views/TournamentMenu.ts") },
{ path: "/tetris", view: () => import("./views/TetrisMenu.ts") },
@ -102,8 +112,6 @@ document.addEventListener("DOMContentLoaded", () => {
router();
});
oneko();
function updateClock()
{
const days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];

View File

@ -1,4 +1,5 @@
import Aview from "./Aview.ts"
import { isLogged} from "../main.ts"
import { setOnekoState } from "../oneko.ts"
export default class extends Aview {

View File

@ -28,8 +28,9 @@ export default class extends Aview {
</div>
<div id="main-div" class="bg-neutral-200 dark:bg-neutral-800 text-center p-10 space-y-4 reverse-border">
<div id="main-div" class="bg-neutral-200 dark:bg-neutral-800 text-center p-5 space-y-4 reverse-border">
<div id="player-inputs" class="flex flex-col space-y-4">
<h1 class="text-lg text-neutral-900 dark:text-white font-bold mt-2">enter the users ids/names</h1>
<div class="flex flex-row">
<span class="reverse-border w-full ml-2"><input type="text" id="player1" placeholder="Player 1" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input></span>
<span class="reverse-border w-full ml-2"><input type="text" id="player2" placeholder="Player 2" class="bg-white text-neutral-900 px-4 py-2 w-full input-border" required></input></span>
@ -265,8 +266,8 @@ export default class extends Aview {
countdown = 3;
countdownTimer = performance.now();
});
let p1_input = document.getElementById("player1");
let p2_input = document.getElementById("player2");
let p1_input: HTMLInputElement = document.getElementById("player1") as HTMLInputElement;
let p2_input: HTMLInputElement = document.getElementById("player2") as HTMLInputElement;
p2_input.value = "Player 2";
if (await isLogged())
@ -283,6 +284,7 @@ export default class extends Aview {
}
let userdata = await userdata_req.json();
p1_input.value = userdata.displayName;
p1_input.readOnly = true;
}
else
p1_input.value = "Player 1";

View File

@ -28,11 +28,11 @@ export default class extends Aview {
<div class="flex flex-col space-y-4 w-full">
<div id="profile-profile" class="default-border h-24 flex flex-row place-content-stretch content-center items-center space-x-6 pr-4">
</div>
<div class="flex flex-row space-x-4 w-full min-w-145">
<ul id="profile-scorelist" class="reverse-border bg-neutral-300 dark:bg-neutral-900 h-48 w-full overflow-scroll no-scrollbar">
<div class="flex flex-row space-x-4 w-full min-w-175">
<ul id="profile-pong-scorelist" class="reverse-border bg-neutral-300 dark:bg-neutral-900 h-48 w-full overflow-scroll no-scrollbar">
</ul>
<ul id="profile-tetris-scorelist" class="reverse-border bg-neutral-300 dark:bg-neutral-900 h-48 w-full overflow-scroll no-scrollbar">
</ul>
<div id="graph-ig-idk-im-scared" class="reverse-border bg-neutral-300 dark:bg-neutral-900 h-48 w-full">
</div>
</div>
</div>
</div>
@ -58,33 +58,108 @@ export default class extends Aview {
}
let userdata = await userdata_req.json();
const matchCount_req = await fetch(`http://localhost:3002/users/${uuid}/matchHistory/count?game=tetris`, {
let matchCount_req = await fetch(`http://localhost:3002/users/${uuid}/matchHistory/count?game=pong`, {
method: "GET",
credentials: "include",
});
const matchCount = await matchCount_req.json();
let matchCount = await matchCount_req.json();
const matches_req = await fetch(`http://localhost:3002/users/${uuid}/matchHistory?game=tetris&iStart=0&iEnd=${matchCount.n_matches}`, {
let matches_req = await fetch(`http://localhost:3002/users/${uuid}/matchHistory?game=pong&iStart=0&iEnd=${matchCount.n_matches}`, {
method: "GET",
credentials: "include",
});
const matches = await matches_req.json();
let matches = await matches_req.json();
const main = document.getElementById("profile-scorelist");
let main = document.getElementById("profile-pong-scorelist");
if (!main)
return console.error("what");
if (matches.matchHistory) {
for (let match of matches.matchHistory) {
const newEntry = document.createElement("li");
newEntry.classList.add("m-2", "default-button", "bg-neutral-200", "dark:bg-neutral-800", "text-neutral-900", "dark:text-white");
newEntry.classList.add("m-1", "default-button", "bg-neutral-200", "dark:bg-neutral-800", "text-neutral-900", "dark:text-white");
newEntry.innerHTML = match.score.p1Score > match.score.p2Score ? `${match.score.p1} - winner` : `${match.score.p2} - winner`;
main.insertBefore(newEntry, main.firstChild);
// ###########################################################################################################################################
//
// ADD TX LINK : https://testnet.snowscan.xyz/tx/${match.tx}
//
// ###########################################################################################################################################
const popup: HTMLDivElement = document.createElement("div");
const id: number = Math.floor(Math.random() * 100000000000);
popup.id = `${id}`;
popup.classList.add("z-10", "absolute", "default-border");
const header = popup.appendChild(document.createElement("div"));
header.classList.add("bg-linear-to-r", "from-orange-200", "to-orange-300", "flex", "flex-row", "min-w-35", "justify-between", "px-2");
header.id = `${id}-header`;
header.appendChild(document.createElement("span")).innerText = "score.ts";
const btn = header.appendChild(document.createElement("button"));
btn.innerText = " × ";
btn.onclick = () => { document.getElementById(`${id}`).remove(); };
const popup_content: HTMLSpanElement = popup.appendChild(document.createElement("div"));
popup_content.classList.add("flex", "flex-col", "bg-neutral-200", "dark:bg-neutral-800", "p-6", "pt-4", "text-neutral-900", "dark:text-white", "space-y-4");
const date = new Date(match.score.date);
popup_content.appendChild(document.createElement("span")).innerText = `${date.toDateString()} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
const score = popup_content.appendChild(document.createElement("span"));
score.classList.add();
score.innerText = `${match.score.p1} : ${match.score.p1Score} - ${match.score.p2Score} : ${match.score.p2}`;
const tx = popup_content.appendChild(document.createElement("a"));
tx.href = `https://testnet.snowscan.xyz/tx/${match.tx}`;
tx.innerText = "transaction proof";
tx.target = "_blank";
tx.classList.add("default-button", "items-center", "justify-center", "text-center");
newEntry.onclick = () => { document.getElementById("app")?.appendChild(popup); dragElement(document.getElementById(`${id}`)); };
console.log(match.tx);
}
}
matchCount_req = await fetch(`http://localhost:3002/users/${uuid}/matchHistory/count?game=tetris`, {
method: "GET",
credentials: "include",
});
matchCount = await matchCount_req.json();
matches_req = await fetch(`http://localhost:3002/users/${uuid}/matchHistory?game=tetris&iStart=0&iEnd=${matchCount.n_matches}`, {
method: "GET",
credentials: "include",
});
matches = await matches_req.json();
main = document.getElementById("profile-tetris-scorelist");
if (!main)
return console.error("what");
if (matches.matchHistory) {
for (let match of matches.matchHistory) {
const newEntry = document.createElement("li");
newEntry.classList.add("m-1", "default-button", "bg-neutral-200", "dark:bg-neutral-800", "text-neutral-900", "dark:text-white");
newEntry.innerHTML = match.score.p1Score > match.score.p2Score ? `${match.score.p1} - winner` : `${match.score.p2} - winner`;
main.insertBefore(newEntry, main.firstChild);
const popup: HTMLDivElement = document.createElement("div");
const id: number = Math.floor(Math.random() * 100000000000);
popup.id = `${id}`;
popup.classList.add("z-10", "absolute", "default-border");
const header = popup.appendChild(document.createElement("div"));
header.classList.add("bg-linear-to-r", "from-orange-200", "to-orange-300", "flex", "flex-row", "min-w-35", "justify-between", "px-2");
header.id = `${id}-header`;
header.appendChild(document.createElement("span")).innerText = "score.ts";
const btn = header.appendChild(document.createElement("button"));
btn.innerText = " × ";
btn.onclick = () => { document.getElementById(`${id}`).remove(); };
const popup_content: HTMLSpanElement = popup.appendChild(document.createElement("div"));
popup_content.classList.add("flex", "flex-col", "bg-neutral-200", "dark:bg-neutral-800", "p-6", "pt-4", "text-neutral-900", "dark:text-white", "space-y-4");
const date = new Date(match.score.date);
popup_content.appendChild(document.createElement("span")).innerText = `${date.toDateString()} ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
const score = popup_content.appendChild(document.createElement("span"));
score.classList.add();
score.innerText = `${match.score.p1} : ${match.score.p1Score} - ${match.score.p2Score} : ${match.score.p2}`;
const tx = popup_content.appendChild(document.createElement("a"));
tx.href = `https://testnet.snowscan.xyz/tx/${match.tx}`;
tx.innerText = "transaction proof";
tx.target = "_blank";
tx.classList.add("default-button", "items-center", "justify-center", "text-center");
newEntry.onclick = () => { document.getElementById("app")?.appendChild(popup); dragElement(document.getElementById(`${id}`)); };
console.log(match.tx);
}
}

View File

@ -77,6 +77,7 @@ export default class extends Aview {
method: "GET",
credentials: "include",
});
isLogged();
if (req.status === 200)
this.run();
else

View File

@ -70,7 +70,7 @@ export default class extends Aview {
});
document.getElementById("deleteAccount-button")?.addEventListener("click", async () => {
const delete_req = await fetch(`http://localhost:3002/users/${uuid}`, {
const delete_req = await fetch(`http://localhost:3001/`, {
method: "DELETE",
credentials: "include",
});
@ -78,7 +78,7 @@ export default class extends Aview {
if (delete_req.status == 200)
navigationManager("/");
else
console.error("xd"); // should never happen, wtf
console.error("xd"); // xd?????????????
});
}
}

View File

@ -47,6 +47,8 @@ export default class extends Aview {
const ROWS = 20;
const BLOCK = 30; // pixels per block
const view = this;
type Cell = number; // 0 empty, >0 occupied (color index)
// Tetromino definitions: each piece is an array of rotations, each rotation is a 2D matrix
@ -542,10 +544,13 @@ export default class extends Aview {
} else if (e.key === "Shift" || e.key === "c" || e.key === "C") {
e.preventDefault();
this.hold();
} else if (e.key === "x" || e.key === "X" || e.key === "ArrowUp")
} else if (e.key === "x" || e.key === "X" || e.key === "ArrowUp") {
e.preventDefault();
this.rotatePiece("cw");
else if (e.key === "z" || e.key === "Z" || e.key === "Control")
} else if (e.key === "z" || e.key === "Z" || e.key === "Control") {
e.preventDefault();
this.rotatePiece("ccw");
}
});
document.addEventListener("keyup", (e) => {
@ -554,6 +559,7 @@ export default class extends Aview {
}
async loop(timestamp: number) {
if (!view.running) return;
if (!this.lastDrop) this.lastDrop = timestamp;
if (!this.isPaused)
{
@ -608,7 +614,7 @@ export default class extends Aview {
if (!ctx || !this.canvas)
return;
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
ctx.strokeStyle = "#222";
ctx.strokeStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(14.5% 0 0)" : "oklch(55.6% 0 0)";
for (let r = 0; r <= ROWS; r++) {
// horizontal lines
ctx.beginPath();
@ -625,6 +631,7 @@ export default class extends Aview {
}
drawBoard() {
this.drawGrid();
for (let r = 0; r < ROWS; r++) {
for (let c = 0; c < COLS; c++) {
const val = this.board[r][c];
@ -647,15 +654,18 @@ export default class extends Aview {
}
drawHold() {
if (!this.holdPiece || !this.holdCtx) return;
if (!this.holdCtx || !this.holdCanvas) return;
this.holdCtx.clearRect(0, 0, 200, 200);
this.holdCtx.fillStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(20.5% 0 0)" : "oklch(70.8% 0 0)";
this.holdCtx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);
if (!this.holdPiece) return;
let y: number = 0;
for (const row of this.holdPiece.rotations[0]) {
let x: number = 0;
for (const val of row) {
if (val)
this.fillBlock(x + (4 - this.holdPiece.rotations[0].length)/ 2 + 0.35, y + 0.5, this.canHold ? COLORS[this.holdPiece.findColorIndex()] : ["#8c8c84", "#393934"], this.holdCtx);
this.fillBlock(x + (4 - this.holdPiece.rotations[0].length)/ 2 + 0.35, y + 0.65, this.canHold ? COLORS[this.holdPiece.findColorIndex()] : ["#8c8c84", "#393934"], this.holdCtx);
x++;
}
y++;
@ -663,8 +673,10 @@ export default class extends Aview {
}
drawQueue() {
if (!this.queueCtx) return ;
this.queueCtx.clearRect(0, 0, 500, 500);
if (!this.queueCtx || !this.queueCanvas) return ;
this.queueCtx.fillStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(20.5% 0 0)" : "oklch(70.8% 0 0)";
this.queueCtx.fillRect(0, 0, this.queueCanvas.width, this.queueCanvas.height);
let placement: number = 0;
for (const nextPiece of this.nextQueue.slice(0, 5)) {
let y: number = 0;
@ -755,7 +767,8 @@ export default class extends Aview {
clearBlock(x: number, y: number) {
if (!this.ctx) return;
const ctx = this.ctx;
ctx.clearRect(x * BLOCK + 1, y * BLOCK + 1, BLOCK - 2, BLOCK - 2);
ctx.fillStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(20.5% 0 0)" : "oklch(70.8% 0 0)";
ctx.fillRect(x * BLOCK + 1, y * BLOCK + 1, BLOCK - 2, BLOCK - 2);
}
drawHUD() {
@ -765,9 +778,9 @@ export default class extends Aview {
ctx.fillRect(4, 4, 120, 60);
ctx.fillStyle = "#fff";
ctx.font = "12px Kubasta";
ctx.fillText(`Score: ${this.score}`, 8, 20);
ctx.fillText(`Lines: ${this.lines}`, 8, 36);
ctx.fillText(`Level: ${this.level}`, 8, 52);
ctx.fillText(`score: ${this.score}`, 8, 20);
ctx.fillText(`lines: ${this.lines}`, 8, 36);
ctx.fillText(`level: ${this.level}`, 8, 52);
if (this.isPaused) {
ctx.fillStyle = "rgba(0,0,0,0.7)";

View File

@ -26,8 +26,16 @@ export default class extends Aview {
</div>
<div id="main-div" class="bg-neutral-200 dark:bg-neutral-800 text-center p-10 space-y-4 reverse-border">
<div class="flex flex-row justify-center items-start space-x-4">
<div id="main-div" class="bg-neutral-200 dark:bg-neutral-800 text-center p-5 pt-2 space-y-4 reverse-border">
<div id="player-inputs" class="flex flex-col space-y-4">
<h1 class="text-lg text-neutral-900 dark:text-white font-bold mt-2">enter the users ids/names</h1>
<div class="flex flex-row">
<span class="reverse-border w-full ml-2"><input type="text" id="player1" placeholder="Player 1" class="bg-white text-neutral-900 px-4 py-2 input-border" required></input></span>
<span class="reverse-border w-full ml-2"><input type="text" id="player2" placeholder="Player 2" class="bg-white text-neutral-900 px-4 py-2 w-full input-border" required></input></span>
</div>
<button id="game-start" class="default-button">play</button>
</div>
<div id="game-boards" class="hidden flex flex-row justify-center items-start space-x-4">
<canvas id="board1-hold" class="reverse-border" width="140" height="100"></canvas>
<canvas id="board1-board" class="reverse-border" width="300" height="600"></canvas>
<canvas id="board1-queue" class="reverse-border" width="140" height="420"></canvas>
@ -45,14 +53,22 @@ export default class extends Aview {
}
async run() {
let game1: Game;
let game2: Game;
dragElement(document.getElementById("window"));
const COLS = 10;
const ROWS = 20;
const BLOCK = 30; // pixels per block
type Cell = number; // 0 empty, >0 occupied (color index)
let uuid: string;
let game1: Game;
let game2: Game;
let p1_score: number = 0;
let p2_score: number = 0;
let p1_name: string;
let p2_name: string;
const view = this;
type Cell = number;
// Tetromino definitions: each piece is an array of rotations, each rotation is a 2D matrix
const TETROMINOES: { [key: string]: number[][][] } = {
@ -388,7 +404,8 @@ export default class extends Aview {
const type = this.nextQueue.shift()!;
this.piece = new Piece(type);
if (this.collides(this.piece)) {
this.isGameOver = true;
game1.isGameOver = true;
game2.isGameOver = true;
}
this.drawHold();
@ -428,7 +445,12 @@ export default class extends Aview {
this.board[cell.y][cell.x] = cell.val;
if (cell.y > 0) isValid = true;
}
if (!isValid) this.isGameOver = true;
if (!isValid)
{
this.id == 0 ? p2_score++ : p1_score++;
game1.isGameOver = true;
game2.isGameOver = true;
}
if (this.garbage)
{
@ -589,10 +611,13 @@ export default class extends Aview {
} else if (this.id === 0 ? e.code === "ShiftLeft" : e.code === "NumpadEnter") {
e.preventDefault();
this.hold();
} else if (this.id === 0 ? e.code === "KeyE" : e.code === "Numpad9")
} else if (this.id === 0 ? (e.code === "KeyE" || e.code === "KeyW") : (e.code === "Numpad9" || e.code === "Numpad8")) {
e.preventDefault();
this.rotatePiece("cw");
else if (this.id === 0 ? e.code === "KeyQ" : e.code === "Numpad7")
} else if (this.id === 0 ? (e.code === "KeyQ" || e.code === "ControlLeft") : e.code === "Numpad7") {
e.preventDefault();
this.rotatePiece("ccw");
}
});
document.addEventListener("keyup", (e) => {
@ -601,6 +626,7 @@ export default class extends Aview {
}
async loop(timestamp: number) {
if (!view.running) return;
if (!this.lastDrop) this.lastDrop = timestamp;
if (!this.isPaused)
{
@ -628,7 +654,16 @@ export default class extends Aview {
if (this.isGameOver)
{
if (await isLogged())
if (p1_score != 3 && p2_score != 3)
{
if (this.id == 0)
{
game1 = new Game("board1", 0);
game2 = new Game("board2", 1);
}
return ;
}
if (await isLogged() && this.id == 0)
{
let uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2];
fetch(`http://localhost:3002/users/${uuid}/matchHistory?game=tetris`, {
@ -637,9 +672,9 @@ export default class extends Aview {
credentials: "include",
body: JSON.stringify({
"game": "tetris",
"opponent": "xd",
"myScore": this.score,
"opponentScore": 0,
"opponent": p2_name,
"myScore": p1_score,
"opponentScore": p2_score,
"date": Date.now(),
}),
});
@ -655,7 +690,7 @@ export default class extends Aview {
if (!ctx || !this.canvas)
return;
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
ctx.strokeStyle = "#222";
ctx.strokeStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(14.5% 0 0)" : "oklch(55.6% 0 0)";
for (let r = 0; r <= ROWS; r++) {
// horizontal lines
ctx.beginPath();
@ -672,6 +707,7 @@ export default class extends Aview {
}
drawBoard() {
this.drawGrid();
for (let r = 0; r < ROWS; r++) {
for (let c = 0; c < COLS; c++) {
const val = this.board[r][c];
@ -694,9 +730,12 @@ export default class extends Aview {
}
drawHold() {
if (!this.holdPiece || !this.holdCtx) return;
if (!this.holdCtx || !this.holdCanvas) return;
this.holdCtx.clearRect(0, 0, 200, 200);
this.holdCtx.fillStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(20.5% 0 0)" : "oklch(70.8% 0 0)";
this.holdCtx.fillRect(0, 0, this.holdCanvas.width, this.holdCanvas.height);
if (!this.holdPiece) return;
let y: number = 0;
for (const row of this.holdPiece.rotations[0]) {
let x: number = 0;
@ -710,8 +749,10 @@ export default class extends Aview {
}
drawQueue() {
if (!this.queueCtx) return ;
this.queueCtx.clearRect(0, 0, 500, 500);
if (!this.queueCtx || !this.queueCanvas) return ;
this.queueCtx.fillStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(20.5% 0 0)" : "oklch(70.8% 0 0)";
this.queueCtx.fillRect(0, 0, this.queueCanvas.width, this.queueCanvas.height);
let placement: number = 0;
for (const nextPiece of this.nextQueue.slice(0, 5)) {
let y: number = 0;
@ -802,7 +843,8 @@ export default class extends Aview {
clearBlock(x: number, y: number) {
if (!this.ctx) return;
const ctx = this.ctx;
ctx.clearRect(x * BLOCK + 1, y * BLOCK + 1, BLOCK - 2, BLOCK - 2);
ctx.fillStyle = window.matchMedia('(prefers-color-scheme: dark)').matches ? "oklch(20.5% 0 0)" : "oklch(70.8% 0 0)";
ctx.fillRect(x * BLOCK + 1, y * BLOCK + 1, BLOCK - 2, BLOCK - 2);
}
drawHUD() {
@ -819,9 +861,9 @@ export default class extends Aview {
ctx.fillRect(4, 4, 120, 60);
ctx.fillStyle = "#fff";
ctx.font = "12px Kubasta";
ctx.fillText(`Score: ${this.score}`, 8, 20);
ctx.fillText(`Lines: ${this.lines}`, 8, 36);
ctx.fillText(`Level: ${this.level}`, 8, 52);
ctx.fillText(`${this.id == 0 ? p1_name : p2_name}: ${this.id == 0 ? p1_score : p2_score}`, 8, 20);
ctx.fillText(`score: ${this.score}`, 8, 36);
ctx.fillText(`lines: ${this.lines}`, 8, 52);
if (this.isPaused) {
ctx.fillStyle = "rgba(0,0,0,0.7)";
@ -882,7 +924,38 @@ export default class extends Aview {
}
document.getElementById("game-retry")?.addEventListener("click", () => { document.getElementById("game-buttons")?.classList.add("hidden"); game1 = new Game("board1", 0); game2 = new Game("board2", 1); });
game1 = new Game("board1", 0);
game2 = new Game("board2", 1);
let p1_input: HTMLInputElement = document.getElementById("player1") as HTMLInputElement;
let p2_input: HTMLInputElement = document.getElementById("player2") as HTMLInputElement;
p2_input.value = "Player 2";
if (await isLogged())
{
uuid = document.cookie.match(new RegExp('(^| )' + "uuid" + '=([^;]+)'))[2];
const userdata_req = await fetch(`http://localhost:3002/users/${uuid}`, {
method: "GET",
credentials: "include",
});
if (userdata_req.status == 404)
{
console.error("invalid user");
return ;
}
let userdata = await userdata_req.json();
p1_input.value = userdata.displayName;
p1_input.readOnly = true;
}
else
p1_input.value = "Player 1";
document.getElementById("game-start")?.addEventListener("click", () => {
p1_name = p1_input.value.length > 16 ? p1_input.value.substring(0, 16) + "." : p1_input.value;
p2_name = p2_input.value.length > 16 ? p2_input.value.substring(0, 16) + "." : p2_input.value;
document.getElementById("player-inputs").remove();
document.getElementById("game-boards").classList.remove("hidden");
game1 = new Game("board1", 0);
game2 = new Game("board2", 1);
});
}
}