Canyon Run
Gemma 4 12b · typescript

Reviews & generation details
Reviews
No human review yet. Unreviewed does not mean unsuccessful.
Generation context
Imported historical artifact. Its exact original instructions and lineage are not known.
Generation prompt · exact text unavailable
See the current prompt for reference. It may differ from the instructions used to generate this artifact.
Inspect original source 16,119 bytes · SHA-256 9335dc0e95fe
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Canyon Racer</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
/* ── css: layout ── */
body {
margin: 0;
background-color: #0a0514;
overflow: hidden;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
#game-canvas {
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
#ui-container {
position: absolute;
width: 100%;
height: 100vh;
padding: 2rem;
box-sizing: border-box;
pointer-events: none;
color: #f8f4ff;
}
#hud {
display: flex;
flex-direction: column;
gap: 1.5rem;
width: fit-content;
}
.stat {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.25rem;
}
#speed-label, #score-label, #energy-label {
font-size: 0.8rem;
letter-spacing: 0.1em;
opacity: 0.7;
}
.bar {
width: 200px;
height: 4px;
background: rgba(255, 255, 255, 0.2);
position: relative;
}
#speed-bar {
position: absolute;
left: 0;
top: 0;
height: 100%;
background: #ffcc33;
transition: width 0.1s linear;
}
#energy-bar {
width: 200px;
height: 8px;
background: #7a4fff;
border-radius: 4px;
box-shadow: 0 0 15px rgba(122, 79, 255, 0.6);
}
#score-value {
font-size: 3rem;
font-weight: bold;
font-variant-numeric: tabular-nums;
}
#overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
background: rgba(10, 5, 20, 0.8);
padding: 4rem;
border: 1px solid #7a4fff;
pointer-events: auto;
}
#title {
font-size: 5rem;
margin: 0;
letter-spacing: 0.5em;
color: #ffcc33;
}
#subtitle {
opacity: 0.6;
margin-bottom: 2rem;
}
button {
background: transparent;
border: 1px solid #ffcc33;
color: #ffcc33;
padding: 1rem 2rem;
font-size: 1.5rem;
cursor: pointer;
transition: all 0.2s;
}
button:hover {
background: #ffcc33;
color: #0a0514;
}
#game-over h2 {
font-size: 3rem;
margin-bottom: 2rem;
}
</style>
</head>
<body>
<div id="ui-container">
<div id="hud">
<div class="stat"><span id="speed-label">SPEED</span><div id="speed-bar" class="bar"></div></div>
<div class="stat"><span id="score-label">SCORE</span><div id="score-value">0.0x</div></div>
<div class="stat"><span id="energy-label">ENERGY</span><div id="energy-bar" class="bar-fill"></div></div>
</div>
<div id="overlay">
<h1 id="title">CANYON RACER</h1>
<p id="subtitle">Use Arrow Keys / WASD to Fly</p>
<button id="start-btn">START MISSION</button>
<div id="game-over" style="display:none;">
<h2 id="final-score">SCORE: 0</h2>
<button id="restart-btn">RETRY</button>
</div>
</div>
</div>
<canvas id="game-canvas"></canvas>
<script>
(function () {
'use strict';
var __mods = {};
var __cache = {};
var __map = {"src/main.ts":{"./state":"src/state.ts","./player":"src/player.ts","./world":"src/world.ts","./input":"src/input.ts"},"src/input.ts":{"./state":"src/state.ts"},"src/player.ts":{"./state":"src/state.ts"},"src/world.ts":{"./state":"src/state.ts","./player":"src/player.ts"}};
function __require(id) {
if (__cache[id]) return __cache[id].exports;
var module = __cache[id] = { exports: {} };
var factory = __mods[id];
if (!factory) throw new Error("Module not found: " + id);
factory(module.exports, function (spec) {
var target = (__map[id] && __map[id][spec]) || spec;
return __require(target);
}, module);
return module.exports;
}
// ── module: src/main.ts ──
__mods["src/main.ts"] = function (exports, require, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GameEngine = void 0;
// Use global THREE variable declared in globals.d.ts
const state_1 = require("./state");
const player_1 = require("./player");
const world_1 = require("./world");
const input_1 = require("./input");
class GameEngine {
constructor(canvas) {
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0x1a0b2e, 0x1a0b2e, 0x1a0b2e);
this.scene.fog = new THREE.Fog(0x1a0b2e, 10, 150);
this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
this.renderer = new THREE.WebGLRenderer({ canvas: canvas, antialias: true, powerPreference: 'high-performance' });
this.renderer.setSize(window.innerWidth, window.innerHeight);
this.renderer.setPixelRatio(window.devicePixelRatio);
const ambient = new THREE.AmbientLight(0x404040, 2);
this.scene.add(ambient);
const sun = new THREE.PointLight(0xffcc33, 5, 200);
sun.position.set(0, 50, -100);
this.scene.add(sun);
this.state = new state_1.GameState();
this.input = new input_1.InputHandler();
this.player = new player_1.Player(this.scene);
this.world = new world_1.WorldManager(this.scene);
this.world.createInitialChunks();
window.addEventListener('resize', () => {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();
this.renderer.setSize(window.innerWidth, window.innerHeight);
});
}
start() {
this.state.reset();
const overlay = document.getElementById('overlay');
if (overlay)
overlay.style.display = 'none';
this.animate();
}
animate() {
if (this.state.isGameOver) {
this.showGameOver();
return;
}
const dt = 0.016;
this.player.update(this.input, dt);
this.world.update(this.player.mesh.position.z);
// Collision & Collection
const collidables = this.world.getCollidables();
const playerBounds = this.player.getBounds();
let nearMissDetected = false;
collidables.forEach((obj) => {
if (obj.isCollectible && obj.position.distanceTo(this.player.mesh.position) < 3) {
this.state.energy = Math.min(100, this.state.energy + 20);
this.scene.remove(obj);
}
else if (obj.geometry && obj !== this.player.mesh) {
const bounds = new THREE.Box3().setFromObject(obj);
if (playerBounds.intersectsBox(bounds)) {
this.state.isGameOver = true;
}
else {
const dist = this.player.mesh.position.distanceTo(obj.position);
if (dist < 8) {
nearMissDetected = true;
}
}
}
});
if (nearMissDetected) {
this.state.multiplier += 0.1;
}
else {
this.state.multiplier = Math.max(1, this.state.multiplier - 0.01);
}
this.state.update(dt, this.player.velocity.z * -1);
// Camera follow
const targetCamPos = new THREE.Vector3(this.player.mesh.position.x, this.player.mesh.position.y + 2, this.player.mesh.position.z + 8);
this.camera.position.lerp(targetCamPos, 0.1);
this.camera.lookAt(this.player.mesh.position);
// Update HUD
this.updateHUD();
this.renderer.render(this.scene, this.camera);
requestAnimationFrame(() => this.animate());
}
updateHUD() {
const speedBar = document.getElementById('speed-bar');
if (speedBar)
speedBar.style.width = `${(this.state.speed / this.state.maxSpeed) * 100}%`;
const scoreVal = document.getElementById('score-value');
if (scoreVal)
scoreVal.innerText = `${this.state.score.toFixed(1)}x`;
const energyBar = document.getElementById('energy-bar');
if (energyBar) {
energyBar.style.width = `${this.state.energy}%`;
if (this.state.energy < 30)
energyBar.style.backgroundColor = '#ff4444';
else
energyBar.style.backgroundColor = '#7a4fff';
}
}
showGameOver() {
const overlay = document.getElementById('overlay');
if (overlay)
overlay.style.display = 'block';
const gameover = document.getElementById('game-over');
if (gameover)
gameover.style.display = 'block';
const finalScore = document.getElementById('final-score');
if (finalScore)
finalScore.innerText = `FINAL SCORE: ${this.state.score.toFixed(0)}`;
}
handleStart() {
this.start();
}
}
exports.GameEngine = GameEngine;
// Initialization logic
const canvas = document.getElementById('game-canvas');
const engine = new GameEngine(canvas);
document.getElementById('start-btn')?.addEventListener('click', () => {
engine.handleStart();
});
};
// ── types: globals.d.ts ──
__mods["globals.d.ts"] = function (exports) {};
// ── module: src/state.ts ──
__mods["src/state.ts"] = function (exports, require, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GameState = void 0;
class GameState {
constructor() {
this.score = 0;
this.multiplier = 1;
this.energy = 100;
this.speed = 0;
this.maxSpeed = 2.5;
this.isGameOver = false;
this.startTime = 0;
}
reset() {
this.score = 0;
this.multiplier = 1;
this.energy = 100;
this.speed = 0;
this.isGameOver = false;
this.startTime = Date.now();
}
update(dt, currentSpeed) {
if (this.isGameOver)
return;
this.speed = currentSpeed;
this.energy -= 2 * dt; // Decay
if (this.energy <= 0)
this.isGameOver = true;
const distance = this.speed * dt;
this.score += distance * this.multiplier;
}
}
exports.GameState = GameState;
};
// ── module: src/input.ts ──
__mods["src/input.ts"] = function (exports, require, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InputHandler = void 0;
class InputHandler {
constructor() {
this.keys = {};
window.addEventListener('keydown', (e) => this.keys[e.code] = true);
window.addEventListener('keyup', (e) => this.keys[e.code] = false);
}
isPressed(code) {
return !!this.keys[code];
}
}
exports.InputHandler = InputHandler;
};
// ── module: src/player.ts ──
__mods["src/player.ts"] = function (exports, require, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Player = void 0;
class Player {
constructor(scene) {
this.velocity = new THREE.Vector3(0, 0, -1);
this.rotationSpeed = 2.0;
this.acceleration = 5.0;
this.turnSpeed = 2.5;
const geometry = new THREE.ConeGeometry(0.4, 1.6, 8);
const material = new THREE.MeshStandardMaterial({
color: 0xffcc33,
metalness: 0.9,
roughness: 0.1
});
this.mesh = new THREE.Mesh(geometry, material);
this.mesh.rotation.x = Math.PI / 2;
scene.add(this.mesh);
}
update(input, dt) {
const thrust = input.isPressed('ArrowUp') || input.isPressed('KeyW') ? 1 : 0.8; // Constant forward force
const pitch = input.isPressed('ArrowDown') || input.isPressed('KeyS') ? -1 : 0;
let roll = 0;
if (input.isPressed('ArrowLeft') || input.isPressed('KeyA')) {
this.mesh.rotation.z += this.turnSpeed * dt;
roll = 1;
}
else if (input.isPressed('ArrowRight') || input.isPressed('KeyD')) {
this.mesh.rotation.z -= this.turnSpeed * dt;
roll = -1;
}
// Pitch rotation based on thrust
if (thrust > 0) {
this.mesh.rotation.x -= pitch * this.turnSpeed * dt;
}
const direction = new THREE.Vector3(0, 0, -1);
direction.applyEuler(this.mesh.rotation);
// Velocity calculation
const targetVel = direction.multiplyScalar(thrust * 15);
this.velocity.lerp(targetVel, dt * this.acceleration);
this.mesh.position.add(this.velocity.clone().multiplyScalar(dt));
// Smoothly interpolate roll back to zero if not turning
const targetRoll = roll * 0.5;
this.mesh.rotation.z = THREE.MathUtils.lerp(this.mesh.rotation.z, targetRoll, dt * 2);
}
getBounds() {
return new THREE.Box3().setFromObject(this.mesh);
}
}
exports.Player = Player;
};
// ── module: src/world.ts ──
__mods["src/world.ts"] = function (exports, require, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorldManager = void 0;
class WorldManager {
constructor(scene) {
this.scene = scene;
this.chunks = [];
this.activeChunkIndex = 0;
this.chunkCount = 5;
this.chunkSize = 120;
}
createInitialChunks() {
for (let i = 0; i < this.chunkCount; i++) {
this.spawnChunk(i * this.chunkSize);
}
}
spawnChunk(zOffset) {
const group = new THREE.Group();
group.position.z = zOffset;
// Create a more complex "Canyon" shape using 8 segments instead of 4
const segments = 8;
for (let i = 0; i < segments; i++) {
const angle = (i / segments) * Math.PI * 2;
const radius = 35 + Math.random() * 15;
const height = 40 + Math.random() * 40;
const width = 60 + Math.random() * 80;
const wallGeo = new THREE.BoxGeometry(width, height, 2);
const wallMat = new THREE.MeshStandardMaterial({
color: i % 2 === 0 ? 0x1e132d : 0x2a1a3d,
flatShading: true
});
const wall = new THREE.Mesh(wallGeo, wallMat);
// Position walls in a jagged circle to create a "craggy" canyon feel
const x = Math.cos(angle) * radius;
const y = (Math.random() * 10) - 5;
wall.position.set(x, height / 2 + y, 0);
// Rotate walls to face inward/outward slightly
wall.rotation.y = -angle + Math.PI / 2;
group.add(wall);
}
// Add floating monoliths (large obstacles)
for (let i = 0; i < 4; i++) {
const obsGeo = new THREE.BoxGeometry(8, 15, 8);
const obsMat = new THREE.MeshStandardMaterial({ color: 0x4a3a6d });
const obs = new THREE.Mesh(obsGeo, obsMat);
obs.position.set((Math.random() - 0.5) * 100, Math.random() * 25, (Math.random() - 0.5) * 60);
group.add(obs);
}
// Add high-energy orbs
for (let i = 0; i < 4; i++) {
const orbGeo = new THREE.SphereGeometry(1.8, 8, 8);
const orbMat = new THREE.MeshBasicMaterial({ color: 0x00ffcc });
const orb = new THREE.Mesh(orbGeo, orbMat);
orb.position.set((Math.random() - 0.5) * 120, Math.random() * 30, (Math.random() - 0.5) * 80);
orb.isCollectible = true;
group.add(orb);
}
this.scene.add(group);
this.chunks.push(group);
}
update(playerZ) {
if (playerZ < -100 && this.activeChunkIndex > 0) {
const oldChunk = this.chunks.shift();
if (oldChunk)
this.scene.remove(oldChunk);
this.activeChunkIndex--;
}
if (playerZ > -40 && this.activeChunkIndex < this.chunkCount - 1) {
const nextZ = (this.activeChunkIndex + 1) * this.chunkSize;
this.spawnChunk(nextZ);
this.activeChunkIndex++;
}
}
getCollidables() {
return this.chunks.flatMap(c => Array.from(c.children));
}
}
exports.WorldManager = WorldManager;
};
// ── entry ──
__require("src/main.ts");
})();
</script>
</body>
</html>