Pygame不会为对角输入选择两个键

时间:2013-12-15 22:14:48

标签: python-2.7 graphics pygame sprite

所以我的代码在背景中有一堆星星可以自动移动,用户可以通过按箭头键设置方向。向上,向下,向左和向右工作都很好,但是,当我测试出“直立”方向时,我无法移动它。

到目前为止我尝试了什么:

while running == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            #cardinal directions
                if event.key ==pygame.K_LEFT:
                    starDirection = "left"

                elif event.key == pygame.K_RIGHT:
                    starDirection = "right"


                elif event.key ==pygame.K_UP:
                    starDirection = "up"


                elif event.key ==pygame.K_DOWN:
                    starDirection ="down"

                elif event.key == pygame.K_UP and event.key == pygame.K_DOWN:
                    starDirection ="upright"




    for a_star in star_list:
        if starDirection == "right":
            a_star.rect.x += 5
            if a_star.rect.x > width:
                a_star.rect.x = 0
                a_star.rect.y = random.randint(0,height)

        elif starDirection == "left":
            a_star.rect.x -=5
            if a_star.rect.x < 0:
                a_star.rect.x = width
                a_star.rect.y = random.randint(0,height)

        elif starDirection == "up":
            a_star.rect.y -= 5
            if a_star.rect.y < 0:
                a_star.rect.x = random.randint(0,width)
                a_star.rect.y = height

        elif starDirection == "down":
            a_star.rect.y += 5
            if a_star.rect.y > height:
                a_star.rect.x = random.randint(0,width)
                a_star.rect.y = 0

        #diagonal directions
        elif starDirection == "upright":
            a_star.rect.y-=5
            a_star.rect.x+=5
            if a_star.rect.y < 0:
                a_star.rect.x = random.randint(0,width)
                a_star.rect.y = height

            elif a_star.rect.x > width:
                a_star.rect.x = 0
                a_star.rect.y = random.randint(0,height)

        elif starDirection == "upleft":

            a_star.rect.y-=5
            a_star.rect.x-=5
            if a_star.rect.y < 0:
                a_star.rect.x = random.randint(0,width)
                a_star.rect.y = height

            elif a_star.rect.x < 0:
                a_star.rect.x = width
                a_star.rect.y = random.randint(0,height)

        elif starDirection == "downright":

            a_star.rect.y += 5
            a_star.rect.x+=5
            if a_star.rect.y > height:
                a_star.rect.x = random.randint(0,width)
                a_star.rect.y = 0

            elif a_star.rect.x > width:
                a_star.rect.x = 0
                a_star.rect.y = random.randint(0,height)



        elif starDirection == "downleft":
            a_star.rect.y += 5
            a_star.rect.x-=5
            if a_star.rect.y > height:
                    a_star.rect.x = random.randint(0,width)
                    a_star.rect.y = 0

            elif a_star.rect.x < 0:
                    a_star.rect.x = width
                    a_star.rect.y = random.randint(0,height)

2 个答案:

答案 0 :(得分:1)

event.key不可能同时成为两个不同的东西。您需要通过处理KEYDOWNKEYUP事件来存储关键状态。

最简单的是为每个向上,向下,向左,向右键设置一个布尔变量。在KEYDOWN上设置它们并在KEYUP上清除它们。

然后你可以测试像if leftIsPressed and upIsPressed

这样的东西

答案 1 :(得分:1)

不是查找KEYDOWN事件,而只是使用pygame.key.get_pressed()查询所有按下的键。这样,显然很容易看出此刻按下哪些键。

此外,您应该使用移动矢量并在移动星星之前将其标准化。否则,您的星星以5对角的速度以√(5² + 5²) = 7,07的速度水平/垂直移动

以下是一个完整的例子:

import pygame
import math

from random import randint
from functools import partial

pygame.init()
width, height = (800, 600)
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
rand_x = lambda: randint(0, width)
rand_y = lambda: randint(0, height)

def magnitude(v):
    """returns the lenght of a vector"""
    return math.sqrt(sum(v[i]*v[i] for i in range(len(v))))

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


class Star(object):

    def __init__(self):
        self.rect = pygame.Rect(rand_x(), rand_y(), 1, 1)
        self.speed = randint(2, 5)

    def move(self, vec):
        if vec == [0, 0]: 
            return

        # move star by applying its speed 
        # to the normalized movement vector
        self.rect.move_ip(*[self.speed * a for a in normalize(vec)])

        # check if the star needs to appear on the opposite edge
        if self.rect.x > width:  
            self.rect.x = 0
            self.rect.y = rand_y()
        elif self.rect.x < 0:    
            self.rect.x = width
            self.rect.y = rand_y()
        if self.rect.y > height:    
            self.rect.y = 0
            self.rect.x = rand_x()
        elif self.rect.y < 0:    
            self.rect.y = height
            self.rect.x = rand_x()

    def draw(self, surface):
        pygame.draw.circle(surface, pygame.Color('white'), self.rect.center, 2)


def main():        
    # create a bunch of stars
    stars = [Star() for _ in xrange(100)]

    # a map of possible movements
    move = {pygame.K_UP: (0, -1),
            pygame.K_DOWN: (0, 1),
            pygame.K_LEFT: (-1, 0),
            pygame.K_RIGHT: (1, 0)}

    quit = False
    while not quit:
        # draw everything
        screen.fill(pygame.Color('black'))    
        for star in stars:
           star.draw(screen)
        pygame.display.flip()

        # check for pressed keys
        keys = pygame.key.get_pressed()

        # create a movement vector by adding all vectors 
        # whose key (according to 'move') is pressed
        vec = map(sum, zip(*[v for (k, v) in move.iteritems() if keys[k]])) or [0, 0]

        # move all stars
        for star in stars:
            star.move(vec)

        # check for exit
        quit = pygame.event.get(pygame.QUIT)
        pygame.event.poll()

        # limit FPS
        clock.tick(60)

if __name__ == '__main__':
    main()

enter image description here