如何用Pygame写游戏(二)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-2/
上次我们试着写了一个最简单的Pygame程序并且解释了一个大概的框架,这次就Pygame中也是游戏中最关键(……好吧,也许并不是最关键,但绝对是至关重要的一项)的事件来展开。
![](http://eyehere.net/wp-content/uploads/2011/04/pygame_demo1.jpg)
此图为一个用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 |
如果你想把这个表现在就背下来,当然我不会阻止你,但实在不是个好主意,在实际的使用中,自然而然的就会记住。我们先来写一个可以把所有方法输出的程序,它的结果是这样的。
我们这里使用了wait(),因为这个程序在有事件发生的时候动弹就可以了。还用了font模块来显示文字(后面会讲的),下面是源代码:
- #!/usr/bin/env python
- background_image_filename='sushiplate.jpg'
- mouse_image_filename='fugu.png'
- #指定图像文件名称
- import pygame
- #导入pygame库
- from pygame.locals import *
- #导入一些常用的函数和常量
- from sys import exit
- #向sys模块借一个exit函数用来退出程序
- pygame.init()
- #初始化pygame,为使用硬件做准备
- 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()
- #刷新一下画面
书上说,如果你把填充色的(0, 0, 0)改为(0, 255, 0),效果会想黑客帝国的字幕雨一样,我得说,实际试一下并不太像……不过以后你完全可以写一个以假乱真甚至更酷的!
这个程序在你移动鼠标的时候产生了海量的信息,让我们知道了Pygame是多么的繁忙……我们第一个程序那样是调用pygame.mouse.get_pos()来得到当前鼠标的位置,而现在利用事件可以直接获得!
处理鼠标事件
MOUSEMOTION事件会在鼠标动作的时候发生,它有三个参数:
- buttons – 一个含有三个数字的元组,三个值分别代表左键、中键和右键,1就是按下了。
- pos – 就是位置了……
- rel – 代表了现在距离上次产生鼠标事件时的距离
和MOUSEMOTION类似的,我们还有MOUSEBUTTONDOWN和MOUSEBUTTONUP两个事件,看名字就明白是什么意思了。很多时候,你只需要知道鼠标点下就可以了,那就可以不用上面那个比较强大(也比较复杂)的事件了。它们的参数为:
- button – 看清楚少了个s,这个值代表了哪个按键被操作
- pos – 和上面一样
处理键盘事件
键盘和游戏手柄的事件比较类似,为KEYDOWN和KEYUP,下面有一个例子来演示使用方向键移动一些东西。
- background_image_filename='sushiplate.jpg'
- import pygame
- from pygame.locals import *
- from sys import exit
- pygame.init()
- screen=pygame.display.set_mode((640,480),0,32)
- background=pygame.image.load(background_image_filename).convert()
- x,y=0,0
- move_x,move_y=0,0
- while True:
- for event in pygame.event.get():
- if event.type==QUIT:
- exit()
- if event.type==KEYDOWN:
- #键盘有按下?
- if event.key==K_LEFT:
- #按下的是左方向键的话,把x坐标减一
- move_x=-1
- elif event.key==K_RIGHT:
- #右方向键则加一
- move_x=1
- elif event.key==K_UP:
- #类似了
- move_y=-1
- elif event.key==K_DOWN:
- move_y=1
- elif event.type==KEYUP:
- #如果用户放开了键盘,图就不要动了
- move_x=0
- move_y=0
- #计算出新的坐标
- x+=move_x
- y+=move_y
- screen.fill((0,0,0))
- screen.blit(background,(x,y))
- #在新的位置上画图
- pygame.display.update()
当我们运行这个程序的时候,按下方向键就可以把背景图移动,但是等等!为什么我只能按一下动一下啊……太不好试了吧?!用脚掌考虑下就应该按着就一直动下去才是啊!?Pygame这么垃圾么……
哦,真是抱歉上面的代码有点小bug,但是真的很小,你都不需要更改代码本身,只要改一下缩进就可以了,你可以发现么?Python本身是缩进编排来表现层次,(注: 做法是将第37-43的代码向前缩进一格)有些时候可能会出现一点小麻烦,要我们自己注意才可以。
KEYDOWN和KEYUP的参数描述如下:
- key – 按下或者放开的键值,是一个数字,估计地球上很少有人可以记住,所以Pygame中你可以使用K_xxx来表示,比如字母a就是K_a,还有K_SPACE和K_RETURN等。
- mod – 包含了组合键信息,如果mod & KMOD_CTRL是真的话,表示用户同时按下了Ctrl键。类似的还有KMOD_SHIFT,KMOD_ALT。
- unicode – 代表了按下键的Unicode值,这个有点不好理解,真正说清楚又太麻烦,游戏中也不太常用,说明暂时省略,什么时候需要再讲吧。
事件过滤
并不是所有的事件都需要处理的,就好像不是所有登门造访的人都是我们欢迎的一样。比如,俄罗斯方块就无视你的鼠标,而在游戏场景切换的时候,你按什么都是徒劳的。我们应该有一个方法来过滤掉一些我们不感兴趣的事件(当然我们可以不处理这些没兴趣的事件,但最好的方法还是让它们根本不进入我们的事件队列,就好像在门上贴着“XXX免进”一样),我们使用pygame.event.set_blocked(事件名)来完成。如果有好多事件需要过滤,可以传递一个列表,比如pygame.event.set_blocked([KEYDOWN, KEYUP]),如果你设置参数None,那么所有的事件有被打开了。与之相对的,我们使用pygame.event.set_allowed()来设定允许的事件。
产生事件
通常玩家做什么,Pygame就产生对应的事件就可以了,不过有的时候我们需要模拟出一些事件来,比如录像回放的时候,我们就要把用户的操作再现一遍。
为了产生事件,必须先造一个出来,然后再传递它:
Python
1
2
3
4
|
|
你甚至可以产生一个完全自定义的全新事件,有些高级的话题,暂时不详细说,仅用代码演示一下:
Python
1
2
3
4
5
6
7
8
|
|
这次的内容很多,又很重要,一遍看下来云里雾里或者看的时候明白看完了全忘了什么的估计很多,慢慢学习吧~~多看看动手写写,其实都很简单。
下次讲解显示的部分。
如何用Pygame写游戏(二)相关推荐
- 如何用Pygame写游戏(十)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-10/ 有时候无聊在网上翻翻小说看看,绝大多数那叫一个无聊.比如说修炼的境 ...
- 如何用Pygame写游戏(一)
转载地址:http://eyehere.net/2011/python-pygame-novice-professional-1/ Pygame的历史 Pygame是一个利用SDL库的写就的游戏 ...
- 如何用Pygame写游戏(二十二)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-22/ 辛苦啦~ 这次是我们系统的pygame理论学习的最后一章了,把这次 ...
- 如何用Pygame写游戏(二十一)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-21/ 紧接着上一次,我们继续来看如何在Pygame中使用声音. Soun ...
- 如何用Pygame写游戏(二十)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-20/ 声音是游戏中必要的元素之一,音效可以给予用户良好的反馈体验.赛车的 ...
- 如何用Pygame写游戏(九)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-9/ 上次我们说到了向量,不得不说向量是一个伟大的发明,在单纯的数字运算之 ...
- 如何用Pygame写游戏(六)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-6/ 掌握了小小的像素,我们可以使用更加复杂一点的东西了,对,就是图像,无 ...
- 如何用Pygame写游戏(三)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-3/ OK,到该讲显示的时候了.没人可以否定好的画面是一款游戏吸引人最直接 ...
- 如何用Pygame写游戏(十九)
本文转自:http://eyehere.net/2011/python-pygame-novice-professional-19/ 3D世界 让我们现在开始写一个3D的程序,巩固一下这几次学习的东西 ...
最新文章
- 厚积薄发的90后:读博前三年零文章,后期发力产出11篇一作,现任985高校博导...
- 3.1.4 内存的连续分配管理方式
- JQuery validate表單驗證
- 计算机网络 | 网络基础 :网络协议,协议分层,数据封装与分用,地址管理,字节序
- java的dom4j怎么调_dom4j.jar 的调试方法
- 用python画分形树的详细解析_基于Python的matplotlib库绘制分形树
- 中国内镜逆行胰胆管造影装置市场趋势报告、技术动态创新及市场预测
- 瑞典正成为欧洲硅谷?
- data参数 layui_layui数据格式
- excel批量替换不同值(根据多个条件匹配、替换不成功的解决办法)
- iOS设备 历代 机型对照表
- 二叉树【按层打印、序列化、反序列化】
- js 幻灯片放映图片_如何制作数据库驱动的首页幻灯片放映
- 另类玩法,使用 REST API 操作 RabbitMQ
- 华硕顽石第四代FL5900u拆机换电池
- 力扣题 <爬楼梯> 递归结合表
- 《孩子快抓紧妈妈的手 -----转载
- java后台判断请求来自移动端访问还是PC端访问
- Ubuntu18.04离线安装网卡驱动、gcc、make等
- 16个非常实用的顶级思维模型!
热门文章
- python中如何保存文件_如何在python中处理后保存文件?
- 科研诚信与学术规范_大学教授学术造假,违背科研诚信
- sklearn中ValueError: Unknown label type: ‘continuous‘错误解决
- Html转快应用方法,卡片跳转快应用指定页面,如何点返回直接退出快应用回到卡片...
- 大型程序是如何开发的_小程序开发好之后如何引流
- PyG图神经网络框架torch-geometric安装
- 如何让外网访问本地电脑(笔记本):路由映射篇
- 某系统有6台输出设备 有多个进程均需要使用2台_双11的秒杀系统,是如何设计的?...
- 个人简历小程序前端源码
- 左右黑白极简滚动个人主页模板