用Python和Pygame写游戏-从入门到精通(2)学习笔记

理解事件

我们上一个程序,会一直运行下去,直到你关闭窗口而产生了一个QUIT事件,Pygame会接受用户的各种操作(比如按键盘,移动鼠标等)产生事件。事件随时可能发生,而且量也可能会很大,Pygame的做法是把一系列的事件存放一个队列里,逐个的处理。一句话就是使用者做的操作都叫产生事件,通过键盘或者鼠标。

事件检索

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

我们先来写一个可以把所有方法输出的程序

#-*- coding:utf-8 -*-
#导入相关块
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_heigh = font.get_linesize()
#定义事件列表
event_text = []
#页面循环
while True:
    #只有在发生事件时动,wait的作用
    event = pygame.event.wait()
    #每产生一个事件就添加进列表
    event_text.append(str(event))
    # 这个切片操作保证了event_text里面只保留一个屏幕的文字
    event_text = event_text[-SCREEN_SIZE[1]/font_heigh:]
    #点X退出
    if event.type == QUIT:
        exit()
    #用白色填充背景
    screen.fill((255, 255, 255))
    # 找一个合适的起笔位置,最下面开始但是要留一行的空
    y = SCREEN_SIZE[1]-font_heigh

    for text in reversed(event_text):
        screen.blit(font.render(text, True, (0, 0 ,0)), (0, y))
        y -= font_heigh
    #刷新
    pygame.display.update()

程序效果:

把填充色的(0, 0, 0)改为(0, 255, 0),效果会想黑客帝国的字幕雨一样;这里字体颜色变成了浅绿色,确实不太像。


或许把背景色用fill调成黑色会好一些,不是重点。。。

鼠标在这个程序上的时候会产生大量的信息,都是程序捕捉到的事件。

扫描二维码关注公众号,回复: 1563423 查看本文章

处理鼠标事件

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

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

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

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

处理键盘事件

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


#-*- coding:utf-8 -*-
background_image_filename = "./images/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循环捕捉每次出现的事件
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        #如果键盘被按下
        if event.type == KEYDOWN:
            #按下左键x左边减1,左移
            if event.key == K_LEFT:
                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,y坐标
    x += move_x
    y += move_y

    screen.fill((0, 0, 0))
    screen.blit(background, (x, y))
    #刷新
    pygame.display.update()

原代码的最后五行放在了for循环中,导致只能按一下键盘移动一次图片,将其改到while这个死循环中,就能很流畅的移动图片了。传递最终结果,而不是每次for循环的结果。

收入一个字典方法的移动图片:

x, y = 320, 240
move = {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(picture, (x,y))
    pygame.display.update()

事件过滤

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

产生事件

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

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

Python

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+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

猜你喜欢

转载自blog.csdn.net/qq_41805514/article/details/80633389