Pygame 介绍
你有没有打开过你计算机的机箱呢?你会发现你的机器由很多部件组成。视频卡产生图形,发射数字信号到处理者。声卡把声音信号混合后送到扬声器。同样,键盘、鼠标等其他这些输入设备,是游戏必要的使用设备。在家用电脑的出现的早期,程序员必须了解计算机的每个元件。游戏程序员必须阅读每个计算机设备的技术文档,并编写驱动程序来通信。这种情形变得越来越坏,当不同的计算机厂商生产出不同的设备时。由于兼容性问题,游戏程序在想进入游戏市场时遇到了很多的问题,这些问题同样也给游戏玩家带来了很多问题。当微软窗口操作系统出现的时候,他们提供了一种简单的方式来与设备通信。这就意味着程序员可以抛弃技术手册了,因为厂家提供了驱动程序,并且这些驱动可以直接被调用用来在操作系统和硬件之间的通信。即使是这样,编写游戏同样还是挺困难的。但是幸运的是,Pygame的出现使我们没必要担心细节。
在这章我们将介绍Pygame并且介绍怎样创建图形显示和读取输入设备状态。
42 CHAPTER 3 ■ INTRODUCING PYGAME
Pygame的历史
Pygame 是建立在SDL(Simple DirectMedia Layer)的基础之上的。SDL
是 Sam Lantinga 在为Loki Software 工作时编写的,是为了简化游戏移植的。它提供了一种普通方式来创建显示在多平台上。由于它很容易使用,在游戏开发中十分受欢迎。
Pygame and SDL已经活跃了很多年了,因为它们是开源的,一大批游戏开发员为完善和增强它而努力。
安装 Pygame
你可以到 www.pygame.org下载。一旦你已经安装了pygame。你可以在交互模式输入以下语句检验是否安装成功:
>>> import pygame
>>> print pygame.ver
如果安装成功,就会显示如下语句:
1.7.1release
在写这本书的时候,1.7.1是最新版本,但是你可以找到更新的版本在这本书发行之后。源码实例照样可以工作。
使用 Pygame
Pygame安装包含有大量的模板可以被独立使用。那里有每一个设备的模板可以在游戏中使用,也有许多其他的模板。看表3-1是Pygame的模板。你可以通过域名来使用;例如,pygame.display就是显示模板。
CHAPTER 3 ■ INTRODUCING PYGAME 43
有一些模块你讲在每一个游戏中用到,你会经常用到显示,说以显示模块是必要的。同样你也会需要输入,它可能是键盘,可能是鼠标。其他模块可能用到的不多,但是他们会给你一个完善的开发环境来开发更好的游戏。
Module Name Purpose
pygame.cdrom CD访问控制驱动
pygame.cursors 载入光标图像
pygame.display 显示
pygame.draw 画形状、线、点
pygame.event 管理外部事件
pygame.font 使用系统字体
pygame.image 载入和保存图形
pygame.joystick 使用操纵杆和类似设备
pygame.key 读取键盘按键
pygame.mixer 载入和显示声音
pygame.mouse 管理鼠标
pygame.movie 播放视频文件
pygame.music 处理音乐和流媒体
pygame.overlay 使用高级视频覆盖技术
pygame Contains 高级PYGAME函数
pygame.rect 管理矩形区域
pygame.sndarray 处理声音数据
pygame.sprite 管理移动图像
pygame.surface 管理图像和屏幕
pygame.surfarray 处理图像像素数据
pygame.time 管理定时器和帧速
pygame.transform 修改和移动图像
* For complete documentation on the Pygame modules, see
www.pygame.org/docs/.
Table 3-1. Modules in the Pygame Package
并不是下面所有的模块都可以在所有的平台使用。有可能你的硬件和游戏没有一定的兼容性,或者请求的驱动没有安装。如果是那样,pygame就会讲模板设置成没有,这样跟容易测试。下面的语句讲测试字体是否载入,如果没有将退出程序。
if pygame.font is None:
print "The font module is not available!"
exit();
Hello World 重写
我们用pygame将创建一个hello world脚本,可以在桌面创建图形窗口和画一个图形在标准鼠标下,当运行的时候,你可以看到下面的图形:
代码如下:
Listing 3-1. Hello World Redux (helloworld.py)
#!/usr/bin/env python
background_image_filename = 'sushiplate.jpg'
mouse_image_filename = 'fugu.png'
import pygame
from pygame.locals import *
from sys import exit
pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption("Hello, World!")
background = pygame.image.load(background_image_filename).convert()
mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha()
while True:
for event in pygame.event.get():
if event.type == QUIT:
exit()
screen.blit(background, (0,0))
x, y = pygame.mouse.get_pos()
x-= mouse_cursor.get_width() / 2
y-= mouse_cursor.get_height() / 2
screen.blit(mouse_cursor, (x, y))
pygame.display.update()
在这个程序中我们需要两幅图像,一副用来做背景,另一副用来做鼠标。你可以在网络上得到这些资源。当然你也可以使用你自己决定的图片。
在程序中的第一和第二行设置图像文件路径。如果你想用不痛的图片,你只需要改变文件路径就可以了。让我们来分析下这段脚本。在脚本开始,我们导入外部模板 、类
、函数,这是我们运行程序说必须要做的。
import pygame
from pygame.locals import *
from sys import exit
第一行导入 pygame package,它讲给予我们使用它所有之模板的权利,象pygame.image and pygame.sound.
第二行导入了一系列的函数和常量。这些不是必要的,但是它讲方便我们使用和建立程序。
最后一行从sys模块导入单个函数。正如你说猜到的,最后导入的这个函数是用来结束脚本的。调用它将会使窗口消失和python关闭。脚本会调用exit()在你点击关闭按钮的时候;否则用户将没有办法关闭窗口。
■提醒:如果你进入到了没法关闭窗口的情形,你可以停止脚本通过按下Ctrl+C.
下面这个简单的语句实际上做了很多的事情。
pygame.init()
它初始化每一个子模块,它载入驱动和硬件请求,这样脚本才可以使用所有的设备在你的计算机上。你也可以只初始化你要使用的模块。调用方式如下:
for example, pygame.sound.init() 将会初始化声音模块. 这样会使你的程序运行的更快一些,因为它只初始化一个模块。对于游戏来说,你讲会使用到大部分,如果不是全部,我们最好分开初始化。在我们调用时,我们将拥有pygame的全部配置。在初始化完成之后,我们要创建一个显示界 面
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption("Hello, World!")
这种显示将是一个在桌面上的窗口或者是整个屏幕,但是一般我们通过对象得到它。通过调用pygame.display.set_mode 将返回一个我们定制的窗口。它有三个参数。只有第一个是必要的,它是一个元组,来说明窗口的宽度和高度。我们的窗口是640*480像素,足够大。
下一个参数是来一个窗口样式的标志,你可以通过或操作符来选择多个样式。例如
DOUBLEBUF|HWSURFACE. 看我们常用的样式3-2。我讲使用到他们在下一章节中。
Table 3-2. Flags for pygame.display.set_mode
FULLSCREEN 创建一个全屏幕的窗口
DOUBLEBUF 创建一个双缓冲的窗口推荐使用 HWSURFACE or OPENGL.
HWSURFACE 创建一个硬件加速的窗口(必须与
FULLSCREEN flag一起使用).
OPENGL创建一个OpenGL renderable display.
RESIZABLE 创建一个可变大小的窗口
NOFRAME 移除边界和标题
最后一个参数指定窗口使用的色彩数
如果你指定为0,将使用和桌面一样的色彩深度
Table 3-3. Bit-Depth Values
Bit Depth Number of Colors
8 bits 256 colors, chosen from a larger palette of colors
15 bits 32,768 colors, with a spare bit
16 bits 65,536 colors
24 bits 16.7 million colors
32 bits 16.7 million colors, with a spare 8 bits
* It is possible to have other bit depths, but these are the most
如果一切顺利,调用set_mode函数后将显示一个游戏窗口,并且返回一个界面对象用来存储这个实例。在创建了窗口之后的第一件事情就是利用set_caption来给窗口设置标题。在这里我们设置标题为”Hello World”.下一步我们用pygame.image中的load函数来载入两幅图片分别作为背景和鼠标图标。我们传递在开始命名的图像的文件名。载入函数从硬盘读取文件,返回包含图片的窗口。他们是同样的对象,存储在内存之中,但是并不可见,知道我们把它们显示。第一次调用load函数载入背景图片并且立即转换。这时图片已经称为窗口对象的成员了。转换函数把图片转换成同样的正如我们显示的格式,这样显示就会快点,因为图片与色彩深度是一致的。鼠标图标的载入是一样的,只是它将图片保留阿拉法信息。没有阿拉法信息再说鼠标里面,我们将只能看到一个矩形或者平方作为我们的鼠标图标。下一张我们将详细讲解图像格式。
下面的语句将使我们进入到游戏循环
while True:
while 循环条件为真,它将一直工作,知道被迫退出。所有的游戏都有类似的循环。在游戏循环的里面还有一层循环,那就是事件循环,大多数的游戏都是建立在事件循环的基础上的。形式如下:
for event in pygame.event.get():
if event.type == QUIT:
exit()
事件循环是告知游戏发生了什么事情,该如何处理这些事情。在这个脚本中,我们仅仅对QUIT消息感兴趣。它是用户在单击退出按钮的时候产生的。所以当存在退出消息的时候,所有的其他消息都将被忽略。在游戏中,我们会处理很多的事件。Blits语句的作用是把图象显示到屏幕上
screen.blit(background, (0,0))
它将背景图片640*480的图片,送到以后面元组为目的地址的窗口中去。
■提醒 把图像的每一部分都显示到屏幕上是很重要的,否则会有奇怪的显示结果。It is important that you blit to every portion of the screen. If you don’t, strange visual effects may occur
当在创造一个对象是,你的游戏可能在不同的平台上看起来不同。这时你应该在screen.blit 上找到原因。
在我们画了背景之后,我们想画鼠标图标,那么就必须先取得鼠标的位置:
x, y = pygame.mouse.get_pos()
x -= mouse_cursor.get_width()/2
y -= mouse_cursor.get_height()/2
screen.blit(mouse_cursor, (x, y))
取得鼠标位置很简单,鼠标模块含有我们所有对鼠标操作的函数。Get_pos函数将返回一个包含鼠标位置的元组。上面的第一条语句将元组分成两个值 x和y。我们可以利用这两个值来建立鼠标图标。但是鼠标的位置却是在图标的左上角,为了使鼠标位置在中心,我们做一些小的数学运算来校正x和y。
.如果你想使用更标准的鼠标图标,那么校正坐标,这样真实的鼠标位置就在顶端下面。
建立鼠标图标与建立背景的方式是一样的,不同的是座标是我们计算得到的。这样我们就可以得到我们需要的效果了。在我们能看见窗口显示在桌面之前,我们还需要使用函数pygame.display.update()
当你建立要使一个图像显示时,你不会看见任何东西,这是因为pygame首先把图片送到缓冲区,用户需要调用pygame.display.update()来显示和更新窗口,防止闪烁,而窗口的闪烁就是程序员的最大敌人。我们希望看到一个平滑没有闪烁的图像。当你运行这个脚本的时候,你会看到如上图所示的结果。
这个是我们今天第一课吧,我也翻译的有点累,今天下午上了三节课,一回到寝室就翻译了这些。当然里面有很多语句不是很通顺,但是基本上够我们理解了。