【MVCD 7】
2026/4/12 16:02:54 网站建设 项目流程

CS 41 课程九:游戏开发(5月24日)

一、课程基本信息

日期:2023年5月24日
主题:🐍 Gaming(游戏开发)

课程安排

下周预览

  • 单元测试(Unit Testing)
  • Pygame游戏开发

二、使用Python制作游戏

1. 游戏示例展示

Example Games(课堂演示各种Python游戏)

2. Pygame安装

安装说明

  • Pygame是非标准库包(上周学习内容)
  • 需要使用pip安装
pipinstallpygame

三、游戏循环(Game Loop)

1. 游戏循环概念

核心作用

  • 游戏控制的中心
  • 更新游戏状态
  • 每个循环周期就是一帧(frame)

基本结构

running=Truewhilerunning:# 1. 处理事件# 2. 更新游戏状态# 3. 绘制画面# 4. 刷新显示

四、事件系统(Events)

1. 什么是事件?

定义

  • 用户操作,游戏循环围绕这些操作展开
  • 通过事件处理器(event handler)访问
  • 每个事件都有一个类型

2. 事件类型

常见事件类型

事件类型说明
QUIT退出事件
ACTIVEEVENT窗口激活事件
KEYDOWN按键按下
KEYUP按键释放
MOUSEMOTION鼠标移动
MOUSEBUTTONUP鼠标按钮释放
MOUSEBUTTONDOWN鼠标按钮按下
JOYAXISMOTION游戏手柄轴移动
JOYBALLMOTION游戏手柄球移动
JOYHATMOTION游戏手柄帽移动
JOYBUTTONUP游戏手柄按钮释放
JOYBUTTONDOWN游戏手柄按钮按下
VIDEORESIZE视频窗口调整大小
VIDEOEXPOSE视频窗口曝光
USEREVENT用户自定义事件

3. 事件队列

访问事件

foreventinpygame.event.get():# 处理事件

事件对象示例

<Event(768-KeyDown{'unicode':'','key':1073741906,'mod':0,'scancode':82,'window':None})><Event(769-KeyUp{'unicode':'','key':1073741906,'mod':0,'scancode':82,'window':None})>

特点

  • 事件存储在队列中
  • 按顺序处理
  • 包含详细的事件信息

五、第一个图形窗口

1. 完整代码示例

importpygame pygame.init()screen=pygame.display.set_mode((500,500))white=(255,255,255)blue=(0,0,255)running=Truewhilerunning:foreventinpygame.event.get():ifevent.type==pygame.QUIT:running=False# 用白色填充背景screen.fill(white)# 在中心绘制蓝色实心圆pygame.draw.circle(screen,blue,(250,250),75)# 更新显示pygame.display.update()# 或使用 pygame.display.flip()# 游戏结束时pygame.quit()

2. 代码详解

(1) 初始化窗口
importpygame pygame.init()screen=pygame.display.set_mode((500,500))
  • 导入pygame库
  • 初始化pygame
  • 创建500x500像素的窗口
(2) 定义颜色
white=(255,255,255)blue=(0,0,255)
  • 使用RGB元组表示颜色
  • (R, G, B) 每个值范围0-255
(3) 初始化游戏循环
running=Truewhilerunning:
  • 控制游戏运行状态
  • 循环直到running变为False
(4) 获取事件队列
foreventinpygame.event.get():
  • 获取所有事件
  • 遍历事件队列
(5) 检查事件类型
ifevent.type==pygame.QUIT:running=False
  • 检查是否点击关闭按钮
  • 退出游戏循环
(6) 绘制图形
screen.fill(white)pygame.draw.circle(screen,blue,(250,250),75)
  • screen.fill(white): 填充背景色
  • pygame.draw.circle(): 绘制圆形
    • 参数1: 绘制表面
    • 参数2: 颜色
    • 参数3: (x, y) 圆心坐标
    • 参数4: 半径
(7) 更新显示
pygame.display.update()# 或 pygame.display.flip()
  • 刷新屏幕显示
  • 显示所有绘制内容

运行代码:Let’s run this code


六、制作贪吃蛇游戏

1. 绘制矩形基础

pygame.draw.rect(surface,color,rect)

参数说明

  • surface: 绘制表面(screen)
  • color: 颜色元组
  • rect: 矩形[left, top, width, height]

示例

# 绘制一个蛇的方块pygame.draw.rect(screen,blue,[100,100,10,10])

2. 键盘控制

检测按键事件
ifevent.type==pygame.KEYDOWN:ifevent.key==pygame.K_LEFT:# 向左移动ifevent.key==pygame.K_RIGHT:# 向右移动ifevent.key==pygame.K_UP:# 向上移动ifevent.key==pygame.K_DOWN:# 向下移动

