这节讲了一些之前出现过的键盘操作。
键盘设备
以前第二部分也稍微使用了一下键盘,那时候是用了pygame.event.get()获取所有的事件,当event.type == KEYDOWN的时候,在判断event.key的种类,而各个种类也使用K_a,K_b……等判断。这里再介绍一个pygame.key.get_pressed()来获得所有按下的键值,它会返回一个元组。这个元组的索引就是键值,对应的就是是否按下,比如说:
pressed_keys = pygame.key.get_pressed() if pressed_keys[K_SPACE]: # Space key has been pressed fire()pressed_keys = pygame.key.get_pressed()
当然key模块下还有很多函数:
- key.get_focused —— 返回当前的pygame窗口是否激活
- key.get_pressed —— 获得所有按下的键值
- key.get_mods —— 按下的组合键(Alt, Ctrl, Shift)
- key.set_mods —— 你也可以模拟按下组合键的效果(KMOD_ALT, KMOD_CTRL, KMOD_SHIFT)
- key.set_repeat —— 无参数调用设置pygame不产生重复按键事件,二参数(delay, interval)调用设置重复事件发生的时间
- key.name —— 接受键值返回键名
使用键盘控制方向
通过向量来控制方向的上下左右,但仅局限于8个方向。
#-*- coding:utf-8 -*- background_image_filename = './images/sushiplate.jpg' sprite_image_filename = './images/fugu.png' import pygame from pygame.locals import * from sys import exit from gameobjects.vector2 import Vector2 pygame.init() screen = pygame.display.set_mode((640, 480), 0, 32) background = pygame.image.load(background_image_filename).convert() sprite = pygame.image.load(sprite_image_filename) clock = pygame.time.Clock() #传入坐标被作为向量 sprite_pos = Vector2(200, 150) #初始速度 sprite_speed = 300. while True: for event in pygame.event.get(): if event.type == QUIT: exit() #获取按下的键值 pressed_keys = pygame.key.get_pressed() #设置按键的向量初值 key_direction = Vector2(0, 0) #若按下左键则像素减一 if pressed_keys[K_LEFT]: key_direction.x = -1 elif pressed_keys[K_RIGHT]: key_direction.x = 1 if pressed_keys[K_UP]: key_direction.y = -1 elif pressed_keys[K_DOWN]: key_direction.y = 1 #按键向量规格化 key_direction.normalize() screen.blit(background, (0, 0)) screen.blit(sprite, sprite_pos) time_passed = clock.tick(30) time_passed_passed = time_passed / 1000.0 #鱼的新的位置=(按键向量*鱼的运动速度*帧)+ 初始位置(前一个位置) sprite_pos += key_direction * sprite_speed * time_passed_passed #刷新鱼图片位置 pygame.display.update()
用上下左右键来控制鱼的移动实例。
下面是一个可以全方位逆时针选择的鱼实例:
#-*- coding:utf-8 -*- background_image_filename = './images/sushiplate.jpg' sprite_image_filename = './images/fugu.png' import pygame from pygame.locals import * from sys import exit from gameobjects.vector2 import Vector2 from math import * pygame.init() screen = pygame.display.set_mode((640, 480), 0, 32) background = pygame.image.load(background_image_filename).convert() sprite = pygame.image.load(sprite_image_filename).convert_alpha() clock = pygame.time.Clock() sprite_pos = Vector2(200, 150) # 初始位置 sprite_speed = 300. # 每秒前进的像素数(速度) sprite_rotation = 0. # 初始角度 sprite_rotation_speed = 360. # 每秒转动的角度数(转速) while True: for event in pygame.event.get(): if event.type == QUIT: exit() pressed_keys = pygame.key.get_pressed() rotation_direction = 0. movement_direction = 0. # 更改角度 if pressed_keys[K_LEFT]: rotation_direction = +1. if pressed_keys[K_RIGHT]: rotation_direction = -1. # 前进、后退 if pressed_keys[K_UP]: movement_direction = -1. if pressed_keys[K_DOWN]: movement_direction = +1. screen.blit(background, (0, 0)) # 获得一条转向后的鱼,rotate(Surface, angle) -> Surface # 未经过滤的逆时针旋转。 角度参数代表度数并可以是任何浮点值。 负角度量将顺时针旋转。 rotated_sprite = pygame.transform.rotate(sprite, sprite_rotation) # 转向后,图片的长宽会变化,因为图片永远是矩形,为了放得下一个转向后的矩形,外接的矩形势必会比较大 w, h = rotated_sprite.get_size() # 获得绘制图片的左上角 sprite_draw_pos = Vector2(sprite_pos.x - w / 2, sprite_pos.y - h / 2) # 将一个平面的一部分或全部图象整块从这个平面复制到另一个平面 screen.blit(rotated_sprite, sprite_draw_pos) time_passed = clock.tick() time_passed_seconds = time_passed / 1000.0 # 图片的转向速度也需要和行进速度一样,通过时间来控制 sprite_rotation += rotation_direction * sprite_rotation_speed * time_passed_seconds # 获得前进(x方向和y方向),这两个需要一点点三角的知识,类似于sin(pi/6)=30 heading_x = sin(sprite_rotation * pi / 180.) heading_y = cos(sprite_rotation * pi / 180.) # 转换为单位速度向量 heading = Vector2(heading_x, heading_y) # 转换为速度 heading *= movement_direction sprite_pos += heading * sprite_speed * time_passed_seconds pygame.display.update()我们通过上下控制前进/后退,而左右控制转向。我们通过 pygame.transform.rotate() 来获得了转向后的图片,具体参数可以参考代码。各条语句的作用也可以参考注释