about summary refs log tree commit diff stats
path: root/html/rogue/js/hex.js
blob: fa08e3db02443988970f085cc1077a93a2e78b30 (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
// This that witchy shit -- we be hexin!

const HexGrid = {
    get SIZE() { return Config.hex.SIZE },
    get WIDTH() { return Config.hex.WIDTH },
    get HEIGHT() { return Config.hex.HEIGHT },
    get GRID_SIZE() { return Config.hex.GRID_SIZE },
    COLOR: Config.colors.GRID,

    // hex to pixel
    toPixel(hex) {
        const x = this.SIZE * (3/2 * hex.q);
        const y = this.SIZE * (Math.sqrt(3)/2 * hex.q + Math.sqrt(3) * hex.r);
        return {x, y};
    },

    // pixel to hex
    fromPixel(x, y) {
        const q = (2/3 * x) / this.SIZE;
        const r = (-1/3 * x + Math.sqrt(3)/3 * y) / this.SIZE;
        return this.round(q, r);
    },

    // Round hex coordinates to nearest hex
    round(q, r) {
        let x = q;
        let z = r;
        let y = -x-z;

        let rx = Math.round(x);
        let ry = Math.round(y);
        let rz = Math.round(z);

        const x_diff = Math.abs(rx - x);
        const y_diff = Math.abs(ry - y);
        const z_diff = Math.abs(rz - z);

        if (x_diff > y_diff && x_diff > z_diff) {
            rx = -ry-rz;
        } else if (y_diff > z_diff) {
            ry = -rx-rz;
        } else {
            rz = -rx-ry;
        }

        return {q: rx, r: rz};
    },

    // Is this hex in the viewport?
    getViewportHexes() {
        const hexes = [];
        const halfGrid = Math.floor(this.GRID_SIZE / 2);
        
        for (let r = -halfGrid; r < halfGrid; r++) {
            for (let q = -halfGrid; q < halfGrid; q++) {
                hexes.push({q, r});
            }
        }
        return hexes;
    },

    // Check if a hex is passable
    isPassable(hex) {
        const halfGrid = Math.floor(this.GRID_SIZE / 2);
        return Math.abs(hex.q) <= halfGrid && Math.abs(hex.r) <= halfGrid;
    },

    // Centralized hex drawing function
    drawHexPath(ctx, x, y, size = this.SIZE, padding = 0) {
        ctx.beginPath();
        for (let i = 0; i < 6; i++) {
            const angle = 2 * Math.PI / 6 * i;
            const xPos = Math.round(x + (size + padding) * Math.cos(angle));
            const yPos = Math.round(y + (size + padding) * Math.sin(angle));
            if (i === 0) {
                ctx.moveTo(xPos, yPos);
            } else {
                ctx.lineTo(xPos, yPos);
            }
        }
        ctx.closePath();
    },

    toScreenCoordinates(hex, camera) {
        const pixel = this.toPixel(hex);
        return {
            x: Math.round(pixel.x - camera.x),
            y: Math.round(pixel.y - camera.y)
        };
    },

    isInViewport(screenX, screenY, canvas) {
        return !(screenX < -this.WIDTH || 
                screenX > canvas.width + this.WIDTH ||
                screenY < -this.HEIGHT || 
                screenY > canvas.height + this.HEIGHT);
    }
};