按键常量

  • pygame.K_LEFT: 左箭头
  • pygame.K_RIGHT: 右箭头
  • pygame.K_UP: 上箭头
  • pygame.K_DOWN: 下箭头

3. 蛇的表示与移动

数据结构
# 使用坐标元组列表表示蛇snake=[(100,100),(100,110),(100,120)]
移动策略问题

方法1:更新所有坐标(复杂)

问题:蛇头需要向下移动snake_size 但需要遍历整个列表更新所有过去的坐标 :(

方法2:添加和删除(优雅)✓

步骤1: 在蛇头应该在的位置添加新方块 步骤2: 删除最后一个方块

图示

移动前: [█][█][█] ↓ 添加新头: [█][█][█][█] ↓ 删除尾部: [█][█][█] (新位置)

4. 动画速度控制

时钟控制

pygame.time.Clock().tick(15)

作用

  • 确保游戏循环最多以每秒15帧运行
  • 放在循环内部
  • 控制游戏速度,使其在不同电脑上表现一致

帧率说明

# 慢速游戏pygame.time.Clock().tick(10)# 10 FPS# 正常速度pygame.time.Clock().tick(15)# 15 FPS# 快速游戏pygame.time.Clock().tick(30)# 30 FPS

七、完整贪吃蛇代码实现

1. 常量和初始化

importtimeimportrandomimportpygame# 常量和变量white=(255,255,255)blue=(50,153,213)green=(0,255,0)dis_width=600dis_height=400block_size=10snake_length=15# 初始化pygame窗口pygame.init()screen=pygame.display.set_mode((dis_width,dis_height))pygame.display.set_caption('CS 41 PYTHON')

2. 辅助函数

(1) 初始化蛇
definitialize_snake(len,start_left,start_top):initialize_snake=[]foriinrange(len):initialize_snake.append((start_left,start_top+(block_size*i)))returninitialize_snake
(2) 绘制蛇
defdraw_snake(snake_coords):forx,yinsnake_coords:pygame.draw.rect(screen,blue,[x,y,block_size,block_size])
(3) 更新蛇的位置
defupdate_snake(x,y,snake):snake.append((x,y))iflen(snake)>snake_length:delsnake[0]returnsnake

工作原理

  • 在蛇头位置添加新方块
  • 如果蛇长度超过限制,删除尾部
  • 实现"移动"效果
(4) 生成食物
defgenerate_food(snake):whileTrue:food_x=random.randrange(0,dis_width,block_size)food_y=random.randrange(0,dis_height,block_size)if(food_x,food_y)notinsnake:returnfood_x,food_y

重要细节

  • 使用random.randrange()生成随机坐标
  • 步长为block_size确保食物在网格上
  • 检查食物不与蛇重叠
(5) 绘制食物
defdraw_food(food_x,food_y):pygame.draw.rect(screen,green,[food_x,food_y,block_size,block_size])
(6) 碰撞检测
defcheck_collision(snake_head,food_x,food_y):ifsnake_head[0]==food_xandsnake_head[1]==food_y:returnTruereturnFalse

3. 主游戏函数

defgame():globalsnake_length# 使用全局变量running=Truex_change=0y_change=0x=dis_width/2y=dis_height/2snake=initialize_snake(snake_length,x,y)food_x,food_y=generate_food(snake)whilerunning:screen.fill(white)draw_snake(snake)draw_food(food_x,food_y)foreventinpygame.event.get():ifevent.type==pygame.QUIT:running=Falseifevent.type==pygame.KEYDOWN:ifevent.key==pygame.K_LEFT:x_change=-block_size y_change=0ifevent.key==pygame.K_RIGHT:x_change=block_size y_change=0ifevent.key==pygame.K_UP:x_change=0y_change=-block_sizeifevent.key==pygame.K_DOWN:x_change=0y_change=block_size x+=x_change y+=y_change snake=update_snake(x,y,snake)ifcheck_collision(snake[-1],food_x,food_y):snake_length+=1food_x,food_y=generate_food(snake)draw_snake(snake)pygame.time.Clock().tick(15)pygame.display.flip()pygame.quit()if__name__=="__main__":game()

4. 游戏逻辑流程

每帧执行步骤

1. 清空屏幕(填充白色) 2. 绘制蛇和食物 3. 处理事件(键盘输入、退出) 4. 更新蛇的位置 5. 检查是否吃到食物 6. 如果吃到食物: - 增加蛇的长度 - 生成新食物 7. 重新绘制 8. 控制帧率(15 FPS) 9. 刷新显示

八、小组活动

活动说明

任务:为贪吃蛇游戏添加食物功能

准备工作

  • 确保已安装pygame:pip install pygame
  • 从网站下载starter code

功能要求

  1. 食物碰撞

    • 当蛇碰到食物时,蛇增长1个单位
  2. 食物生成

    • 食物应该出现在窗口的随机位置
    • 被吃掉后重新出现
  3. 提示

    • 思考蛇移动的倍数
    • 食物坐标应该只在这些倍数位置上
  4. 扩展功能(可选):

    • 如果想添加其他有趣的功能,随意发挥!

实现建议

关键点

# 1. 食物坐标必须是block_size的倍数food_x=random.randrange(0,dis_width,block_size)food_y=random.randrange(0,dis_height,block_size)# 2. 检测碰撞ifsnake_head==(food_x,food_y):snake_length+=1# 生成新食物# 3. 确保食物不在蛇身上while(food_x,food_y)insnake:# 重新生成

九、课程总结

Pygame核心概念

游戏开发三要素

1. 游戏循环(Game Loop) └─ 持续运行直到游戏结束 2. 事件处理(Event Handling) └─ 响应用户输入 3. 绘制更新(Draw & Update) └─ 显示游戏状态

游戏循环模式

# 标准游戏循环模式pygame.init()screen=pygame.display.set_mode((width,height))clock=pygame.time.Clock()running=Truewhilerunning:# 1. 处理事件foreventinpygame.event.get():ifevent.type==pygame.QUIT:running=False# 其他事件处理# 2. 更新游戏逻辑# 更新位置、检测碰撞等# 3. 绘制screen.fill(background_color)# 绘制游戏元素# 4. 刷新和控制帧率pygame.display.flip()clock.tick(FPS)pygame.quit()

Pygame常用函数速查

初始化与窗口

pygame.init()screen=pygame.display.set_mode((width,height))pygame.display.set_caption('Title')

事件处理

pygame.event.get()# 获取所有事件event.type# 事件类型event.key# 按键值

绘制函数

screen.fill(color)# 填充背景pygame.draw.circle(screen,color,(x,y),r)# 圆形pygame.draw.rect(screen,color,[x,y,w,h])# 矩形pygame.draw.line(screen,color,(x1,y1),(x2,y2))# 线条

显示更新

pygame.display.flip()# 刷新整个屏幕pygame.display.update()# 更新特定区域

时间控制

clock=pygame.time.Clock()clock.tick(FPS)# 控制帧率

贪吃蛇实现要点

数据结构选择

# 用列表存储蛇的所有方块snake=[(x1,y1),(x2,y2),(x3,y3)]# 蛇头:snake[-1]# 蛇尾:snake[0]

移动算法

# 添加新头snake.append((new_x,new_y))# 删除旧尾(如果没吃食物)ifnotate_food:delsnake[0]

网格对齐

# 确保所有坐标都是block_size的倍数x=random.randrange(0,width,block_size)y=random.randrange(0,height,block_size)

可能的扩展功能

基础扩展

  1. 添加得分显示
  2. 增加游戏难度(随时间加速)
  3. 添加边界检测(撞墙游戏结束)
  4. 添加自咬检测(蛇咬到自己)

进阶扩展
5. 多个食物
6. 特殊食物(加速/减速/双倍分数)
7. 障碍物
8. 暂停功能
9. 最高分记录
10. 音效和背景音乐

调试技巧

常见问题

# 1. 窗口一闪而过# 解决:确保有游戏循环和事件处理# 2. 游戏太快/太慢# 解决:调整clock.tick()的参数# 3. 绘制不显示# 解决:确保调用了pygame.display.flip()# 4. 蛇移动不连续# 解决:确保坐标是block_size的倍数

学习资源

官方文档

  • Pygame官网:https://www.pygame.org/
  • Pygame文档:https://www.pygame.org/docs/

教程推荐

  • Pygame官方教程
  • Real Python的Pygame系列
  • YouTube上的游戏开发教程

关键要点

  1. 游戏循环是核心

    • 所有游戏都基于循环
    • 每帧更新状态和绘制
  2. 事件驱动编程

    • 响应用户输入
    • 处理各种事件类型
  3. 帧率控制重要

    • 使用Clock控制速度
    • 保证不同设备体验一致
  4. 数据结构选择

    • 合适的数据结构简化逻辑
    • 列表非常适合表示蛇
  5. 模块化设计

    • 将功能分解为函数
    • 提高代码可读性和可维护性

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询