Python(Pygame)事件处理

来源:互联网 发布:java获取泛型的class 编辑:程序博客网 时间:2024/06/08 17:48

理解事件

      事件是什么,其实从名称来看我们就能想到些什么,而且你所想到的基本就是事件的真正意思了。我们上一个程序,会一直运行下去,直到你关闭窗口而产生了一个QUIT事件,Pygame会接受用户的各种操作(比如按键盘,移动鼠标等)产生事件。事件随时可能发生,而且量也可能会很大,Pygame的做法是把一系列的事件存放一个队列里,逐个的处理。

事件检索

       pygame.event.get()来处理所有的事件,这好像打开大门让所有的人进入。如果我们使用pygame.event.wait(),Pygame就会等到发生一个事件才继续下去,就好像你在门的猫眼上盯着外面一样,来一个放一个……一般游戏中不太实用,因为游戏往往是需要动态运作的;而另外一个方法pygame.event.poll()就好一些,一旦调用,它会根据现在的情形返回一个真实的事件,或者一个“什么都没有”。下表是一个常用事件集:

事件产生途径参数QUIT用户按下关闭按钮noneATIVEEVENTPygame被激活或者隐藏gain, stateKEYDOWN键盘被按下unicode, key, modKEYUP键盘被放开key, modMOUSEMOTION鼠标移动pos, rel, buttonsMOUSEBUTTONDOWN鼠标按下pos, buttonMOUSEBUTTONUP鼠标放开pos, buttonJOYAXISMOTION游戏手柄(Joystick or pad)移动joy, axis, valueJOYBALLMOTION游戏球(Joy ball)?移动joy, axis, valueJOYHATMOTION游戏手柄(Joystick)?移动joy, axis, valueJOYBUTTONDOWN游戏手柄按下joy, buttonJOYBUTTONUP游戏手柄放开joy, buttonVIDEORESIZEPygame窗口缩放size, w, hVIDEOEXPOSEPygame窗口部分公开(expose)?noneUSEREVENT触发了一个用户事件code

#coding=utf-8'''Created on 2017年2月27日@author: zxt'''import pygamefrom pygame.locals import QUITfrom sys import exitpygame.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))    print(str(event))    #这个切片操作保证了event_text里面只保留一个屏幕的文字    event_text = event_text[-SCREEN_SIZE[1]/font_height:]        if event.type == QUIT:        exit()        screen.fill((0, 0, 0))        #找到一个合适的起笔位置,最下面开始但是要留一行的空    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()

处理鼠标事件

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

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

和MOUSEMOTION类似的,我们还有MOUSEBUTTONDOWNMOUSEBUTTONUP两个事件,看名字就明白是什么意思了。很多时候,你只需要知道鼠标点下就可以了,那就可以不用上面那个比较强大(也比较复杂)的事件了。它们的参数为:

  • button – 看清楚少了个s,这个值代表了哪个按键被操作
  • pos – 和上面一样

处理键盘事件

键盘和游戏手柄的事件比较类似,为KEYDOWNKEYUP,下面有一个例子来演示使用方向键移动一些东西。

KEYDOWN和KEYUP的参数描述如下:

  • key – 按下或者放开的键值,是一个数字,估计地球上很少有人可以记住,所以Pygame中你可以使用K_xxx来表示,比如字母a就是K_a,还有K_SPACEK_RETURN等。
  • mod – 包含了组合键信息,如果mod & KMOD_CTRL是真的话,表示用户同时按下了Ctrl键。类似的还有KMOD_SHIFTKMOD_ALT
  • unicode – 代表了按下键的Unicode值,这个有点不好理解,真正说清楚又太麻烦,游戏中也不太常用,说明暂时省略,什么时候需要再讲吧。
#coding=utf-8'''Created on 2017年2月27日@author: zxt'''import pygamefrom sys import exitfrom pygame.locals import QUITfrom pygame.locals import KEYDOWN, KEYUPfrom pygame.locals import K_LEFT, K_RIGHT, K_UP, K_DOWNbackground_image_filename = "./images/sushiplate.jpg"pygame.init()screen = pygame.display.set_mode((640, 480), 0, 32)background = pygame.image.load(background_image_filename).convert()x, y = 0, 0move = {K_LEFT:0, K_RIGHT:0, K_UP:0, K_DOWN:0}while True:        for event in pygame.event.get():        if event.type == QUIT:            exit()                    if event.type == KEYDOWN:            if event.key in move:                move[event.key] = 1        elif event.type == KEYUP:            if event.key in move:                move[event.key] = 0        x -= move[K_LEFT]    x += move[K_RIGHT]    y -= move[K_UP]    y += move[K_DOWN]    screen.fill((0,0,0))    screen.blit(background, (x, y))        pygame.display.update()

事件过滤

并不是所有的事件都需要处理的,就好像不是所有登门造访的人都是我们欢迎的一样。比如,俄罗斯方块就无视你的鼠标,而在游戏场景切换的时候,你按什么都是徒劳的。我们应该有一个方法来过滤掉一些我们不感兴趣的事件(当然我们可以不处理这些没兴趣的事件,但最好的方法还是让它们根本不进入我们的事件队列,就好像在门上贴着“XXX免进”一样),我们使用pygame.event.set_blocked(事件名)来完成。如果有好多事件需要过滤,可以传递一个列表,比如pygame.event.set_blocked([KEYDOWN, KEYUP]),如果你设置参数None,那么所有的事件有被打开了。与之相对的,我们使用pygame.event.set_allowed()来设定允许的事件。

产生事件

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

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

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)

你甚至可以产生一个完全自定义的全新事件,有些高级的话题,暂时不详细说,仅用代码演示一下:

CATONKEYBOARD = USEREVENT+1my_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




0 0
原创粉丝点击