Coding
PromptBeginner5 minmarkdown
Markdown Converter
Agent skill for markdown-converter
7
- Use modular architecture with clear separation of concerns
Sign in to like and favorite skills
Application - Main entry point and game loopInputManager - Handle keyboard and mouse inputAssetManager - Load and manage 3D models, textures, audioGameWorld - Manage scene, lighting, and physical worldUIManager - Handle UI interactions and HUDPlayer - Player character controller and cameraEntityManager - Manage game entities (enemies, pickups)PhysicsSystem - Handle collisions and physics// Store key states in an object this.keyState = {}; // Update key states on events document.addEventListener('keydown', (e) => { this.keyState[e.code] = true; }); document.addEventListener('keyup', (e) => { this.keyState[e.code] = false; }); // Access key state in game loop if (this.keyState['KeyW']) { // Move forward }
// Request pointer lock on container click container.addEventListener('click', () => { container.requestPointerLock(); }); // Track pointer lock state document.addEventListener('pointerlockchange', () => { this.pointerLocked = document.pointerLockElement === container; }); // Track mouse movement when pointer is locked document.addEventListener('mousemove', (e) => { if (this.pointerLocked) { this.mouseMovement.x = e.movementX || 0; this.mouseMovement.y = e.movementY || 0; } });
camera.rotation.order = 'YXZ'; // Critical for FPS camera
// Apply mouse movement to camera rotation const sensitivity = 0.002; // Horizontal rotation (yaw) this.rotation.y -= mouseMovement.x * sensitivity; // Vertical rotation (pitch) with clamping this.rotation.x -= mouseMovement.y * sensitivity; this.rotation.x = Math.max(-Math.PI/2 + 0.01, Math.min(Math.PI/2 - 0.01, this.rotation.x)); // Apply rotation to camera camera.rotation.copy(this.rotation);
// Get input direction const moveX = (keyState['KeyD'] ? 1 : 0) - (keyState['KeyA'] ? 1 : 0); const moveZ = (keyState['KeyS'] ? 1 : 0) - (keyState['KeyW'] ? 1 : 0); // Create and normalize movement vector const moveDir = new THREE.Vector3(moveX, 0, moveZ); if (moveDir.length() > 1) moveDir.normalize(); // Get forward and right vectors from camera const forward = new THREE.Vector3(0, 0, 1).applyEuler(new THREE.Euler(0, rotation.y, 0)); const right = new THREE.Vector3(1, 0, 0).applyEuler(new THREE.Euler(0, rotation.y, 0)); // Calculate world movement direction const worldDir = new THREE.Vector3(); worldDir.addScaledVector(forward, -moveDir.z); worldDir.addScaledVector(right, moveDir.x); worldDir.normalize(); // Apply movement position.addScaledVector(worldDir, moveSpeed * deltaTime);
const now = performance.now(); const deltaTime = Math.min((now - lastTime) / 1000, 0.1); // Seconds, clamped to 100ms lastTime = now; // Update game systems inputManager.update(); player.update(deltaTime); enemyManager.update(deltaTime); physics.update(deltaTime); renderer.render(scene, camera);
async loadAssets(onProgress) { const total = this.assetList.length; let loaded = 0; // Create load promises for all assets const promises = this.assetList.map(asset => { return this.loadAsset(asset).then(() => { loaded++; onProgress(loaded / total); }); }); // Wait for all assets to load await Promise.all(promises); }
// FPS counter let frames = 0; let lastFpsTime = 0; function updateFps(now) { frames++; if (now >= lastFpsTime + 1000) { const fps = frames * 1000 / (now - lastFpsTime); debugText.textContent = `FPS: ${Math.round(fps)}`; frames = 0; lastFpsTime = now; } }