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

Love2D平台跳跃游戏碰撞问题求助:贴墙时跳跃/下落卡顿

Love2D平台跳跃游戏贴墙移动问题修复

问题现象

  • 玩家贴墙跳跃时,水平方向会停止移动
  • 玩家贴墙下落时,水平方向会停止移动

问题根源

  1. X轴碰撞触发条件过于宽泛:原代码中self.pos.y + self.size.y > tile.pos.y的判断逻辑,只要玩家底部高于tile顶部就触发墙碰撞,不管玩家是否处于tile的侧面区域,直接将X速度置0,导致贴墙时无法保持水平移动。
  2. Y轴碰撞逻辑错误:碰到tile底部(头顶撞墙)时,错误地将self.vel.y设为self.gravity,会导致玩家持续加速;同时Y轴与X轴碰撞的处理顺序不合理,没有优先处理垂直方向的落地/头顶碰撞逻辑。

修复后的代码

--------------------- Collision Check ----------------------

-- 预测下一帧的玩家位置
local box = Vt2:new(self.pos.x + self.vel.x * dt * self.dirXTemp, 
            self.pos.y + self.vel.y * dt)

local isOnGround = false
local isOnWall = false

for i = 1, #collTile do
    local tile = collTile[i]
    local isColl = BdBoxCollision(box, self.size, tile.pos, tile.size)

    -- 仅当四个方向都碰撞时处理
    if isColl[1] and isColl[2] and isColl[3] and isColl[4] then
        -- 优先处理Y轴碰撞(落地/头顶撞墙)
        local playerCenterY = box.y + self.size.y / 2
        local tileCenterY = tile.pos.y + tile.size.y / 2

        if playerCenterY < tileCenterY then
            -- 玩家碰撞tile顶部(落地)
            if box.y + self.size.y > tile.pos.y then
                self.pos.y = tile.pos.y - self.size.y
                self.vel.y = 0
                isOnGround = true
            end
        else
            -- 玩家碰撞tile底部(头顶撞墙)
            if box.y < tile.pos.y + tile.size.y then
                self.pos.y = tile.pos.y + tile.size.y
                self.vel.y = 0
            end
        end

        -- 处理X轴碰撞(贴墙),仅当玩家与tile在Y轴有重叠(侧面碰撞)
        local playerBottom = self.pos.y + self.size.y
        local tileTop = tile.pos.y
        local playerTop = self.pos.y
        local tileBottom = tile.pos.y + tile.size.y

        if playerTop < tileBottom and playerBottom > tileTop then
            local playerCenterX = box.x + self.size.x / 2
            local tileCenterX = tile.pos.x + tile.size.x / 2

            if playerCenterX < tileCenterX then
                -- 玩家碰撞tile左侧(向右移动时)
                if box.x + self.size.x > tile.pos.x and self.dirX == 1 then
                    self.pos.x = tile.pos.x - self.size.x
                    self.vel.x = 0
                    isOnWall = true
                end
            else
                -- 玩家碰撞tile右侧(向左移动时)
                if box.x < tile.pos.x + tile.size.x and self.dirX == -1 then
                    self.pos.x = tile.pos.x + tile.size.x
                    self.vel.x = 0
                    isOnWall = true
                end
            end
        end
    end
end

-- 应用重力(仅当不在地面时)
if not isOnGround then
    self.vel.y = self.vel.y + self.gravity * dt
end

-- 更新玩家位置
self.pos.x = self.pos.x + self.vel.x * dt
self.pos.y = self.pos.y + self.vel.y * dt

修复说明

  1. 调整碰撞处理顺序:优先处理Y轴碰撞,确保落地/头顶撞墙的逻辑先生效,避免X轴碰撞干扰垂直方向的移动。
  2. 严格X轴碰撞触发条件:只有当玩家与tile在Y轴范围有重叠(即确实处于tile侧面)时,才触发墙碰撞的X速度重置。
  3. 修正Y轴碰撞逻辑:头顶撞墙时将玩家位置调整到tile上方,并重置Y速度;重力仅在玩家不在地面时应用,避免落地后持续加速。
  4. 增加状态标记:用isOnGround和isOnWall管理玩家状态,逻辑更清晰。

内容的提问来源于stack exchange,提问作者SpinRoleDevelop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 19:10:19