Pygame Event事件模块(示例)

本文详细介绍了Pygame中的事件处理机制,包括事件队列、常用事件类型和处理方法。重点讲解了键盘事件(如KEYDOWN、KEYUP)和鼠标事件(如MOUSEBUTTONDOWN、MOUSEBUTTONUP、MOUSEMOTION)的处理,以及如何实现键盘的连续监听。示例代码展示了如何响应键盘和鼠标操作,实现图像移动和绘制。
摘要由CSDN通过智能技术生成

Pygame Event事件模块(示例)

原文链接
参考文章
事件(Event)是 Pygame 的重要模块之一,它是构建整个游戏程序的核心,比如鼠标点击、键盘敲击、游戏窗口移动、调整窗口大小、触发特定的情节、退出游戏等等,这些都可以看做是“事件”,Pygame 会接受用户产生的各种操作(或事件),这些操作随时产生,并且操作量可大可小,那么 Pygame 是如何处理这些事件的呢?

事件类型

Pygame 定义了一个专门用来处理事件的结构,即事件队列,该结构遵循队列“先到先处理”的基本原则,通过事件队列,我们可以有序的、逐一的处理用户的操作(触发事件)。下述表格列出了 Pygame 中常用的游戏事件:

事件类型描述成员属性
QUIT用户按下窗口的关闭按钮none
ATIVEEVENTPygame被激活或者隐藏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
VIDEORESIZEPygame窗口缩放size, w, h
VIDEOEXPOSEPygame窗口部分公开(expose)none
USEREVENT触发一个用户事件事件代码

注意,当使用 Pygame 做游戏开发时,上述事件并非都会应用的到,因此在学习的过程中,我们要懂得触类旁通、举一反三。

事件处理方法

Pygame.event 模块提供了处理事件队列的常用方法,如下表所示:

方法说明
pygame.event.get()从事件队列中获取一个事件,并从队列中删除该事件
pygame.event.wait()阻塞直至事件发生才会继续执行,若没有事件发生将一直处于阻塞状态
pygame.event.set_blocked()控制哪些事件禁止进入队列,如果参数值为None,则表示禁止所有事件进入
pygame.event.set_allowed()控制哪些事件允许进入队列
pygame.event.pump()调用该方法后,Pygame 会自动处理事件队列
pygame.event.poll()会根据实际情形返回一个真实的事件,或者一个None
pygame.event.peek()检测某类型事件是否在队列中
pygame.event.clear()从队列中清除所有的事件
pygame.event.get_blocked()检测某一类型的事件是否被禁止进入队列
pygame.event.post()放置一个新的事件到队列中
pygame.event.Event()创建一个用户自定义的新事件

当我们使用 Pygame 处理事件时,逻辑一般都是相似的。首先是判断事件的类型,然后根据不同的事件操作,执行不同的游戏操作。因此这种情况非常适合使用 if … else 语句。如下所示:

while True:
    #等待事件发生
    event = pygame.event.wait()
    if event.type == pygame.QUIT:
        exit()
    if event.type == pygame.MOUSEBUTTONDOWN:
        print('鼠标按下',event.pos)
    if event.type == pygame.MOUSEBUTTONUP:
        print('鼠标弹起')
    if event.type == pygame.MOUSEMOTION:
        print('鼠标移动')
        # 键盘事件
    if event.type ==pygame.KEYDOWN:
        # 打印按键的英文字符
        print('键盘按下',chr(event.key))
    if event.type == pygame.KEYUP:
        print('键盘弹起')

下面应用上述方法对鼠标事件和键盘事件分别做简单的介绍。

处理键盘事件

键盘事件会涉及到大量的按键操作,比如游戏中的上下左右,或者人物的前进、后退等操作,这些都需要键盘来配合实现。

键盘事件提供了一个 key 属性,通过该属性可以获取键盘的按键。Pygame 将键盘上的字母键、数字键、组合键等按键以常量的方式进行了定义,下表列出了按键的常量:

