Add desktop games, robot pet and TCG app
This commit is contained in:
1 parent
812503251b
commit
c664f573b8
55 files changed
+5090
-15
No files matched your search
@@ -0,0 +1,69 @@
|
||||
<script lang="ts">
|
||||
import { boardSize, type Point } from '#lib/games/snake';
|
||||
import { themeState } from '#lib/theme/theme.svelte';
|
||||
|
||||
let { snake, food, size }: { snake: Point[]; food: Point | null; size: number } = $props();
|
||||
|
||||
const emptyCellOpacity = 0.06;
|
||||
|
||||
let canvasElement = $state<HTMLCanvasElement>();
|
||||
let pixelRatio = $state(1);
|
||||
|
||||
const canvasSize = $derived(Math.round(size * pixelRatio));
|
||||
|
||||
function themeColor(name: string): string {
|
||||
return getComputedStyle(canvasElement!).getPropertyValue(name).trim();
|
||||
}
|
||||
|
||||
function drawBoard(context: CanvasRenderingContext2D) {
|
||||
const gap = Math.max(1, Math.round(pixelRatio));
|
||||
const cellSpan = (canvasSize - gap) / boardSize;
|
||||
|
||||
const fillCell = (point: Point) => {
|
||||
const left = gap + Math.round(point.x * cellSpan);
|
||||
const top = gap + Math.round(point.y * cellSpan);
|
||||
const right = Math.round((point.x + 1) * cellSpan);
|
||||
const bottom = Math.round((point.y + 1) * cellSpan);
|
||||
context.fillRect(left, top, right - left, bottom - top);
|
||||
};
|
||||
|
||||
context.clearRect(0, 0, canvasSize, canvasSize);
|
||||
|
||||
context.globalAlpha = emptyCellOpacity;
|
||||
context.fillStyle = themeColor('--foreground');
|
||||
for (let y = 0; y < boardSize; y++) {
|
||||
for (let x = 0; x < boardSize; x++) fillCell({ x, y });
|
||||
}
|
||||
context.globalAlpha = 1;
|
||||
|
||||
if (food) {
|
||||
context.fillStyle = themeColor('--red');
|
||||
fillCell(food);
|
||||
}
|
||||
|
||||
context.fillStyle = themeColor('--green');
|
||||
snake.slice(1).forEach(fillCell);
|
||||
|
||||
context.fillStyle = themeColor('--accent');
|
||||
if (snake[0]) fillCell(snake[0]);
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
size;
|
||||
pixelRatio = window.devicePixelRatio || 1;
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
themeState.currentId;
|
||||
const context = canvasElement?.getContext('2d');
|
||||
if (context && canvasSize > 0) drawBoard(context);
|
||||
});
|
||||
</script>
|
||||
|
||||
<canvas bind:this={canvasElement} width={canvasSize} height={canvasSize} style="width: {size}px; height: {size}px"></canvas>
|
||||
|
||||
<style>
|
||||
canvas {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user