博客刚开,想把最近学习的东西记录下来,算是一种笔记。最近打算开始学习Python,因为我感觉Python是一门很有意思的语言,很早以前就想学了(碍于懒),它的功能很强大,你可以用它来做科学运算,或者数字图像处理,或者任务的自动化,还可以构建动态网站,很多很多听起来就很有意思的实现。关于Python你还可以找到更多的资料,这里不一一赘述。
一说到开始学习一门新的编程语言,很多童鞋可能马上想到,“嗯,哥去买本书啃啃!”,结果买了本大部头,全是枯燥的语法知识,看了后面忘了前面,事倍功半。记得以前有位朋友跟我说,想学一门新技术,从做一个项目开始,这句话还是很值得思考的!(作沉思状(`・ω・´))所以!入正题了!我们不如做个小游戏吧,熟悉熟悉Python的语法,还不怕闷到自己~
Python的库是Python相当重要的组成部分,我们可以通过这些库来实现许多的功能。我们的目标就是通过pygame来实现一个小游戏!那具体做什么呢?我已经找到方向了!就是做个PC端的微信飞机大战~因为这个游戏的模式简单,功能明确,界面简洁,非常符合我们预期的目标。不过我在这里要重申一点,这个想法并不是由我想出来的,是我在github上找到的,附上地址:PyShootGame (使用的资源也在这里哦!)。
最后说明一下,本系列博文使用的是Python 3.3.5 + pygame 1.9.2a0。关于Python 2.x和3.x版本我就不作比较了,语义理解就好。记得Python要跟对应的pygame版本对应好哦~
1.1 pygame的安装
首先Python你得有吧,pygame最简单的办法当然是从官网下载啦(附上:www.pygame.org/download.shtml)。但现在问题又来了,官网上给的pygame版本好像只有for Python 2.5/2.6/2.7/3.1/3.2了,如果你的Python版本大于3.2那咋办呢?stack overflow上一位大哥说了句“The main Pygame page seems to be rarely updated.”,众人仿佛明白了什么,然后大哥笑笑,“去这下载吧(附上:bitbucket.org/pygame/pygame/downloads)”。这里的版本好像更新得比官网上勤快(仅仅是...好像)。版本号上面都写得很清楚,各取所需就好~
最后我们来确认下自己是否正确安装~
>>> import pygame >>> print(pygame.ver) 1.9.2a0
如果没有报错,应该是安装好了~
如果报错找不到模块,很可能是安装版本的问题了。
The specified module could not be found.
1.2 pygame文档的路径
pygame的文档还是很齐全的,当我们遇到用法问题时,先看看文档,很多问题就迎刃而解了。
Pygame Documentation:%你的Python安装路径%/python/Lib/site-packages/pygame/docs/index.html
(不同版本的Python和pygame的文档位置可能不一样,我这里只是贴出自己的路径,大家参考参考,库装好后在自己的Python安装路径下找找就是了;如果觉得麻烦,还有在线文档,附上:www.pygame.org/docs/)
那pygame中有哪些模块呢,docs中也已给出:
模块 | 简介 |
pygame.BufferProxy | An array protocol view of surface pixels |
pygame.cdrom | How to access and control the CD audio devices. |
pygame.Color | Color representation. |
pygame.cursors | Loading and compiling cursor images. |
pygame.display | Configure the display surface. |
pygame.draw | Drawing simple shapes like lines and ellipses to surfaces. |
pygame.event | Manage the incoming events from various input devices and the windowing platform. |
pygame.examples | Various programs demonstrating the use of individual pyame modules. |
pygame.font | Loading and rendering Truetype fonts. |
pygame.freetype | Enhanced Pygame module for loading and rendering font faces. |
pygame.gfxdraw | Anti-aliasing draw functions. |
pygame.image | Loading, saving, and transferring of surfaces. |
pygame.joystick | Manage the joystick devices. |
pygame.key | Manage the keyboard device. |
pygame.locals | Pygame constants. |
pygame.mixer | Load and play sounds |
pygame.mouse | Manage the mouse device and display. |
pygame.movie | Video playback from MPEG movies. |
pygame.mixer.music | Play streaming music tracks. |
pygame.Overlay | Access advanced video overlays. |
pygame | Top level functions to manage Pygame. |
pygame.PixelArray | Manipulate image pixel data. |
pygame.Rect | Flexible container for a rectangle. |
pygame.scrap | Native clipboard access. |
pygame.sndarray | Manipulate sound sample data. |
pygame.sprite | Higher level objects to represent game images. |
pygame.Surface | Objects for images and the screen. |
pygame.surfarray | Manipulate image pixel data. |
pygame.tests | Test Pygame. |
pygame.time | Manage timing and framerate. |
pygame.transform | Resize and move images. |
简介里都是很直观的介绍,这里不多解释。模块里面提供比较直接的操作(只是相对的),像贴一幅图像;也提供抽象层次比较高的操作,像精灵模块(sprite)。反正我们有个大致的了解,用到什么,再去认真学习相关的东西。
2.1 在载入背景前,我们得先有个window吧?动手吧~
1 import pygame # 导入pygame库 2 from pygame.locals import * # 导入pygame库中的一些常量 3 from sys import exit # 导入sys库中的exit函数 4 5 # 定义窗口的分辨率 6 SCREEN_WIDTH = 480 7 SCREEN_HEIGHT = 640 8 9 # 初始化游戏 10 pygame.init() # 初始化pygame 11 screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) # 初始化一个用于显示的窗口 12 pygame.display.set_caption('This is my first pygame-program') # 设置窗口标题 13 14 #事件循环(main loop) 15 while True: 16 17 # 处理游戏退出 18 # 从消息队列中循环取 19 for event in pygame.event.get(): 20 if event.type == pygame.QUIT: 21 pygame.quit() 22 exit()
程序运行结果:
虽然漆黑一片,也不见得能干什么,但总算是踏出了第一步~
2.2 接下来要对程序中几个部分进行着重解释:
line 2:pygame.locals模块里面包含了很多pygame需要用到的常量,例如set_mode里面窗口的标志(flags)、消息事件(event)的类型等等。另外,程序想使用pygame.locals模块里面pygame的常量的话,只能使用“from pygame.locals import *”。
line 3:Python简洁性的一个体现就是,你需要用什么功能,就导入什么功能。这里我们需要用到exit函数来关闭窗口,从sys库中导入便是。
line 5:背景图片的分辨率实际是480*800,但我电脑屏幕分辨率只有1280*800,所以我暂时把它改“矮”了。
line 10:pygame.init()将会初始化所有导入的pygame模块。不过当某一模块发生错误时,这个函数并不会抛出异常,相对地,init()会返回一个元组,包括成功初始化的模块的数量以及发生错误的模块的数量。在这个例子中,输出init()返回的信息可以看到,
>>> ================================ RESTART ================================ >>> (6, 0)
如果你愿意的话也可以手动的逐个模块初始化,这样就可以捕捉到抛出的异常了。
line 11:set_mode()函数将会创建一个显示面板(surface),它有三个参数,第一个是surface的分辨率,也就是窗口的大小,以元组的形式输入(width, height) ,如果没有输入或者设置为(0, 0)的话,系统将会把surface的分辨率设置成当前屏幕分辨率(pygame uses sdl version 1.2.10 or above);第二个是标志位(flags),也就是选定surface的显示模式,见下列表:
#pygame.FULLSCREEN create a fullscreen display #pygame.DOUBLEBUF recommended for HWSURFACE or OPENGL #pygame.HWSURFACE hardware accelerated, only in FULLSCREEN #pygame.OPENGL create an OpenGL renderable display #pygame.RESIZABLE display window should be sizeable #pygame.NOFRAME display window will have no border or controls
第三个参数是位深(depth),即用多少位来表现颜色,文档建议不需要设置此参数,系统会选择最优值。
line 15:在我们主程序中,我们需要一个事件的循环(loop)来不断地检测交互过程中用户的操作。pygame.event.get()方法可以从事件队列得到所有事件的一个列表,我们使用一个循环不断地检测每一个事件,一旦我们找到quit事件,我们就退出游戏关闭窗口。还有一点值得我们思考,如果我们不设置退出操作,我们的黑窗口又会变成怎样呢?结果是,我们点击窗口右上角的红色叉叉时,程序依然可以检测到quit事件,但是窗口是不会关闭的,因为我们没有为它设置相关的操作。
2.3 正式载入背景
有了上面的知识,我们已经大致了解程序的框架了,那么入正题!载入背景图片~
注意,我们添加几条语句即可~(。・ω・。)
import pygame # 导入pygame库 from pygame.locals import * # 导入pygame库中的一些常量 from sys import exit # 导入sys库中的exit函数 # 定义窗口的分辨率 SCREEN_WIDTH = 480 SCREEN_HEIGHT = 640 # 初始化游戏 pygame.init() # 初始化pygame screen = pygame.display.set_mode([SCREEN_WIDTH, SCREEN_HEIGHT]) # 初始化窗口 pygame.display.set_caption('This is my first pygame-program') # 设置窗口标题 # 载入背景图 background = pygame.image.load('resources/image/background.png') # new # 事件循环(main loop) while True: # 绘制背景 screen.blit(background, (0, 0)) # new # 更新屏幕 pygame.display.update() # new # 处理游戏退出 # 从消息队列中循环取 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() exit()
程序运行结果:
我们在原来的程序上增加了3条语句。第一句是载入背景图片的,resources文件夹要跟你的py文件放在一起哦;第二句用来绘制图像,surface.blit()算是很常用的函数了,第一个参数是图像资源,第二个参数决定图像放置的位置(左上角的坐标);第三个语句是更新屏幕,就是把绘制好的背景给“刷”上去。在这里多说一点,关于pygame.display.flip()和pygame.display.update(),文档上说,update更像是flip的优化版本,主要区别是flip是屏幕的整体刷新(entire),而update是局部刷新(portion)。最后来思考一个问题,假如我们把后面两条新语句移到while循环上面会怎样?在这个demo中不会有明显影响,但当以后我们在屏幕中加入其它图像元素后,一执行update操作,背景图就没有了。
※有位博主用心的把pygame的模块简介翻译了一下,附上地址:eyehere.net/2011/python-pygame-novice-professional-1/