← Canyon Run results

Canyon Run

Gemma 4 12b · typescript

Initial view of Canyon Run

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>