From 3c7796f066647090ed8436778bdfe25f11844c05 Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Tue, 4 Aug 2026 04:35:44 -0400 Subject: Prepare for upload --- 2026/games_submissions/ellg/assets/beef1.png | Bin 1245 -> 0 bytes 2026/games_submissions/ellg/assets/beef2.png | Bin 1280 -> 0 bytes 2026/games_submissions/ellg/assets/chefhat.png | Bin 1224 -> 0 bytes 2026/games_submissions/ellg/assets/guy1.png | Bin 1179 -> 0 bytes 2026/games_submissions/ellg/assets/guy2.png | Bin 1186 -> 0 bytes 2026/games_submissions/ellg/assets/guy3.png | Bin 1212 -> 0 bytes 2026/games_submissions/ellg/assets/guy4.png | Bin 1319 -> 0 bytes 2026/games_submissions/ellg/assets/hungry.png | Bin 1450 -> 0 bytes 2026/games_submissions/ellg/assets/lose.png | Bin 1629 -> 0 bytes 2026/games_submissions/ellg/assets/pot.png | Bin 1074 -> 0 bytes 2026/games_submissions/ellg/assets/song.mp3 | Bin 1196325 -> 0 bytes 2026/games_submissions/ellg/assets/table.png | Bin 276 -> 0 bytes 2026/games_submissions/ellg/assets/win.png | Bin 2357 -> 0 bytes 2026/games_submissions/ellg/game.js | 378 ------------------------- 2026/games_submissions/ellg/index.html | 38 --- 2026/games_submissions/ellg/vector.js | 64 ----- 16 files changed, 480 deletions(-) delete mode 100644 2026/games_submissions/ellg/assets/beef1.png delete mode 100644 2026/games_submissions/ellg/assets/beef2.png delete mode 100644 2026/games_submissions/ellg/assets/chefhat.png delete mode 100644 2026/games_submissions/ellg/assets/guy1.png delete mode 100644 2026/games_submissions/ellg/assets/guy2.png delete mode 100644 2026/games_submissions/ellg/assets/guy3.png delete mode 100644 2026/games_submissions/ellg/assets/guy4.png delete mode 100644 2026/games_submissions/ellg/assets/hungry.png delete mode 100644 2026/games_submissions/ellg/assets/lose.png delete mode 100644 2026/games_submissions/ellg/assets/pot.png delete mode 100644 2026/games_submissions/ellg/assets/song.mp3 delete mode 100644 2026/games_submissions/ellg/assets/table.png delete mode 100644 2026/games_submissions/ellg/assets/win.png delete mode 100644 2026/games_submissions/ellg/game.js delete mode 100644 2026/games_submissions/ellg/index.html delete mode 100644 2026/games_submissions/ellg/vector.js (limited to '2026/games_submissions/ellg') diff --git a/2026/games_submissions/ellg/assets/beef1.png b/2026/games_submissions/ellg/assets/beef1.png deleted file mode 100644 index 0dbc9d9..0000000 Binary files a/2026/games_submissions/ellg/assets/beef1.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/beef2.png b/2026/games_submissions/ellg/assets/beef2.png deleted file mode 100644 index d2bd0c0..0000000 Binary files a/2026/games_submissions/ellg/assets/beef2.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/chefhat.png b/2026/games_submissions/ellg/assets/chefhat.png deleted file mode 100644 index 951cac4..0000000 Binary files a/2026/games_submissions/ellg/assets/chefhat.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/guy1.png b/2026/games_submissions/ellg/assets/guy1.png deleted file mode 100644 index 7b9b503..0000000 Binary files a/2026/games_submissions/ellg/assets/guy1.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/guy2.png b/2026/games_submissions/ellg/assets/guy2.png deleted file mode 100644 index fdecfe7..0000000 Binary files a/2026/games_submissions/ellg/assets/guy2.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/guy3.png b/2026/games_submissions/ellg/assets/guy3.png deleted file mode 100644 index f9a8ad2..0000000 Binary files a/2026/games_submissions/ellg/assets/guy3.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/guy4.png b/2026/games_submissions/ellg/assets/guy4.png deleted file mode 100644 index a3074a5..0000000 Binary files a/2026/games_submissions/ellg/assets/guy4.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/hungry.png b/2026/games_submissions/ellg/assets/hungry.png deleted file mode 100644 index 1acc9dc..0000000 Binary files a/2026/games_submissions/ellg/assets/hungry.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/lose.png b/2026/games_submissions/ellg/assets/lose.png deleted file mode 100644 index 7a1b38c..0000000 Binary files a/2026/games_submissions/ellg/assets/lose.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/pot.png b/2026/games_submissions/ellg/assets/pot.png deleted file mode 100644 index 75e0ad9..0000000 Binary files a/2026/games_submissions/ellg/assets/pot.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/song.mp3 b/2026/games_submissions/ellg/assets/song.mp3 deleted file mode 100644 index 1437c97..0000000 Binary files a/2026/games_submissions/ellg/assets/song.mp3 and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/table.png b/2026/games_submissions/ellg/assets/table.png deleted file mode 100644 index 9ec1aab..0000000 Binary files a/2026/games_submissions/ellg/assets/table.png and /dev/null differ diff --git a/2026/games_submissions/ellg/assets/win.png b/2026/games_submissions/ellg/assets/win.png deleted file mode 100644 index f47a046..0000000 Binary files a/2026/games_submissions/ellg/assets/win.png and /dev/null differ diff --git a/2026/games_submissions/ellg/game.js b/2026/games_submissions/ellg/game.js deleted file mode 100644 index a82d24b..0000000 --- a/2026/games_submissions/ellg/game.js +++ /dev/null @@ -1,378 +0,0 @@ -import { Vector } from "./vector.js"; - -const WIDTH = 240; -const HEIGHT = 160; -const STANDALONE = window.self === window.top; -const DIFFICULTY = 4; - -const canvas = document.getElementById("game"); - -const ctx = canvas.getContext("2d"); -ctx.imageSmoothingEnabled = false; - -function notifyHarness(msg) { - if (!STANDALONE) window.parent.postMessage(msg); -} - -const music = new Audio("./assets/song.mp3"); -music.loop = true; -music.volume = 0.5; - -function playMusic() { - music.currentTime = 0; - music.play().catch(() => { }); -} - -function stopMusic() { - music.pause(); -} - -export async function loadImage(url) { - return new Promise((resolve, reject) => { - const img = new Image(); - img.onload = () => resolve(img); - img.onerror = reject; - img.src = url; - }); -}; - -export async function loadAssets() { - const [guy1, guy2, guy3, guy4, pot, table, beef1, beef2, hat, win, lose, hungry] = await Promise.all([ - loadImage("./assets/guy1.png"), - loadImage("./assets/guy2.png"), - loadImage("./assets/guy3.png"), - loadImage("./assets/guy4.png"), - loadImage("./assets/pot.png"), - loadImage("./assets/table.png"), - loadImage("./assets/beef1.png"), - loadImage("./assets/beef2.png"), - loadImage("./assets/chefhat.png"), - loadImage("./assets/win.png"), - loadImage("./assets/lose.png"), - loadImage("./assets/hungry.png"), - ]); - - return { - guy1, - guy2, - guy3, - guy4, - pot, - table, - beef1, - beef2, - hat, - win, - lose, - hungry - }; -}; - -let lastTime = 0; -let assets = {}; -let state = { - scene: null, -}; - -class Scene { - constructor() { } - - draw(dt) { } - update(dt) { } - handleInput(dt) { } - onClick(p) { } -} - -const END_SCREEN_TIME = 3; - -class EndScreen extends Scene { - constructor(win) { - super(); - - stopMusic(); - - this.win = win; - this.t = 0; - this.sent = false; - } - - update(dt) { - this.t += dt; - - if (!this.sent && this.t >= END_SCREEN_TIME) { - this.sent = true; - notifyHarness({ op: "done", win: this.win }); - } - } -} - -class WinScreen extends EndScreen { - constructor() { super(true) } - - draw() { - ctx.drawImage(assets.win, 0, 0); - } -} - -class GameOverScreen extends EndScreen { - constructor(endType = "death") { - super(false); - this.endType = endType; - } - - draw() { - ctx.drawImage(this.endType === "death" ? assets.lose : assets.hungry, 0, 0); - ctx.drawImage(assets.guy4, 50, 75); - } -} - -const POT = { x: 25, y: 90, size: 64 }; -const POT_CENTER = Vector.of([POT.x + POT.size / 2, POT.y + POT.size / 2]); -const COLLECT_TIME = 0.4; - -const BOUNDS = { x: 8, y: 8, w: 125, h: 96 }; - -class Icon { - constructor(img, pos, correct) { - this.img = img; - this.pos = pos; - this.size = 32; - this.correct = correct; - this.vel = new Vector(0, 0); - this.collect = null; - this.dead = false; - } - - static spawn(img, correct, speed) { - const icon = new Icon(img, Vector.of([0, 0]), correct); - icon.pos = Vector.of([ - BOUNDS.x + Math.random() * (BOUNDS.w - icon.size), - BOUNDS.y + Math.random() * (BOUNDS.h - icon.size), - ]); - const a = Math.random() * Math.PI * 2; - icon.vel = new Vector(Math.cos(a), Math.sin(a)).multiply(speed); - return icon; - } - - center() { return this.pos.add(new Vector(this.size / 2, this.size / 2)); } - - contains(p) { - return p.x >= this.pos.x && p.x <= this.pos.x + this.size && - p.y >= this.pos.y && p.y <= this.pos.y + this.size; - } - - startCollect() { - if (this.collect) return; - this.collect = { t: 0, fromCenter: this.center() }; - } - - update(dt) { - if (this.collect) { - this.collect.t += dt; - const k = Math.min(1, this.collect.t / COLLECT_TIME); - const e = k * k; - this._drawCenter = this.collect.fromCenter.add( - POT_CENTER.subtract(this.collect.fromCenter).multiply(e)); - this._scale = 1 - k; - if (k >= 1) this.dead = true; - return; - } - - this.pos = this.pos.add(this.vel.multiply(dt)); - const maxX = BOUNDS.x + BOUNDS.w - this.size; - const maxY = BOUNDS.y + BOUNDS.h - this.size; - if (this.pos.x < BOUNDS.x) { this.pos.x = BOUNDS.x; this.vel.x *= -1; } - if (this.pos.x > maxX) { this.pos.x = maxX; this.vel.x *= -1; } - if (this.pos.y < BOUNDS.y) { this.pos.y = BOUNDS.y; this.vel.y *= -1; } - if (this.pos.y > maxY) { this.pos.y = maxY; this.vel.y *= -1; } - } - - draw(ctx) { - const c = this._drawCenter ?? this.center(); - const s = this.size * (this._scale ?? 1); - ctx.drawImage( - this.img, - Math.round(c.x - s / 2), Math.round(c.y - s / 2), - Math.round(s), Math.round(s), - ); - } -} - -function difficultyConfig(raw) { - const K = 5; - const d = raw / (raw + K); - const lerp = (a, b) => a + (b - a) * d; - return { - correct: Math.round(lerp(3, 5)), - decoys: Math.round(lerp(3, 10)), - speed: lerp(20, 90), - timeLimit: lerp(8, 4), - }; -} - -function spawnIcons(cfg) { - const icons = []; - for (let i = 0; i < cfg.correct; i++) icons.push(Icon.spawn(assets.beef1, true, cfg.speed)); - for (let i = 0; i < cfg.decoys; i++) icons.push(Icon.spawn(assets.beef2, false, cfg.speed)); - return icons; -} - -class GameScreen extends Scene { - constructor(cfg) { - super(); - this.cfg = cfg; - this.timeTotal = cfg.timeLimit; - this.timeLeft = cfg.timeLimit; - this.state = { - guy: { - img: assets.guy2, - pos: Vector.of([125, 50]), - reactImg: null, - reactT: 0, - }, - icons: spawnIcons(cfg), - }; - } - - draw() { - const guy = this.state.guy; - - ctx.drawImage(guy.reactImg ?? guy.img, guy.pos.x, guy.pos.y); - ctx.drawImage(assets.hat, guy.pos.x + 45, guy.pos.y - 25, 50, 50); - ctx.drawImage(assets.table, 0, 50); - - for (const icon of this.state.icons) icon.draw(ctx); - - ctx.drawImage(assets.pot, POT.x, POT.y, POT.size, POT.size); - - const frac = this.timeLeft / this.timeTotal; - ctx.fillStyle = "#3a2a1a"; - ctx.fillRect(0, 0, WIDTH, 6); - ctx.fillStyle = frac < 0.25 ? "#e44" : "#f2c14e"; - ctx.fillRect(0, 0, Math.round(WIDTH * frac), 6); - } - - update(dt, ct) { - if (this.state.guy.reactT > 0) { - this.state.guy.reactT -= dt; - if (this.state.guy.reactT <= 0) this.state.guy.reactImg = null; - } - - this.timeLeft -= dt; - if (this.timeLeft <= 0) { - this.timeLeft = 0; - this.lose("hungry"); - return; - } - - const baseY = 50; - const amp = 4; - const speed = 0.01; - this.state.guy.pos.y = baseY + Math.round(Math.sin(ct * speed) * amp); - - for (const icon of this.state.icons) icon.update(dt); - this.state.icons = this.state.icons.filter(i => !i.dead); - } - - lose(endType = "death") { - state.scene = new GameOverScreen(endType); - } - - win() { - state.scene = new WinScreen(); - } - - onClick(p) { - for (let i = this.state.icons.length - 1; i >= 0; i--) { - const icon = this.state.icons[i]; - if (icon.collect) continue; - if (icon.contains(p)) { - if (!icon.correct) { this.lose() } - - icon.startCollect(); - - const correctLeft = this.state.icons.filter(x => x.correct && !x.collect).length; - if (correctLeft === 0) this.win() - - if (icon.correct) { - this.state.guy.reactImg = assets.guy3; - this.state.guy.reactT = 2; - }; - - return; - } - } - } -} - -async function init() { - assets = await loadAssets(); - notifyHarness({ op: "ready" }); -} - -function update(dt, ct) { - if (state.scene) { - state.scene.update(dt, Math.floor(ct)); - } -} - -function draw(dt) { - ctx.fillStyle = "#222"; - ctx.fillRect(0, 0, WIDTH, HEIGHT); - - if (state.scene) { - state.scene.draw(dt); - } -} - -function handleInput(dt) { - if (state.scene) { - state.scene.handleInput(dt); - } -} - -function main(currentTime) { - if (!lastTime) lastTime = currentTime; - const dt = Math.min((currentTime - lastTime) / 1000, 0.1); - - lastTime = currentTime; - - handleInput(dt); - update(dt, currentTime); - draw(dt); - - requestAnimationFrame(main); -} - -function startGame(difficulty = DIFFICULTY) { - state.scene = new GameScreen(difficultyConfig(difficulty)); - notifyHarness({ op: "started", verb: "make some chili!" }); - playMusic(); -} - -canvas.addEventListener("click", (ev) => { - if (music.paused && state.scene instanceof GameScreen) music.play().catch(() => { }); - - const r = canvas.getBoundingClientRect(); - const p = Vector.of([ - (ev.clientX - r.left) / r.width * WIDTH, - (ev.clientY - r.top) / r.height * HEIGHT, - ]); - state.scene?.onClick(p); -}); - -window.addEventListener("message", ev => { - switch (ev.data.op) { - case "start": - startGame(ev.data.difficulty ?? 0); - break; - default: console.log(`unknown event: ${ev}`); break; - } -}); - -await init(); - -requestAnimationFrame(main); - -if (STANDALONE) startGame(); - diff --git a/2026/games_submissions/ellg/index.html b/2026/games_submissions/ellg/index.html deleted file mode 100644 index a845dea..0000000 --- a/2026/games_submissions/ellg/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - watch the pot - - - - - - - diff --git a/2026/games_submissions/ellg/vector.js b/2026/games_submissions/ellg/vector.js deleted file mode 100644 index cf32d81..0000000 --- a/2026/games_submissions/ellg/vector.js +++ /dev/null @@ -1,64 +0,0 @@ -export class Vector { - static of([x, y]) { - return new Vector(x, y) - } - - constructor(x, y) { - this.x = x - this.y = y - } - - add(val) { - return new Vector(this.x + val.x, this.y + val.y) - } - - subtract(val) { - return new Vector(this.x - val.x, this.y - val.y) - } - - multiply(scalar) { - return new Vector(this.x * scalar, this.y * scalar) - } - - divide(scalar) { - return new Vector(this.x / scalar, this.y / scalar) - } - - dot(other) { - return this.x * other.x + this.y * other.y - } - - cross(other) { - return this.x * other.y - other.x * this.y - } - - hadamard(other) { - return new Vector(this.x * other.x, this.y * other.y) - } - - length() { - return Math.sqrt(this.x ** 2 + this.y ** 2) - } - - distance(other) { - return this.subtract(other).length() - } - - normalize() { - const length = this.length() - if (length === 0) { - return new Vector(0, 0) - } - return new Vector(this.x / length, this.y / length) - } - - rotateByRadians(radians) { - const cos = Math.cos(radians) - const sin = Math.sin(radians) - return new Vector(this.x * cos - this.y * sin, this.x * sin + this.y * cos) - } - - rotateByDegrees(degrees) { - return this.rotateByRadians((degrees * Math.PI) / 180) - } -} -- cgit v1.3.1