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


                              
 

                 
             

  
                       


                                                         
                        
                 



                                                 
                                         




                                                        
    
                                    
                    
                 

 
                                  
                                                            
    

                                                                  


               




                                                          
                        
                                                 


                                           


                                                                                 
                                             

                          
     

 
                                
                                    
    
                                                               
               
     
    
                                                                                        
                                
 


                               
                            


                                                                      



                                                           
                    
                                                     
    




                                                   
                                                     

                                               
                                                                          

       
                                                                               
                                                                                
                             
                                
                          

 
                             




                                      



                                                      
                                                                   






                                                                               

 
                           
const FPS = 60;
const FRAME_TIME = 1000 / FPS;
let lastFrameTime = 0;

const state = {
    canvas: null,
    ctx: null
};

async function init() {
    state.canvas = document.getElementById('gameCanvas');
    state.ctx = state.canvas.getContext('2d');
    
    await player.init();
    Debug.init();
    
    function resize() {
        state.canvas.width = window.innerWidth;
        state.canvas.height = window.innerHeight;
        Camera.centerOn(player.position);
    }
    
    window.addEventListener('resize', resize);
    resize();
    state.canvas.addEventListener('click', handleClick);
    
    requestAnimationFrame(gameLoop);
    FogOfWar.init();
    Items.init();
}

function drawHex(ctx, x, y, hex) {
    const screen = HexGrid.toScreenCoordinates(hex, Camera);
    
    // Only draw if hex is visible on screen (with padding)
    if (!HexGrid.isInViewport(screen.x, screen.y, state.canvas)) {
        return;
    }
    
    // Skip drawing completely if hex hasn't been revealed
    if (!FogOfWar.isRevealed(hex)) {
        return;
    }
    
    // Draw the hex fill
    HexGrid.drawHexPath(ctx, screen.x, screen.y);
    ctx.fillStyle = Config.colors.HEX_FILL;
    ctx.fill();
    
    // Only draw grid lines for currently visible hexes
    // (fog of war will handle the grid lines for revealed but not visible hexes)
    if (FogOfWar.isVisible(hex)) {
        ctx.strokeStyle = Config.colors.GRID;
        ctx.lineWidth = 1;
        ctx.stroke();
    }
}

function gameLoop(currentTime) {
    requestAnimationFrame(gameLoop);
    
    if (currentTime - lastFrameTime < Config.game.FRAME_TIME) {
        return;
    }
    
    const deltaTime = Math.min(currentTime - lastFrameTime, Config.game.FRAME_TIME * 2);
    lastFrameTime = currentTime;

    // Update debug information
    Debug.update(currentTime);

    // Clear with background
    state.ctx.fillStyle = Config.colors.BACKGROUND;
    state.ctx.fillRect(0, 0, state.canvas.width, state.canvas.height);
    
    // Round camera position to prevent sub-pixel rendering
    Camera.x = Math.round(Camera.x);
    Camera.y = Math.round(Camera.y);
    
    player.update();
    Camera.smoothFollow(player.getCurrentPosition());
    
    if (player.hasMoved) {
        FogOfWar.updateVisibility(player.position);
        player.hasMoved = false;
    }
    
    // Draw everything in one pass to prevent flicker
    HexGrid.getViewportHexes().forEach(hex => {
        const pixel = HexGrid.toPixel(hex);
        drawHex(state.ctx, Math.round(pixel.x), Math.round(pixel.y), hex);
    });
    
    Items.draw(state.ctx, HexGrid.toPixel.bind(HexGrid), Camera, HexGrid.SIZE);
    player.draw(state.ctx, HexGrid.toPixel.bind(HexGrid), Camera, HexGrid.SIZE);
    FogOfWar.draw(state.ctx);
    InventoryUI.draw(state.ctx);
    Debug.draw(state.ctx);
}

function handleClick(event) {
    if (InventoryUI.isOpen) {
        InventoryUI.toggleInventory();
        return;
    }
    
    const rect = state.canvas.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY - rect.top;
    
    const hexCoord = HexGrid.fromPixel(x + Camera.x, y + Camera.y);
    
    // Check if clicking on player's position
    if (hexCoord.q === player.position.q && hexCoord.r === player.position.r) {
        InventoryUI.toggleInventory();
    } else {
        player.moveTo(hexCoord);
    }
}

init().catch(console.error);