0.3.0-0-pre.4

This commit is contained in:
2026-09-20 13:14:40 +02:00
parent c7ccf57723
commit c4b68b8a60
27 changed files with 1195 additions and 48 deletions

View File

@@ -0,0 +1,103 @@
// file: Web/game-snake-poc/frontend/ts/game.ts
// version: 1
import init, { SnakeWasmGame } from "@snake-wasm";
const FRAME_MILLIS = 16;
const MAX_FRAME_ELAPSED_MILLIS = 250;
export type SnakeDirection = "left" | "right" | "up" | "down";
export interface SnakeWebSession {
queueDirection(direction: SnakeDirection): void;
}
function color(red: number, green: number, blue: number): string {
return `rgb(${red} ${green} ${blue})`;
}
function resizeCanvas(canvas: HTMLCanvasElement): void {
const ratio = window.devicePixelRatio || 1;
const width = Math.max(1, Math.floor(canvas.clientWidth * ratio));
const height = Math.max(1, Math.floor(canvas.clientHeight * ratio));
if (canvas.width !== width || canvas.height !== height) {
canvas.width = width;
canvas.height = height;
}
}
function render(
game: SnakeWasmGame,
canvas: HTMLCanvasElement,
context: CanvasRenderingContext2D,
score: HTMLOutputElement,
length: HTMLOutputElement,
): void {
resizeCanvas(canvas);
context.fillStyle = color(game.background_red(), game.background_green(), game.background_blue());
context.fillRect(0, 0, canvas.width, canvas.height);
const count = game.rectangle_count();
for (let index = 0; index < count; index += 1) {
context.fillStyle = color(game.rectangle_red(index), game.rectangle_green(index), game.rectangle_blue(index));
context.fillRect(
game.rectangle_x(index) * canvas.width,
game.rectangle_y(index) * canvas.height,
game.rectangle_width(index) * canvas.width,
game.rectangle_height(index) * canvas.height,
);
}
score.value = `Score : ${game.score()}`;
length.value = `Longueur : ${game.length()}`;
}
function queueDirection(game: SnakeWasmGame, direction: SnakeDirection): void {
switch (direction) {
case "left":
game.left();
return;
case "right":
game.right();
return;
case "up":
game.up();
return;
case "down":
game.down();
return;
}
}
export async function startGame(
canvas: HTMLCanvasElement,
score: HTMLOutputElement,
length: HTMLOutputElement,
): Promise<SnakeWebSession> {
await init();
const context = canvas.getContext("2d");
if (context === null) {
throw new Error("Le contexte Canvas 2D est indisponible.");
}
const game = new SnakeWasmGame();
let previous = performance.now();
let accumulator = 0;
function frame(now: number): void {
const elapsed = Math.min(Math.max(0, now - previous), MAX_FRAME_ELAPSED_MILLIS);
previous = now;
accumulator += elapsed;
while (accumulator >= FRAME_MILLIS) {
game.tick();
accumulator -= FRAME_MILLIS;
}
render(game, canvas, context, score, length);
window.requestAnimationFrame(frame);
}
render(game, canvas, context, score, length);
window.requestAnimationFrame(frame);
return {
queueDirection(direction: SnakeDirection): void {
queueDirection(game, direction);
},
};
}