此文说明
我做《Python编程:从入门到实践》_第1版_Eric Matthes 中的 外星人入侵项目 时感觉必须扩展学习 pygame,不然无法完全消化理解这个项目的逻辑。完整的 pygame 学习框架建议参考:http://c.biancheng.net/pygame.
参考文档
- Pygame 官网文档: https://www.pygame.org/docs/
查看 Pygame 的知识 - Pygame 学习(C语言中文网):http://c.biancheng.net/pygame/
为什么学
- 了解 Python 游戏开发库 pygame
- 掌握基本的图形编程能力
- 完成《Python编程:从入门到实践》中的外星人入侵项目
Python Pygame 是一款专门为开发和设计 2D 电子游戏而生的软件包,是入门级游戏开发库。
它支 Windows、Linux、Mac OS 等操作系统,具有良好的跨平台性。Pygame 由 Pete Shinners 于 2000 年开发而成,是一款免费开源的的软件包。
Pygame 是在 SDL(Simple DirectMedia Layer,使用 C语言编写的多媒体开发库) 的基础上开发而成,它提供了诸多操作模块,比如图像模块(image)、声音模块(mixer)、输入/输出(鼠标、键盘、显示屏)模块等。相比于开发 3D 游戏而言,Pygame 更擅长开发 2D 游戏,比如于飞机大战、贪吃蛇、扫雷等游戏。
pygame.init()
pygame.init()
的作用是自动检测 Pygame 软件包是否正常可用。它会完成 Pygame 中所有模块的初始化操作,比如 display(显示模块)、font(字体模块)、mixer(声音控制模块)、cursors(光标控制模块)等。
Pygame 使用 pygame.display 模块控制显示窗口和屏幕。
初始化(创建)要显示的窗口或屏幕:
pygame.display.set_mode()
# set_mode(size=(0, 0), flags=0, depth=0, display=0, vsync=0) -> Surface
set_mode()
函数将创建一个 Surface。传入的参数是对 Surface 的设置。
注意!!!调用这个函数会默认地初始化 pygame.display,也就是具有 pygame.display.init() 的作用。
掌握 Pygame 的编程逻辑,首先要理解 Surface 对象的概念,它是 Pygame 中最重要的部分。
Surface 译为表面,图像。在 Pygame 中,可以把 surface 对象理解成一张“白纸”,通过这张纸可以做许多的事情,比如在纸上添加文字、填充颜色、添加图片以及绘制任意形状的图形。既然是“纸”就有规格尺寸,Pygame 允许您创建任意大小的纸。
创建 Surface几种创建 Surface 对象的方法:
screen_surface = pygame.display.set_mode() # 创建的主窗口即 Surface
text_surface = pygame.font.Font.render() # Pygame 无法直接在其他 Surface 上添加文字,当时可以创建一个 Surface,把文字渲染在此 Surface 上面
image_surface = pygame.image.load() # 加载的图片即为一个 Surface
draw_surface = pygame.draw.rect() # 绘制一个矩形作为 Surface
Surface 相关的方法
pygame.Surface.get_rect()
# get the rectangular area of the Surface
pygame.Surface.blit()
# draw one image onto another
pygame.Rect
Pygame 使用 Rect 对象来存储和操作矩形区域。一个矩形可以由左、顶、宽和高值的组合创建。也可以从已经是 Rect 的 python 对象或具有" Rect "属性的对象中创建 Rect。
rect = pygame.Rect(left,top,width,height)
pygame.event
什么是 event
事件(Event)是 Pygame 的重要模块之一,它是构建整个游戏程序的核心,比如鼠标点击、键盘敲击、游戏窗口移动、调整窗口大小、触发特定的情节、退出游戏等等,这些都可以看做是“事件”,Pygame 会接受用户产生的各种操作(或事件),这些操作随时产生,并且操作量可大可小。
详细内容,参考:https://www.pygame.org/docs/ref/event.html
event 类型Pygame 定义了一个专门用来处理事件的结构,即事件队列,队列遵循 “先到先处理” 的基本原则。通过事件队列,我们可以有序的、逐一的处理用户的操作(触发事件)。
事件类型用全大写字母的常量名表示,如 QUIT (用户按下窗口的关闭按钮)。
Pygame 制作游戏时,最常处理的两类事件是 鼠标事件 和 键盘事件。
外星人入侵if event.type == pygame.KEYDOWN: # 判断事件类型
if event.key == pygame.K_RIGHT: # 判断判断 KEYDOWN 事件的属性
ship.rect.centerx += 1 # 飞船向右移动 1 个像素
event 方法
pygame.event 模块提供了处理事件队列的常用方法(method),如下表:
当我们使用 Pygame 处理事件时,逻辑一般都是相似的。首先是判断事件的类型,然后根据不同的事件操作,执行不同的游戏操作。因此这种情况非常适合使用 if ... else 语句,比如:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
pygame.sprite
精灵 和 碰撞检测
精灵(Sprite),在一个游戏程序中,精灵本质指的是一张张小尺寸的图片。
比如,游戏中的各种道具、人物、场景装饰,它们都可以看成一张张小的“精灵”图。因此,人物的移动可以看做是一系列小精灵图构成的序列(按帧组成的序列),如下图所示:
如果将逐帧分解动作图,按照一定的频率播放,那么就形成了精灵动画,你将会看到雄鹰展翅高飞、人在策马奔腾、运动员奋力跳远。
游戏中的精灵之间可以进行交互,也称为碰撞,而碰撞检测,指的就是检测两个精灵之间是否发生了碰撞。
比如,在贪吃蛇游戏中蛇的头部是否与食物发生了碰撞,飞机大战游戏中子弹是否击中了外星人。当检测到碰撞发生后,接下来会触发某些事件,比如子弹击中外星人,外星人消失,玩家得分随之增加,并且在游戏屏幕上又出现一个外星人。
pygam.sprite 简介官方简介
Sprite 模块包含基本的游戏对象类。该模块包含几个简单的类,可用于游戏中。有一个主要的 Sprite 类和几个包含 Sprite 的 Group 类。在使用pygame时,这些类的使用完全是可选的。这些类是相当轻量级的,只是为大多数游戏中通用的代码提供了一个开始。
Sprite 类的目的是作为游戏中不同类型对象的基础类。还有一个简单存储精灵的基类——Group。一个游戏可以创建新类型的 Group 类,对它们所包含的特别定制的 Sprite 实例进行操作。
基本的 Sprite 类可以把它所包含的 Sprite 画到 Surface 上。Group.draw() 方法要求每个 Sprite 有一个 Surface.image 属性和一个Surface.rect。Group.clear() 方法也需要这些属性,并且可以用来擦除所有带有背景的 Sprite。还有更高级的 Group: pygame.sprite.RenderUpdates() 和 pygame.sprite.OrderedUpdates() 。
最后,本模块包含几个碰撞函数。这些函数有助于找到 Groups 内的精灵,这些精灵的 Rectangel 边界相交。为了找到这些碰撞,要求精灵有一个 Surface.rect 属性。
这些组的设计是为了在移除和添加精灵时有较高的效率。它们还允许进行廉价的测试,看一个 Sprite 是否已经存在于一个组中。一个给定的精灵可以存在于任何数量的组中。一个游戏可以用一些组来控制物体的渲染,而用一组完全独立的组来控制交互或玩家的移动。与其向派生的 Sprite 类添加类型属性或 bools,不如考虑将 Sprite 放在有组织的 Group 中。这将允许在游戏的后期更容易查找。
Sprite 和 Groups 用 add() 和 remove() 方法管理它们的关系。这些方法可以接受一个或多个目标作为参数。这些类的默认初始化器也需要一个或一系列的目标作为初始参数。从一个组中重复添加和删除同一个精灵是安全的。
虽然可以设计不从 Sprite 和 AbstractGroup 类派生出来的 Sprite 和 Group 类,但强烈建议你在添加 Sprite 或 Group 类时扩展这些类。
Sprite 不是线程安全的。因此,如果使用线程,请自己锁定它们。
直白简介
pygame.sprite 是一个处理精灵(sprite)的模块。通常会基于 pygame.sprite 中的基础类 Sprite 来创建子类,从而达到处理精灵的目的。
比如,创建一个继承 Sprite 的 Bullet 子类:
from pygame.sprite import Sprite
class Bullet(Sprite):
# a class to manage bullets fired from ship.
pygame.sprite 模块里最基础的两个类是:pygame.sprite.Sprite 和 pygame.sprite.Group.
pygame.sprite 内置方法Sprite 是针对可见游戏对象的基础类,用于创建精灵。
pygame.sprite.Group Group 是一个容纳和管理多个精灵对象的容器类,它是一个封装了一个列表及针对此列表的一些列方法的容器。Sprite 和 Group 一般结合使用,如下:
bullets = pygame.sprite.Group() # 创建 bullets 精灵组
bullets.add(new_bullet) # 向组内添加一个 new_bullet
Group 类相关的方法
以下总结一些做 外星人入侵 项目时用到的 Group 类相关的方法:
pygame.sprite.Group.draw(Surface):
官方的解释是:blit the Sprite images.
这个方法将包含的精灵绘制到 另一个 Surface 上(即draw ()括号内传递的参数)。这使用了 Sprite 的 image 属性用于绘图,以及 Sprite 的 rect 属性用于确定绘制的位置。