上次我们试着写了一个最简单的Pygame程序并且解释了一个大概的框架,这次就Pygame中也是游戏中最关键(……好吧,也许并不是最关键,但绝对是至关重要的一项)的事件来展开。

此图为一个用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模块来显示文字(后面会讲的),下面是源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import pygame from pygame.locals import * from sys import exit pygame.init() SCREEN_SIZE = (640, 480) screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32) font = pygame.font.SysFont("arial", 16); font_height = font.get_linesize() event_text = [] while True: event = pygame.event.wait() event_text.append(str(event)) #获得时间的名称 event_text = event_text[-SCREEN_SIZE[1]/font_height:] #这个切片操作保证了event_text里面只保留一个屏幕的文字 if event.type == QUIT: exit() screen.fill((255, 255, 255)) y = SCREEN_SIZE[1]-font_height #找一个合适的起笔位置,最下面开始但是要留一行的空 for text in reversed(event_text): screen.blit( font.render(text, True, (0, 0, 0)), (0, y) ) #以后会讲 y-=font_height #把笔提一行 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,下面有一个例子来演示使用方向键移动一些东西。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
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本身是缩进编排来表现层次,有些时候可能会出现一点小麻烦,要我们自己注意才可以。
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就产生对应的事件就可以了,不过有的时候我们需要模拟出一些事件来,比如录像回放的时候,我们就要把用户的操作再现一遍。
为了产生事件,必须先造一个出来,然后再传递它:
1 2 3 4 |
my_event = pygame.event.Event(KEYDOWN, key=K_SPACE, mod=0, unicode=u' ') #你也可以像下面这样写,看起来比较清晰(但字变多了……) my_event = pygame.event.Event(KEYDOWN, {"key":K_SPACE, "mod":0, "unicode":u' '}) pygame.event.post(my_event) |
你甚至可以产生一个完全自定义的全新事件,有些高级的话题,暂时不详细说,仅用代码演示一下:
1 2 3 4 5 6 7 8 |
CATONKEYBOARD = USEREVENT+1 my_event = pygame.event.Event(CATONKEYBOARD, message="Bad cat!") pgame.event.post(my_event) #然后获得它 for event in pygame.event.get(): if event.type == CATONKEYBOARD: print event.message |
这次的内容很多,又很重要,一遍看下来云里雾里或者看的时候明白看完了全忘了什么的估计很多,慢慢学习吧~~多看看动手写写,其实都很简单。
下次讲解显示的部分。
哪里的缩进改一下阿?
37 38
@wlimi: 三个for递进啊
@wlimi: 不好意思回复错了地方了
我觉得是把后面5行缩进去
同意上面,后5行往左缩进两格。
要传递最终结果,而不是每次结果
你好,在处理键盘事件的例子中,for event in pygame.event.get():语句何种情况下退出此循环?
后5行缩进了后,应该是执行完for再执行这后5句,为何当我按下右键感觉for的语句和后五句是同时执行的呢?难道是event机制?不懂啊
@77: 再补充一下,按住右键不放,是一个事件还是多个啊。。。
@77: 在for循环中,print event 发现按住右键,是多个事件。。。
@77: 失误啊 是一个事件 写错了。。。
抱歉打扰了,一个事件的话那我就懂了。while是为了让一个事件产生的结果,不断地影响后面的语句。当松开按钮就给值为0,并不断地继续影响后面的结果。。。
@77: 自问自答的可爱77,congratulation!很多时候,把问题前后调查一下,答案也就呼之欲出了。
能教我这个愚笨的人怎样在windows7上安装livewires模块吗?我点了里面的setup.py一点用也没,大师请教教
setup.py 不是点击的啊。。。。。。。你百度怎么安装setup.py。。。
试了下这个上下左右移动,如果按键交换太快,就会导致错乱失效,而且不支持同时按下几个方向键,于是我改进了下:
赞!不过有个小瑕疵:同时松开两个键时图片会往其中一个方向移动一像素。始终不知道为什么!
不可能是同时的,总有一个先放,这时后放的移动
赞 不过我好像遇到了一个问题 ,按下键移动以后,图像动的太快了 ,解决这个是需要控制帧数吗?
改下move值可以控制速度
帧数最低好像不能再低了,太快了可以试试在每次的循环反馈中加入time.sleep()。
niubi
你的理解高啊,就是先统计好上下左右都动多少,然后统一的一动一次就到最后,所以可以识别多个按钮一起按
完全没有遇到这个问题,而且是支持同时按下几个方向键的。
持续按键突然改变会遇到的
@wazedix: Great! 我帮您把空格加回去了,HTML总会把多个空格合并为一个,除非把代码放在<pre>…</pre>里面。
为什么x+= move_x
y+= move_y放在for循环里是移动一次啊?不是一直循环吗?
这个我也理解了,原来是本来没理解透event.get()…
@wei: 每当想帅气的回答疑问的时候,却突然发现你们自己搞明白了,就会在欣慰感叹之余又有了一些莫名的落寞感……
在36~43行缩进
大神老师啊,我在定义一个新的函数
def gameover(root,screen):
root.close()
screen.exit()
这样的话 ,执行这个函数时,pygame的窗口“screen”会关闭么?如果不行,该怎么办呢?
python 爱好者 , 路过
为何啊 还是不能理解 为什么只能移动一下 get不是提取多个event么
@Yo:
哈哈哈理解了 原来一直按着键算一个事件么
之前以为一直按着键算一直都是那个事件
@wazedix:
同时按住左右键或者上下键,你的方法似乎更好一些~~
我有个小问题
第二个程式
按着上下左右其中一颗键后
移动滑鼠
图也会跟着动,为什么会这样?
虽然不知道你能不能看到,但我还是想说一说:
我也遇到了这个情况,也解决了,原来我把最外if 语句的elif部分忽略了,不知你是否是这种情况。这个疏忽会导致另一个问题,不知你有没有发现,当key up的时候背景也会同方向移动一个像素。我猜想光标移动一个像素点同key_up 都是一种最。。。基本的事件,不知道说的准确不,但它们确实导致同一种现象,真正原理我却不知道。
我知道了:如果if语句不以elif结束,pygame.event.get()接收到key_up(我们松键),或者任何事件(如光标移动一个像素),x和y都会再运算一次。
@wazedix:,@xishui: 这样做,还是有一点问题,同时按下左右键,然后再按向上方向的键,图并不会向上移,但若同时按下左右键,然后再按向下方向的键,则图会向下移,请问这是怎么回事
Traceback (most recent call last):
File “C:Documents and Settings小电脑桌面用Python和Pygame写游戏-从入门到精通2moveImg.py”, line 17, in
exit()
SystemExit
在按下关闭按钮的时候总是报这个错误
并且卡死,最后窗口是强制关闭的,我想问问是不是在python2.7.2里退出函数有修改?
@1111: 调用exit()先调用pygame.exit()就不会卡死了。SystemExit是正常现象,exit()就是通过SystemExit异常终止解释器进程的,文档上有说
同意,第一个例子也是这样,关闭按钮时就死了,不知道为什么,然后看到别人有用 pygame.quit() 时就试了一下,
我复制你写的源码来执行
>>> while True:
event=pygame.event.wait()
event_text.append(str(event))
event_text=event_text[-SCREEN_SIZE[1]/font_height:]
if event.type==QUIT:
exit()
screen.fill((255,255,255))
y=SCREEN_SIZE[1]-font_height
for text in reversed(event_text):
screen.blit(font.render(text,True,(0,0,0)),(0,y))
y-=font_height
pygame.display.update()
我执行后IDLE报出:
Traceback (most recent call last):
File “”, line 4, in
event_text=event_text[-SCREEN_SIZE[1]/font_height:]
TypeError: slice indices must be integers or None or have an __index__ method
>>>
我用windows命令提示符也报这个错,我用的是python 3.2.2,请帮忙查一下错在哪里。谢谢!
请使用2.X的Python来执行。。。
如果已经是3.3了,那应该怎样改呢?
event_text是个LIST,LIST后的【】里要是整型,所以,在【】里加个int()进行转化就行了
感谢
把切片event_text[-SCREEN_SIZE[1]/font_height:]中的“/”用“//”替换即可。
我也遇到了同样的问题,感谢你的回答,但是为什么会出现这样的情况呢?是python版本的问题吗?我是python新手,刚入门就要学习pygame。。
event_text = event_text[-SCREEN_SIZE[1]*font_height:]
list[-x:]代表切片操作从倒数第x个元素,到最后。
我刚运行的时候也是出现这个问题
是我搞错了…
感谢编者,非常感谢!
我现在才开始学习,不知道编者是否还在,请多多指教呀
学渣的路过,有木有具体的关于这些method的用法,里面有哪些可以调用,怎么调用,有什么作用,我目前都不清楚。理解初学者,求具体教程。
@fatfatface:
因为移动鼠标也是一些事件,处理x-=move_x和y-=move_y放在键盘事件处理的if判断之外了,所以只要有事件就会做x-=move_x y-=move_y。
@MaximusZhou:试过了没有出现你说得问题啊,上下移动都可以。
我感觉把最后5行缩进之后,可以做按下方向键进行多次移动的操作,但这种操作貌似与运行程序的电脑速度有关:如果机子速度快,while循环进行的很密集,在按下按键的那段时间里得到的key_down events很多,移动的也就多,反之亦然。
我觉得那个if event.type == QUIT那里,在sys.exit()之前还要添加pygame.quit(),否则在我的电脑上每次运行都报错…
第二段例程琢磨了许久,大概了解了,有些问题:
1,似乎event.get()中只读取事件,不会消除已读取的事件?那有什么method可以实现消除已读取事件吗?
2,同时按(左/右)和(上/下)可以实现斜向移动,但是为什么同时按上下或者同时按左右 不会像想象中的一样固定不动?
我的想法是: 事件中同时存在UP和DOWN,那for循环结束后move_y应该为0啊?
请指教。
3,如果想实现那种“长按方向键时,移动速度逐渐加快”,应该怎么做?我的想法是还要设个计时器来记录时间距离,不知道event对象里有发生时间这个属性么?
@Mr Li: 3.2.2里要用floor除法,普通除法结果是浮点数。
不知道哪缩进,好像怎么按都是event
出发一次就执行一次呀~~~
自己好笨 求解答
pygame.key.set_repeat(200, 2)
加到第十行
@Mr Li 把-SCREEN_SIZE[1]/font_height:改成-SCREEN_SIZE[1]//font_height:就可以了
请问,为什么改了缩进后就可以一直移动了呢,按下方向键不是依旧是一个事件吗,难道和for有关系吗?
按键代码
http://nullege.com/codes/show/src@t@r@trosnoth-1.6.0@trosnoth@gui@keyboard.py/73/pygame.K_KP_MULTIPLY
@Mr Li: 在2.X里/得到的是int,在3.X里边是除法,需要来个int()
我运行出现错误: python2.7 pygame1.9 win32
Traceback (most recent call last):
File “E:/Python27/pygame_example/game3.py”, line 20, in
print event.event_name(KEYDOWN)
AttributeError: event member not defined
@wanghuixd: sorry, it’s my fault.
i recognised.
Pingback: pygame系列_游戏中的事件 - Python教程 - 开发者
评论的貌似有些晚。呵呵,11年接触的PYTHON,至今一直QQ未改名字,目前在银行工作,用的COBOL。
但依然没有减退我对PYTHON的热爱,特地最近学习这个语言。谢谢您热心的分享,对于后来之人,这些是您成功的宝贵经验与成果。再次谢谢!
Pingback: pygame系列_游戏中的事件 - Python教程 - 开发者
我觉得按下移动 有时候太快了,可以加个延时函数 不知道行不
while (True):
time+=1
if not time%10000 == 0:
continue
我试了一下 的确是wazedix的程序号 = =
event_text = event_text[-SCREEN_SIZE[1]/font_height:]
这句话要改成
event_text = event_text[int(-SCREEN_SIZE[1]/font_height):] 才行。。不然类型不对。无法运行。。
CATONKEYBOARD = USEREVENT+1
这句是啥意思
video system not initialized是什么情况啊?
要先创建窗口,
为什么一直按着键图片会加快速度?
关于缩进:最后五行语句都向前缩进一个TAB的距离
试了一下,不用form sys import exit 也能正常退出
太悲惨了,游戏玩多的后遗症,键盘移动的时候图片一直移动不了,纠结了半天,最后发现我一直按的是wasd,难怪不能移动,oh my god!
感谢作者,我正在作者的帮助下学习,收获很大!
受教
总算搞懂为什么后五行缩进后会持续动了。。。就是当按下一个键不放后,event.get里面就只有一个事件,这时候执行完for之后会开始画图,画图完因为while的原因本来还要再执行for循环的,但是这时候的for里面的event.get里是没有事件的,所以for被跳过了,直接又开始执行后面的后五行,所以就产生了不断前进的效果。注:同时按下两个键的时候因为for里将这两个键的移动设置为1了,所以后五行会不断的按照这两个值来移动,直到key被放下,重新进入for,更新。
闲来无聊,发现有pygame这么个东西,拿来看看,发现博主的地盘,就跟着博主学学,看到这句话:如果你把填充色的(0, 0, 0)改为(0, 255, 0),效果会想黑客帝国的字幕雨一样。
其实是真的,很像。这是我修改了一下的代码
不错不错~~
我很喜欢你的这段程序,希望可以一起交流,我还是在校学生,可以的话加我qq注明在这个网站上的朋友就行了516259684,谢谢啦,渴望学习
之前我的我的代码有错,我照着你的改了,没有报错,但为什么弹出的Python Windows 没显示任何字母,我关闭时提示项目正在运行,这是什么原因?求解
您好,我想请问下关于那个图片不断的动的问题.,按照我的理解,按下是一个事件,所以一直在for循环里,当松开的时候,又是一个事件,这时候就没有事件了,,所以跳出for循环,执行后五行.但是,图片要动起来,得松开之后才能动啊,为什么会一边按一边动??
这个动并不是靠事件驱动,而是在现有位置上不断加上一个偏移量,这个偏移量是由事件除非设置的,只要没有新的有效事件,这个偏移量就会不停作用在现有位置上。
有个问题想请教一下,我改了后五行的缩进,
pygame.event.get()是得到所有的事件,举个例子,假如我就是按一下向上键(up),再松开,应该是两个时间,也就是说pygame.event.get()应该是[‘keyup’,’keydown’]这两个值,然后for循环开始生效,依次去判断event.类型,没问题,但是我们在for循环之上不是使用了一个while true:这个无限循环吗,我的意识也就是说执行完第一遍for循环,不是还应该执行第二遍for循环吗,直到执行到无数遍,一直循环下去,结果也就是我按一下然后再松开,图片也应该一直动
查了python有关pygame的官网才懂,http://www.pygame.org/docs/ref/event.html#pygame.event.get,
其实get.event()方法最后是要将序列中的message清空的
加了一句,以免移动到窗口显示以外去移动不回来了。
if event.key == K_SPACE:
x,y,move_x,move_y = 0,0,0,0
赞一个666
好吧,我看得不够细心,没有看到这个缩进错误,毕竟不是一行一行看着打的,自己想当然就打了(按照第一课的逻辑,执行代码不会放在事件检测的for循环内)……另外,if…elif…群是不是可以用一个dict字典解决?我是用这两行:
to_do = {K_LEFT:(-1,0),K_RIGHT:(1,0),K_UP:(0,-1),K_DOWN:(0,1)}
#…
moveX,moveY = to_do[event.key]
按照我以前VB的逻辑,我一直在盼望着有一个KEYPRESS……这样就不用moveX,moveY了
….
是的。
将21、22行移到33行来让程序能捕捉退出事件。
我有一个问题,在我的图片还没有移动出屏幕外时,我移动鼠标不会对桌面造成影响,当我的图片移动出屏幕窗口外之后,我移动鼠标,便会不停的画出鼠标的轨迹(鼠标我用带alpha的图片替代中),这是为什么?
C:\Users\Administrator\Desktop>Python pygame.py
Traceback (most recent call last):
File “pygame.py”, line 1, in
import pygame
File “C:\Users\Administrator\Desktop\pygame.py”, line 2, in
from pygame.locals import *
ImportError: No module named locals
为什么会提示 No module named locals? 在第一讲中,代码里也有用到 from pygame.locals import *,在那里就没有问题,在这个第二讲中,就会提示这个。是什么问题呢?是我按楼主的代码,缩进有误?还想请教一个问题,写Python代码,用什么编辑器编辑适合初学者?谢谢!
Pingback: 用Python和Pygame写游戏-从入门到精通(2)-演道网
博主我想问下为什么没改缩进前的那段代码运行的时候,按住某个方向键是只能移动一下的,但是我按住之后然后移动鼠标,图片就一直会往那个方向移动,这是为什么啊?另外我想请博主解释一下缩进之前不能一直移动的原因。。。。
pygame.event.get()是一直执行的,返回当前的所有事件,如果当前什么都没做就返回空list
按照博主的代码,如果什么都没做,那么画面就不会更新(pygame.display.update()不会调用)
当你按下方向键后只是设置了移动方向和移动距离,真正”移动”了几次看`for event in pygame.event.get():`循环次数
如果你只按下了方向键让后什么都不做,那么循环只执行一次。但如果你有做了其他事(移动鼠标),此时·pygame.event.get()·返回不为空,鼠标移动事件触发了几次就循环了几次,也就“移动”了几次
博主可以转载吗?会标明出处,因为自己又敲了一遍,加了些自己的注释等,想发布到自己的博客中去,望回复
#获得时间的名称
event_text = event_text[-SCREEN_SIZE[1]//font_height:]
不知道你们的可不可以 我的除法需要双斜杠 是版本问题么?
因为在Python3中‘/’得到的是真除法,可能会是浮点型,而‘//’是floor除法,得到的是整数
Pingback: 用Python和Pygame写游戏-从入门到精通(2) – 易可信blog系统
非常感谢博主的讲解
但是处理键盘事件那里,因为pygame.event.get()的原因会导致长摁的连续移动会卡顿并斜行,可以在循环开头加入pygame.key.set_repeat( 10 )
循环中刷新之前加入
move_x = 0
move_y = 0
来解决。
另外,该怎么让图片受控制的斜着走没有头绪,有没有朋友解答一下。。。
发现一个奇怪的现象,键盘操作的那一段代码,当按住一个键不放是,鼠标在窗口内运动,背景也会移动,求解
pygame.event.get()是一直执行的,返回当前的所有事件,如果当前什么都没做就返回空list
按照博主的代码,如果什么都没做,那么画面就不会更新(pygame.display.update()不会调用)
当你按下方向键后只是设置了移动方向和移动距离,真正”移动”了几次看`for event in pygame.event.get():`循环次数
如果你只按下了方向键让后什么都不做,那么循环只执行一次。但如果你有做了其他事(移动鼠标),此时·pygame.event.get()·返回不为空,鼠标移动事件触发了几次就循环了几次,也就“移动”了几次
这是之前其他人的回复,我搬运过来
为什么循环里的代码改成这样只能按一下动一下啊, 不能按住连续动, 看代码应该能连续动才对啊, 有没有大佬愿意解答一下
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
if event.type == KEYDOWN:
if event.key == K_UP:
y -= 1
elif event.key == K_DOWN:
y += 1
elif event.key == K_LEFT:
x -= 1
elif event.key == K_RIGHT:
x += 1
elif event.type == KEYUP:
pass
surf.fill((0, 0, 0))
surf.blit(background, (x, y))
pygame.display.update()
没有缩进了…最后三个语句是定格写的
上面大佬的代码,我试一下怎么弄出的这种格式, 还没搞懂怎么回复…
为什么这样写不能按住连续移动啊
又看了一会,懂了,,,
Python版本3.6.1,在执行切片操作语句”event_text = event_text[-SCREEN_SIZE[1]/font_height:]”时,会报错,原因是单斜杠操作符表示浮点数除法,得到的结果是小数,将单斜杠改为双斜杠后程序成功运行
import pygame
pygame.init()
screen_size=(640,480)
screen=pygame.display.set_mode(screen_size,0,32)
font=pygame.font.SysFont(“arial”,16);
font_height=font.get_linesize()
event_text=[]
while True:
event=pygame.event.wait()
event_text.append(str(event))
event_text=event_text[-screen_size[1]//font_height:]
if event.type==pygame.QUIT:
pygame.quit()
screen.fill((255,255,255))
y=screen_size[1]-font_height
for text in reversed(event_text):
screen.blit(font.render(text,True,(0,255,0)),(0,y))
y-=font_height
pygame.display.update()
改进了一下
本来我也想写一点pygame笔记分享到博客,看到楼主的博客后,觉得记笔记有点多余了,哈哈