前面我们已经学习了pygame游戏的代码框架,了解了pygame游戏窗口、pygame的事件检测以及如何在窗口绘图。接下来我们细说游戏中的各种事件。
主要内容: pygame事件、键盘事件、鼠标事件
一、pygame事件
在游戏运行时会产生很对时间,如鼠标的移动,键盘或鼠标按键的按下与松开、游戏手柄的操作等。pygame的event模块将这一系列时间存储在一个事件列表(list)中,并逐个处理,先看一段程序。
import pygame, sys
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Check event")
screen = pygame.display.set_mode((640,480), 0, 32)
while True:
for event in pygame.event.get():
print(event)
if event.type == QUIT:
pygame.quit()
sys.exit()
screen.fill((255,255,255))
pygame.display.update()
运行后可以打印出一系列的事件,如图:
<Event(1-ActiveEvent {
'gain': 1, 'state': 1})>
<Event(3-KeyUp {
'key': 306, 'mod': 0, 'scancode': 0})>
<Event(6-MouseButtonUp {
'pos': (289, 139), 'button': 1})>
<Event(5-MouseButtonDown {
'pos': (289, 139), 'button': 1})>
<Event(2-KeyDown {
'unicode': '', 'key': 306, 'mod': 0, 'scancode': 0})>
<Event(4-MouseMotion {
'pos': (592, 1), 'rel': (3, -1), 'buttons': (0, 0, 0)})>
<Event(4-MouseMotion {
'pos': (593, 0), 'rel': (1, -1), 'buttons': (0, 0, 0)})>
<Event(1-ActiveEvent {
'gain': 0, 'state': 1})>
<Event(12-Quit {
})>
上面,我们使用pygame.event.get来得到事件列表,并遍历所有事件。
其中,包含了MouseMotion(鼠标移动)、ActiveEvent(pygame被激活/被隐藏)、KeyDown(按键按下)、KeyUp(按键松开)、Quit(按下关闭按钮)等类型的事件,这些时间被存储在一个列表中,游戏循环中被依次检测到。
二、键盘事件
pygame包含了key模块,键盘事件有KEYUP和KEYDOWN两种类型,但不同的按键对应着不同的key值,如下面的例子,我们将兔子的图形在指定坐标处绘制,通过按键控制兔子的移动:
import pygame, sys
from pygame.locals import *
pygame.init()
pygame.display.set_caption("Check event")
screen = pygame.display.set_mode((640,480), 0, 32)
rabbit = pygame.image.load("rabbit.png")
x = 300
y = 200
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_LEFT or event.key == K_a:
x -= 10
elif event.key == K_RIGHT or event.key == K_d:
x += 10
elif event.key == K_UP or event.key == K_w:
y -= 10
elif event.key == K_DOWN or event.key == K_s:
y += 10
screen.fill((200,200,255))
screen.blit(rabbit, (x, y))
pygame.display.update()
我们使用event.key来判断所按下的按键,当我们按下上下左右键或者WSAD可以实现兔子的上下左右移动,上面使用了K_UP、K_DOWN、K_LEFT、K_UP、K_a…等常量,当我们导入pygame.locals模块时,已经将它们导入到程序中了。
检测按键事件的关键代码
在检测按键事件时,首先需要判断事件type,在类型为按键按下/松开的前提下,判断按键的key值并做出相应的行为,就像这样:
import pygame, sys
from pygame.locals import *
while True:
# 遍历时间列表里面的事件
for event in pygame.event.get():
# 判断事件类型是否为按键事件
if event.type == KEYDOWN:
if event.key == KEY_NAME:
pass
常见的键盘按键以及它对应的KEY值
KEY值 | 按键名 | KEY值 | 按键名 |
---|---|---|---|
K_BACKSPACE | backspace | K_SPACE | space |
K_TAB | tab | K_ESCAPE | escape |
K_0 | 0 | K_1 | 1 |
K_a | a | K_b | b |
K_F1 | F1 | K_F2 | F2 |
K_KP0 | keypad 0 | K_KP1 | keypad 1 |
K_UP | up arrow | K_DOWN | down arrow |
K_LEFT | left arrow | K_RIGHT | right arrow |
持续移动
上面,我们使用even.key来判断所按下的按键。但由于按下只被检测到一次,所以一次按下只能让兔子移动10像素,能否检测键盘按键被按下的状态呢?
我们可以使用pygame.key.get_pressed函数,它可以获得所有被按下的键值,并返回一个字典。我们只要以一个键的KEY值作为索引访问字典中对于的value,就可以判断该键是否被按下,如果按下,则对应的value != 0。
我们改改上面的程序,只修改while主循环:
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pressed_keys = pygame.key.get_pressed()
if pressed_keys[K_RIGHT]:
x += 1
elif pressed_keys[K_LEFT]:
x -= 1
elif pressed_keys[K_UP]:
y -= 1
elif pressed_keys[K_DOWN]:
y += 1
screen.fill((200,200,255))
screen.blit(rabbit, (x, y))
pygame.display.update()
运行之后结果有点小惊喜 ( •̀ ω •́ )✧
按下上下左右导航键后,兔子可以持续运动。因为持续按键时,pressed_keys[KEY] != 0,每次while循环绘图的坐标都可以得到增量,刷新后效果就是不断移动。
三、鼠标事件
鼠标是玩游戏时不可或缺的工具了,当然,对于简单的2D游戏鼠标也是用的上,我们通过鼠标事件可以获取鼠标的位置,鼠标的按键,我们回到上面看看打印的一系列pygame事件。
1、 MOUSEMOTION事件包含了以下3个参数:
- pos:鼠标当前所在的位置
- rel:代表相对上一事件发生位置的相对距离
- button:3个数组成的元组,3个数代表鼠标的左中右键,1就是按下了
<Event(4-MouseMotion {
'pos': (589, 2), 'rel': (2, -2), 'buttons': (0, 0, 0)})>
2、设置鼠标
# 设置不在窗口显示鼠标
pygame.mouse.set_visible(False)
# 设置鼠标位置不离开窗口
pygame.event.set_grab(True)
通过上面的设置,鼠标就不会影响游戏视野啦
3、pygame.mouse常用函数
- pygame.mouse.get_pressed():得到一个描述按键状态的字典,按下则为True
- pygame.get_pos():返回鼠标的当前位置(x, y)
- pygame.mouse.get_rel():返回鼠标的位置增量
- pygame.mouse.set_visible():设置光标是否可见
4、mouse模块的应用
import pygame, sys, math
from pygame.locals import *
pygame.init()
pygame.display.set_caption("胡萝卜")
screen = pygame.display.set_mode((640, 480), 0, 32)
carrot = pygame.image.load("carrot.png")
background = pygame.image.load("background.png")
pygame.mouse.set_visible(False)
pygame.event.set_grab(True)
while True:
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
mouse_x, mouse_y = pygame.mouse.get_pos()
screen.fill((255,255,255))
screen.blit(background, (0, 0))
screen.blit(carrot, (mouse_x, mouse_y))
pygame.display.update()
在上面的程序中,我们隐藏鼠标,并限制鼠标范围为窗口内,使用pygame.mouse.get_pos函数来获取鼠标的位置,并在这个位置上画了一个胡萝卜,这样胡萝卜就会在鼠标位置随鼠标运动,并且胡萝卜跑不出窗口,退出窗口操作为按下Esc按键。效果图如下 (●ˇ∀ˇ●)
第二篇pygame学习笔记完结 cheers! ?
附上:代码压缩包
提取码:rqyu
参考博客:用Python和Pygame写游戏-从入门到精通
图标引用:Iconfont