Python学习笔记-第8天:项目实战练习(3)
第八天 项目实战练习(3)
今天计划继续利用编写一个游戏,来加强对基础知识学习的理解。依然使用Pygame框架进行学习。昨天已经列出了Pygame中的模块列表,然后
在测试游戏编程时遇到了坑,后来升级一下Python的版本就好了。在官网下载最新的pkg安装包安装后即可。学习项目及练习源码地址:
GitHub源码
基础模块简介
display模块介绍
-
set_mode
set_mode会返回一个Surface对象,代表了在桌面上出现的那个窗口,三个参数第一个为元祖,代表分 辨率(必须);第二个是一个标志位,具体意思见下表,如果不用什么特性,就指定0;第三个为色深.
标识位 功能 FULLSCREEN 创建一个全屏窗口 DOUBLEBUF 创建一个“双缓冲“窗口,建议在HWSURFACE或OPENGL时使用 HWSURFACE 创建一个硬件加速窗口,必须和FULLSCREEN同时使用 OPENGL 创建一个OPENGL渲染的窗口 RESIZABLE 创建一个可以改变大小的窗口 NOFRAME 创建一个没有边框的窗口 -
set_caption
设置窗口标题
-
convert
将图像数据都转化为Surface对象,每次加载完图像以后就应该做这件事件(事实上因为 它太常用了,如果你不写pygame也会帮你做);
-
convert_alpha
相比convert,保留了Alpha 通道信息(可以简单理解为透明的部分),这样我们的光标才可以是不规则的形状。
-
blit
是个重要函数,第一个参数为一个Surface对象,第二个为左上角位置。
-
update
刷新窗口
pygame中的事件
事件是什么,其实从名称来看我们久能想到些什么,而且你所想到的基本就是事件的真正意思了。游戏程序,一般会一直运行下去,它会知道你关闭窗口而产生一个QUIT事件。Pygame会接受用户的各种操作(比如按键盘,移动鼠标等)产生事件。事件随时可能发生,而且量也可能会很大,Pygame的做法是把一系列的事件存放一个队列里,逐个的处理。
事件检索
-
pygame.event.get()
它处理所有的事件,这好像打开大门让所有的人进入。
-
pygame.event.wait()
Pygame就会等到发生一个事件才继续下去,就好像有哨兵把守的门一样,来一个进一个。
-
pygame.event.poll()
它会根据现在的情形返回一个真实的事件,或者一个“什么都没有”。
常用事件集
事件 | 产生途径 | 参数 |
---|---|---|
QUIT | 用户按下关闭按钮 | none |
ATIVEEVENT | Pygame被激活或者隐藏 | gain, state |
KEYDOWN | 键盘被按下 | unicode, key, mod |
KEYUP | 键盘被放开 | key, mod |
MOUSEMOTION | 鼠标移动 | pos, rel, buttons |
MOUSEBUTTONDOWN | 鼠标按下 | pos, button |
MOUSEBUTTONUP | 鼠标放开 | pos, button |
JOYAXISMOTION | 游戏手柄 | (Joystick or pad)移动 joy, axis, value |
JOYBALLMOTION | 游戏球 | (Joy ball)移动 joy, axis, value |
JOYHATMOTION | 游戏手柄 | (Joystick)移动 joy, axis, value |
JOYBUTTONDOWN | 游戏手柄按下 | joy, button |
JOYBUTTONUP | 游戏手柄放开 | joy, button |
VIDEORESIZE | Pygame窗口缩放 | size, w, h |
VIDEOEXPOSE | Pygame窗口部分公开 | (expose) none |
USEREVENT | 触发了一个用户事件 | code |
处理鼠标事件
MOUSEMOTION事件会在鼠标动作时发生,它有三个参数:
- buttons:一个含有三个数字的元组,三个值分别代表左键、中键和右键,1就是按下了。
- pos:鼠标光标的位置
- rel:代表了现在距离上次产生鼠标事件时的距离
和MOUSEMOTION类似的,我们还有MOUSEBUTTONDOWN和MOUSEBUTTONUP两个事件,看名字就知道什么意思了。很多时候,你只需要知道鼠标点下就可以了,那就可以不用上面那个比较强大(也比较复杂)的事件了。它们的参数为:
- button:看清楚了少了个s,这个值代表了哪个按键被操作
- pos:鼠标光标的位置
处理键盘事件
键盘和游戏手柄的事件比较类似,为KEYDOWN和KEYUP。
KEYDOWN和KEYUP的参数秒速如下:
- key -按下或者放开的键值,是一个数字,估计地球上很少有人可以记住,所以Pygame中你可以使用K_xxx来表示,比如字母a就是K_a,还有K_SPACE和K_RETURN等。
- mod -包含了组合键信息,如果mod & KMOD_CTRL是真值,表示用户同时按下了Ctrl键。类似的还有KMOD_SHIFT,KMOD_ALT。
- unicode -代表了按下键的Unicode值。
事件过滤
并不是所有的事件都需要处理的,就好像不是所有登门造访的人都是我们欢迎的一样。比如,俄罗斯方块就无视你的鼠标,而在游戏场景切换的时候,你按什么都是徒劳的。我们应该有一个方法来过滤掉一些我们不感兴趣的事件(当然我们可以不处理这些没兴趣的事件,但最好的方法还是让它们根本不进入我们的事件队列),我们使用pygame.event.set_blocked(事件名)来完成。如果有好多事件需要过滤,可以传递一个列表,比如pygame.event.set_blocked([KEYDOWN, KEYUP]),如果你设置参数None,那么所有的事件都被打开了。与之相对的,我们使用pygame.event,set_allowed()来设定允许的事件。
产生事件
通常玩家做什么,Pygame就产生对应的事件就可以了,不过有的时候我们西药模拟出一些事件来,不如录像回放的时候,我们就要把用户的操作再现一遍。
import pygame
from pygame.locals import *
me_event = pygame.event.Event(KEYDOWN, {"key": K_SPACE, "mod": 0, "unicode": u''})
pygame.event.post(me_event) # 出发事件
使用字头模块
一个游戏,再怎么寒碜也得有文字,俄罗斯方块还有个计分数得呢。pygame可以直接调用系统字体,或者也可以使用TTF字体。为了使用字体,你得先创建一个Font对象,对于系统自带的字体。
my_font = pygame.font.SysFont("arial", 16)
第一个参数是字体名,第二个自然就是大小,一般来说“Arial”字体在很多系统都是存在的,如果找不到的画,就会使用一个默认字体,这个默认字体和灭个操作系统相关,你也可以使用pygame.font.get_fonts()来获取当前系统所有的可用字体。还有一个更好的方法,使用TTF的方法:
my_font = pygame.font.Font("my_font.ttf", 16)
这个语句使用了一个叫做“my_font.ttf”,这个方法之所以好是因为你可以把字体文件随游戏文件一起分发,避免用户机器上没有需要的字体,一旦你创建了一个字体对象,你就可以使用render方法来写字了,然后久能blit到屏幕上。
text_surface = my_font.render("Pyame is cool!", True, (0, 0, 0), (255, 255, 255))
第一个参数是写的文字,第二个参数是个布尔值(代表是否开启抗锯齿),就是说True的话字体会比较平滑,不过相应的速度会有一点点的影响;第三个是字体颜色;第四个是背景色,如果你不想有背景色(也就是透明),那么可以不加这第四个参数。
追加说明一下如何显示中文。简单来说,首先你得用一个可以使用中文的字体,宋体、黑体什么的,或者你可以直接用中文的TTF文件呢,然后文字使用Unicode,即u“中文的文字”。最后不要忘了在源文件里加上一句关于文件编码的“魔法注释”,比如:
# _*_coding:utf-8_*_
像素
凑近显示器,你能看到图像是由一个一个点构成,这就是像素(如果能够熟练的使用PS的,对像素的了解就能更透彻了)。至于屏幕分辨率的意义,也就不用多说了,一个1280x1024的显示器,有着1310720个像素,一般为32的RGB系统,每个像素就可以显示16.7百万种颜色。
动起来 - 理解帧率
FPS(Frame Per Second)是游戏和硬件间较量的永恒话题,我也不想多插话了,相信玩游戏的朋友都知道。
只是记住几个常用的量:一般的电视画面是24FPS;30FPS基本可以给玩家提供流程的体验了;LCD的话,60FPS是常用的刷新率,所以你的游戏的帧率再高也就没什么意义了;而绝大多数地球人都无法分辨70FPS以上的画面了!
播放音乐
在Pygame里播放音频有两个方法,一个用来播放特效声音,一个用来播放背景音乐:
pygame.mixer.Sound(filename)
该方法返回一个Sound 对象,调用它的.play( )方法,即可播放较短的音频文件(比如玩 家受到伤害、收集到金币等);
pygame.mixer.music.load(filename)
该方法用来加载背景音乐,之后调用 pygame.mixer.music.play( )方法就可以播放背景音乐(Pygame只允许加载一个背景音乐在同一个时刻)
实战一个游戏(坦克大战)
本游戏主要分为两个对象,分别是我方坦克和敌方坦克。用户可以通过控制我方的坦克来摧毁敌方的坦克保护自己的“家”,把所有的敌方坦克消灭完达到胜利。敌方的坦克在初 始的时候是默认 5 个的(这可以自己设置),当然,如果我方坦克被敌方坦克的子弹打中,游戏结束。
分析
游戏中需要哪些类呢?
- 主类:主要包括开始游戏、结束游戏的功能
- 坦克类:主要包括坦克的创建、显示、移动及射击的功能
- 我方坦克类继承坦克类,主要包括创建、与敌方坦克的碰撞方法。
- 敌方坦克类继承坦克类,主要包括创建、与我方坦克碰撞方法。
- 子弹类:主要包括子弹的创建、显示及移动的功能。
- 墙壁类:主要包括墙壁的创建、显示的功能。
- 爆炸效果类:主要展示爆炸效果。
- 音效类:主要播放音乐。