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

如何获取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添加标记:

  1. 加载地图时,遍历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
  1. 修改你的碰撞回调代码,通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:35:20