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

如何修复Flappy Bird克隆游戏中的碰撞检测代码?

Flappy Bird碰撞检测问题修复方案

核心问题分析

碰撞检测失效的核心原因:

  • 碰撞逻辑依赖静态的pipe_1/pipe_2列表,完全没用到实际在屏幕上移动的pipes1/pipes2中的管道对象
  • 小鸟位置管理混乱:bird[1]未同步实际显示的y_pos,导致碰撞检测用了错误的Y坐标
  • 碰撞判定的半径值完全不符合图形实际尺寸
  • 管道初始化和移动逻辑存在错误(比如pipes2错误添加pipe1、管道移动速度设置异常)

修复后的完整代码

import turtle as t
import random

# 屏幕设置
wn = t.Screen()
wn.setup(width=600, height=800)  # 明确窗口尺寸,替代模糊的screensize
wn.title("Flappy Bird")
wn.bgcolor("light blue")
wn.tracer(0)  # 手动控制刷新,提升游戏流畅度

# 小鸟配置
bird_radius = 15  # 对应shapesize(1,1)的实际碰撞半径
b = t.Turtle()
b.penup()
b.shape("circle")
b.shapesize(1, 1)
b.color("yellow")
b.goto(-200, 0)

bird_y_vel = 0
gravity = -0.5
flap_force = 8

# 管道配置
pipe_width = 100  # shapesize(5,5)对应实际宽度:5*20=100
pipe_height = 400  # shapesize(20,5)对应实际高度:20*20=400
pipes1 = []  # 上管道列表
pipes2 = []  # 下管道列表

def flap():
    global bird_y_vel
    bird_y_vel = flap_force

wn.onkeypress(flap, "Up")
wn.listen()

# 创建管道的工具函数
def create_pipe(is_top):
    pipe = t.Turtle()
    pipe.penup()
    pipe.shape('square')
    pipe.shapesize(20, 5)
    pipe.color('green')
    pipe.dx = -2  # 统一管道移动速度
    x_pos = 300
    if is_top:
        y_pos = random.randint(100, 300)
    else:
        y_pos = random.randint(-300, -100)
    pipe.goto(x_pos, y_pos)
    return pipe

# 生成初始管道
pipes1.append(create_pipe(True))
pipes2.append(create_pipe(False))

# 碰撞检测函数(矩形碰撞判定,适配管道形状)
def check_collision(bird, pipe):
    bird_x, bird_y = bird.pos()
    pipe_x, pipe_y = pipe.pos()
    
    # 计算碰撞边界
    bird_left = bird_x - bird_radius
    bird_right = bird_x + bird_radius
    bird_top = bird_y + bird_radius
    bird_bottom = bird_y - bird_radius
    
    pipe_left = pipe_x - pipe_width/2
    pipe_right = pipe_x + pipe_width/2
    pipe_top = pipe_y + pipe_height/2
    pipe_bottom = pipe_y - pipe_height/2
    
    # 判断是否发生碰撞
    return (bird_right > pipe_left and bird_left < pipe_right) and (bird_top > pipe_bottom and bird_bottom < pipe_top)

# 主游戏循环
while True:
    # 小鸟移动逻辑
    bird_y_vel += gravity
    b.sety(b.ycor() + bird_y_vel)
    
    # 上管道处理
    for pipe in pipes1:
        pipe.setx(pipe.xcor() + pipe.dx)
        # 管道移出屏幕则替换
        if pipe.xcor() < -400:
            pipes1.remove(pipe)
            pipes1.append(create_pipe(True))
        # 碰撞检测
        if check_collision(b, pipe):
            print("碰撞!游戏结束")
            wn.bye()
            exit()
    
    # 下管道处理
    for pipe in pipes2:
        pipe.setx(pipe.xcor() + pipe.dx)
        if pipe.xcor() < -400:
            pipes2.remove(pipe)
            pipes2.append(create_pipe(False))
        # 碰撞检测
        if check_collision(b, pipe):
            print("碰撞!游戏结束")
            wn.bye()
            exit()
    
    # 屏幕边界碰撞检测
    if b.ycor() > 380 or b.ycor() < -380:
        print("撞边界!游戏结束")
        wn.bye()
        exit()
    
    wn.update()

wn.mainloop()

关键修改说明

  • 移除冗余的静态列表,直接通过Turtle对象的pos()获取实时位置
  • 用矩形碰撞判定替代圆形判定,适配管道的矩形形状
  • 修复管道初始化错误,分离上下管道生成逻辑
  • 统一管道移动速度,修正原代码中速度异常的问题
  • 添加屏幕边界碰撞检测,完善游戏逻辑
  • 启用手动刷新机制,提升游戏运行流畅度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:17:06