html canvas等距瓦片地图渲染

问题描述 投票:0回答:1

我正在努力实现这样的目标

desired result

但我总是在到达边界时最终无法渲染图块,它应该绘制 200x200 地图,但它只显示 17x17

正在构建的游戏在理念上与 Travian Kingdoms 类似,但故事和设计完全不同

这是代码

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>

current result

感谢您的帮助,提前谢谢您

我尝试了所有可能的解决方案,但没有希望

javascript html canvas tile isometric
1个回答
0
投票

全图优化绘制:

function loadMap() {
    ctx.clearRect(0, 0, canvas.width, canvas.height); // Clear the canvas

    for (let x = -200; x <= 200; x++) {
        for (let y = -200; y <= 200; y++) {
            // Convert grid coordinates to screen coordinates
            const screenX = (x - y) * (tileWidth / 2) + offsetX;
            const screenY = (x + y) * (tileHeight / 2) + offsetY;
            if (screenX >= -tileWidth && screenX < canvas.width &&
                screenY >= -tileHeight && screenY < canvas.height) {
                // Draw the tile
                const tileColor = testData[(x + y + gridSize) % testData.length];
                drawTile(x, y, screenX, screenY, tileColor);
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.