Battle-Isle-REBORN 1.08
by velo_ninja
HTML
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Perfectly Centered Hexagonal Grid with Units and Obstacles</title>
<style>
</style>
</head>
<body>
<canvas></canvas>
<script>
// Configurable Data for Units and Obstacles
const gridColor = '#f0f0f0';
const gridBorderColor = '#cccccc';
const usedHexColor = '#9c9c9c';
const iconSize = 80; // Size for icons on units
const hexGridPadding = 30;
// Unit and Obstacle Data (Example)
const unitTypes = ['TANK', 'INFANTRY', 'MEDIC', 'TOWER'];
const unitData = {
TANK: {
title: 'Lightweight-Tank',
color: 'green',
energy: 10,
armory: 10,
//visibility: true,
health: 10,
skill: 5,
weapons: [],
capacity: [],
pic: '' },
INFANTRY: { title: 'Heavy-Infantry', color: 'green', capacity: 1, energy: 5, armory: 7, health: 15, skill: 3, pic: 'https://i.imgur.com/VrwtpSQ.png' },
MEDIC: { title: 'Field-Medic', color: 'orange', capacity: 1, energy: 8, armory: 2, health: 5, skill: 10, pic: 'https://i.imgur.com/wswXEzz.png' },
TOWER: { title: 'Field-Tower', color: 'black', capacity: 1, energy: 8, armory: 2, health: 5, skill: 10, pic: 'https://i.imgur.com/Eb6OyCy.png' }
};
const obstacleData = {
FOREST: { title: 'Forest', color: 'green', bgColor: 'lightgreen', capacity: 0, energy: 0, armory: 0, health: 10, skill: 0, pic: 'https://i.imgur.com/yWF4P2J.png' },
BRIDGE: { title: 'Bridge', color: 'grey', bgColor: 'lightgreen', capacity: 1, energy: 5, armory: 7, health: 15, skill: 3, pic: 'https://i.imgur.com/yWF4P2J.png' },
STONE: { title: 'Stone', color: 'grey', bgColor: 'darkgrey', capacity: 1, energy: 8, armory: 2, health: 5, skill: 10, pic: 'https://i.imgur.com/b4IuXIc.png' },
...
CSS
body {
font-family: 'Arial', sans-serif;
background: #f4f4f4;
color: #333;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
overflow: hidden;
flex-direction: column;
}
canvas {
border: 3px solid darkblue;
border-radius: 20px;
background-color: grey;
box-shadow: 0 4px 8px rgba(110, 110, 110, 0.5);
width: 60%; /* Ensure proper scaling */
height: auto;
display: block; /* Helps in centering if within a flex container */
}
/* Hover effect for canvas */
canvas:hover {
cursor: pointer;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.5);
}
JavaScript
class HexGrid {
constructor(canvas, rows, cols, hexSize, spacing) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.rows = rows;
this.cols = cols;
this.hexSize = hexSize;
this.spacing = spacing;
this.hexWidth = 2 * hexSize * Math.cos(Math.PI / 6) + spacing;
this.hexHeight = hexSize * 1.5 + spacing;
this.gridWidth = (cols - 1) * this.hexWidth + this.hexWidth + (hexSize - spacing)+hexGridPadding*2;
this.gridHeight = (rows - 1) * this.hexHeight + this.hexHeight + spacing + hexGridPadding*2;
this.canvas.width = this.gridWidth;
this.canvas.height = this.gridHeight;
this.gridTop = this.hexHeight / 2+hexGridPadding;
this.gridLeft = this.hexWidth / 2+hexGridPadding;
this.units = [];
this.occupiedPositions = new Set();
this.drawGrid();
}
checkOccupied(row, col) {
const posKey = `${row},${col}`;
return this.occupiedPositions.has(posKey);
}
drawHexagon(x, y, color) {
const ctx = this.ctx;
ctx.beginPath();
for (let i = 0; i < 6; i++) {
const angle = Math.PI / 3 * i + Math.PI / 6;
const px = x + this.hexSize * Math.cos(angle) + this.gridLeft;
const py = y + this.hexSize * Math.sin(angle) + this.gridTop;
if (i === 0) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.closePath();
ctx.fillStyle = color;
ctx.fill();
ctx.strokeStyle = gridBorderColor;
ctx.stroke();
}
drawGrid() {
for (let row = 0; row < this.rows; row++) {
for (let col = 0; col < this.cols; col++) {
const x = col * this.hexWidth + (row % 2 === 0 ? 0 : this.hexWidth / 2);
const y = row * this.hexHeight;
this.drawHexagon(x, y, gridColor);
...