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

如何用Python Turtle检测小球与Paddle的碰撞侧边

问题:如何正确检测小球与Paddle侧边/顶面的碰撞

你当前用==判断碰撞位置的逻辑存在问题——小球是连续移动的,几乎不可能刚好卡到那个精确数值,所以效果很差。另外,碰撞范围的判断也可以更清晰,下面是修正方案:

核心修正点

  • 放弃用==做位置判断,改用范围区间检测碰撞
  • 明确计算Paddle和小球的实际边界尺寸,避免硬编码数值
  • 区分侧边碰撞和顶面碰撞的条件:
    • 侧边碰撞:小球Y坐标落在Paddle的垂直范围内,且X坐标触碰到Paddle的左右边缘
    • 顶面碰撞:小球X坐标落在Paddle的水平范围内,且Y坐标触碰到Paddle的上边缘

修改后的完整代码

from turtle import Turtle, Screen
import time
import random

# --------------- GLOBAL VARIABLES --------------------
speed_x = 20
speed_y = 20
bricks = []

# 预定义尺寸,避免硬编码
BALL_RADIUS = 10
PADDLE_WIDTH = 150  # 基础正方形20px * 缩放比例7.5
PADDLE_HEIGHT = 20  # 基础正方形20px * 缩放比例1
PADDLE_HALF_W = PADDLE_WIDTH / 2
PADDLE_HALF_H = PADDLE_HEIGHT / 2

def check_collision():
    global speed_x, speed_y, bricks

    # 左右墙壁碰撞
    if ball.xcor() > (window.window_width() / 2) - BALL_RADIUS or ball.xcor() < -(window.window_width() / 2) + BALL_RADIUS:
        speed_x *= -1
    # 顶部墙壁碰撞
    elif ball.ycor() > (window.window_height() / 2) - BALL_RADIUS:
        speed_y *= -1
    # 底部边界(掉球,可自行扩展重置逻辑)
    elif ball.ycor() < -(window.window_height() / 2) + BALL_RADIUS:
        speed_y *= -1
    # Paddle碰撞检测
    elif (abs(paddle.xcor() - ball.xcor()) < PADDLE_HALF_W + BALL_RADIUS 
          and abs(paddle.ycor() - ball.ycor()) < PADDLE_HALF_H + BALL_RADIUS):
        # 判断是侧边碰撞还是顶面碰撞
        # 侧边碰撞:小球Y坐标在Paddle的垂直区间内
        if (ball.ycor() > paddle.ycor() - PADDLE_HALF_H 
            and ball.ycor() < paddle.ycor() + PADDLE_HALF_H):
            # 根据小球位置判断撞左侧还是右侧
            speed_x = abs(speed_x) * (-1 if ball.xcor() < paddle.xcor() else 1)
        # 顶面碰撞:小球X坐标在Paddle的水平区间内
        else:
            speed_y *= -1

def game_loop():
    ball.goto(ball.xcor() + speed_x, ball.ycor() + speed_y)
    check_collision()

    window.update()
    window.ontimer(game_loop, 1)
    
def move_right():
    paddle.setx(paddle.xcor() + 25)

def move_left():
    paddle.setx(paddle.xcor() - 25)

window = Screen()
time.sleep(2)

ball = Turtle(shape='circle')
ball.pu()
ball.speed(0)
ball.goto(0, -300)
ball.left(random.randint(45, 135))

paddle = Turtle(shape='square')
paddle.speed(0)
paddle.goto(0, -400)
paddle.shapesize(1, 7.5, 3)
paddle.up()

window.listen()
window.onkeypress(move_right, 'Right')
window.onkeypress(move_left, 'Left')
window.onkeypress(move_right, 'd')
window.onkeypress(move_left, 'a')

game_loop()
window.mainloop()

关键说明

  1. 尺寸预定义:把小球半径、Paddle的宽高都定义成变量,后续调整Paddle大小不需要修改碰撞逻辑
  2. 碰撞条件优化:用范围判断替代精确值相等,符合小球连续移动的特性
  3. 侧边碰撞逻辑:先判断小球Y坐标是否在Paddle的垂直区间内,再根据X坐标方向调整速度,确保撞侧边时只改变X方向
  4. 顶面碰撞逻辑:当小球不在Paddle垂直区间但触发碰撞时,判定为撞顶面,改变Y方向速度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 15:53:18