KeyASCIIASCII描述
K_BACKSPACE\b退格键(Backspace)
K_TAB\t制表键(Tab)
K_CLEAR清楚键(Clear)
K_RETURN\r回车键(Enter)
K_PAUSE暂停键(Pause)
K_ESCAPE^[退出键(Escape)
K_SPACE空格键(Space)
K_EXCLAIM!感叹号(exclaim)
K_QUOTEDBL"双引号(quotedbl)
K_HASH# 井号(hash)
K_DOLLAR$ 美元符号(dollar)
K_AMPERSAND& and 符号(ampersand)
K_QUOTE'单引号(quote)
K_LEFTPAREN( 左小括号(left parenthesis)
K_RIGHTPAREN)右小括号(right parenthesis)
K_ASTERISK* 星号(asterisk)
K_PLUS+ 加号(plus sign)
K_COMMA, 逗号(comma)
K_MINUS- 减号(minus sign)
K_PERIOD. 句号(period)
K_SLASH/ 正斜杠(forward slash)
K_000
K_111
K_222
K_333
K_444
K_555
K_666
K_777
K_888
K_999
K_COLON:冒号(colon)
K_SEMICOLON;分号(semicolon)
K_LESS<小于号(less-than sign)
K_EQUALS=等于号(equals sign)
K_GREATER>大于号(greater-than sign)
K_QUESTION?问号(question mark)
K_AT@at 符号(at)
K_LEFTBRACKET[左中括号(left bracket)
K_BACKSLASH\反斜杠(backslash)
K_RIGHTBRACKET]右中括号(right bracket)
K_CARET^脱字符(caret)
K_UNDERSCORE_下划线(underscore)
K_BACKQUOTE`重音符(grave)
K_aaa
K_bbb
K_ccc
K_ddd
K_eee
K_fff
K_ggg
K_hhh
K_iii
K_jjj
K_kkk
K_lll
K_mmm
K_nnn
K_ooo
K_ppp
K_qqq
K_rrr
K_sss
K_ttt
K_uuu
K_vvv
K_www
K_xxx
K_yyy
K_zzz
K_DELETE删除键(delete)
K_KP00(小键盘)
K_KP11(小键盘)
K_KP22(小键盘)
K_KP33(小键盘)
K_KP44(小键盘)
K_KP55(小键盘)
K_KP66(小键盘)
K_KP77(小键盘)
K_KP88(小键盘)
K_KP99(小键盘)
K_KP_PERIOD.句号(小键盘)
K_KP_DIVIDE/除号(小键盘)
K_KP_MULTIPLY*乘号(小键盘)
K_KP_MINUS-减号(小键盘)
K_KP_PLUS+加号(小键盘)
K_KP_ENTER\r回车键(小键盘)
K_KP_EQUALS= 等于号(小键盘)
K_UP向上箭头(up arrow)
K_DOWN向下箭头(down arrow)
K_RIGHT向右箭头(right arrow)
K_LEFT向左箭头(left arrow)
K_INSERT插入符(insert)
K_HOMEHome 键(home)
K_ENDEnd 键(end)
K_PAGEUP上一页(page up)
K_PAGEDOWN下一页(page down)
K_F1F1
K_F2F2
K_F3F3
K_F4F4
K_F5F5
K_F6F6
K_F7F7
K_F8F8
K_F9F9
K_F10F10
K_F11F11
K_F12F12
K_F13F13
K_F14F14
K_F15F15
K_NUMLOCK数字键盘锁定键(numlock)
K_CAPSLOCK大写字母锁定键(capslock)
K_SCROLLOCK滚动锁定键(scrollock)
K_RSHIFT右边的 shift 键(right shift)
K_LSHIFT左边的 shift 键(left shift)
K_RCTRL右边的 ctrl 键(right ctrl)
K_LCTRL左边的 ctrl 键(left ctrl)
K_RALT右边的 alt 键(right alt)
K_LALT左边的 alt 键(left alt)
K_RMETA右边的元键(right meta)
K_LMETA左边的元键(left meta)
K_LSUPER左边的 Window 键(left windows key)
K_RSUPER右边的 Window 键(right windows key)
K_MODE模式转换键(mode shift)
K_HELP帮助键(help)
K_PRINT打印屏幕键(print screen)
K_SYSREQ魔术键(sysrq)
K_BREAK中断键(break)
K_MENU菜单键(menu)
K_POWER电源键(power)
K_EURO欧元符号(euro)

下面通过“图片移动”示例来了解键盘事件的处理过程,如下所示:

import pygame
import sys
# 初始化pygame
pygame.init()
# 定义变量
size = width, height = 600, 400
bg = (255, 255, 255)
# 加载logo图
img = pygame.image.load("C:/Users/Administrator/Desktop/logo.jpg")
# 获取图像的位置
position = img.get_rect()
# 创建一个主窗口
screen = pygame.display.set_mode(size)
# 标题
pygame.display.set_caption("C语言中文网")
# 创建游戏主循环
while True:
    # 设置初始值
    site = [0, 0]
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        # 图像移动 KEYDOWN 键盘按下事件
        # 通过 key 属性对应按键
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                site[1] -= 8
            if event.key == pygame.K_DOWN:
                site[1] += 8
            if event.key == pygame.K_LEFT:
                site[0] -= 8
            if event.key == pygame.K_RIGHT:
                site[0] += 8
    # 移动图像
    position = position.move(site)
    # 填充背景
    screen.fill(bg)
    # 放置图片
    screen.blit(img, position)
    # 更新显示界面
    pygame.display.flip()
对键盘的连续监听

大家请看下面这一段代码:

for event in pygame.event.get():
    if event.type == pygame.QUIT:
    	exit()
    elif event.type == pygame.KEYDOWN:
    	if event.key == pygame.K_RIGHT:
    		print("右")
    	if event.key == pygame.K_UP:
    		print("上")
        if event.key == pygame.K_DOWN:
        	print("下")
        if event.key == pygame.K_LEFT:
        	print("左")

大家首次监控键盘事件一般都会写出这样的代码我们着重来看一下对键盘上下左右键的监控。我们运行代码块我们会发现这几行代码和我们的想法是不一样的,我们在开发游戏的时候,我们大部分时候希望是可以连续控制,这样可以大大减少我们的手部疲劳,对玩家们也会非常的友好,但是我们现在的代码块,是敲一下键盘响应一次事件。所以我们要对代码进行改进,改进的方法有以下两种,大家可以根据自己的理解进行选择。

方法一:设置中间变量
moving_r = False
moving_l = False
moving_u = False
moving_d = False
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT:
                moving_r = True
            if event.key == pygame.K_UP:
                moving_u = True
            if event.key == pygame.K_DOWN:
                moving_d = True
            if event.key == pygame.K_LEFT:
                moving_l = True
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT:
                moving_r = False
            if event.key == pygame.K_UP:
                moving_u = False
            if event.key == pygame.K_DOWN:
                moving_d = False
            if event.key == pygame.K_LEFT:
                moving_l = False
    if moving_r:
        print("右")
    elif moving_u:
        print("上")
    elif moving_d:
        print("下")
    elif moving_l:
        print("左")

引入四个moving变量将四个变量的初值均设为Flase,用pygame的KEYDOWN和KEYUP方法来改变四个变量的值,以此来实现对键盘的连续监控,这种方法虽然很好理解,但是如果是小白对代码的重构不是很熟悉会显得非常缀余。

方法二:运用pygame中get_pressed()
    Key_pressed = pygame.key.get_pressed()
    if Key_pressed[K_UP]:
        print("上")
    if Key_pressed[K_DOWN]:
        print("下")
    if Key_pressed[K_LEFT]:
        print("左")
    if Key_pressed[K_RIGHT]:
        print("右")

这样也是能连续监听键盘事件,但是这里需要注意一下if半段语句后面是中括号并非是小括号,第二个要注意的地方便是键盘名称,如果直接输入K_UP等是会报错的,有两种解决办法一种是导入pygame的方法:

from pygame import *

这样就不会报错了,另一种是在K_UP 前面加上pygame如:

if Key_pressed[pygame.K_UP]:
    print("上")
处理鼠标事件

鼠标是计算机最重要外接设备之一,同时它也是游戏玩家必不可少的工具之一。

Pygame 提供了三个鼠标事件,分别是鼠标移动
MOUSEMOTION)、鼠标按下(MOUSEBUTTONDOWN)、鼠标释放(MOUSEBUTTONUP),不同事件类型对应着不同的成员属性。如下所示:

  1. pygame.event.MOUSEMOTION鼠标移动事件
  • event.pos 相对于窗口左上角,鼠标的当前坐标值(x,y)
  • event.rel 鼠标相对运动距离(X,Y),相对于上次事件
  • event.buttons 鼠标按钮初始状态(0,0,0),分别对应(左键,滑轮,右键),移动过程中点击那个键,相应位置变会为1
  1. pygame.event.MOUSEBUTTONUP鼠标键释放事件
  • event.pos 相对于窗口左上角,鼠标的当前坐标值(x,y)
  • event.button 鼠标释放键编号(整数)左键为1,按下滚动轮2、右键为3
  1. pygame.event.MOUSEBUTTONDOWN 鼠标键按下事件
  • event.pos 相对于窗口左上角,鼠标的当前坐标值(x,y)
  • event.button 鼠标按下键编号(整数),左键为1,按下滚动轮2、右键为3,向前滚动滑轮4、向后滚动滑轮5

通过一组简单的示例对鼠标事件进行演示,示例代码如下:

import pygame
from random import randint
# 初始化程序
pygame.init()
screen = pygame.display.set_mode((450,400))
pygame.display.set_caption("c语言中文网")
# 更新显示

pygame.display.flip()
while True:
    #等待事件发生
    event = pygame.event.wait()
    if event.type == pygame.QUIT:
        exit("成功退出")
    if event.type == pygame.MOUSEBUTTONDOWN:
        # pos 获取鼠标当前位置
        print('鼠标按下',event.pos)
        mx,my = event.pos
        # 调用 pygame.draw 模块画圆
        pygame.draw.circle(screen,(255,255,0),(mx,my),50)

    if event.type == pygame.MOUSEBUTTONUP:
        print('鼠标弹起')
        pass
    if event.type == pygame.MOUSEMOTION:
        print('鼠标移动')
        mx, my = event.pos
        # 随机生成 RGB 颜色值
        r = randint(0,255)
        g = randint(0,255)
        b = randint(0,255)
        pygame.draw.circle(screen, (r,g,b,),(mx, my), 50)
        
	# 处理完,更新显示
	pygame.display.update()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔚蓝慕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值