赞
踩
原文链接:https://www.pygame.org/docs/tut/PygameIntro.html
作者:Pete Shinners
这篇文章是写给Python程序员的pygame库介绍。最初的版本刊登于Py Zine杂志的第一册第三期。当前这个版本包括了一些细微的修订,我们尽力打造出一篇全面优化的文章。Pygame是一个Python的扩展库,它囊括了SDL库以及这个库的辅助库。
Pygame起源于2000年的夏天。作为一个有多年经验的C语言程序员,我几乎是同时发现Python和SDL的。你已经对1.5.2版本的Python非常熟悉了,但是你可能需要一些对SDL的介绍。SDL的全称是Simple DirectMedia Layer(简易直控媒体层),它是由Sam Lantinga开发出来的。SDL是一个跨平台的C语言库,它能够用来控制多媒体,和DirectX的功能不相上下。它已经被用于数以百计的商业游戏以及开源游戏。我震惊于Python和SDL的简洁与直接,而且我很快就意识到把Python和SDL组合起来一定会非常有意思。
我找到了一个跟我的想法完全一致的小项目,PySDL,彼时它已经在开发的途中了。PySDL的创建者是Mark Baker。PySDL是一个SDL的简单实现,它被作为Python的扩展。它的接口比通用的SWIG封装简洁多了,但是我感觉它强制使用C语言风格的代码。PySDL项目的突然夭亡促使我开发我自己的的项目。
我想开发一个真正利用Python优势的项目。我的目标是,其他程序员利用我的项目开发简单的项目时,要非常容易;开发复杂的项目时,也要非常直接。Pygame是从2000年10月开始开发的,6个月后,pygame的1.0版本正式发行。
我发现,要想理解一个新的库,最好的方法就是直接看例子。在开发出Pygame的初期,我写了一个7行代码的弹球动画。依然是这个动画,我们现在看一个更加友好的版本。这个例子应该足够简单了,而且后面我还会逐行讲解。
- import sys, pygame
- pygame.init()
-
- size = width, height = 320, 240
- speed = [2,2]
- black = 0, 0, 0
-
- screen = pygame.display.set_mode(size)
-
- ball = pygame.image.load('intro_ball.gif')
- ballrect = ball.get_rect()
-
- while 1:
- 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(black)
- screen.blit(ball, ballrect)
- pygame.display.flip()
这是一个尽量简单的反弹动画。首先我们看到了导入pygame库还有初始化pygame库,这些都是显而易见的。import pygame把这个库以及库里面所有可用的模块都导入了,pygame.init()初始化了所有的这些模块。
第8行,我们调用pygame.display.set_mode()创建了一个图形化的窗口。Pygame和SDL默认选取对图像硬件最好的模式,这就使得这项工作变得非常容易。你也可以自定义模式,SDL会补偿那些硬件做不到的部分。Pygame把图形表示为Surface对象。
display.set_mode()函数创建了一个新的Surface对象,它就代表实际展示出来的那个图形窗口。你在这个Surface对象上画的任何东西,在显示器上都可以看到。
在第10行,我们加载了我们的小球图像。Pygame通过SDL的图像库,支持多种图片格式,包括BMP, JPG, PNG, TGA和GIF.
pygame.image.load()函数给我们返回了一个Surface对象,这个对象里保存着小球的数据。这个Surface对象会保存来自小球原始图片的所有颜色值和透明度值。加载小球图像之后,我们创建另一个名为ballrect的变量。Pygame有一个非常方便的实用对象类型,叫Rect,它代表一个矩形区域。稍后,在代码里的动画部分,我们就会看到Rect对象的作用。
这时候,第13行,我们的程序已经被初始化了,并且准备好运行了。在这个无限循环里面,我们检测用户输入,移动小球,然后绘制小球。如果你熟悉GUI(图形化用户界面)编程,那么你一定对事件和事件循环有一定的经验了。在Pygame里面,也是一样的,我们检查是否发生了一个QUIT(退出)事件。如果发生了,我们就简单地退出程序,pygame会确保所有东西都关得干干净净。
是时候更新小球的位置了。第17行使用当前的速度移动了ballrect变量。如果小球移动到了屏幕外面,第18行到21行的代码就会反转小球的运动速度。不完全符合牛顿的运动定律,但是这对我们来说已经够用了。
在第23行,我们通过给屏幕填充黑色的RGB颜色,达到了清屏的效果。如果你以前从来没有做过动画,这可能看起来有点奇怪。你可能会问:“我们为什么要把屏幕上的东西擦除呢?我们为什么不只是在屏幕上移动小球?”这不是电脑动画的工作方式。动画其实就是一序列的单幅图片,它们按照一定的顺序展示的时候,很好地欺骗了人类的眼睛,给人一种动起来了的错觉。屏幕其实就是用户看到的一张图片。如果我们不把原来的小球从屏幕上擦除,当我们继续在新的位置绘制小球的时候,实际上我们会看到小球运动的“轨迹”。
在第24行,我们把小球的图像画到了屏幕上。我们是用Surface.blit()方法来绘制图像的。blit的意思是把像素颜色从一个图像复制到另一个图像上。我们给blit方法传递了一个源Surface对象,它是被复制的对象,还传递了一个位置,这就是我们绘制图像的目的地。
我们最后要做的事情其实就是更新展示出来的画面。Pygame是用双缓冲区来管理显示的。当我们完成了图像绘制,我们就调用pygame.display.flip()方法。这会使得我们在屏幕上绘制的所有内容都变为可见。这个缓冲确保我们只能看到屏幕上完全绘制好的图像。如果没有它,用户就会在屏幕绘制过程中看到绘制了一半的屏幕。
这就是对Pygame的简短介绍。Pygame还有其他的一些模块,能处理键盘、鼠标还有操纵杆的输入。它可以混音,也可以解码流媒体音乐。有了Surface对象,你就可以画简单的形状、旋转以及缩放图片,甚至还可以把图像的像素点作为numpy的数组来实时操作。Pygame甚至有能力做PyOpenGL的跨平台展示层。Pygame的大部分模块是用C语言写的,只有很少的是真正用Python写的。
Pygame网站有每个函数的完整参考文档,也有给各种用户编写的使用指南。Pygame资源里面有很多例子,比如猴子拳击和UFO大战等。
“Python适合游戏编程吗?” 答案是,“那得看是什么游戏”。
Python实际上很适合运行游戏。Python在30毫秒里能做的事情可能会让你感到惊讶。然而,当你的游戏开始变得更加复杂,很容易触碰到天花板。任何实时运行的游戏都会充分利用电脑的性能。
在过去的几年里,游戏开发有一个很有意思的趋势,朝向更高级的语言移动。通常,一个游戏被分为两个主要部分。游戏引擎——它必须尽可能地快,游戏逻辑——它指导游戏引擎工作。不久前,游戏引擎还是用汇编语言写的呢,里面有一些部分是用C语言写的。如今,C语言走向了用来写游戏引擎的道路,而通常游戏本身是用更高级的脚本语言写的。像Quake3和Unreal这些游戏就是以字节码的方式运行这些脚本的。
在2001年早些时候,Rebel Act Studios的开发人员完成了他们的游戏——Severance:Blade of Darkness.该游戏使用了他们自己定制的3D引擎,而游戏的其他部分是用Python写的。这是一个第三人称视角的血腥动作游戏。在探索地下城和城堡的过程中,你控制着中世纪勇士使用错综复杂的攻击招数。你可以给这个游戏下载第三方扩展,然后你就会发现它们不过就是一些Python源文件。
近期,Python被用于多种游戏,比如Freedom Force,还有Humungous' Backyard Sports系列。
Pygame和SDL给2D游戏担当了优秀的C语言引擎。游戏依然会发现它们的大部分运行时间是耗费在SDL处理图像上面的。SDL会利用图像硬件加速。利用这一点,能够使游戏的运行从每秒40帧增加至每秒超过200帧。当你看到Python游戏以每秒200帧的速度运行,你会意识到Python和游戏是可以兼容的。
Python和SDL的跨平台特性让人印象深刻。比方说,2001年5月,我发行了我的全pygame项目,SolarWolf, 一个街机风格的动作游戏。让我感到惊讶的一点就是,一年后,这个游戏不需要任何的补丁、bug修复或者更新。这个游戏是完全在windows平台开发的,但是在Linux, Mac OSX还有很多Unix平台上面都能够运行良好,不需要任何额外的调整。
但是,依然有非常清晰的局限性。控制硬件图形加速的最好方法不总是能在软件端也得到最快的渲染结果。硬件支持不是在所有平台都行得通的。当游戏变得更复杂,它通常只能顾及一个,而牺牲另一个。SDL有一些其他的设计限制,像全屏滚动的图像很快就会让你的游戏下降到没法玩儿的速度。尽管SDL并不适用于所有类型的游戏,记得还有Loki这样的公司使用SDL来滚动显示零售字幕。
写游戏的时候,Pygame是相当低级的。你很快就会发现你需要把一些常用的函数封装到你自己的游戏环境里面。好处是pygame里面没有什么东西能挡住你的路。你的程序掌控全场。副作用就是你会发现你自己需要借用很多代码来得到一个更高级的框架。你需要更好地理解你写的代码。
开发游戏是非常有益的,能够看到代码并且跟你写的代码交互是一件让人兴奋的事情。Pygame目前有大概30个其他的项目使用它。它们中的几个已经可以玩儿了。访问一下Pygame的网站,你可能会感到惊讶。你可以看看其他用户使用Python都做出了什么作品。
有一件事情引起了我的注意,就是那些初次使用Python进行游戏开发的人群数量。我能理解为什么游戏吸引了那么多新手程序员,但是开发游戏是比较困难的,因为开发游戏要求程序员对编程语言有扎实的理解。我曾尝试过编写一些例子还有pygame指南给那些对相关概念不太熟悉的用户,通过这样的方式给他们提供支持。
最后,我的建议就是把你的程序写得简单点。我要着重强调这一点。如果你打算开发你的第一个游戏,你需要学习很多东西。即使是更简单的游戏,也会挑战你的设计能力,再说了,复杂的游戏也不一定那么好玩儿。当你理解了Python这门语言,你可以使用pygame在一两个星期的时间里就开发出一款简单的游戏。然后你需要大量的时间改进它,让它达到能够发行的程度。
cdrom | 播放音乐 |
cursors | 加载光标的图像,包括标准的光标 |
display | 控制展示窗口或者屏幕 |
draw | 在一个平面上绘制简单的形状 |
event | 控制事件和事件队列 |
font | 创建并渲染TrueType字体 |
image | 保存并加载图像 |
joystick | 控制操纵杆设备 |
key | 控制键盘 |
mouse | 控制鼠标 |
sndarray | 用numpy操纵音效 |
surfarray | 用numpy操纵图像 |
time | 控制时间 |
transform | 缩放,旋转以及翻转图像 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。