pygame 游戏框架
- 初识 pygame
- 安装 pygame
- pygame 常用模块
- pygame 的基本使用(跳跃的小球游戏)
初识 pygame
pygame 是跨平台 Python 模块,专为电子游戏设计,包含图像、声音。创建在 SDL(Simple Direct Media Layer) 基础上,允许实时电子游戏研发而无需被低级语言、如 C 语言或是更低级的汇编语言束缚。基于这样一个设想,所有需要的游戏功能和理念都(主要是图像方便)完全简化为游戏逻辑本身,所有的资源就够都可以由 Python 提供。
安装 pygame
pygame 的安装非常简单,只需要一行命令:
pip install pygame
安装完后,检测以下是否安装成功,输入如下命令:
import pygame
pygame.ver
运行结果:
pygame 常用模块
用 pygame 做游戏开发的优势在于不需要过多地考虑底层相关的内容,而可以把工作重心放在游戏逻辑上。例如,pygame 中集成了很多和底层相关的模块,如访问显示设备、管理事件、使用字体等。pygame 的常用模块如图:
模块名 | 功能 |
pygame.cdrom | 访问光驱 |
pygame.cursors | 加载光标 |
pygame.display | 访问显示设备 |
pygame.draw | 绘制形状、线和点 |
pygame.event | 管理事件 |
pygame.font | 使用字体 |
pygame.imgae | 加载和存储图片 |
pygame.joystick | 使用游戏手柄或者类似的东西 |
pygame.key | 读取键盘按键 |
pygame.mixer | 声音 |
pygame.mouse | 鼠标 |
pygame.movie | 播放视频 |
pygame.music | 播放音频 |
pygame.overlay | 访问高级视频叠加 |
pygame.rect | 管理矩形区域 |
pygame.sndarray | 操作声音数据 |
pygame.sprite | 操作移动图形 |
pygame.surface | 管理图像和屏幕 |
pygame.surfarray | 管理点阵图像数据 |
pygame.time | 管理时间和帧信息 |
pygame.transform | 缩放和移动图像 |
下面,使用 pygame 的 display 模块和 event 模块创建一个 pygame 窗口,代码如下:
# -*- coding:utf-8 -*-
import sys
import pygame
pygame.init() # 初始化 pygame
size = (width, height) = (300, 240) # 设置窗口
screen = pygame.display.set_mode(size) # 显示窗口
# 执行死循环,确保窗口一直显示
while True:
# 检查事件
for event in pygame.event.get(): # 遍历所有事件
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
sys.exit()
pygame.quit()
运行效果:
pygame 的基本使用(跳跃的小球游戏)
实例:制作一个跳跃的小球游戏
创建一个游戏窗口,然后在窗口内创建一个小球。以一定的速度移动小球,当小球碰到游戏窗口的边缘时,小球弹回,继续移动。按照如下步骤实现:
(1)创建一个游戏窗口,宽和高设置为 640*480。代码如下:
import sys
import pygame
pygame.init() # 初始化pygame
size = (width, height) = (640, 480) # 设置窗口
screen = pygame.display.set_mode(size) # 显示窗口
上述代码中,首先导入 pygame 模块,然后调用 init() 方法初始化 pygame 模块。接下来,设置窗口的宽和高,最后使用 display 模块显示窗体。display 模块的常用方法如下:
方法名 | 功能 |
pygame.display.init | 初始化 display 模块 |
pygame.display.quit | 结束 display 模块 |
pygame.display.get_init | 如果 display 模块已经被初始化,则返回 True |
pygame.display.set_mode | 初始化一个准备显示的界面 |
pygame.display.get_surface | 获取当前的 surface 对象 |
pygame.display.flip | 更新整个待显示的 surface 对象到屏幕上 |
pygame.display.update | 更新部分内容显示到屏幕上,如果没有参数则与 flip 功能相同 |
(2)运行上述代码,会出现一个一闪而过的黑色窗口,这是因为程序执行完成后,会自动关闭。如果让窗口一直显示,需要使用 while True 语句让程序一直运行,此外,还需要设置关闭按钮。具体代码如下:
# -*- coding = UTF-8 -*-
import sys
import pygame
pygame.init() # 初始化pygame
size = (width, height) = (640, 480) # 设置窗口
screen = pygame.display.set_mode(size) # 显示窗口
# 执行死循环,确保窗口一直显示
while True:
# 检查事件
for event in pygame.event.get():
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
sys.exit()
pygame.quit() # 退出 pygame
上述代码中,添加了轮询事件检测。pygame.event.get() 方法能够获取事件队列,使用 for ··· in 语句遍历事件,然后根据 type 属性判断事件类型。这里的事件处理与 GUI 类似,如 event.type 等于 pygame.QUIT,表示检测到关闭 pygame 窗口事件;pygame.KEYDOWN 表示键盘按下事件,pygame.MOUSEBUTTONDOWN 表示鼠标按下事件等。
(3)在窗口中添加小球。先准备好一张 ball.png 图片,然后加载该图片,最后将图片显示在窗口中,具体代码如下:
# -*- coding = UTF-8 -*-
import sys
import pygame
pygame.init() # 初始化pygame
size = (width, height) = (640, 480) # 设置窗口
screen = pygame.display.set_mode(size) # 显示窗口
color = (0, 0, 0) # 设置背景颜色
ball = pygame.image.load("ball.jpg") # 加载图片,返回一个 Surface 对象
ballrect = ball.get_rect() # 获取矩形区域
# 执行死循环,确保窗口一直显示
while True:
# 检查事件
for event in pygame.event.get():
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
sys.exit()
screen.fill(color) # 填充颜色
screen.blit(ball, ballrect) # 将图片画到窗口上
pygame.display.flip() # 更新全部显示
pygame.quit() # 退出 pygame
上书代码中使用 image 模块的 load() 方法加载图片,返回值 ball 是一个 Surface 对象。Surface 是用来代表图片的 pygame 对象,可以对一个 Surface 对象进行涂画、变形、复制等各种操作。事实上,屏幕也只是一个 surface ,pygame.display.set_mode 就返回了一个屏幕 surface 对象。如果将 ball 这个 surface 对象画到 screen Surface 对象,需要使用 bilt() 方法,最后使用 display 模块的 flip 方法更新整个待显示的 Surface 对象到屏幕上。Surface 对象的常用方法如下:
方法名 | 功能 |
pygame.Surface.blit | 将一个图像画到另一个图像上 |
pygame.Surface.convert | 转换图片的像素格式 |
pygame.Surface.convert_alpha | 转换图片的像素格式,包含 alpha 通道的转换 |
pygame.Surface.fill | 使用颜色填充 Surface |
pygame.Surface.get_rect | 获取 Surface 的矩形区域 |
运行上述代码,结果如图所示:
(4)下面该让小球动起来了。ball.get_rect() 方法返回值 ballrect 是一个 Rect 对象,该对象有一个 move() 方法可以用于移动矩形。move(x,y) 函数有两个参数:第一个参数是 x 轴移动的距离;第二个参数是 y 轴移动的距离。窗体左上角坐标为 (0,0)。
为实现小球不停的移动,将 move() 函数添加到 while 循环内,代码如下:
# -*- coding = UTF-8 -*-
import sys
import pygame
pygame.init() # 初始化pygame
size = (width, height) = (640, 480) # 设置窗口
screen = pygame.display.set_mode(size) # 显示窗口
color = (0, 0, 0) # 设置背景颜色
ball = pygame.image.load("ball.jpg") # 加载图片,返回一个 Surface 对象
ballrect = ball.get_rect() # 获取矩形区域
speed = [5, 5] # 设置移动的 x 轴, y 轴距离
# 执行死循环,确保窗口一直显示
while True:
# 检查事件
for event in pygame.event.get():
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
sys.exit()
ballrect = ballrect.move(speed)
screen.fill(color) # 填充颜色
screen.blit(ball, ballrect) # 将图片画到窗口上
pygame.display.flip() # 更新全部显示
pygame.quit() # 退出 pygame
(5)运行上述代码,发现小球在屏幕中一闪而过,此时,小球没有真正消失,而是移动到了窗体之外,此时需要添加碰撞检测的功能。当小球与窗体任一边缘发生碰撞,则更改小球的移动方向。具体代码如下:
# -*- coding = UTF-8 -*-
import sys
import pygame
pygame.init() # 初始化pygame
size = (width, height) = (640, 480) # 设置窗口
screen = pygame.display.set_mode(size) # 显示窗口
color = (0, 0, 0) # 设置背景颜色
ball = pygame.image.load("ball.jpg") # 加载图片,返回一个 Surface 对象
ballrect = ball.get_rect() # 获取矩形区域
speed = [5, 5] # 设置移动的 x 轴, y 轴距离
# 执行死循环,确保窗口一直显示
while True:
# 检查事件
for event in pygame.event.get():
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
sys.exit()
ballrect = ballrect.move(speed) # 移动小球
# 碰到左右边缘
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
# 碰到上下边缘
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[-1]
screen.fill(color) # 填充颜色
screen.blit(ball, ballrect) # 将图片画到窗口上
pygame.display.flip() # 更新全部显示
pygame.quit() # 退出 pygame
(6)运行上述代码,发现好像有多个小球在飞快移动,这是因为运行上述代码的时间非常短,导致肉眼观察出现错觉,因此需要添加一个“时钟”来控制程序运行的时间。这时就需要使用 pygame 的 time 模块。使用 pygame 时钟之前,必须先创建 Clock 对象的一个实例,然后在 while 循环中 设置多长时间运行一次。
具体代码如下:
# -*- coding = UTF-8 -*-
import sys
import pygame
pygame.init() # 初始化pygame
size = (width, height) = (640, 480) # 设置窗口
screen = pygame.display.set_mode(size) # 显示窗口
color = (0, 0, 0) # 设置背景颜色
ball = pygame.image.load("ball.jpg") # 加载图片,返回一个 Surface 对象
ballrect = ball.get_rect() # 获取矩形区域
speed = [5, 5] # 设置移动的 x 轴, y 轴距离
clock = pygame.time.Clock() # 设置时钟
# 执行死循环,确保窗口一直显示
while True:
clock.tick(60) # 每秒执行60次
# 检查事件
for event in pygame.event.get():
if event.type == pygame.QUIT: # 如果单击关闭窗口,则退出
sys.exit()
ballrect = ballrect.move(speed) # 移动小球
# 碰到左右边缘
if ballrect.left < 0 or ballrect.right > width:
speed[0] = -speed[0]
# 碰到上下边缘
if ballrect.top < 0 or ballrect.bottom > height:
speed[1] = -speed[-1]
screen.fill(color) # 填充颜色
screen.blit(ball, ballrect) # 将图片画到窗口上
pygame.display.flip() # 更新全部显示
pygame.quit() # 退出 pygame
至此,完成了“跳跃的小球”游戏。