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

Roblox PONG游戏:小球方向异常与碰撞失效问题求助

修复Roblox PONG游戏的小球移动与碰撞问题

问题根源分析

1. 小球持续斜向移动

你的初始ballSpeed设置了固定Y轴速度0.01,导致小球从一开始就会向下偏移,再加上上下边界碰撞判断未考虑UI锚点逻辑,Y方向速度无法正确反弹,最终持续朝斜向移动。

2. 碰撞检测完全失效

Roblox UI元素的Position默认基于AnchorPoint(0.5, 0.5)(元素中心位置),但你的碰撞逻辑错误地将Position.Y.Scale当成元素左上角坐标,导致边界计算完全错误,无法检测到与球拍或容器的碰撞。

修复后的完整代码

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local ball = script.Parent.ball
local frame1 = script.Parent.Frame1
local frame2 = script.Parent.Frame2

-- 初始化小球速度:初始水平方向随机,Y方向设为0实现纯左右飞行,需斜向可改为±0.005
local initialXDir = math.random(0, 1) == 0 and -0.01 or 0.01
local ballSpeed = Vector2.new(initialXDir, 0)

-- 获取UI元素的实际边界(基于默认锚点(0.5,0.5)计算)
local function getElementBounds(element)
    local pos = element.Position
    local size = element.Size
    return {
        left = pos.X.Scale - size.X.Scale/2,
        right = pos.X.Scale + size.X.Scale/2,
        top = pos.Y.Scale - size.Y.Scale/2,
        bottom = pos.Y.Scale + size.Y.Scale/2
    }
end

local function moveFrames(direction)
    local deltaY = direction == "up" and -0.05 or 0.05 -- 调整步长避免移动过快
    local frame1Bounds = getElementBounds(frame1)
    local frame2Bounds = getElementBounds(frame2)

    -- 确保左球拍不超出容器范围
    local newFrame1Top = frame1Bounds.top + deltaY
    if newFrame1Top >= 0 and newFrame1Top + frame1.Size.Y.Scale <= 1 then
        frame1.Position = frame1.Position + UDim2.new(0, 0, deltaY, 0)
    end

    -- 确保右球拍不超出容器范围
    local newFrame2Top = frame2Bounds.top + deltaY
    if newFrame2Top >= 0 and newFrame2Top + frame2.Size.Y.Scale <= 1 then
        frame2.Position = frame2.Position + UDim2.new(0, 0, deltaY, 0)
    end
end

local function onInputBegan(input, gameProcessed)
    if gameProcessed then return end

    if input.KeyCode == Enum.KeyCode.W then
        moveFrames("up")
    elseif input.KeyCode == Enum.KeyCode.S then
        moveFrames("down")
    end
end

local function updateBallPosition()
    ball.Position = ball.Position + UDim2.new(ballSpeed.X, 0, ballSpeed.Y, 0)
end

local function checkBallCollision()
    local ballBounds = getElementBounds(ball)
    local frame1Bounds = getElementBounds(frame1)
    local frame2Bounds = getElementBounds(frame2)

    -- 上下边界碰撞:反转Y速度并修正位置避免卡边界
    if ballBounds.top <= 0 or ballBounds.bottom >= 1 then
        ballSpeed = Vector2.new(ballSpeed.X, -ballSpeed.Y)
        ball.Position = ballBounds.top <= 0 
            and UDim2.new(ball.Position.X.Scale, 0, ball.Size.Y.Scale/2, 0)
            or UDim2.new(ball.Position.X.Scale, 0, 1 - ball.Size.Y.Scale/2, 0)
    end

    -- 左球拍碰撞:反转X速度并修正位置避免卡球拍
    if ballBounds.left <= frame1Bounds.right and
       ballBounds.right >= frame1Bounds.left and
       ballBounds.bottom >= frame1Bounds.top and
       ballBounds.top <= frame1Bounds.bottom then
        ballSpeed = Vector2.new(-ballSpeed.X, ballSpeed.Y)
        ball.Position = UDim2.new(frame1Bounds.right + ball.Size.X.Scale/2, 0, ball.Position.Y.Scale, 0)
    end

    -- 右球拍碰撞:反转X速度并修正位置避免卡球拍
    if ballBounds.right >= frame2Bounds.left and
       ballBounds.left <= frame2Bounds.right and
       ballBounds.bottom >= frame2Bounds.top and
       ballBounds.top <= frame2Bounds.bottom then
        ballSpeed = Vector2.new(-ballSpeed.X, ballSpeed.Y)
        ball.Position = UDim2.new(frame2Bounds.left - ball.Size.X.Scale/2, 0, ball.Position.Y.Scale, 0)
    end
end

local function pongGameLoop()
    -- 用Heartbeat替代固定wait,保证帧率稳定
    RunService.Heartbeat:Connect(function()
        checkBallCollision()
        updateBallPosition()
    end)
end

UserInputService.InputBegan:Connect(onInputBegan)
pongGameLoop()

关键修改说明

  • 锚点边界计算:新增getElementBounds函数,基于UI默认锚点(0.5,0.5)正确计算元素实际边界,这是碰撞检测生效的核心。
  • 小球初始速度:将Y轴初始速度设为0,实现纯左右飞行;若需要初始斜向效果,可改为math.random(-0.005, 0.005)生成随机小值。
  • 碰撞后位置修正:碰撞后调整小球位置,避免卡在边界或球拍内部。
  • 游戏循环优化:使用RunService.Heartbeat替代固定时间的wait,让游戏运行更流畅稳定。
  • 球拍移动步长调整:将步长从0.1改为0.05,避免移动幅度过大导致操作不精准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:10:42