python Pygame-检测是否有按键被按下?

frebpwbc  于 2022-10-30  发布在  Python
关注(0)|答案(2)|浏览(535)

我正在做一件简单的事情,并且一直在关注youtube上的一个教程。我有能力用WASD移动女妖(我用了Halo中的一张图片作为我的飞船),但是我必须重复地敲击按键,而我希望能够通过按住按键来移动它。下面是代码;

import pygame
from pygame.locals import *

pygame.init()

screen = pygame.display.set_mode((1440,900))

pygame.display.update()

black=(0,0,0)
white=(255,255,255)

## loads the background

background = pygame.image.load("G:/starfield.jpg")

### loads sprite of a spaceship that will move.

banshee = pygame.image.load("G:/banshee.png")
x=1
y=1

while True:
    gamexit = False

    while not gamexit:
        screen.blit(background,(0,0))
        screen.blit(banshee,(x,y))
        pygame.display.update()
        # if it touches the sides of the window, the window closes
        if x==1440 or x==0 or y==900 or y==0:
                pygame.quit()
                quit()
        else:
            for event in pygame.event.get():
                pressed= pygame.key.get_pressed()
                if event.type == pygame.QUIT:
                    gamexit=True
                    pygame.quit()
                    quit()
                elif event.type==KEYDOWN:
                    # moves banshee up if w pressed, same for the other WASD keys below
                    if event.key==K_w:
                        y=y-5
                        x=x
                        screen.blit(banshee,(x,y))
                        pygame.display.update()
                    elif event.key==K_a:
                        x=x-5
                        y=y
                        screen.blit(banshee,(x,y))
                        pygame.display.update()
                    elif event.key==K_d:
                        x=x+5
                        y=y
                        screen.blit(banshee,(x,y))
                        pygame.display.update()
                    elif event.key==K_s:
                        y=y+5
                        x=x
                        screen.blit(banshee,(x,y))
                        pygame.display.update()

我已经尝试了许多不同的方法来做这件事(在这里和其他地方),但收效甚微。有什么我可以在这里做的,而不需要重写一大段代码?

  • 谢谢-谢谢
vmjh9lq9

vmjh9lq91#

使用pygame.key.get_pressed()来检查某个键是否被按下要容易得多,因为您不需要自己通过事件来跟踪键的状态。
我通常创建一个字典,将键Map到它们应该移动对象的方向。
这样,查询pygame.key.get_pressed()的结果就很容易了。
您可以使用一些简单的矢量数学来规范化移动方向,这样您就可以以与仅沿着x或y轴相同的速度沿对角线移动。
此外,使用Rect来存储对象的位置也更容易,因为pygame提供了许多与Rect类一起工作的有用函数。

import pygame, math
from pygame.locals import *

# some simple functions for vetor math

# note that the next pygame release will ship with a vector math module included!

def magnitude(v):
    return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))

def add(u, v):
    return [ u[i]+v[i] for i in range(len(u)) ]

def normalize(v):
    vmag = magnitude(v)
    return [ v[i]/vmag  for i in range(len(v)) ]

pygame.init()

screen = pygame.display.set_mode((1440,900))
screen_r = screen.get_rect()

pygame.display.update()

black=(0,0,0)
white=(255,255,255)

background = pygame.image.load("G:/starfield.jpg")##loads the background

# here we define which button moves to which direction

move_map = {pygame.K_w: ( 0, -1),
            pygame.K_s: ( 0,  1),
            pygame.K_a: (-1,  0),
            pygame.K_d: ( 1,  0)}

banshee = pygame.image.load("G:/banshee.png")  

# create a Rect from the Surface to store the position of the object

# we can pass the initial starting position by providing the kwargs top and left

# another useful feature is that when we create the Rect directly from the

# Surface, we also have its size stored in the Rect

banshee_r = banshee.get_rect(top=50, left=50)

speed = 5

gameexit = False

while not gameexit:

    # exit the game when the window closes
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameexit = True

    # if it touches the sides of the window, end the game
    # note how easy this part becomes if you use the Rect class
    if not screen_r.contains(banshee_r):
        gameexit = True

    # get all pressed keys
    pressed = pygame.key.get_pressed()

    # get all directions the ship should move
    move = [move_map[key] for key in move_map if pressed[key]]

    # add all directions together to get the final direction
    reduced = reduce(add, move, (0, 0))
    if reduced != (0, 0):

        # normalize the target direction and apply a speed
        # this ensures that the same speed is used when moving diagonally
        # and along the x or y axis. Also, this makes it easy to
        # change the speed later on.
        move_vector = [c * speed for c in normalize(reduced)]

        # move the banshee
        # Another useful pygame functions for Rects
        banshee_r.move_ip(*move_vector)

    screen.blit(background,(0,0))
    # we can use banshee_r directly for drawing
    screen.blit(banshee, banshee_r)
    pygame.display.update()
z31licg0

z31licg02#

首先,尝试添加变量dxdy来存储密钥的状态

elif event.type==KEYDOWN:
                # moves banshee up if w pressed,
                # same for the other WASD keys below
                if event.key==K_w:
                    dy = -5
                elif event.key==K_a:
                    dx = -5
                elif event.key==K_d:
                    dx = 5
                elif event.key==K_s:
                    dy = 5
           elif event.type==KEYUP:
                # moves banshee up if w pressed,
                # same for the other WASD keys below
                if event.key==K_w:
                    dy = 0
                elif event.key==K_a:
                    dx = 0
                elif event.key==K_d:
                    dx = 0
                elif event.key==K_s:
                    dy = 0

    x += dx
    y += dy
    screen.blit(banshee,(x,y))
    pygame.display.update()

相关问题