Я кодировал змейку на python. Но если мы быстро нажмем 2 кнопки, потребуется две команды за один галочку. что я могу сделать, чтобы это предотвратить? - PullRequest
2 голосов
/ 06 августа 2020

У меня есть следующая проблема в моей игре со змейкой: если змея движется вправо, а игрок быстро нажимает клавиши ВВЕРХ и ВЛЕВО, змея поворачивает налево, выходит за пределы своего тела, и игра заканчивается, принимая это за столкновение. . Как я могу запретить игре принимать две команды для изменения направления до того, как змея двинется?

Код, в котором я проверяю, какая клавиша нажата, следующий:

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT and left == False:
                right = True
                up = False
                down = False
            elif event.key == pygame.K_LEFT and right == False:
                left = True
                up = False
                down = False
            elif event.key == pygame.K_DOWN and up == False:
                down = True
                right = False
                left = False
            elif event.key == pygame.K_UP and down == False:
                up = True
                right = False
                left = False

Полный код проекта можно найти в этом Git репозитории .

Для запуска кода вам необходимо установить пакет pygame через pip.

Ответы [ 3 ]

2 голосов
/ 06 августа 2020

Проблема в том, что все события сохраняются в списке, и вы замедляете код, поэтому у системы есть время поместить два (или более) KEYDOWN событий в этот список, прежде чем вы запустите for event l oop, который проверяет все KEYDOWN в этом списке.

Как упоминалось в @ VaclavPel c, вы можете использовать переменную для управления, если вы уже изменили направление и пропустите другие клавиши.

Таким образом, будет использоваться только первый правильный ключ / направление при нажатии многих клавиш - поэтому вы не можете быстро изменить решение - ie. когда вы двигаетесь вниз и нажимаете left и right, тогда он будет использовать left, потому что это первое правильное направление.

while True:

    changed_direction = False

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if not changed_direction:
                if event.key == pygame.K_RIGHT and left == False:
                    right = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_LEFT and right == False:
                    left = True
                    up = False
                    down = False
                    changed_direction = True
                elif event.key == pygame.K_DOWN and up == False:
                    down = True
                    right = False
                    left = False
                    changed_direction = True
                elif event.key == pygame.K_UP and down == False:
                    up = True
                    right = False
                    left = False
                    changed_direction = True

Другой метод - сохранить предыдущее направление в разных переменных и использовать эти переменные при проверке предыдущего направления.

Таким образом, при нажатии многих клавиш будет использоваться последняя правильная клавиша / направление - так что вы можете быстро изменить решение - ie. когда вы двигаетесь вниз и нажимаете left и right, тогда он будет использовать right, потому что это последнее правильное направление.

while True:

    previous_left = left
    previous_right = right
    previous_up = up
    previous_down = down
    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_RIGHT and previous_left == False:
                right = True
                up = False
                down = False
            elif event.key == pygame.K_LEFT and previous_right == False:
                left = True
                up = False
                down = False
            elif event.key == pygame.K_DOWN and previous_up == False:
                down = True
                right = False
                left = False
            elif event.key == pygame.K_UP and previous_down == False:
                up = True
                right = False
                left = False
2 голосов
/ 06 августа 2020

Если я правильно понимаю, у вас проблема, заключающаяся в том, что когда ваша змея движется вправо, и вы нажимаете клавишу вверх и быстро последовательно нажимаете клавишу влево, голова вашей змеи поворачивается влево, что фактически приводит к столкновению с его собственное тело.

Похоже, движение вашей змеи не зависит от нажатия клавиш, что затем дает возможность нажать две клавиши за одно движение, и поскольку единственное условие - змея не движется вправо , что фактически становится истинным, когда вы нажимаете клавишу вверх, это приводит к такому поведению.

Один из быстрых способов предотвратить это - установить некоторую переменную с именем, например, moved_from_last_press, где каждый раз, когда змея движется, вы назначьте True, и каждый раз, когда вы нажимаете клавишу, вы назначаете False. Затем вы проверяете значение True, когда проверяете, какая клавиша была нажата.

1 голос
/ 06 августа 2020

Проблема в том, что ваши ключи проверяются чаще, чем движется змея. Например, вы можете нажать вверх и влево до того, как змея начнет двигаться вверх, в результате чего останется go. Чтобы решить эту проблему, вам нужен флаг, указывающий, что змея переместилась, чтобы вы знали, когда проверять нажатие другой клавиши:

moved = True

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if(moved):
                if event.key == pygame.K_RIGHT and left == False:
                    right = True
                    up = False
                    down = False
                    moved = False
                elif event.key == pygame.K_LEFT and right == False:
                    left = True
                    up = False
                    down = False
                    moved = False
                elif event.key == pygame.K_DOWN and up == False:
                    down = True
                    right = False
                    left = False
                    moved = False
                elif event.key == pygame.K_UP and down == False:
                    up = True
                    right = False
                    left = False
                    moved = False

    if up:
        next = (snakes_block[0][0], snakes_block[0][1] - 1)
        imghadd = pygame.transform.rotate(imghad, 180)
        moved = True
    elif down:
        next = (snakes_block[0][0], snakes_block[0][1] + 1)
        imghadd = pygame.transform.rotate(imghad, 360)
        moved = True
    elif left:
        next = (snakes_block[0][0] - 1, snakes_block[0][1])
        imghadd = pygame.transform.rotate(imghad, 270)
        moved = True
    elif right:
        next = (snakes_block[0][0] + 1, snakes_block[0][1])
        imghadd = pygame.transform.rotate(imghad, 90)
        moved = True

Перемещаемая переменная используется для проверки того, была ли перемещена змея с момента нажатия клавиши , программа будет обнаруживать ключи только после того, как движение было сделано, поэтому вы не можете повернуть змейку go в направлении, которое она не должна

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...