Pygame初体验
Pygame是跨平台的Python模块,专为电子游戏设计。 包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低阶语言,如C语言或是更低阶的组合语言束缚。基于这样一个设想,所有需要的游戏功能和理念都(主要是图像方面)都完全简化位游戏逻辑本身,所有的资源结构都可以由高级语言提供,如Python。
上面是一段摘自维基百科的关于Pygame的简介。既然是一个用来写游戏的模块,不妨先来了解一下计算机游戏的结构。首先想象一下视频,是通过把一帧一帧的静态图片快速连续的播放来实现“动画”的效果。其实游戏也类似,不断地把图像、文字、状态等按照一定的次序绘制到屏幕上,就可以看到运动的游戏画面。
因此,一个游戏一般要完成这两个主要任务:
第一、游戏要在开始运行的时候载入需要显示的图像文件以及其他数据。
这一步的目的是由于程序要直接从硬盘上读取数据的话是想当缓慢的。相比硬盘,从内存读取数据就要快得多的多。所以在游戏开始的时候,我们就把所有的图片、数据等等载入到内存中,使得游戏能够直接调用内存里的数据。
第二、游戏要运行一个“主循环”。
顾名思义,主循环肯定是一个重要的循环体。游戏在这个循环体里面要做的就是根据玩家的输入信息和游戏的规则改变图像,并且改变游戏的数据。例如,在一次循环里,游戏检测到了玩家的输入是按下了方向键上键,那么根据规则,主角会往前走一步,这样要显示的图像就有所改变,并且在游戏内部,记录主角位置的数据也要相应地改变。
游戏在运行的过程中,几乎一直是在进行着主循环的。一般地,一个游戏在运行的时候,每秒要进行60次左右的主循环,每秒钟进行的主循环的次数叫做FPS —— frame per second(不是First Person Shooting)。在每一次主循环中,游戏都要根据玩家的操作和游戏的规则来改变一些数据。
这两个任务是通用的,是一般的游戏的基本思想,和语言和平台无关。我以前用过微软的XNA框架和C#语言写一个小游戏,其游戏主体和结构也大致如此。具体到Pygame,一个Pygame游戏的流程或步骤一般是这样的
游戏开始运行后,首先是载入数据。如前文所述,这些数据一般是游戏运行时所需要的图片、文字、视频或其他数据。接下来就是初始化,这个步骤调用pygame模块的init()函数,初始化pygame,为使用硬件做准备。之后是一些基本设置,比如窗口是否全屏、窗口标题、分辨率、字体等。这几个基本步骤完成后,就来到了游戏的主体部分。游戏将进入一个while无限循环,在这个循环里可以获取和处理游戏状态、数据、事件。比如获取鼠标的位置、检测并相应鼠标点击、键盘按键操作等。当然最重要和必不可少的还是这两个:绘制和更新。Pygame可以调用Surface方法blit来进行绘制(下一篇博客会更详细的介绍),该方法会将一个Surface对象中的图像传递到另一个Surface对象的给定的位置上。然后再主循环里必须要做得就是更新。pygame.display模块里的flip函数和update都是用来更新显示的,区别在于前者是修改整个屏幕,而后者只是更新屏幕的一部分。一般的,在主循环的开始处会有对退出事件的检测,如果玩家点击关闭或按下Esc等选择退出,游戏将调用sys模块的exit退出。
1 #!/usr/bin/env python 2 # -*- coding: UTF-8 -*- 3 4 background_image_filename = 'sushiplate.jpg' 5 mouse_image_filename = 'fugu.png' 6 #指定图像文件名称 7 8 import pygame 9 #导入pygame库 10 from pygame.locals import * 11 #导入一些常用的函数和常量 12 from sys import exit 13 #向sys模块借一个exit函数用来退出程序 14 15 pygame.init() 16 #初始化pygame,为使用硬件做准备 17 18 screen = pygame.display.set_mode((640, 480), 0, 32) 19 #创建了一个窗口 20 pygame.display.set_caption("Hello, World!") 21 #设置窗口标题 22 23 background = pygame.image.load(background_image_filename).convert() 24 mouse_cursor = pygame.image.load(mouse_image_filename).convert_alpha() 25 #加载并转换图像 26 27 while True: 28 #游戏主循环 29 30 for event in pygame.event.get(): 31 if event.type == QUIT: 32 #接收到退出事件后退出程序 33 exit() 34 35 screen.blit(background, (0,0)) 36 #将背景图画上去 37 38 x, y = pygame.mouse.get_pos() 39 #获得鼠标位置 40 x-= mouse_cursor.get_width() / 2 41 y-= mouse_cursor.get_height() / 2 42 #计算光标的左上角位置 43 screen.blit(mouse_cursor, (x, y)) 44 #把光标画上去 45 46 pygame.display.update() 47 #刷新一下画面
这个“游戏”没有什么实际意义,只是用一张图片做背景,然后捕捉到鼠标的位置,并把另一张图片绘制上去。然而麻雀虽小五脏俱全,这个程序完整的呈现了一个pygame游戏的整体结构和运行流程。其中一个运行截图如下
到这里,pygame的初体验算是基本结束了。给我的印象就是,可以很方便的用来开发一些小游戏,而且相比XNA之类的框架,可以做到代码简介优雅,这也正符合了python的风格。由于缺乏了解,不知道pygame在大型游戏的开发领域有怎样的表现。不过我猜测,由于python是解释型语言,而非编译型,会不会在大型程序里有性能的瓶颈?pygame的简单介绍就到这里,下一篇介绍一下pygame的一些常用模块。
参考资料: