ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Flame 等轴测视角实战:4 步搭建带纵深感的 2.5D 瓦片地图

Flame 等轴测视角实战:4 步搭建带纵深感的 2.5D 瓦片地图 Flame 等轴测视角实战4 步搭建带纵深感的 2.5D 瓦片地图【免费下载链接】flameA Flutter based game engine.项目地址: https://gitcode.com/GitHub_Trending/fl/flame你在用 Flutter 做策略或 RPG 游戏想把地图从顶视正交换成有纵深感的等轴测Isometric视角最先卡住你的通常是坐标网格里的(行, 列)怎么算成屏幕上的等轴测位置点击位置又怎么反查回网格。Flame 自带IsometricTileMapComponent组件把这两个方向的换算都封装好了你不用手写投影公式。原理速览一次线性变换解决正反两个方向等轴测投影本质是一次线性变换把网格坐标旋转压扁成屏幕上的菱形。正向变换里屏幕横坐标取列与行之差纵坐标取两者之和再乘压缩比Flame 源码里就是一个几行的函数// cartToIso网格坐标 - 等轴测屏幕坐标 Vector2 cartToIso(Vector2 p) { final x p.x - p.y; final y ((p.x p.y) * scalingFactor) / 2; return Vector2(x, y); }scalingFactor是瓦片高宽比2:1 的菱形瓦片它就是 0.5。反向变换isoToCart是这组公式的逆变换点击拾取全靠它。记住一句话就够了等轴测视角的所有问题都是正向还是反向做变换的问题。最小可行实现4 步跑通一张地图第 1 步准备图集和地图数据。图集是一张切分成等大方块的图用SpriteSheet表示地图数据就是二维整数数组每个值是图集中的方块编号-1 表示空位。第 2 步组装组件并加入游戏。final tileset SpriteSheet( image: await images.load(tiles.png), srcSize: Vector2.all(32), ); final matrix [ [3, 1, 1, 0, 0], [-1, 2, 1, 0, 0], [1, 1, 1, 0, 2], ]; add(IsometricTileMapComponent( tileset, matrix, destTileSize: Vector2.all(64), tileHeight: 32, ));第 3 步两个参数要分清。destTileSize是瓦片在屏幕上的宽高图集里 32 像素的瓦片想显示成 64 像素就靠它缩放tileHeight是方块在图集中的厚度不传会默认取瓦片高度的一半。第 4 步验证换算。调getBlockRenderPosition(Block(1, 0))拿到某方块的屏幕位置再把这个位置传回getBlock应当得到Block(1, 0)。往返一致地图就算通了。再进一步点击拾取、Tiled 地图与动态修改点击拾取方块用 getBlock 做反查等轴测游戏最常见的交互是点中方块就高亮或弹出面板。不要自己算变换把鼠标位置直接交给getBlock组件内部已经处理了自己的位置偏移和缩放void onMouseMove(MouseMoveEvent event) { final block map.getBlock(event.canvasPosition); if (map.containsBlock(block)) { selector.position.setFrom( map.position map.getBlockRenderPosition(block), ); } }完整写法可以参考等轴测示例源码它就是这个思路加一个高亮选择器。注意想把角色或建筑站在方块顶面上要用getBlockCenterPosition(block)而不是getBlockRenderPosition——前者是方块顶面中心后者是瓦片图片绘制的左上角。更大的地图用 flame_tiled 渲染 Tiled 等轴测地图地图规模超过手写数组后去 Tiled 编辑器里画导出 .tmx。flame_tiled 桥接包支持 Tiled 原生的等轴测投影加载即可渲染final component await TiledComponent.load( assets/tiles/dungeon.tmx, images, ); add(component);动态修改运行时直接改矩阵地图数据只是普通ListListintsetBlockValue(Block(2, 2), 5)换一个方块、blockValue(block)读一个值建造消除类游戏不必重建整个组件。踩坑实录点击位置与看到的瓦片对不上。现象整体放大地图后鼠标拾取的方块总差一列。原因换算公式受scale影响手写公式容易漏掉缩放而组件内置公式已包含当前缩放。解决统一使用组件的getBlock/getBlockRenderPosition成对调用变换实现就这一个源文件对着读一遍比翻帖子快。地图看起来扁平没有方块的侧面。现象瓦片铺出来了但像一层贴纸。原因没设tileHeight默认值与图集中方块的实际厚度不一致厚度方向被压扁。解决量一下图集中方块厚度目标像素显式传入tileHeight。getBlock 返回越界方块。现象鼠标移出棋盘后数组下标崩溃。原因任何屏幕位置都能反算出网格算出来的网格可能超出矩阵范围。解决拿到 block 后先用containsBlock(block)校验再使用。下一步先按上面矩阵版示例把往返换算跑通再把一张小地图画进 Tiled、接上 flame_tiled 替换手写矩阵如果点击交互对不上直接读getBlock的几行源码偏移的来龙去脉都在里面 ✅【免费下载链接】flameA Flutter based game engine.项目地址: https://gitcode.com/GitHub_Trending/fl/flame创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表