2015-06-18 6 views
1

Так что я делаю простую вещь и слежу за учебником на youtube. У меня есть возможность переместить банши (я использовал изображение из Halo для своего корабля) с использованием WASD, но мне приходится повторно нажимать клавиши, тогда как я хочу, чтобы их можно было перемещать, удерживая клавиши. Вот код;Pygame - определить, удерживается ли клавиша?

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) 

background = pygame.image.load("G:/starfield.jpg")##loads the background 
banshee = pygame.image.load("G:/banshee.png")###loads sprite of a spaceship that will move. 
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 x==1440 or x==0 or y==900 or y==0:#if it touches the sides of the window, the window closes 
       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: 
        if event.key==K_w:#moves banshee up if w pressed, same for the other WASD keys below 
         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() 

Я пробовал много разных способов сделать это (здесь и в другом месте), чтобы не помогло. Есть ли что-нибудь, что я могу здесь сделать, что не нужно переписывать большой раздел кода?

Спасибо.

ответ

1

В первом ходу, попробуйте добавить переменные dx и dy хранить состояние ключей

  elif event.type==KEYDOWN: 
       if event.key==K_w:#moves banshee up if w pressed, same for the other WASD keys below 
        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: 
       if event.key==K_w:#moves banshee up if w pressed, same for the other WASD keys below 
        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() 
+0

Это прекрасно работает! Большое спасибо! – BaconShelf

1

Это способ проще использовать pygame.key.get_pressed(), чтобы проверить, если клавиша нажата, так как вам не нужно следить за состоянием ключей самостоятельно с помощью событий.

Обычно я создаю словарь, который отображает ключи в направлении, в котором они должны перемещать объект.

Таким образом, можно легко запросить результат 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() 
Смежные вопросы