2024.js/island.ts

84 lines
1.9 KiB
TypeScript

import { canvas2d } from "./lib/html";
import { Prng, mulberry32 } from "./lib/prng";
const BLOWUP = 4;
const WIDTH = 240;
const HEIGHT = 135;
type Lookup2d = (x: number, y: number) => number;
function dim(width: number, height: number): Lookup2d {
return function xy(x: number, y: number) {
return (
(((x % width) + width) % width) +
width * (((y % height) + height) % height)
);
};
}
class IslandGrid {
data: number[];
rng: Prng;
xy: Lookup2d;
constructor(public width: number, public height: number, seed: number) {
this.data = Array(width * height).fill(0);
this.rng = mulberry32(seed);
this.xy = dim(width, height);
}
public get(x: number, y: number): number {
return this.data[this.xy(x, y)];
}
public set(x: number, y: number, tile: number) {
this.data[this.xy(x, y)] = tile;
console.log(x, y, this.xy(x, y), this.data[this.xy(x, y)]);
}
}
function renderIslands(islands: IslandGrid, cx: CanvasRenderingContext2D) {
for (let y = 0; y < islands.height; y++) {
for (let x = 0; x < islands.width; x++) {
const tile = islands.data[islands.xy(x, y)];
switch (tile) {
case 0:
cx.fillStyle = "blue";
break;
case 1:
cx.fillStyle = "yellow";
break;
case 2:
cx.fillStyle = "#00ff00";
break;
case 3:
cx.fillStyle = "#008800";
break;
default:
cx.fillStyle = "#666666";
break;
}
cx.fillRect(x, y, 1, 1);
}
}
}
export function IslandApplet() {
const [canvas, cx] = canvas2d({
width: WIDTH * BLOWUP,
height: HEIGHT * BLOWUP,
});
cx.scale(BLOWUP, BLOWUP);
const islands = new IslandGrid(WIDTH, HEIGHT, 128);
const x = islands.rng();
const y = islands.rng();
islands.set(x, y, 1);
renderIslands(islands, cx);
return [canvas];
}
(globalThis as any).IslandApplet = IslandApplet;