(五)连续按键与二维方向
1. 从按键状态组成方向向量
先让方块在窗口内上下左右移动。右减左得到 x 方向,下减上得到 y 方向;同时按住相反方向时相互抵消:
# 项目文件:demos/move_dt.py
# 连续按键决定方向;单位方向乘速度和秒数,浮点位置最后再投影到整数Rect。
import pygame
def main():
pygame.init()
try:
screen = pygame.display.set_mode((480, 320))
clock = pygame.time.Clock()
position = pygame.Vector2(216, 142)
player = pygame.Rect(round(position.x), round(position.y), 48, 36)
running = True
while running:
dt = clock.tick(60) / 1000
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if not running:
break
keys = pygame.key.get_pressed()
direction = pygame.Vector2(
int(keys[pygame.K_d]) - int(keys[pygame.K_a]),
int(keys[pygame.K_s]) - int(keys[pygame.K_w]),
)
if direction.length_squared() > 0:
direction = direction.normalize()
position += direction * 240 * dt
position.x = max(0, min(480 - player.width, position.x))
position.y = max(0, min(320 - player.height, position.y))
player.topleft = round(position.x), round(position.y)
screen.fill("#F5F7FB")
pygame.draw.rect(screen, "#087F82", player)
pygame.display.flip()
finally:
pygame.quit()
if __name__ == "__main__":
main()Vector2 保存两个浮点分量,可以读取 x、y,也可以整体乘以速度与秒数。get_pressed() 的结果按键常量索引,交回当前是否按着这个键;先处理事件队列,再读取这一帧的状态。持续键盘状态
position 保存真实计算位置,player 是用于绘制的整数矩形。每次先完成浮点更新和位置限制,再把它映射到 Rect,不能每一步都把小数运动丢掉。
2. 斜向输入先归一化
只向右时方向为 (1, 0),长度为 1;同时向右下时是 (1, 1),长度为 。若直接乘速度,斜向移动就会更快。
length_squared() 计算 x*x + y*y,用它判断方向是否为零。代码在方向非零时调用 normalize,把它变成长度为 1 的新向量。斜向分量约为 (0.7071, 0.7071);乘每秒 240 后,两个分量约为 169.7,合成速度仍为 240。没有方向输入时保持零向量,停在原处。