Pygame开发Flappy Bird时管道生成、移动、销毁功能如何实现
管道功能实现方案
首先明确:不需要给管道设置加速度,这类横版躲避游戏的管道默认采用匀速左移的逻辑即可,实现步骤和修改后的代码如下:
核心实现逻辑
- 用列表存储所有存活的管道数据,每个管道对包含上下两个
pygame.Rect对象 - 随机生成:调用
random.randint()随机设置上下管道的间隙位置,每间隔固定帧数在屏幕右侧外生成新管道对 - 移动逻辑:每帧遍历所有管道,x坐标统一减去固定移动速度,实现匀速左移
- 销毁逻辑:管道完全移出屏幕左边界时,直接从列表中移除该管道对
- 碰撞检测:调用
playerrect.colliderect(管道rect)即可快速判断是否发生碰撞
修改后可运行代码
# 软盘飞鸟游戏 import sys, pygame, random from pygame import mixer import time pygame.init() pygame.mixer.init() FRAMERATE = 60 clock = pygame.time.Clock() # 音乐加载(本地有对应文件可以取消注释) # mixer.music.load('africa-toto.wav') # mixer.music.play(1, 0.0, 3000) size = width, height = 1000, 1000 # 管道移动速度,固定值即可不需要加速度 PIPE_SPEED = 2 # 管道参数 PIPE_WIDTH = 100 PIPE_GAP = 200 # 上下管道的间隙高度 # 生成管道的间隔帧数(每2秒生成一组新管道) SPAWN_INTERVAL = 120 power = [0.1, 0.1] white = 255, 255, 255 black = 0, 0, 0 blue = 0, 255, 200 green = 0, 200, 0 dy = 2 screen = pygame.display.set_mode(size) # 玩家加载(注意替换为自己的图片路径) player1 = pygame.image.load("floppy1.jpg") pygame.key.set_repeat(1,1) playerrect = player1.get_rect() # 初始化玩家位置到左侧 playerrect.x = 100 playerrect.y = height//2 background_image = pygame.image.load("circuit.jpeg").convert() # 存储所有管道的列表,每个元素是[上管道rect, 下管道rect] pipes = [] # 计数帧,用来控制管道生成间隔 frame_count = 0 def spawn_pipe(): """生成随机位置的管道对""" # 随机生成间隙的y坐标位置 gap_y = random.randint(200, height - 200 - PIPE_GAP) top_pipe = pygame.Rect(width, 0, PIPE_WIDTH, gap_y) bottom_pipe = pygame.Rect(width, gap_y + PIPE_GAP, PIPE_WIDTH, height - gap_y - PIPE_GAP) pipes.append([top_pipe, bottom_pipe]) def draw_pipes(): """绘制所有管道""" for top, bottom in pipes: pygame.draw.rect(screen, green, top) pygame.draw.rect(screen, green, bottom) def move_pipes(): """移动所有管道,并且销毁移出屏幕的管道""" global pipes new_pipes = [] for top, bottom in pipes: top.x -= PIPE_SPEED bottom.x -= PIPE_SPEED # 只要管道还没完全移出左边界就保留 if top.right > 0: new_pipes.append([top, bottom]) pipes = new_pipes def check_collision(): """检测玩家和管道是否碰撞""" for top, bottom in pipes: if playerrect.colliderect(top) or playerrect.colliderect(bottom): return True # 碰到上下边界也算碰撞 if playerrect.top < 0 or playerrect.bottom > height: return True return False while True: clock.tick(FRAMERATE) frame_count += 1 # 到间隔时间就生成新管道 if frame_count % SPAWN_INTERVAL == 0: spawn_pipe() # 玩家重力逻辑 if dy > 0: dy *= 1.03 if dy < 2: dy *= 1.03 if dy < 0: dy *= 0.9 if dy > -1.3: dy *= 0.95 if dy < 0 and dy > -0.6: # 减速点 dy *= -1.2 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: dy = -10 if event.key == pygame.K_DOWN: dy = 10 # 移动玩家 playerrect = playerrect.move(0, dy) # 移动管道 move_pipes() # 碰撞检测 if check_collision(): # 这里可以自定义游戏结束逻辑,当前直接退出方便测试 print("游戏结束!") pygame.quit() sys.exit() # 绘制内容 screen.blit(background_image, [0,0]) screen.blit(player1, playerrect) draw_pipes() pygame.display.flip()
参数调整说明
- 修改
PIPE_SPEED可以调整管道移动速度,数值越大管道移动越快 - 修改
PIPE_GAP可以调整上下管道的间隙大小,数值越小游戏难度越高 - 修改
SPAWN_INTERVAL可以调整管道生成的间隔,数值越小管道生成越密集
内容的提问来源于stack exchange,提问作者KGGaming Fluff
相关产品推荐
相关产品推荐

