about summary refs log blame commit diff stats
path: root/html/rogue/js/rogue.js
blob: 64716a47605de217f5ffdc01c1d9ef6cb6fbfc8d (plain) (tree)
1
2
3
4
5
6
7
8
9
10




                                                         




                                  




                                           



                                                   




                                                    



                                                              


                     
                                                  
                                   





                             




                                         

                                          
 

                                     








                                                                          

                                   


                                                         





                                                     
                              



                                        
                                      














                                                                    
                                                                 
 
                         
                                
                                                               

     
                                                   




                                                    

                                        
                        
          
                                           


                         


                                                             
    
                       




                                                                              
                                    
                                                             
 

                                                  



                                
         

      
                             
                              
                      
                                    
            
                      
     



                                            
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);