下载 App

开发日记:(正面俯视角瓦片)地图的房间旋转实现(逻辑)

修改于05/28136 浏览开发交流
需求背景做一个像素风俯视角经营游戏,房间是 9x9 的瓦片方块,有一扇门。玩家建造时需要选择门朝哪个方向(下、左、上、右),这样可以灵活规划道路和布局。核心问题:一套墙壁素材,怎么实现四个方向的旋转?
horizontal linehorizontal line
TapTap
思路:不旋转图片,旋转"摆放逻辑"最初想法是把贴图旋转 90/180/270 度——但俯视角瓦片游戏里,墙壁贴图有透视效果(顶部石头、底部草地),旋转图片会穿帮。最终方案:贴图不旋转,通过偏移实现视觉旋转。把一个房间拆成三层:层1: 地基(草地铺满,永不变化)
层2: 墙体(固定一张图,整体偏移)
层3: 门(4个方向各画一张,按方向切换)
素材设计一共只需要 6 张图:素材说明building_foundation.png9x9 草地纹理(铺满整个建筑区域)building_wall.png墙体,画在"门朝下"的默认位置door_bottom.png门朝下时的门door_top.png门朝上时的门door_left.png门朝左时的门door_right.png门朝右时的门关键设计:墙体图只画一张(默认 bottom 朝向),其他方向通过位移实现。墙体图的特征:
  • 上边缘紧贴图片顶部(后墙)
  • 下边缘留出 2 格绿化区空间(门口前方)
  • 左右各留 1 格绿化区
旋转的核心:Layout 重新生成 + 贴图偏移第一层:逻辑层(Layout 数组)房间的每个格子有类型:wall(墙)、floor(地板)、door(门)、deco(绿化装饰区)。旋转时不是"把数组转 90 度",而是根据门朝向重新生成整个 layout:lua
复制-- 根据门朝向确定各方向的绿化厚度
if doorSide == "bottom" then
    decoTop = 0; decoBottom = 2; decoLeft = 1; decoRight = 1
elseif doorSide == "top" then
    decoTop = 2; decoBottom = 0; decoLeft = 1; decoRight = 1
elseif doorSide == "left" then
    decoTop = 1; decoBottom = 1; decoLeft = 2; decoRight = 0
elseif doorSide == "right" then
    decoTop = 1; decoBottom = 1; decoLeft = 0; decoRight = 2
end
规则很简单:门那一侧留 2 格绿化,对面留 0 格,左右各 1 格。墙壁紧贴绿化区内侧。这决定了碰撞体、寻路、放置检测等逻辑层行为。第二层:渲染层(贴图偏移)墙体素材只有一张(画的是 bottom 默认版本),其他方向通过整体平移来对齐:lua
复制-- 墙体偏移表(单位:格数)
local ds = building.doorSide
local dxTile, dyTile = 0, 0
if ds == "left" then
    dxTile, dyTile = 1, 1      -- 右移1格,下移1格
elseif ds == "top" then
    dxTile, dyTile = 0, 2      -- 下移2格
elseif ds == "right" then
    dxTile, dyTile = -1, 1     -- 左移1格,下移1格
-- bottom 是默认位置,偏移为 (0,0)
end
原理:默认图的墙壁上边缘贴顶、下边缘留 2 格空间。当门朝上时,需要上面留空、下面贴底——只要把整张图往下推 2 格就行了。第三层:门贴图直接切换门比较特殊,4 个方向的形态差异大(横门 vs 竖门),所以直接准备 4 张小图,按方向选用:lua
复制-- 加载 4 张门图
for _, side in ipairs({"bottom", "top", "left", "right"}) do
    buildingImgs[key].door[side] = nvgCreateImage(vg, "image/door_" .. side .. ".png")
