diff options
Diffstat (limited to 'html/rogue/js/hex.js')
-rw-r--r-- | html/rogue/js/hex.js | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/html/rogue/js/hex.js b/html/rogue/js/hex.js new file mode 100644 index 0000000..fa08e3d --- /dev/null +++ b/html/rogue/js/hex.js @@ -0,0 +1,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); + } +}; \ No newline at end of file |