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

Pong游戏开发问题:球碰撞Paddle后始终直线反弹如何解决?

解决Pong球碰撞Paddle时固定反弹方向的问题

当前你的球使用velocity.bounce(collision.get_normal())处理反弹,这只会基于碰撞法线(竖直Paddle的法线为水平方向)做标准反弹,y方向速度始终不变,导致无论撞Paddle哪个位置都是直线反弹。要实现随碰撞位置改变反弹方向,需要结合碰撞点在Paddle上的相对位置调整y方向速度。

修改后的Ball代码

extends CharacterBody2D

var speed: int = 14
# 控制y方向偏移强度,数值越大,碰撞边缘时y方向速度变化越明显
var bounce_strength: float = 0.8

func _ready():
    var target_position = Vector2(0, 350)
    var direction = global_position.direction_to(target_position)
    velocity = direction.normalized() * speed

func _physics_process(delta):
    var collision = move_and_collide(velocity)
    
    if collision != null:
        # 仅处理与Paddle的碰撞
        if collision.get_collider() is CharacterBody2D:
            var paddle = collision.get_collider()
            # 将碰撞点转换为Paddle局部坐标系位置
            var local_hit_pos = paddle.global_to_local(collision.get_position())
            # 计算碰撞点在Paddle高度上的相对比例,范围-1(顶部)到1(底部)
            var y_ratio = local_hit_pos.y / (paddle.size.y / 2)
            # 反转x方向速度,同时根据比例调整y方向速度
            var new_x_velocity = -velocity.x
            var new_y_velocity = velocity.y + y_ratio * speed * bounce_strength
            # 归一化速度并保持原速度大小,避免速度异常波动
            velocity = Vector2(new_x_velocity, new_y_velocity).normalized() * speed
        else:
            # 墙壁等其他碰撞仍使用标准反弹
            velocity = velocity.bounce(collision.get_normal())

原理说明

  • 碰撞点相对定位:通过global_to_local将碰撞点转换为Paddle局部坐标,明确球撞在Paddle的顶部、中间还是底部。
  • 比例映射:将碰撞点y坐标除以Paddle半高,得到-1到1的比例值,代表碰撞点偏离中心的程度。
  • 速度调整:反转x方向速度保证水平反弹的基础逻辑,同时根据比例值给y方向速度添加偏移,碰撞边缘时y方向速度变化更显著,实现不同反弹角度。
  • 速度归一化:调整后重新归一化速度并乘以原speed,确保球的总速度始终一致,避免因碰撞位置导致速度忽快忽慢。

额外优化建议

  • 可调整bounce_strength数值控制反弹角度灵敏度,数值越大,碰撞边缘时球的y方向速度变化越剧烈。
  • 若Paddle非竖直方向,需调整坐标计算逻辑,保证比例计算准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:59:52