From 37678470b277498f4de8f56a3c4e22ed984fe2d0 Mon Sep 17 00:00:00 2001 From: Atharva Pandey <93546392+Finite-Code@users.noreply.github.com> Date: Wed, 29 Jul 2026 03:31:57 +0530 Subject: [PATCH] Sprig App - uncharted-galaxies --- games/uncharted-galaxies.js | 385 ++++++++++++++++++++++++++++++++++++ 1 file changed, 385 insertions(+) create mode 100644 games/uncharted-galaxies.js diff --git a/games/uncharted-galaxies.js b/games/uncharted-galaxies.js new file mode 100644 index 0000000000..8205289e3c --- /dev/null +++ b/games/uncharted-galaxies.js @@ -0,0 +1,385 @@ +// 1. Asset Definitions and Legend +setLegend( + [ "p", bitmap` +................ +.......5........ +......555....... +.....55555...... +....5555555..... +....55...55..... +....5.....5..... +....5.....5..... +................ +................ +................ +................ +................ +................ +................ +................` ], + [ "f", bitmap` +................ +.......5........ +......555....... +.....55555...... +....5555555..... +....55...55..... +....5.....5..... +....5.....5..... +.......9........ +......989....... +.......9........ +................ +................ +................ +................ +................` ], + [ "s", bitmap` +.......3........ +......353....... +.....35553...... +....3555553..... +...355555553.... +...355...553.... +...35.....53.... +...35.....53.... +....3.....3..... +.....33333...... +................ +................ +................ +................ +................ +................` ], + [ "e", bitmap` +................ +.......2........ +......222....... +.....22222...... +....2222222..... +....22...22..... +....2.....2..... +....2.....2..... +................ +................ +................ +................ +................ +................ +................ +................` ], + [ "o", bitmap` +................ +......1111...... +....11111111.... +...1111111111... +..111111111111.. +..111111111111.. +..111111111111.. +...1111111111... +....11111111.... +......1111...... +................ +................ +................ +................ +................ +................` ], + [ "F", bitmap` +.......33....... +.......3........ +......1111...... +....11111111.... +...1111111111... +..111111111111.. +..111111111111.. +..111111111111.. +...1111111111... +....11111111.... +......1111...... +................ +................ +................ +................ +................` ], + [ "^", bitmap` +................ +.......9........ +.......9........ +.......9........ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................` ], + [ "x", bitmap` +................ +.......3........ +.......3........ +.......3........ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................ +................` ], + [ "b", bitmap` +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000 +0000000000000000` ] +); + +// Render the black background +setBackground("b"); + +// 2. State Management +const AppState = { + current: "MENU", + simulationClock: null, + tick: 0, + health: 3, + checkpoints: 0 +}; + +const voidSpace = map` +............... +............... +............... +............... +............... +............... +............... +............... +............... +............... +............... +...............`; + +// 3. Interface Rendering +function renderMenuScreen() { + clearText(); + setMap(voidSpace); + addText("UNCHARTED", { x: 3, y: 3, color: color`6` }); + addText("GALAXIES", { x: 4, y: 5, color: color`3` }); + addText("Press 'i' to Launch", { x: 1, y: 10, color: color`5` }); +} + +function triggerGameOver() { + AppState.current = "GAME_OVER"; + setMap(voidSpace); + clearText(); + addText("GAME OVER", { x: 3, y: 4, color: color`3` }); + addText(`Flags: ${AppState.checkpoints}`, { x: 4, y: 6, color: color`6` }); + addText("Press 'i' to Menu", { x: 1, y: 10, color: color`5` }); +} + +// 4. Input Handling +onInput("i", () => { + if (AppState.current === "MENU") { + AppState.current = "PLAYING"; + AppState.health = 3; + AppState.checkpoints = 0; + clearText(); + startContinuousSimulation(); + } else if (AppState.current === "GAME_OVER") { + AppState.current = "MENU"; + renderMenuScreen(); + } +}); + +// Player Movement (Dodging) +onInput("w", () => { + const p = getFirst("p") || getFirst("f") || getFirst("s"); + if (AppState.current === "PLAYING" && p) p.y = Math.max(0, p.y - 1); +}); +onInput("s", () => { + const p = getFirst("p") || getFirst("f") || getFirst("s"); + if (AppState.current === "PLAYING" && p) p.y = Math.min(height() - 1, p.y + 1); +}); +onInput("a", () => { + const p = getFirst("p") || getFirst("f") || getFirst("s"); + if (AppState.current === "PLAYING" && p) p.x = Math.max(0, p.x - 1); +}); +onInput("d", () => { + const p = getFirst("p") || getFirst("f") || getFirst("s"); + if (AppState.current === "PLAYING" && p) p.x = Math.min(width() - 1, p.x + 1); +}); + +// Defensive Shield Activation +onInput("k", () => { + const player = getFirst("p") || getFirst("f"); + if (AppState.current === "PLAYING" && player) { + player.type = "s"; + setTimeout(() => { + const shieldedPlayer = getFirst("s"); + if (shieldedPlayer) shieldedPlayer.type = "p"; + }, 1500); + } +}); + +// Fire Preemptive Projectile +onInput("j", () => { + const ship = getFirst("p") || getFirst("f") || getFirst("s"); + if (AppState.current === "PLAYING" && ship) { + if (ship.y > 0) addSprite(ship.x, ship.y - 1, "^"); + } +}); + +// 5. Core Simulation Loop +function startContinuousSimulation() { + // Spawn the player at the bottom center + addSprite(7, 10, "p"); + + AppState.simulationClock = setInterval(() => { + if (AppState.current!== "PLAYING") { + clearInterval(AppState.simulationClock); + return; + } + + AppState.tick++; + const player = getFirst("p") || getFirst("f") || getFirst("s"); + + // Render Top UI + clearText(); + addText(`HP: ${AppState.health}`, { x: 0, y: 0, color: color`3` }); + addText(`Flags: ${AppState.checkpoints}`, { x: 7, y: 0, color: color`6` }); + + // Player Fire Animation Toggle + if (player && player.type!== "s") { + player.type = (AppState.tick % 2 === 0)? "f" : "p"; + } + + // Procedural Planet Generation (Starfield & Checkpoints) + if (Math.random() < 0.2) { + // Small chance for a checkpoint flag planet + const type = Math.random() < 0.15? "F" : "o"; + addSprite(Math.floor(Math.random() * width()), 0, type); + } + + // Spawn Enemies independently + if (Math.random() < 0.1 && getAll("e").length < 3) { + addSprite(Math.floor(Math.random() * width()), 0, "e"); + } + + // Environment Translation + const allPlanets = [...getAll("o"),...getAll("F")]; + allPlanets.forEach(planet => { + if (planet.y + 1 >= height()) { + planet.remove(); + } else { + planet.y += 1; + } + }); + + // Enemy AI and Targeting + getAll("e").forEach(enemy => { + if (enemy.y + 1 >= height()) { + enemy.remove(); + } else { + if (AppState.tick % 2 === 0) enemy.y += 1; + + if (Math.random() < 0.4) { + const dir = Math.random() < 0.5? 1 : -1; + if (enemy.x + dir >= 0 && enemy.x + dir < width()) { + enemy.x += dir; + } + } + + if (Math.random() < 0.15 && enemy.y + 1 < height()) { + addSprite(enemy.x, enemy.y + 1, "x"); + } + } + }); + + // Curving Projectiles (Homing) + getAll("x").forEach(enemyProj => { + if (enemyProj.y + 1 >= height()) { + enemyProj.remove(); + } else { + enemyProj.y += 1; + if (AppState.tick % 2 === 0 && player) { + if (enemyProj.x < player.x) enemyProj.x += 1; + else if (enemyProj.x > player.x) enemyProj.x -= 1; + } + } + }); + + // Player Projectile Upward Movement + getAll("^").forEach(playerProj => { + if (playerProj.y - 1 < 0) { + playerProj.remove(); + } else { + playerProj.y -= 1; + } + }); + + // Collision Detection Matrix + if (player) { + // Checkpoint Flag Gathering + getAll("F").forEach(flag => { + if (Math.abs(flag.x - player.x) <= 1 && Math.abs(flag.y - player.y) <= 1) { + flag.remove(); + AppState.checkpoints += 1; + AppState.health = Math.min(AppState.health + 1, 5); // Heal player slightly + } + }); + + // Threat evaluation + const threats = [...getAll("x"),...getAll("e")]; + for (let threat of threats) { + if (threat.x === player.x && Math.abs(threat.y - player.y) <= 1) { + threat.remove(); + if (player.type === "s") { + player.type = "p"; // Shield absorbs hit + } else { + AppState.health -= 1; + if (AppState.health <= 0) { + triggerGameOver(); + return; // Stop processing further physics this tick + } + } + } + } + } + + // Check if player lasers hit enemies + getAll("^").forEach(laser => { + getAll("e").forEach(enemy => { + if (laser.x === enemy.x && Math.abs(laser.y - enemy.y) <= 1) { + enemy.remove(); + laser.remove(); + } + }); + }); + + }, 250); +} + +// 6. Application Boot +renderMenuScreen(); \ No newline at end of file