mirror of
https://github.com/KeyZox71/knl_meowscendence.git
synced 2025-12-31 21:56:41 +01:00
「🏗️」 wip(front): profile page
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import Aview from "./Aview.ts";
|
||||
import { dragElement } from "./drag.js";
|
||||
import { setOnekoState, setBallPos, setOnekoOffset } from "../oneko.ts"
|
||||
|
||||
export default class extends Aview {
|
||||
running: boolean;
|
||||
@ -7,6 +8,7 @@ export default class extends Aview {
|
||||
constructor() {
|
||||
super();
|
||||
this.setTitle("tetris (local match)");
|
||||
setOnekoState("tetris");
|
||||
this.running = true;
|
||||
}
|
||||
|
||||
@ -274,33 +276,42 @@ export default class extends Aview {
|
||||
canvas: HTMLCanvasElement | null;
|
||||
holdCanvas: HTMLCanvasElement | null;
|
||||
queueCanvas: HTMLCanvasElement | null;
|
||||
ctx: CanvasRenderingContext2D;
|
||||
holdCtx: CanvasRenderingContext2D;
|
||||
queueCtx: CanvasRenderingContext2D;
|
||||
ctx: CanvasRenderingContext2D | null;
|
||||
holdCtx: CanvasRenderingContext2D | null;
|
||||
queueCtx: CanvasRenderingContext2D | null;
|
||||
piece: Piece | null = null;
|
||||
holdPiece: Piece | null = null;
|
||||
canHold: boolean = true;
|
||||
nextQueue: string[] = [];
|
||||
score = 0;
|
||||
level = 1;
|
||||
lines = 0;
|
||||
dropInterval = 1000;
|
||||
lastDrop = 0;
|
||||
isGameOver = false;
|
||||
isPaused = false;
|
||||
score: number = 0;
|
||||
level: number = 1;
|
||||
lines: number = 0;
|
||||
dropInterval: number = 1000;
|
||||
lastDrop: number = 0;
|
||||
isLocking: boolean = false;
|
||||
lockRotationCount: number = 0;
|
||||
lockLastRotationCount: number = 0;
|
||||
isGameOver: boolean = false;
|
||||
isPaused: boolean = false;
|
||||
|
||||
constructor(canvasId: string) {
|
||||
const el = document.getElementById(
|
||||
canvasId,
|
||||
) as HTMLCanvasElement | null;
|
||||
this.canvas = el;
|
||||
if (!this.canvas)
|
||||
throw console.error("no canvas :c");
|
||||
this.canvas.width = COLS * BLOCK;
|
||||
this.canvas.height = ROWS * BLOCK;
|
||||
const ctx = this.canvas.getContext("2d");
|
||||
this.ctx = ctx;
|
||||
if (!this.ctx)
|
||||
throw console.error("no ctx D:");
|
||||
|
||||
this.holdCanvas = document.getElementById("hold");
|
||||
this.queueCanvas = document.getElementById("queue");
|
||||
this.holdCanvas = document.getElementById("hold") as HTMLCanvasElement;
|
||||
this.queueCanvas = document.getElementById("queue") as HTMLCanvasElement;
|
||||
if (!this.holdCanvas || !this.queueCanvas)
|
||||
throw console.error("no canvas :c");
|
||||
this.holdCtx = this.holdCanvas.getContext("2d");
|
||||
this.queueCtx = this.queueCanvas.getContext("2d");
|
||||
|
||||
@ -337,6 +348,7 @@ export default class extends Aview {
|
||||
|
||||
[this.piece, this.holdPiece] = [this.holdPiece, this.piece];
|
||||
if (!this.piece) this.spawnPiece();
|
||||
if (!this.piece) return;
|
||||
|
||||
this.piece.x = Math.floor((COLS - this.piece.shape[0].length) / 2);
|
||||
this.piece.y = -2;
|
||||
@ -352,7 +364,6 @@ export default class extends Aview {
|
||||
if (this.nextQueue.length < 7) this.fillBag();
|
||||
const type = this.nextQueue.shift()!;
|
||||
this.piece = new Piece(type);
|
||||
// If spawn collides immediately -> game over
|
||||
if (this.collides(this.piece)) {
|
||||
this.isGameOver = true;
|
||||
}
|
||||
@ -374,12 +385,11 @@ export default class extends Aview {
|
||||
let y: number = 0;
|
||||
while (true) {
|
||||
for (const cell of piece.getCells()) {
|
||||
console.log(cell.y + y);
|
||||
if (
|
||||
cell.y + y >= ROWS ||
|
||||
(cell.y + y >= 0 && this.board[cell.y + y][cell.x])
|
||||
)
|
||||
return y - 1;
|
||||
return y - 1;
|
||||
}
|
||||
|
||||
y++;
|
||||
@ -388,11 +398,12 @@ export default class extends Aview {
|
||||
|
||||
lockPiece() {
|
||||
if (!this.piece) return;
|
||||
this.isLocking = false;
|
||||
let isValid: boolean = false;
|
||||
for (const cell of this.piece.getCells()) {
|
||||
if (cell.y >= 0 && cell.y < ROWS && cell.x >= 0 && cell.x < COLS)
|
||||
this.board[cell.y][cell.x] = cell.val;
|
||||
if (cell.y < 20) isValid = true;
|
||||
if (cell.y > 0) isValid = true;
|
||||
}
|
||||
if (!isValid) this.isGameOver = true;
|
||||
|
||||
@ -427,6 +438,8 @@ export default class extends Aview {
|
||||
|
||||
rotatePiece(dir: "cw" | "ccw") {
|
||||
if (!this.piece) return;
|
||||
if (this.isLocking && this.lockRotationCount < 15)
|
||||
this.lockRotationCount++;
|
||||
// Try rotation with wall kicks
|
||||
const originalIndex = this.piece.rotationIndex;
|
||||
if (dir === "cw") this.piece.rotateCW();
|
||||
@ -446,6 +459,7 @@ export default class extends Aview {
|
||||
if (!this.piece) return;
|
||||
this.piece.x += dx;
|
||||
this.piece.y += dy;
|
||||
|
||||
if (this.collides(this.piece)) {
|
||||
this.piece.x -= dx;
|
||||
this.piece.y -= dy;
|
||||
@ -470,6 +484,26 @@ export default class extends Aview {
|
||||
}
|
||||
|
||||
keys: Record<string, boolean> = {};
|
||||
direction: number = 0;
|
||||
inputDelay = 200;
|
||||
inputTimestamp = Date.now();
|
||||
move: boolean = false;
|
||||
|
||||
inputManager() {
|
||||
if (this.move || Date.now() > this.inputTimestamp + this.inputDelay)
|
||||
{
|
||||
if (this.keys["ArrowLeft"] && !this.keys["ArrowRight"])
|
||||
this.movePiece(-1, 0);
|
||||
else if (!this.keys["ArrowLeft"] && this.keys["ArrowRight"])
|
||||
this.movePiece(1, 0);
|
||||
else if (this.keys["ArrowLeft"] && this.keys["ArrowRight"])
|
||||
this.movePiece(this.direction, 0);
|
||||
this.move = false;
|
||||
}
|
||||
|
||||
/*if (this.keys["ArrowDown"])
|
||||
this.softDrop();*/
|
||||
}
|
||||
|
||||
registerListeners() {
|
||||
window.addEventListener("keydown", (e) => {
|
||||
@ -482,8 +516,18 @@ export default class extends Aview {
|
||||
|
||||
if (this.isPaused) return;
|
||||
|
||||
if (e.key === "ArrowLeft") this.movePiece(-1, 0);
|
||||
else if (e.key === "ArrowRight") this.movePiece(1, 0);
|
||||
if (e.key === "ArrowLeft")
|
||||
{
|
||||
this.inputTimestamp = Date.now();
|
||||
this.direction = -1;//this.movePiece(-1, 0);
|
||||
this.move = true;
|
||||
}
|
||||
else if (e.key === "ArrowRight")
|
||||
{
|
||||
this.inputTimestamp = Date.now();
|
||||
this.direction = 1;//this.movePiece(1, 0);
|
||||
this.move = true;
|
||||
}
|
||||
else if (e.key === "ArrowDown") this.softDrop();
|
||||
else if (e.code === "Space") {
|
||||
e.preventDefault();
|
||||
@ -504,9 +548,25 @@ export default class extends Aview {
|
||||
|
||||
loop(timestamp: number) {
|
||||
if (!this.lastDrop) this.lastDrop = timestamp;
|
||||
if (!this.isPaused && !this.isGameOver) {
|
||||
if (timestamp - this.lastDrop > this.dropInterval) {
|
||||
if (!this.movePiece(0, 1)) this.lockPiece();
|
||||
if (!this.isPaused && !this.isGameOver)
|
||||
{
|
||||
this.inputManager();
|
||||
if (this.isLocking ? timestamp - this.lastDrop > 500 : timestamp - this.lastDrop > this.dropInterval)
|
||||
{
|
||||
if (this.isLocking && this.lockRotationCount == this.lockLastRotationCount)
|
||||
this.lockPiece();
|
||||
this.lockLastRotationCount = this.lockRotationCount;
|
||||
if (!this.movePiece(0, 1))
|
||||
{
|
||||
if (!this.isLocking)
|
||||
{
|
||||
this.lockRotationCount = 0;
|
||||
this.lockLastRotationCount = 0;
|
||||
this.isLocking = true;
|
||||
}
|
||||
}
|
||||
else if (this.isLocking)
|
||||
this.lockRotationCount = 0;
|
||||
this.lastDrop = timestamp;
|
||||
}
|
||||
}
|
||||
@ -516,6 +576,8 @@ export default class extends Aview {
|
||||
|
||||
drawGrid() {
|
||||
const ctx = this.ctx;
|
||||
if (!ctx || !this.canvas)
|
||||
return;
|
||||
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
ctx.strokeStyle = "#222";
|
||||
for (let r = 0; r <= ROWS; r++) {
|
||||
@ -556,7 +618,7 @@ export default class extends Aview {
|
||||
}
|
||||
|
||||
drawHold() {
|
||||
if (!this.holdPiece) return;
|
||||
if (!this.holdPiece || !this.holdCtx) return;
|
||||
|
||||
this.holdCtx.clearRect(0, 0, 200, 200);
|
||||
let y: number = 0;
|
||||
@ -567,6 +629,7 @@ export default class extends Aview {
|
||||
this.holdCtx.fillStyle = this.canHold
|
||||
? COLORS[this.holdPiece.findColorIndex()]
|
||||
: "gray";
|
||||
console.log(this.holdCtx.fillStyle);
|
||||
this.holdCtx.fillRect(
|
||||
x * BLOCK +
|
||||
1 +
|
||||
@ -584,9 +647,9 @@ export default class extends Aview {
|
||||
}
|
||||
|
||||
drawQueue() {
|
||||
if (!this.queueCtx) return ;
|
||||
this.queueCtx.clearRect(0, 0, 500, 500);
|
||||
let placement: number = 0;
|
||||
console.log(this.nextQueue.slice(0, 5));
|
||||
for (const nextPiece of this.nextQueue.slice(0, 5)) {
|
||||
let y: number = 0;
|
||||
for (const row of TETROMINOES[nextPiece][0]) {
|
||||
@ -620,22 +683,26 @@ export default class extends Aview {
|
||||
}
|
||||
|
||||
fillBlock(x: number, y: number, color: string) {
|
||||
if (!this.ctx) return;
|
||||
const ctx = this.ctx;
|
||||
ctx.fillStyle = color;
|
||||
ctx.fillRect(x * BLOCK + 1, y * BLOCK + 1, BLOCK - 2, BLOCK - 2);
|
||||
}
|
||||
fillGhostBlock(x: number, y: number, color: string) {
|
||||
if (!this.ctx) return;
|
||||
const ctx = this.ctx;
|
||||
ctx.strokeStyle = color;
|
||||
ctx.strokeRect(x * BLOCK + 1, y * BLOCK + 1, BLOCK - 2, BLOCK - 2);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
drawHUD() {
|
||||
if (!this.ctx || !this.canvas) return;
|
||||
const ctx = this.ctx;
|
||||
ctx.fillStyle = "rgba(0,0,0,0.6)";
|
||||
ctx.fillRect(4, 4, 120, 60);
|
||||
@ -675,6 +742,7 @@ export default class extends Aview {
|
||||
}
|
||||
|
||||
draw() {
|
||||
if (!this.ctx || !this.canvas) return;
|
||||
// clear everything
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
|
||||
@ -698,6 +766,7 @@ export default class extends Aview {
|
||||
this.drawBoard();
|
||||
this.drawPiece();
|
||||
this.drawHUD();
|
||||
this.drawQueue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user