You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Canvas等距瓦片地图边界渲染异常:仅显示17x17而非200x200求助

问题:Canvas等距瓦片地图边界瓦片无法渲染

我想要实现Canvas等距瓦片地图效果,原本计划绘制200x200的地图,但实际仅显示17x17的范围,边界处的瓦片无法渲染。我正在开发一款玩法类似《Travian Kingdoms》但剧情与设计完全不同的游戏,尝试多种解决方案均无果,以下是相关代码:

HTML代码

<canvas id="mapCanvas"></canvas>

CSS代码

body {
  margin: 0;
  overflow: hidden;
}

canvas {
  display: block;
  background-color: #e0e0e0;
}

JavaScript代码

const canvas = document.getElementById('mapCanvas');
const ctx = canvas.getContext('2d');

const tileWidth = 128; // 瓦片宽度
const tileHeight = 64; // 瓦片高度
const gridSize = 1000; // 大网格尺寸,对应1,000,000块瓦片(1000x1000)
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

let offsetX = canvas.width / 2; // 初始居中偏移X
let offsetY = canvas.height / 2; // 初始居中偏移Y
let isDragging = false;
let startX, startY;

// 瓦片测试颜色数据
const testData = [
  '#76b041', // 草地
  '#557a29', // 森林
  '#c2b280', // 平原
  '#a4a4a4', // 山地
];

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'; // 可选:为每个瓦片添加边框
  ctx.stroke();

  // 在瓦片上绘制坐标
  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); // 清空画布

  // 计算需要绘制多少瓦片才能覆盖屏幕
  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++) {
      // 将网格坐标转换为屏幕坐标
      const screenX = (x - y) * (tileWidth / 2) + offsetX;
      const screenY = (x + y) * (tileHeight / 2) + offsetY;

      // 绘制瓦片
      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(); // 根据新位置重绘地图
}

function onMouseUp() {
  isDragging = false;
}

// 初始加载
loadMap();

// 处理窗口大小调整
window.addEventListener('resize', () => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  loadMap();
});

内容的提问来源于stack exchange,提问作者Majed Faraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 13:22:13