Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
385 changes: 385 additions & 0 deletions games/uncharted-galaxies.js
Original file line number Diff line number Diff line change
@@ -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();
Loading