end
-- 渲染时选对应方向
local doorImg = buildingImgs[key].door[doorSide]
旋转交互:NanoVG 按钮直接跟随建筑操作按钮(旋转/确认/取消)直接在 NanoVG 渲染层画,跟建筑预览同一个坐标系:lua
复制-- 按钮锚定在建筑右上角
local anchorX = ((previewX + width) * tileSize - camera.x) * zoom
local anchorY = ((previewY - 1) * tileSize - camera.y) * zoom
-- 画圆形按钮
nvgBeginPath(vg)
nvgCircle(vg, btnX, btnY, 20)
nvgFillColor(vg, nvgRGBA(60, 80, 120, 220))
nvgFill(vg)
点击检测用简单的圆形碰撞:lua
复制function BuildSystem:HitTestButtons(screenX, screenY, camera)
    for _, btn in ipairs(buttons) do
        local dx = screenX - btn.cx
        local dy = screenY - btn.cy
        if dx * dx + dy * dy <= radius * radius then
            return btn.action
        end
    end
end
好处:不走 UI 层,不需要坐标转换,按钮天然跟着建筑走。
建筑实例存储旋转信息放置建筑时,把旋转相关信息存进实例:lua
复制local building = {
    id = nextId,
    templateKey = "hero_house",
    rotation = 90,              -- 旋转角度 (0/90/180/270)
    doorSide = "left",          -- 门朝向
    layout = actualLayout,      -- 实际使用的 layout(已旋转版本)
    originX = 5, originY = 3,
}
为什么要存 layout?因为拆除时需要知道当初实际占了哪些格子。如果只存 templateKey 去查 Config,拿到的永远是默认 bottom 版本的 layout,旋转过的建筑拆除就会清错格子。
总结层次旋转方式说明逻辑层 (layout)重新生成根据 doorSide 计算绿化/墙壁/门的位置渲染层 (墙体)整体偏移一张图 + 4组偏移量,无需旋转图片渲染层 (门)切换图片4个方向各一张门图数据层 (实例)存储旋转建筑实例记录 rotation + layout 副本核心取巧点:俯视角瓦片游戏的"旋转"其实是"平移"。墙壁的视觉结构在上下左右是对称的(三面墙+一面开口),只需要把开口挪到对应方向——而"挪开口"在渲染上就是平移整张贴图的绘制起点。
猜你想搜
taptap 制造房间旋转逻辑
03:06
为了不被斩杀,我只能做到这些了截图
为了不被斩杀,我只能做到这些了
之前一直申请不到计划3,之前说太花哨,后面说体量完成度不足,在我一番小作文下,编辑终于给了我解答,什么原生质感,玩家开局体验啥的。 本来计划2也够用,准备以后再优化了,结果计划2赠送的积分要砍半了,学生党实在消费不起,于是只能再冲一波计划3了 从周六中午到现在一天半时间,优化了一遍角色卡,战斗卡,还有抽卡界面,优化了新手教程,该说不说确实比之前要舒服些。 前半部分为新版,后半部分为旧版。 明天再次
27 赞
6 回复
01:27
《大二暑假,我用AI做了一款属于自己的游戏》截图
《大二暑假,我用AI做了一款属于自己的游戏》
本人自制游戏现已加入taptap封闭测试(仅适配安卓机型)欢迎大家前来尝试(八月十号可以正式开始游玩) 如果有建议或者bug反馈可以加入qq群928501443 #发现好游戏 #游戏日常 #浅评一下 #今天游戏圈发生了啥
3 赞
别再烧积分了!从每次 2000 到每次 50 的血泪经验截图
别再烧积分了!从每次 2000 到每次 50 的血泪经验
适用场景:所有在用 TapTap Code 开发游戏的小白 难度:★☆☆☆☆ 背景最近群里总有人"炫耀"一次操作花了几千积分,说实话这不是值得高兴的事——这是在告诉所有人你的开发方式有根本性问题。我也走过这条弯路,所以来说说怎么改。 积分消耗的本质是什么积分 = AI 处理的 token 数量 = 你发给 AI 的内容 + AI 回给你的内容所以烧积分的本质只有两种: 你让 AI 做了大量无效/重
精华
65 赞
20 回复
05:39
游戏目前开发状态截图
游戏目前开发状态
基本玩法都做的差不多了,采集、探索、制作、建造。 全部都由塔塔完成。 塔塔太厉害了。
4 赞
4 回复
如何提升你游戏中的UI美术水平截图
如何提升你游戏中的UI美术水平
一、请为你的游戏挑选一款合适的字体 很多开发者没有注意到其实UI界面中最重要的元素是字体,一款合适的字体能给整个游戏的界面感官带来蜕变。 请看案例 那么如何挑选适合自己的字体呢? 我总结出了一些小经验可供参考: 黑体:通用 宋体:古风、武侠、修仙 楷体:古风、武侠、修仙 圆体:卡通、动漫、Q版 科技:科幻、未来、电子 顺手分享一个免费可商用字体网站: 当然 如果你不知道自己的游戏适合什么风格
精华
122 赞
44 回复
00:48
我做了一款哥特风像素射击游戏|《失落庭院》实机演示截图
我做了一款哥特风像素射击游戏|《失落庭院》实机演示
序列帧实在是太好丸辣! 一直想做哥特风的游戏哈哈,目前做了三把武器,三个怪物和两个房间,不知道有生之年能不能做完😭
11 赞
7 回复
01:29
官方阅,申请积分计划2,希望官方继续支持我完成这款游戏,截图
官方阅,申请积分计划2,希望官方继续支持我完成这款游戏,
视频内容只是一部分, 本游戏耗时3个月,目前完成进度百分之80, 是生存游戏,进入修仙界,走剧情找到宗门加入, 这时游戏才是真正开始, 提升实力境界后就可以变强,获取功法法术法宝, @视频内是游戏里挑战妖族入侵一种主流玩法,游戏就是围绕着这个来进行, 还有很多地方可以战斗,获得资源修炼变强,比如去藏书阁学习功法, 去法宝楼抽法宝,每一个宗门数十个法宝抽取 去修仙界探索,获得各自的资源,可能遇见妖兽
1 赞
3 回复
01:13
【游戏自荐】《王朝崛起》——一个人做的2D骑马砍杀,但真的上头截图
【游戏自荐】《王朝崛起》——一个人做的2D骑马砍杀,但真的上头
略沙盒,玩法硬核,还在修bug,但真的上头 先声明:我不是托,是开发者自己来安利的。如果你喜欢《骑马与砍杀》那种从零拉起部队、跑商、招降将领、攻城叛变的玩法,那这款游戏大概率会对你的胃口。 一、这游戏玩什么? · 超大的2D沙盒地图:64座城市 + 128个村庄,四大势力割据,满地图的蛮族部落。· 动态世界 & AI:AI势力之间会自己宣战、结盟、叛变;武将忠诚度低了会自立为王,最多能冒出8个新势
9 赞
7 回复
嗯,真的,随便了(并不是什么下台阶)截图
嗯,真的,随便了(并不是什么下台阶)
只是觉得,为以前这样让朋友推荐这个平台的我,感到。。。无所谓了。你们喜欢吧。
1 赞
3 回复
00:45
一个在做的小项目截图
一个在做的小项目
这是7月11 创建的项目 内容不是很多,但是因为是菜鸡小白,所以很多东西进度很慢。 开发了7天,进度也仅仅才达到这样。 我是用慢慢推进的方式一点点做的,从开始界面,然后一点点往里面推。 点开的都是开发得差不多了,没点的那就是没做。 战斗场景也没做, 缺的东西很多。 但是都在规划中,我的思路是先做好UI布局,然后再完善内部数值系统。 玩法也是比较常用的刷宝玩法。 刷宝养成类 所以没有太复杂的系统,所
1 赞
5 回复