【3】【MOOC】Python游戏开发入门-北京理工大学【第三部分-游戏开发之机制(事件处理机制)】
Pygame事件处理机制
1.Pygame事件处理机制简介
===================================================================================
2.键盘事件及类型的使用
按键的修饰符
event.mod
修饰符的按位或运算
event.mod = KMOD_ALT | KMOD_SHITF
测试一下键盘的事件吧:
测试代码:
1 import pygame, sys 2 3 pygame.init() 4 screen = pygame.display.set_mode((600, 400)) 5 pygame.display.set_caption("Pygame事件处理") 6 7 while True: 8 for event in pygame.event.get(): 9 if event.type == pygame.QUIT: 10 sys.exit() 11 elif event.type == pygame.KEYDOWN: 12 if event.unicode == "": 13 print("[KEYDOWN]:", "#", event.key, event.mod) 14 else: 15 print("[KEYDOWN]:", event.unicode, event.key, event.mod) 16 elif event.type == pygame.MOUSEMOTION: 17 print("[MOUSEMOTION]:", event.pos, event.rel, event.buttons) 18 elif event.type == pygame.MOUSEBUTTONUP: 19 print("[MOUSEBUTTONUP]:", event.pos, event.button) 20 elif event.type == pygame.MOUSEBUTTONDOWN: 21 print("[MOUSEBUTTONDOWN]:", event.pos, event.button) 22 23 pygame.display.update()
===================================================================================
3.鼠标事件及类型的使用
鼠标事件及属性
pygame.event.MOUSEMOTION 鼠标移动事件
pygame.event.MOUSEBUTTONUP 鼠标键释放事件
pygame.event.MOUSEBUTTONDOWN 鼠标键按下事件
-------------------------------------------------------------
鼠标事件及属性
pygame.event.MOUSEMOTION 鼠标移动事件
•event.pos 鼠标当前坐标值(x,y),相对于窗口左上角
•event.rel 鼠标相对运动距离(X,Y),相对于上次事件
•event.buttons 鼠标按钮状态(a,b,c),对应于鼠标的三个键
------------------------------------------------------------
鼠标事件及属性
pygame.event.MOUSEBUTTONUP 鼠标键释放事件
•event.pos 鼠标当前坐标值(x,y),相对于窗口左上角
•event.button 鼠标按下键编号n 取值0/1/2,分别对应三个键
-------------------------------------------------------------
鼠标事件及属性
pygame.event.MOUSEBUTTONDOWN 鼠标键按下事件
•event.pos 鼠标当前坐标值(x,y),相对于窗口左上角
•event.button 鼠标按下键编号n 取值为整数,左键为1,右键为3,设备相关
用上面测试键盘事件的代码再测试一下鼠标事件吧!
===================================================================================
4.壁球小游戏(鼠标型)
壁球小游戏(鼠标型)
需求:
鼠标可以通过左键摆放壁球,当释放按键时壁球运动
从需求到实现的关键要素:
•鼠标事件:对于鼠标键按下和释放的合理处置
-------------------------------------------------------------
壁球小游戏(鼠标型)
鼠标左键按下(左键按下拖拽小球)
鼠标左键释放(左键释放小球继续运动)
-------------------------------------------------------------
壁球小游戏(鼠标型)
局部处理:
增加一种交互方式要考虑
额外的局部处理
游戏逻辑的调试
源代码:
1 # 壁球小游戏(鼠标型)源代码 2 import pygame, sys 3 4 pygame.init() 5 size = width, height = 600, 400 6 speed = [1, 1] 7 BLACK = 0, 0, 0 8 screen = pygame.display.set_mode(size, pygame.RESIZABLE) # 窗口大小可调 9 10 icon = pygame.image.load("PYG03-flower.png") 11 pygame.display.set_icon(icon) 12 pygame.display.set_caption("Pygame壁球") 13 ball = pygame.image.load("PYG02-ball.gif") 14 ballrect = ball.get_rect() 15 fps = 300 16 fclock = pygame.time.Clock() 17 still = False 18 19 while True: 20 for event in pygame.event.get(): 21 if event.type == pygame.QUIT: 22 sys.exit() 23 elif event.type == pygame.KEYDOWN: 24 if event.key == pygame.K_LEFT: 25 speed[0] = speed[0] if speed[0] == 0 else (abs(speed[0]) - 1) * int(speed[0] / abs(speed[0])) 26 elif event.key == pygame.K_RIGHT: 27 speed[0] = speed[0] + 1 if speed[0] > 0 else speed[0] - 1 28 elif event.key == pygame.K_UP: 29 speed[1] = speed[1] + 1 if speed[1] > 0 else speed[1] - 1 30 elif event.key == pygame.K_DOWN: 31 speed[1] = speed[1] if speed[1] == 0 else (abs(speed[1]) - 1) * int(speed[1] / abs(speed[1])) 32 elif event.key == pygame.K_ESCAPE: 33 sys.exit() 34 elif event.type == pygame.VIDEORESIZE: 35 size = width, height = event.size[0], event.size[1] 36 screen = pygame.display.set_mode(size, pygame.RESIZABLE) 37 elif event.type == pygame.MOUSEBUTTONDOWN: 38 if event.button == 1: 39 still = True 40 elif event.type == pygame.MOUSEBUTTONUP: 41 still = False 42 if event.button == 1: 43 ballrect = ballrect.move(event.pos[0] - ballrect.left, event.pos[1] - ballrect.top) 44 elif event.type == pygame.MOUSEMOTION: 45 if event.buttons[0] == 1: 46 ballrect = ballrect.move(event.pos[0] - ballrect.left, event.pos[1] - ballrect.top) 47 if pygame.display.get_active() and not still: 48 ballrect = ballrect.move(speed) 49 if ballrect.left < 0 or ballrect.right > width: 50 speed[0] = - speed[0] 51 if ballrect.right > width and ballrect.right + speed[0] > ballrect.right: 52 speed[0] = - speed[0] 53 if ballrect.top < 0 or ballrect.bottom > height: 54 speed[1] = - speed[1] 55 if ballrect.bottom > height and ballrect.bottom + speed[1] > ballrect.bottom: 56 speed[1] = - speed[1] 57 58 screen.fill(BLACK) 59 screen.blit(ball, ballrect) 60 pygame.display.update() 61 fclock.tick(fps)
===================================================================================
5.Pygame事件处理函数
事件处理的重要函数:
处理事件:
pygame.event.get()
pygame.event.poll()
pygame.event.clear()
操作事件队列:
pygame.event.set_blocked()
pygame.event.get_blocked()
pygame.event.set_allowed()
生成事件:
pygame.event.post()
pygame.event.Event()
Pygame事件队列
事件队列(同时仅能存储128个事件 当队列满时,更多事件将被丢弃)
pygame.event.set_blocked()
pygame.event.set_allowed()
pygame.event.get_blocked()
•设置事件队列能够缓存事件的类型
-------------------------------------------------------------
事件处理函数:
pygame.event.get()
•从事件队列中获得事件列表,即获得所有在队列的事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
•可以增加参数,获得某类或某些类事件:
pygame.event.get(type)
pygame.event.get(typelist)
pygame.event.poll()
•从事件队列中获得一个事件
While True:
event= pygame.event.poll()
•事件获取将从事件队列中删除
•如果事件队列为空,则返回event.NOEVENT
pygame.event.clear()
•从事件队列中删除事件,默认删除所有事件
•该函数与pygame.event.get()类似,区别仅是不对事件进行处理
•可以增加参数,删除某类或某些类事件:
pygame.event.clear(type)
pygame.event.clear(typelist)
-------------------------------------------------------------
事件处理函数:
pygame.event.set_blocked(type or typelist)
•控制哪些类型事件不允许被保存到事件队列中
pygame.event.set_allowed(type or typelist)
•控制哪些类型事件允许被保存到事件队列中
pygame.event.get_blocked(type)
•测试某个事件类型是否被事件队列所禁止
•如果事件类型被禁止,则返回True,否则返回False
pygame.event.post(Event)
•产生一个事件,并将其放入事件队列
•一般用于放置用户自定义事件(pygame.USEREVENT)
•也可以用于放置系统定义事件(如鼠标或键盘等),给定参数
pygame.event.Event(type, dict)
•创建一个给定类型的事件
•其中,事件的属性和值采用字典类型复制,属性名采用字符串形式
•如果创建已有事件,属性需要一致
测试事件产生机制
源代码:
1 import pygame, sys 2 3 pygame.init() 4 screen = pygame.display.set_mode((600, 400)) 5 pygame.display.set_caption("Pygame事件处理") 6 fps = 1 7 fclock = pygame.time.Clock() 8 num = 1 9 10 while True: 11 uevent = pygame.event.Event(pygame.KEYDOWN, {"unicode": 123, "key": pygame.K_SPACE, "mod": pygame.KMOD_ALT}) 12 pygame.event.post(uevent) 13 num = num + 1 14 for event in pygame.event.get(): 15 if event.type == pygame.QUIT: 16 sys.exit() 17 elif event.type == pygame.KEYDOWN: 18 if event.unicode == "": 19 print("[KEYDOWN {}]:".format(num), "#", event.key, event.mod) 20 else: 21 print("[KEYDOWN {}]:".format(num), event.unicode, event.key, event.mod) 22 23 pygame.display.update() 24 fclock.tick(fps)