am trying to achieve something like this
but i always endup tiles are not rendering when reaching to boundries , it should be drawing 200×200 map how ever it only show 17×17
the game am building is similer in idea to travian kingdoms but whole different story and design
here is the code
const canvas = document.getElementById('mapCanvas');
const ctx = canvas.getContext('2d');
const tileWidth = 128; // Tile width
const tileHeight = 64; // Tile height
const gridSize = 1000; // Large grid size for 1,000,000 tiles (1000x1000)
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let offsetX = canvas.width / 2; // Start with center offset
let offsetY = canvas.height / 2; // Start with center offset
let isDragging = false;
let startX, startY;
// Test data for tiles using colors
const testData = [
'#76b041', // Grass
'#557a29', // Forest
'#c2b280', // Plain
'#a4a4a4', // Mountain
];
function drawTile(x, y, screenX, screenY, color) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(screenX, screenY);
ctx.lineTo(screenX + tileWidth / 2, screenY + tileHeight / 2);
ctx.lineTo(screenX, screenY + tileHeight);
ctx.lineTo(screenX - tileWidth / 2, screenY + tileHeight / 2);
ctx.closePath();
ctx.fill();
ctx.strokeStyle = '#000'; // Optional: add border to each tile
ctx.stroke();
// Draw the coordinates on the tile
ctx.fillStyle = '#000';
ctx.font = '14px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(`(${x}, ${y})`, screenX, screenY + tileHeight / 2);
}
function loadMap() {
ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas
// Calculate how many tiles we need to draw to cover the screen
const tilesX = Math.ceil(canvas.width / tileWidth) + 2;
const tilesY = Math.ceil(canvas.height / tileHeight) + 2;
for (let x = -tilesX; x <= tilesX; x++) {
for (let y = -tilesY; y <= tilesY; y++) {
// Convert grid coordinates to screen coordinates
const screenX = (x - y) * (tileWidth / 2) + offsetX;
const screenY = (x + y) * (tileHeight / 2) + offsetY;
// Draw the tile
const tileColor = testData[(x + y + gridSize) % testData.length];
drawTile(x, y, screenX, screenY, tileColor);
}
}
}
canvas.addEventListener('mousedown', onMouseDown);
canvas.addEventListener('mousemove', onMouseMove);
canvas.addEventListener('mouseup', onMouseUp);
function onMouseDown(e) {
isDragging = true;
startX = e.clientX;
startY = e.clientY;
}
function onMouseMove(e) {
if (!isDragging) return;
const dx = e.clientX - startX;
const dy = e.clientY - startY;
offsetX += dx;
offsetY += dy;
startX = e.clientX;
startY = e.clientY;
loadMap(); // Redraw the map based on the new position
}
function onMouseUp() {
isDragging = false;
}
// Initial load
loadMap();
// Handle window resizing
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
loadMap();
});
body {
margin: 0;
overflow: hidden;
}
canvas {
display: block;
background-color: #e0e0e0;
}
<canvas id="mapCanvas"></canvas>
your help is appreciated thank you in advance
i tried every possible solution with no hope
2
Answers
An optimized drawing of the whole map:
The number of tiles to draw should not be computed.
Also, don’t render the tiles that are not visible. This will improve performance.
In the code below, I chose a fixed number of tiles to draw i.e. 64×64, but you could change this to 200×200. I chose a smaller number for demonstration.
Demo