about summary refs log tree commit diff stats
path: root/html/rogue/js/game.js
blob: e0010b705a46b8e8e2609044bd34fb199e741f70 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
const FPS = 60;
const FRAME_TIME = 1000 / FPS;
let lastFrameTime = 0;

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

function init() {
    state.canvas = document.getElementById('gameCanvas');
    state.ctx = state.canvas.getContext('2d');
    
    player.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);
}

// Draw a single hex
function drawHex(ctx, x, y, hex) {
    const screenX = x - Camera.x;
    const screenY = y - Camera.y;
    
    // Only draw if hex is visible on screen (with some padding)
    if (screenX < -HexGrid.WIDTH || screenX > state.canvas.width + HexGrid.WIDTH ||
        screenY < -HexGrid.HEIGHT || screenY > state.canvas.height + HexGrid.HEIGHT) {
        return;
    }
    
    ctx.beginPath();
    for (let i = 0; i < 6; i++) {
        const angle = 2 * Math.PI / 6 * i;
        const xPos = screenX + HexGrid.SIZE * Math.cos(angle);
        const yPos = screenY + HexGrid.SIZE * Math.sin(angle);
        if (i === 0) {
            ctx.moveTo(xPos, yPos);
        } else {
            ctx.lineTo(xPos, yPos);
        }
    }
    ctx.closePath();

    // Fill hex with appropriate color
    if (HexGrid.isPassable(hex)) {
        ctx.fillStyle = Config.colors.HEX_FILL;
    } else {
        ctx.fillStyle = Config.colors.BACKGROUND;
    }
    ctx.fill();
    
    // Draw border
    ctx.strokeStyle = HexGrid.COLOR;
    ctx.lineWidth = 1;
    ctx.stroke();
}

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

    // Clear the entire canvas first
    state.ctx.clearRect(0, 0, state.canvas.width, state.canvas.height);
    
    // Then fill with background color
    state.ctx.fillStyle = Config.colors.BACKGROUND;
    state.ctx.fillRect(0, 0, state.canvas.width, state.canvas.height);
    
    player.update();
    Camera.smoothFollow(player.getCurrentPosition());
    
    HexGrid.getViewportHexes().forEach(hex => {
        const pixel = HexGrid.toPixel(hex);
        drawHex(state.ctx, pixel.x, pixel.y, hex);
    });
    
    player.draw(state.ctx, HexGrid.toPixel.bind(HexGrid), Camera, HexGrid.SIZE);
    
    requestAnimationFrame(gameLoop);
}

function handleClick(event) {
    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);
    player.moveTo(hexCoord);
}

init();