如何在Canvas网格两点间绘制平铺墙?PixiJS模拟器鼠标绘墙求助
解决PixiJS瓦片模拟器的墙体绘制问题
嘿,我来帮你搞定这个瓦片墙体绘制的难题!你说得对,核心确实是坐标转换和行列遍历的数学逻辑,咱们一步步把它捋清楚:
1. 先把Canvas点击坐标转成瓦片行列索引
Tink返回的是相对于Canvas的原始(x,y)坐标,但我们需要的是瓦片的行列位置——这是所有逻辑的基础。假设你的瓦片尺寸是tileSize(比如64x64),用整除就能快速转换:
const tileSize = 64; // 根据你的实际瓦片尺寸调整 // 把Canvas坐标转成瓦片的行列 function getTilePosition(canvasX, canvasY) { const col = Math.floor(canvasX / tileSize); const row = Math.floor(canvasY / tileSize); return { col, row }; }
注意:PixiJS的y轴是向下的,所以直接用
Math.floor(canvasY / tileSize)计算行号是正确的,不用反转。
2. 判断两次点击是否在同一行或列
存储第一次点击的瓦片位置(比如startTile = {col: x1, row: y1}),第二次点击后拿到endTile,然后做判断:
// 假设已经通过Tink拿到第二次点击的canvasX和canvasY const endTile = getTilePosition(canvasX, canvasY); const isSameRow = startTile.row === endTile.row; const isSameCol = startTile.col === endTile.col; if (!isSameRow && !isSameCol) { // 提示用户只能选择同一行或列的瓦片 console.log("请点击同一行或列的瓦片来绘制墙体!"); return; }
3. 遍历生成所有墙体瓦片
这是最关键的数学逻辑:不管是从左到右、右到左,还是从上到下、下到上,我们只需要取行列的最小值到最大值,遍历中间所有瓦片(包括起始和目标):
function renderWall(startTile, endTile) { const wallTiles = []; if (isSameRow) { // 同一行,遍历列的范围 const minCol = Math.min(startTile.col, endTile.col); const maxCol = Math.max(startTile.col, endTile.col); for (let col = minCol; col <= maxCol; col++) { wallTiles.push({ col, row: startTile.row }); } } else { // 同一列,遍历行的范围 const minRow = Math.min(startTile.row, endTile.row); const maxRow = Math.max(startTile.row, endTile.row); for (let row = minRow; row <= maxRow; row++) { wallTiles.push({ col: startTile.col, row }); } } // 把这些瓦片渲染成墙体 wallTiles.forEach(tile => { // 这里替换成你创建墙体Sprite的逻辑 const wallSprite = new PIXI.Sprite(yourWallTexture); wallSprite.x = tile.col * tileSize; wallSprite.y = tile.row * tileSize; app.stage.addChild(wallSprite); }); }
额外小提示
- 如果你的瓦片地图有层级,记得把墙体添加到高于地面瓦片的层级,避免被遮挡;
- 可以给已绘制的瓦片加个标记(比如用一个二维数组记录
isWall[col][row]),防止重复绘制同一位置的墙体; - 测试时可以在控制台打印
startTile和endTile的行列值,确认坐标转换是否正确。
内容的提问来源于stack exchange,提问作者Emmanuel
相关产品推荐
相关产品推荐

