about summary refs log tree commit diff stats
path: root/html/space/renderer.js
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-04-09 21:14:39 -0400
committerelioat <elioat@tilde.institute>2025-04-09 21:14:39 -0400
commite83bd303e3186fd7823b39678feed753c20736d1 (patch)
treecb6b9ce885d6d17435a6c94b2a2454a30ef52c89 /html/space/renderer.js
parente0e75864e0d9981236bd50e2febdd0edd95019ea (diff)
downloadtour-e83bd303e3186fd7823b39678feed753c20736d1.tar.gz
*
Diffstat (limited to 'html/space/renderer.js')
-rw-r--r--html/space/renderer.js171
1 files changed, 171 insertions, 0 deletions
diff --git a/html/space/renderer.js b/html/space/renderer.js
new file mode 100644
index 0000000..3df55a7
--- /dev/null
+++ b/html/space/renderer.js
@@ -0,0 +1,171 @@
+// Renderer module using HTML5 Canvas
+import { getPlayerState } from './physics.js';
+import { getGameState } from './gameState.js';
+
+let canvas;
+let ctx;
+let width;
+let height;
+
+// Star field
+const stars = [];
+const NUM_STARS = 2000;  // Increased from 1000
+const STAR_FIELD_DEPTH = 20000;  // Increased from 2000
+
+// Initialize the renderer
+export function initRenderer() {
+    canvas = document.createElement('canvas');
+    document.body.appendChild(canvas);
+    ctx = canvas.getContext('2d');
+    
+    // Make canvas fullscreen
+    function resize() {
+        width = window.innerWidth;
+        height = window.innerHeight;
+        canvas.width = width;
+        canvas.height = height;
+    }
+    
+    window.addEventListener('resize', resize);
+    resize();
+    
+    // Initialize star field
+    for (let i = 0; i < NUM_STARS; i++) {
+        stars.push({
+            x: (Math.random() - 0.5) * width * 4,  // Increased spread
+            y: (Math.random() - 0.5) * height * 4, // Increased spread
+            z: Math.random() * STAR_FIELD_DEPTH,
+            size: Math.random() * 2
+        });
+    }
+}
+
+// Project 3D point to 2D screen coordinates
+function projectPoint(point, player) {
+    // Calculate relative position to player
+    const relativeX = point.x - player.position.x;
+    const relativeY = point.y - player.position.y;
+    const relativeZ = point.z - player.position.z;
+
+    // Apply player rotation
+    const cosY = Math.cos(player.rotation.y);
+    const sinY = Math.sin(player.rotation.y);
+    const cosX = Math.cos(player.rotation.x);
+    const sinX = Math.sin(player.rotation.x);
+
+    // Rotate around Y axis (yaw)
+    let rotatedX = relativeX * cosY - relativeZ * sinY;
+    let rotatedZ = relativeX * sinY + relativeZ * cosY;
+
+    // Rotate around X axis (pitch)
+    let rotatedY = relativeY * cosX - rotatedZ * sinX;
+    rotatedZ = relativeY * sinX + rotatedZ * cosX;
+
+    // Project to screen
+    if (rotatedZ <= 0) return null; // Behind camera
+
+    const scale = 1000 / rotatedZ;
+    return {
+        x: width/2 + rotatedX * scale,
+        y: height/2 + rotatedY * scale,
+        scale
+    };
+}
+
+// Main render function
+export function render() {
+    const player = getPlayerState();
+    const gameState = getGameState();
+
+    // Clear canvas
+    ctx.fillStyle = 'black';
+    ctx.fillRect(0, 0, width, height);
+    
+    // Draw star field
+    ctx.fillStyle = 'white';
+    stars.forEach(star => {
+        // Calculate star position relative to player
+        const relativeX = star.x - player.position.x;
+        const relativeY = star.y - player.position.y;
+        const relativeZ = star.z - player.position.z;
+
+        // Apply player rotation
+        const cosY = Math.cos(player.rotation.y);
+        const sinY = Math.sin(player.rotation.y);
+        const cosX = Math.cos(player.rotation.x);
+        const sinX = Math.sin(player.rotation.x);
+
+        // Rotate around Y axis (yaw)
+        let rotatedX = relativeX * cosY - relativeZ * sinY;
+        let rotatedZ = relativeX * sinY + relativeZ * cosY;
+
+        // Rotate around X axis (pitch)
+        let rotatedY = relativeY * cosX - rotatedZ * sinX;
+        rotatedZ = relativeY * sinX + rotatedZ * cosX;
+
+        // Project to screen
+        if (rotatedZ <= 0) return; // Behind camera
+
+        const scale = STAR_FIELD_DEPTH / rotatedZ;
+        const x = width/2 + rotatedX * scale;
+        const y = height/2 + rotatedY * scale;
+        const size = star.size * scale;
+        
+        if (x >= 0 && x <= width && y >= 0 && y <= height) {
+            ctx.beginPath();
+            ctx.arc(x, y, size, 0, Math.PI * 2);
+            ctx.fill();
+        }
+    });
+
+    // Draw planets
+    gameState.planets.forEach(planet => {
+        const projected = projectPoint(planet.position, player);
+        if (projected) {
+            const radius = planet.radius * projected.scale;
+            ctx.fillStyle = planet.color;
+            ctx.beginPath();
+            ctx.arc(projected.x, projected.y, radius, 0, Math.PI * 2);
+            ctx.fill();
+        }
+    });
+
+    // Draw enemy ships
+    gameState.enemyShips.forEach(ship => {
+        const projected = projectPoint(ship.position, player);
+        if (projected) {
+            const size = 10 * projected.scale;
+            ctx.fillStyle = '#ff0000';
+            ctx.beginPath();
+            ctx.moveTo(projected.x, projected.y - size);
+            ctx.lineTo(projected.x + size, projected.y + size);
+            ctx.lineTo(projected.x - size, projected.y + size);
+            ctx.closePath();
+            ctx.fill();
+        }
+    });
+
+    // Draw projectiles
+    gameState.projectiles.forEach(projectile => {
+        const projected = projectPoint(projectile.position, player);
+        if (projected) {
+            const size = 3 * projected.scale;
+            ctx.fillStyle = projectile.type === 'primary' ? '#ffff00' : '#00ffff';
+            ctx.beginPath();
+            ctx.arc(projected.x, projected.y, size, 0, Math.PI * 2);
+            ctx.fill();
+        }
+    });
+
+    // Draw cockpit overlay
+    ctx.strokeStyle = '#ffffff';
+    ctx.lineWidth = 2;
+    
+    // Center crosshair
+    ctx.beginPath();
+    ctx.moveTo(width/2 - 10, height/2);
+    ctx.lineTo(width/2 + 10, height/2);
+    ctx.moveTo(width/2, height/2 - 10);
+    ctx.lineTo(width/2, height/2 + 10);
+    ctx.stroke();
+} 
\ No newline at end of file