如何获取Tiled中Object Layer的Fixture?LOVE2D开发求助
问题分析
你代码里的核心错误是把map.layers.Solid(图层对象)和碰撞回调里的a/b(Fixture对象)直接比较,这两者根本不是同一类东西,所以永远匹配不上。
解决思路
分两种方案,推荐第一种(更高效,避免无效创建金币):
方案一:生成金币前先过滤墙体位置
用STI的内置方法,在生成金币前先判断当前坐标是否属于墙体区域,直接跳过这些位置:
-- 假设每个格子大小是32px,根据你的地图实际尺寸调整 local tileSize = 32 -- 遍历地图所有可放置金币的格子 for x = 1, map.width do for y = 1, map.height do -- 获取当前格子的世界坐标 local worldX = (x - 1) * tileSize local worldY = (y - 1) * tileSize -- 检查当前格子是否属于Solid层(墙体) local tile = map:tileAt(worldX, worldY) if not tile or not tile.layers.Solid then -- 这里创建金币实例,加入ActiveCoins数组 local coin = Coin.new(worldX, worldY) table.insert(ActiveCoins, coin) end end end
如果你的Solid是Object Layer(不是Tile Layer),就用map:checkCollision来检测该位置是否有碰撞对象:
local tileSize = 32 for x = 1, map.width do for y = 1, map.height do local worldX = (x - 1) * tileSize local worldY = (y - 1) * tileSize -- 检测当前位置是否和Solid层的碰撞对象重叠 if not map:checkCollision(worldX, worldY, tileSize, tileSize) then local coin = Coin.new(worldX, worldY) table.insert(ActiveCoins, coin) end end end
方案二:给墙体Fixture打标记,碰撞时识别
如果你一定要先创建所有金币再删除和墙体碰撞的,那需要先给墙体的Fixture添加标记:
- 加载地图时,遍历Solid层的所有Fixture并设置userdata:
-- 假设你已经用STI加载了地图并启用了碰撞 map:addCustomLayer("Collision", 10) local collisionLayer = map.layers.Collision -- 遍历Solid层的所有对象,获取它们的Fixture for _, obj in ipairs(map.layers.Solid.objects) do if obj.fixture then obj.fixture:setUserData("wall") end end
- 修改你的碰撞回调代码,通过userdata识别墙体:
function Coin.beginContact(a, b, collision) for i, instance in ipairs(ActiveCoins) do local coinFixture = instance.physics.fixture if a == coinFixture or b == coinFixture then -- 判断是否是玩家碰撞 if a == Player.physics.fixture or b == Player.physics.fixture then instance.toBeRemoved = true return true end -- 判断是否是墙体碰撞 local otherFixture = a == coinFixture and b or a if otherFixture:getUserData() == "wall" then instance.toBeRemoved = true return true end end end end
注意事项
- 确保你的Solid层在Tiled里已经设置了碰撞属性,并且STI加载时启用了碰撞(比如
map:setCollisionLayer("Solid")) - 金币的碰撞体尺寸要和格子匹配,避免误判
内容的提问来源于stack exchange,提问作者Dio
相关产品推荐
相关产品推荐

