python中的pygame模块
pygame模块
pygame是跨平台Python模块,专为电子游戏设计,包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚。
pygame常用的模块名以及功能如下表所示:
pygame编程基本流程步骤
1. 我们在用一个模块前,都要先导入这个模块。
import pygame # 导入模块
from pygame.locals import * # 导入pygame一些常用的函数和常量
2.我们做什么程序都要先创建一个创建一个窗口,用来显示屏幕。
2.1 这里要先初始化pygame,为硬件使用做准备。
pygame.init()
2.2 创建窗口代码
set_mode(resolution=(0,0), flags=0, depth=0) -> Surface
参数
resolution
指定屏幕的 宽
和 高
,默认创建的窗口大小和屏幕大小一致
flags
参数指定屏幕的附加选项,例如是否全屏等等,默认不需要传递
depth
参数表示颜色的位数,默认自动匹配
3. 游戏的屏幕,游戏的元素 都需要被绘制到 游戏的屏幕上
绘制背景图像
-
加载
background.png
创建背景 -
将 背景 绘制在屏幕的
(0, 0)
位置 -
调用屏幕更新显示背景图像
绘制背景图像
1> 加载图像
bg = pygame.image.load("./images/background.png")
2> 绘制在屏幕
screen.blit(bg, (0, 0))
3> 更新显示
pygame.display.update()
3.1 理解 图像 并实现图像绘制
在游戏中,能够看到的 游戏元素 大多都是 图像
图像文件 初始是保存在磁盘上的,如果需要使用,第一步 就需要 被加载到内存
要在屏幕上 看到某一个图像的内容,需要按照三个步骤:
1. 使用 pygame.image.load()
加载图像的数据
2. 使用 游戏屏幕 对象,调用 blit
方法 将图像绘制到指定位置
3. 调用 pygame.display.update()
方法更新整个屏幕的显示
1.加载位图,用pygame.image加载图片模块 。
surface = pygame.image.load('xxx,pnng')
2.绘制图片,用surface对象,surface类里有一个名为blit()的函数用来绘制位图。
作用:把一块内存从一个位置复制到另一个位置。
sc.blit(surface,(x,y)) # 为左上角坐标
3.更新显示
pygame.display.update()
理解pygame游戏中的坐标系
原点 在 左上角 (0, 0)
x 轴 水平方向向 右,逐渐增加
y 轴 垂直方向向 下,逐渐增加
游戏中的主循环
简单的游戏循环
为了做到游戏程序启动后,不会立即退出,通常会在游戏程序中增加一个 游戏循环
所谓 游戏循环 就是一个 无限循环
在 创建游戏窗口 代码下方,增加一个无限循环
注意:游戏窗口不需要重复创建
创建游戏主窗口
screen = pygame.display.set_mode((480, 700))
游戏循环
while True:
pass
游戏监听
3 在游戏循环中 监听 事件
事件 event
就是游戏启动后,用户针对游戏所做的操作
例如:点击关闭按钮,点击鼠标,按下键盘…
监听
在 游戏循环 中,判断用户 具体的操作
只有 捕获 到用户具体的操作,才能有针对性的做出响应
代码实现
pygame
中通过 pygame.event.get()
可以获得 用户当前所做动作 的 事件列表
用户可以同一时间做很多事情
提示:这段代码非常的固定,几乎所有的 pygame
游戏都 大同小异!
游戏循环
while True:
事件监听
for event in pygame.event.get():
判断用户是否点击了关闭按钮
if event.type == pygame.QUIT:
print("退出游戏...")
pygame.quit()
直接退出系统
import sys
sys.exit()
理解 精灵 和 精灵组
在刚刚完成的案例中,图像加载、位置变化、绘制图像 都需要程序员编写代码分别处理,为了简化开发步骤,pygame
提供了两个类。
pygame.sprite.Sprite精灵类 — 存储 图像数据 image 和 位置 rect 的对象
在游戏开发中,通常把 显示图像的对象 叫做精灵 Sprite
精灵 需要 有 两个重要的属性
image
要显示的图像
rect
图像要显示在屏幕的位置
默认的 update()
方法什么事情也没做
子类可以重写此方法,在每次刷新屏幕时,更新精灵位置
注意:pygame.sprite.Sprite
并没有提供 image
和 rect
两个属性
需要程序员从 pygame.sprite.Sprite
派生子类
并在 子类 的 初始化方法 中,设置 image
和 rect
属性
pygame.sprite.Group 精灵组类 — 一个精灵 可以包含 多个 精灵 对象
一个 精灵组 可以包含多个 精灵 对象
调用 精灵组 对象的 update()
方法
可以 自动 调用 组内每一个精灵 的 update()
方法
调用 精灵组 对象的 draw(屏幕对象)
方法
可以将 组内每一个精灵 的 image
绘制在 rect
位置
Group(sprites) -> Group
> 注意:仍然需要调用 `pygame.display.update()` 才能在屏幕看到最终结果
4.2 派生精灵子类
1. 新建 `plane_sprites.py` 文件
2. 定义 `GameSprite` 继承自 `pygame.sprite.Sprite`
注意
如果一个类的 父类 不是 `object`
在重写 初始化方法 时,一定要 先 `super()` 一下父类的 `__init__` 方法
保证父类中实现的 `__init__` 代码能够被正常执行
```python
import pygame
class GameSprite(pygame.sprite.Sprite):
"""游戏精灵基类"""
def __init__(self, image_name, speed=1):
调用父类的初始化方法
super().__init__()
加载图像
self.image = pygame.image.load(image_name)
设置尺寸
self.rect = self.image.get_rect()
记录速度
self.speed = speed
def update(self, args):
默认在垂直方向移动
self.rect.y += self.speed
- 在 游戏循环中 让 精灵组 分别调用
update()
和draw(screen)
方法
职责
精灵
封装 图像 image、位置 rect 和 速度 speed
提供 update()
方法,根据游戏需求,更新位置 rect
精灵组
包含 多个 精灵对象
update
方法,让精灵组中的所有精灵调用 update
方法更新位置
draw(screen)
方法,在 screen
上绘制精灵组中的所有精灵
创建精灵和精灵组
sprite1 = GameSprite("./images/enemy1.png")
sprite2 = GameSprite("./images/enemy1.png", 2)
sprite2.rect.x = 200
sprite_group = pygame.sprite.Group(sprite1, sprite2)
3) 修改游戏循环部分代码
```python
让精灵组调用 update 和 draw 方法
sprite_group.update()
sprite_group.draw(screen)
更新屏幕显示
pygame.display.update()
这里用pygame模块基本实现一个游戏流程。