feat: Migrate to Vite build system, update dependencies, and refine graphics setup with debugging aids.
This commit is contained in:
@@ -39,7 +39,7 @@ export class Game {
|
||||
loop(time) {
|
||||
requestAnimationFrame(this.loop.bind(this));
|
||||
|
||||
const dt = Math.min((time - this.lastTime) / 1000, 0.1); // Cap dt
|
||||
const dt = this.lastTime === 0 ? 0 : Math.min((time - this.lastTime) / 1000, 0.1); // Cap dt
|
||||
this.lastTime = time;
|
||||
|
||||
if (this.isRunning) {
|
||||
|
||||
@@ -4,23 +4,38 @@ export class Graphics {
|
||||
constructor() {
|
||||
// Main scene rendering
|
||||
this.scene = new THREE.Scene();
|
||||
this.scene.fog = new THREE.Fog(0x000000, 2, 15);
|
||||
this.scene.background = new THREE.Color(0x000000);
|
||||
this.scene.fog = new THREE.Fog(0x111122, 2, 15);
|
||||
this.scene.background = new THREE.Color(0x111122); // Dark blue background instead of black
|
||||
|
||||
this.camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 100);
|
||||
|
||||
// Real Screen Renderer
|
||||
this.renderer = new THREE.WebGLRenderer({ antialias: false });
|
||||
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
document.getElementById('game-container').appendChild(this.renderer.domElement);
|
||||
this.renderer.setClearColor(0xff00ff); // STRIKING MAGENTA for diagnostic
|
||||
this.renderer.domElement.style.border = '5px solid yellow'; // VISIBLE BORDER
|
||||
this.renderer.domElement.style.zIndex = '100'; // FORCE TO FRONT
|
||||
this.renderer.domElement.id = 'three-canvas';
|
||||
|
||||
const container = document.getElementById('game-container');
|
||||
if (container) {
|
||||
container.appendChild(this.renderer.domElement);
|
||||
window.log('Renderer attached to DOM');
|
||||
} else {
|
||||
window.log('ERROR: game-container not found');
|
||||
}
|
||||
|
||||
this.scene.add(new THREE.AxesHelper(10)); // Add axis lines (Red, Green, Blue)
|
||||
this.camera.position.set(5, 5, 5); // Move camera out of the floor
|
||||
this.camera.lookAt(0, 0, 0);
|
||||
|
||||
// --- Retro Pipeline Setup ---
|
||||
|
||||
|
||||
// 1. Off-screen Render Target (Small Resolution)
|
||||
// We render the 3D scene here first.
|
||||
this.targetWidth = 320;
|
||||
this.targetHeight = 240;
|
||||
|
||||
|
||||
this.renderTarget = new THREE.WebGLRenderTarget(this.targetWidth, this.targetHeight, {
|
||||
minFilter: THREE.NearestFilter,
|
||||
magFilter: THREE.NearestFilter,
|
||||
@@ -38,7 +53,7 @@ export class Graphics {
|
||||
const postMaterial = new THREE.ShaderMaterial({
|
||||
uniforms: {
|
||||
tDiffuse: { value: this.renderTarget.texture },
|
||||
colorDepth: { value: 32.0 } // 32 levels per channel (5-bit)
|
||||
colorDepth: { value: 16.0 } // 16 levels per channel (4-bit per channel - 4096 colors)
|
||||
},
|
||||
vertexShader: `
|
||||
varying vec2 vUv;
|
||||
@@ -53,8 +68,8 @@ export class Graphics {
|
||||
varying vec2 vUv;
|
||||
void main() {
|
||||
vec4 tex = texture2D(tDiffuse, vUv);
|
||||
// Quantize color
|
||||
vec3 color = floor(tex.rgb * colorDepth) / colorDepth;
|
||||
// Quantize color and ensure it's not absolutely zeroed if there's light
|
||||
vec3 color = floor(tex.rgb * colorDepth + 0.5) / colorDepth;
|
||||
gl_FragColor = vec4(color, tex.a);
|
||||
}
|
||||
`
|
||||
@@ -74,7 +89,7 @@ export class Graphics {
|
||||
|
||||
handleResize() {
|
||||
const aspect = window.innerWidth / window.innerHeight;
|
||||
|
||||
|
||||
// Update 3D Camera
|
||||
this.camera.aspect = aspect;
|
||||
this.camera.updateProjectionMatrix();
|
||||
@@ -89,6 +104,17 @@ export class Graphics {
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.renderCount) this.renderCount = 0;
|
||||
this.renderCount++;
|
||||
if (this.renderCount % 100 === 0) window.log(`Rendering frame ${this.renderCount}`);
|
||||
|
||||
// --- Diagnostic: Render directly to screen ---
|
||||
// 1. Render 3D Scene to Screen
|
||||
this.renderer.setRenderTarget(null);
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
|
||||
/*
|
||||
// Original Post-Processing Pipeline
|
||||
// 1. Render 3D Scene to RenderTarget
|
||||
this.renderer.setRenderTarget(this.renderTarget);
|
||||
this.renderer.render(this.scene, this.camera);
|
||||
@@ -96,5 +122,6 @@ export class Graphics {
|
||||
// 2. Render Post-Processing Quad to Screen
|
||||
this.renderer.setRenderTarget(null);
|
||||
this.renderer.render(this.postScene, this.postCamera);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import * as THREE from 'three';
|
||||
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
|
||||
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls.js';
|
||||
|
||||
export class Player {
|
||||
constructor(camera, colliders) {
|
||||
@@ -20,8 +20,23 @@ export class Player {
|
||||
this.moveRight = false;
|
||||
this.velocity = new THREE.Vector3();
|
||||
this.direction = new THREE.Vector3();
|
||||
this.flashlightOn = true; // Started as ON
|
||||
|
||||
this.setupInput();
|
||||
this.setupFlashlight();
|
||||
}
|
||||
|
||||
setupFlashlight() {
|
||||
this.flashlight = new THREE.SpotLight(0xffffff, 10);
|
||||
this.flashlight.angle = Math.PI / 6;
|
||||
this.flashlight.penumbra = 0.3;
|
||||
this.flashlight.decay = 2;
|
||||
this.flashlight.distance = 15;
|
||||
|
||||
this.camera.add(this.flashlight);
|
||||
this.flashlight.position.set(0, 0, 0);
|
||||
this.flashlight.target.position.set(0, 0, -1);
|
||||
this.camera.add(this.flashlight.target);
|
||||
}
|
||||
|
||||
setupInput() {
|
||||
@@ -31,6 +46,7 @@ export class Player {
|
||||
case 'KeyA': this.moveLeft = true; break;
|
||||
case 'KeyS': this.moveBackward = true; break;
|
||||
case 'KeyD': this.moveRight = true; break;
|
||||
case 'KeyF': this.toggleFlashlight(); break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -47,6 +63,14 @@ export class Player {
|
||||
document.addEventListener('keyup', onKeyUp);
|
||||
}
|
||||
|
||||
toggleFlashlight() {
|
||||
if (!this.controls.isLocked) return; // Only toggle when game is active
|
||||
this.flashlightOn = !this.flashlightOn;
|
||||
if (this.flashlight) {
|
||||
this.flashlight.visible = this.flashlightOn;
|
||||
}
|
||||
}
|
||||
|
||||
lockControls() {
|
||||
this.controls.lock();
|
||||
}
|
||||
@@ -105,5 +129,10 @@ export class Player {
|
||||
|
||||
// Keep player on ground
|
||||
playerPos.y = this.height;
|
||||
|
||||
// Flashlight flicker effect (subtle)
|
||||
if (this.flashlight && this.flashlightOn) {
|
||||
this.flashlight.intensity = 10 + Math.random() * 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
17
src/World.js
17
src/World.js
@@ -7,15 +7,14 @@ export class World {
|
||||
}
|
||||
|
||||
load() {
|
||||
// Basic lighting
|
||||
const ambientLight = new THREE.AmbientLight(0x404040, 0.5); // Dim ambient
|
||||
this.scene.add(ambientLight);
|
||||
// Grid helper for depth
|
||||
this.scene.add(new THREE.GridHelper(20, 20));
|
||||
|
||||
// Floor
|
||||
// Floor (Basic Material - no light needed)
|
||||
const floorGeo = new THREE.PlaneGeometry(20, 20);
|
||||
const floorMat = new THREE.MeshStandardMaterial({
|
||||
const floorMat = new THREE.MeshBasicMaterial({
|
||||
color: 0x333333,
|
||||
roughness: 0.8
|
||||
side: THREE.DoubleSide
|
||||
});
|
||||
const floor = new THREE.Mesh(floorGeo, floorMat);
|
||||
floor.rotation.x = -Math.PI / 2;
|
||||
@@ -27,10 +26,10 @@ export class World {
|
||||
this.createWall(-10, 2.5, 0, 20, 5, true); // Left
|
||||
this.createWall(10, 2.5, 0, 20, 5, true); // Right
|
||||
|
||||
// Add a reference cube to see depth
|
||||
// Add a reference cube (Bright Yellow Basic Material)
|
||||
const cube = new THREE.Mesh(
|
||||
new THREE.BoxGeometry(1, 1, 1),
|
||||
new THREE.MeshStandardMaterial({ color: 0xff0000 })
|
||||
new THREE.MeshBasicMaterial({ color: 0xffff00 })
|
||||
);
|
||||
cube.position.set(0, 0.5, -5);
|
||||
this.scene.add(cube);
|
||||
@@ -39,7 +38,7 @@ export class World {
|
||||
|
||||
createWall(x, y, z, width, height, rotate = false) {
|
||||
const geo = new THREE.BoxGeometry(width, height, 0.5);
|
||||
const mat = new THREE.MeshStandardMaterial({ color: 0x555555 });
|
||||
const mat = new THREE.MeshBasicMaterial({ color: 0x555555 });
|
||||
const wall = new THREE.Mesh(geo, mat);
|
||||
wall.position.set(x, y, z);
|
||||
if (rotate) wall.rotation.y = Math.PI / 2;
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
window.log = (msg) => {
|
||||
const logDiv = document.getElementById('debug-log');
|
||||
if (logDiv) logDiv.innerHTML += `> ${msg}<br>`;
|
||||
console.log(msg);
|
||||
};
|
||||
|
||||
import { Game } from './Game.js';
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
window.log('DOM Content Loaded');
|
||||
const game = new Game();
|
||||
game.start();
|
||||
window.log('Game Started');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user