diff options
Diffstat (limited to 'html/side-scrolling-rogue-thing/js/rogue.js')
-rw-r--r-- | html/side-scrolling-rogue-thing/js/rogue.js | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/html/side-scrolling-rogue-thing/js/rogue.js b/html/side-scrolling-rogue-thing/js/rogue.js new file mode 100644 index 0000000..64716a4 --- /dev/null +++ b/html/side-scrolling-rogue-thing/js/rogue.js @@ -0,0 +1,144 @@ +window.gameState = null; + +const initGame = () => { + const canvas = document.getElementById('gameCanvas'); + const ctx = canvas.getContext('2d'); + + // Target frame rate + const FPS = 60; + const FRAME_TIME = 1000 / FPS; + let lastFrameTime = 0; + + // Set canvas to full viewport size + const resizeCanvas = () => { + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + // Clear any cached gradients when resizing + if (window.gameState) { + window.gameState.cachedGradient = null; + } + }; + + window.addEventListener('resize', resizeCanvas); + resizeCanvas(); + + // Calculate initial player position at ground level + const groundY = canvas.height - CONFIG.world.groundHeight; + const initialPlayerY = groundY - CONFIG.player.height; + + // Game state + let gameState = { + time: 0, + player: createPlayer(100, initialPlayerY), + camera: createCamera(0, 0), + world: createWorld(), + debug: { + enabled: false, + mouseX: 0, + mouseY: 0 + } + }; + + // Make gameState globally accessible + window.gameState = gameState; + + // Set up input handlers + setupInputHandlers(canvas, gameState); + + // Game loop + const gameLoop = (timestamp) => { + // Check if enough time has passed since last frame + if (timestamp - lastFrameTime < FRAME_TIME) { + requestAnimationFrame(gameLoop); + return; + } + + // Calculate delta time (capped at 1 second to prevent huge jumps) + const deltaTime = Math.min(timestamp - lastFrameTime, 1000); + lastFrameTime = timestamp; + gameState.time = timestamp; + + // Clear the entire canvas + ctx.clearRect(0, 0, canvas.width, canvas.height); + + // Update + gameState = updateGame(gameState, deltaTime); + + // Render + render(ctx, gameState); + + // Schedule next frame + requestAnimationFrame(gameLoop); + }; + + // Start the game loop + lastFrameTime = performance.now(); + requestAnimationFrame(gameLoop); +}; + +const updateGame = (state, deltaTime) => { + const updatedPlayer = updatePlayer(state.player, deltaTime); + const updatedCamera = updateCamera(state.camera, updatedPlayer); + + return { + ...state, + player: updatedPlayer, + camera: updatedCamera + }; +}; + +const render = (ctx, state) => { + const groundY = ctx.canvas.height - state.world.groundHeight; + + // Cache sky gradient + if (!state.cachedGradient) { + state.cachedGradient = createSkyGradient(ctx, groundY); + } + + const viewBounds = getViewBounds(state.camera); + + // Apply camera transform + ctx.save(); + ctx.translate(-state.camera.x, -state.camera.y); + + // Clear the transformed canvas area + ctx.clearRect( + viewBounds.left, + 0, + viewBounds.right - viewBounds.left, + ctx.canvas.height + ); + + // Render layers + renderBackground(ctx, state, groundY, viewBounds); + renderBackgroundObjects(ctx, state, groundY, viewBounds); + + // Render platforms + state.world.platforms.forEach(platform => { + ctx.fillStyle = platform.color; + ctx.fillRect(platform.x, platform.y, platform.width, platform.height); + }); + + renderPlayer(ctx, state.player); + renderForegroundObjects(ctx, state, groundY, viewBounds); + + // Render ground line + ctx.fillStyle = RENDER_CONSTANTS.GROUND_COLOR; + ctx.fillRect( + state.camera.x - 1000, + groundY, + ctx.canvas.width + 2000, + 1 + ); + + // Handle debug rendering + if (state.debug.enabled) { + ctx.restore(); + renderDebugInfo(ctx, state); + } else { + ctx.restore(); + } +}; + +// Initialize the game when the window loads +window.addEventListener('load', initGame); |