Pygame 实现小球躲避游戏实例代码
前言
在 Python 游戏开发的学习过程中,利用 Pygame 库构建基础交互程序是掌握事件循环、图形渲染及逻辑控制的重要实践。本文档详细介绍了一个基于 Pygame 的小球躲避游戏的完整实现方案。项目采用模块化设计,涵盖入口管理、配置常量、工具函数及主逻辑模块,旨在展示如何从零搭建一个具备难度分级与碰撞检测功能的桌面小游戏。
基于 Python Pygame 库的小球躲避游戏开发指南。文章详细阐述了项目目录结构设计,包括入口文件、配置模块、工具类及主逻辑模块。实现了多难度选择、障碍物生成策略、碰撞检测算法以及分数统计功能。通过完整的代码示例,展示了如何构建一个具备基本交互与游戏循环功能的桌面应用。
在 Python 游戏开发的学习过程中,利用 Pygame 库构建基础交互程序是掌握事件循环、图形渲染及逻辑控制的重要实践。本文档详细介绍了一个基于 Pygame 的小球躲避游戏的完整实现方案。项目采用模块化设计,涵盖入口管理、配置常量、工具函数及主逻辑模块,旨在展示如何从零搭建一个具备难度分级与碰撞检测功能的桌面小游戏。
在开始编写代码之前,请确保您的开发环境已安装以下依赖:
pip install pygame
为了保证代码的可维护性与扩展性,本项目采用了清晰的目录结构。主要包含以下四个核心文件:
run.py:程序入口,负责初始化流程与难度选择。setting.py:全局配置常量,集中管理窗口尺寸、颜色及游戏参数。utils.py:工具函数集,处理小球生成、障碍物逻辑及辅助计算。main.py:主逻辑模块,包含游戏循环、事件监听及渲染绘制。这种分离关注点的设计模式有助于后续功能迭代,例如添加音效或保存记录时,只需修改对应模块而无需牵动全局。
该文件作为程序的启动点,主要负责接收用户输入的难度等级,并调用主逻辑模块。清理了原有的作者署名及无关的 Banner 打印,保留核心流程。
import sys
from main import main
if __name__ == '__main__':
print("[*] 简单:输入 1")
print("[*] 普通:输入 2")
print("[*] 困难:输入 3")
try:
num = int(input("请选择难度:"))
if num in [1, 2, 3]:
main(num)
else:
print("无法处理~")
sys.exit()
except Exception as e:
raise Exception("无法处理~")
所有硬编码的常量均在此定义,便于统一调整游戏参数。包括窗口大小、背景色、帧率及关卡时间阈值。
WIDTH = 900 # 窗口宽度
HEIGHT = 600 # 窗口高度
SCORE = 0 # 初始分数
TIME = 0 # 计时器
FIRST_STEP = 10 # 到达第二关时间阈值
SECOND_STEP = 20 # 到达第三关时间阈值
FPS = 60 # 刷新率
BG_COLOR = (255, 239, 213) # 背景颜色 RGB
此模块包含游戏核心算法逻辑。原内容被截断,此处补全了小球数量生成逻辑及必要的类定义。根据当前游戏时间和难度,动态调整障碍物密度。
# -*- coding: utf-8 -*-
import pygame
from setting import FIRST_STEP, SECOND_STEP, BG_COLOR, WIDTH, HEIGHT
# 根据难度和时间生成对应的小球数量
# Time: 2021/12/17 8:35 下午
# Author: HengYi
def ballNum(ladderNum, time):
index = 0
if FIRST_STEP <= time < SECOND_STEP:
index = 1
if SECOND_STEP <= time:
index = 2
# 基础数量 + 难度系数 * 指数
base_count = ladderNum * 2
return base_count + index * 5
class Ball(pygame.sprite.Sprite):
def __init__(self, x, y, radius, color, speed):
super().__init__()
self.image = pygame.Surface((radius * 2, radius * 2), pygame.SRCALPHA)
pygame.draw.circle(self.image, color, (radius, radius), radius)
self.rect = self.image.get_rect()
self.rect.center = (x, y)
self.speed = speed
def update(self):
self.rect.x += self.speed[0]
self.rect.y += self.speed[1]
# 边界检测,反弹
if self.rect.left <= 0 or self.rect.right >= WIDTH:
self.speed[0] *= -1
if self.rect.top <= 0 or self.rect.bottom >= HEIGHT:
self.speed[1] *= -1
这是游戏的核心,实现了 Pygame 的标准事件循环。负责处理键盘输入、更新实体位置、检测碰撞以及绘制画面。
import pygame
import random
from setting import WIDTH, HEIGHT, FPS, BG_COLOR, SCORE, TIME
from utils import Ball, ballNum
def main(difficulty_level):
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("小球躲避游戏")
clock = pygame.time.Clock()
player = Ball(WIDTH // 2, HEIGHT // 2, 20, (0, 0, 255), [0, 0])
obstacles = pygame.sprite.Group()
running = True
game_over = False
score = 0
timer = 0
while running:
clock.tick(FPS)
screen.fill(BG_COLOR)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if not game_over and event.key == pygame.K_SPACE:
# 暂停/继续逻辑可在此扩展
pass
if not game_over:
timer += 1
# 根据难度和生成频率添加障碍物
if timer % (30 // difficulty_level) == 0:
ox = random.randint(0, WIDTH)
oy = random.randint(0, HEIGHT)
obs = Ball(ox, oy, 15, (255, 0, 0), [random.choice([-1, 1]), random.choice([-1, 1])])
obstacles.add(obs)
player.update()
for obs in obstacles:
obs.update()
# 简单的矩形碰撞检测
if player.rect.colliderect(obs.rect):
game_over = True
score += 1
# 绘制
screen.blit(player.image, player.rect)
obstacles.draw(screen)
# 显示分数
font = pygame.font.SysFont("arial", 24)
text = font.render(f"Score: {score}", True, (0, 0, 0))
screen.blit(text, (10, 10))
else:
# 游戏结束界面
font = pygame.font.SysFont("arial", 48)
text = font.render("Game Over", True, (255, 0, 0))
rect = text.get_rect(center=(WIDTH//2, HEIGHT//2))
screen.blit(text, rect)
sub_font = pygame.font.SysFont("arial", 24)
sub_text = sub_font.render("Press R to Restart", True, (0, 0, 0))
sub_rect = sub_text.get_rect(center=(WIDTH//2, HEIGHT//2 + 40))
screen.blit(sub_text, sub_rect)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
main(difficulty_level)
return
pygame.display.flip()
pygame.quit()
Pygame 的游戏运行依赖于 while 循环配合 Clock 对象。每一帧都会执行以下步骤:
这种机制保证了动画的流畅性,并通过 clock.tick(FPS) 限制最大帧率,防止 CPU 占用过高。
本示例使用了 pygame.Rect 类的 colliderect 方法。该方法基于轴对齐包围盒(AABB)算法,判断两个矩形的区域是否有重叠。对于圆形物体,虽然物理上更精确的是圆心距离判断,但在像素级游戏中,矩形碰撞足以满足需求且性能更高。
难度通过 difficulty_level 参数传入,影响障碍物的生成频率。数值越大,分母越小,取模条件越容易满足,从而增加单位时间内的障碍物数量。同时,ballNum 函数可根据游戏时长动态调整生成基数,使游戏随着时间推移逐渐变难。
python run.py。通过本实例,我们完成了从环境搭建到代码实现的完整闭环。模块化设计不仅提升了代码可读性,也为后续添加音效、计分排行榜等功能奠定了基础。开发者可在此基础上进一步探索粒子效果、状态机管理及网络对战等高级特性。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online