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


接下来我们写一个把所有发生的事件输出的程序

# -*- coding: utf-8 -*- 
# Time : 2019/1/29 21:39 
# Author : ***
import pygame
from pygame.locals import *
from sys import exit

if __name__ == "__main__":
    pygame.init()
    SCREEN_SIZE = (640, 480)
    screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)

    # font = pygame.font.SysFont("my_font.ttf", 16)
    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[int(-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()

结果如下,会将发生的事件列出。在程序中使用wait(),因为这个程序只要在有动作时执行就好了。

三、处理鼠标事件
MOUSEMOTION事件会在鼠标动作的时候发生,它有三个参数:

buttons一个含有三个数字的元组,三个值分别代表左键、中键和右键,1就是按下了。
pos位置
rel代表了现在距离上次产生鼠标事件时的距离

   和MOUSEMOTION类似的,我们还有MOUSEBUTTONDOWNMOUSEBUTTONUP两个事件。它们的参数为:

button这个值代表了哪个按键被操作
pos位置

四、处理键盘事件
键盘的事件为KEYDOWN和KEYUP 。

下面这个例子演示的是使用方向键来移动图片。

# -*- coding: utf-8 -*- 
# Time : 2019/1/29 22:03 
# Author : hubozhi
import pygame
from pygame.locals import *
from sys import exit
import time
background_image_filename = './image/sushiplate.jpg'

if __name__ == "__main__":
    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()
        # 休眠,减缓持续移动时的速度
        time.sleep(0.035)

KEYDOWN和KEYUP的参数描述如下:具体描述请点击这里

key按下或者放开的键值,是一个数字,Pygame中可以使用K_xxx来表示,比如字母a就是K_a,还有K_SPACE和K_RETURN等。
mo包含了组合键信息,如果mod & KMOD_CTRL是真的话,表示用户同时按下了Ctrl键。类似的还有KMOD_SHIFT,KMOD_ALT。
unicode代表了按下键的Unicode值

五、事件过滤
       并不是所有的事件都需要处理。我们使用pygame.event.set_blocked(type)来完成。如果有好多事件需要过滤,可以传递一个列表,比如pygame.event.set_blocked([KEYDOWN, KEYUP]),如果你设置参数None,那么所有的事件有被打开了。与之相对的,我们使用pygame.event.set_allowed()**来设定允许的事件。

六、产生事件
        通常玩家做什么,Pygame就产生对应的事件就可以了,不过有的时候我们需要模拟出一些事件来,比如录像回放的时候,我们就要把用户的操作再现一遍。

为了产生事件,必须先造一个出来,然后再传递它:

my_event = pygame.event.Event(KEYDOWN, key=K_SPACE, mod=0, unicode=' ')
# 你也可以像下面这样写
my_event = pygame.event.Event(KEYDOWN, {"key":K_SPACE, "mod":0, "unicode":' '})
pygame.event.post(my_event)

Event():Event(type, dict) 或者 Event(type, **attributes),

post(): 把新的事件放在事件队列的最后。

下面的代码会显示效果:

# -*- coding: utf-8 -*- 
# Time : 2019/1/30 21:15 
# Author : ***
import pygame
from pygame.locals import *
from sys import exit

if __name__ == "__main__":
    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[int(-SCREEN_SIZE[1] / font_height):]

        # 这个切片操作保证了event_text里面只保留一个屏幕的文字
        # 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' '})


        if event.type == QUIT:
            exit()
        # 将模拟的操作加入到队列的最后
        # event_text.append('my====='+str(my_event))
        pygame.event.post(my_event)#注意:该种写法需要在退出判断的后面,否则退出操作会被覆盖

        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()

也可以产生一个完全自定义的全新事件。

import pygame
from pygame.locals import *

pygame.init()

my_event = pygame.event.Event(KEYDOWN, key=K_SPACE, mod=0, unicode=' ')
# my_event = pygame.event.Event(KEYDOWN,{"key":K_SPACE, "mod":0, "unicode":' '})
pygame.event.post(my_event)

###############
# 产生一个自定义的全新事件
CATONKEYBOARD = USEREVENT + 1
my_event = pygame.event.Event(CATONKEYBOARD, message="bad act!")
pygame.event.post(my_event)
# 获得这个事件
for event in pygame.event.get():
    if event.type == CATONKEYBOARD:
        print( event.message)

五、显示
全屏显示
在第一个例子“hello world”中,使用了如下语句

screen = pygame.display.set_mode((640, 480), 0, 32)

如果把第二个参数设置成FULLSCREEN,就会得到一个全屏显示的窗口。

screen = pygame.display.set_mode((640, 480), FULLSCREEN | RESIZEABLE, 32)
#两个及以上用‘|’分隔开

在全屏模式下,显卡可能就切换了一种模式,你可以用如下代码获得您的机器支持的显示模式

>>> import pygame
>>> pygame.init()
>>> pygame.display.list_modes()

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值