2016-01-13 2 views
3

Привет, я создаю игру, где у меня несколько этапов. Я хочу сделать так, чтобы каждый раз, когда пользователь нажимает клавишу a, запускается следующий этап. Вот пример моего кода.Pygame: Как получить KEYDOWN для ввода только один раз?

gameStage = 0 ## outside while loop 

##INSIDE whileloop 
if gameStage == 0: 
    ##insert drawings,music, etc 
    if event.type == pygame.KEYDOWN: 
     if event.key == pygame.K_a: 
      gameStage += 1 

if gameStage == 1: 
    ##insert drawings,music, etc 
    if event.type == pygame.KEYDOWN: 
     if event.key == pygame.K_a: 
      gameStage += 1 

моя проблема заключается в том, что, когда пользователь нажимает клавишу a, a будет введено более чем один раз в зависимости, как долго держится ключ. Поэтому он просто пропустит весь путь до моего последнего этапа. Как сделать так, чтобы gameStage был + = 1 только при нажатии и нажатии клавиши? Скажите, пожалуйста, если я не понимаю. Цените любую помощь. Благодарю.

+2

Как использовать вместо этого ключ? –

+1

Где ваше событие 'for в pygame.event.get():' loop на данный момент? С вашим текущим макетом кода, похоже, вам нужен отдельный цикл событий на каждом этапе. – Marius

ответ

0

Вы можете использовать событие pygame.KEYUP.

например.

if event.type == pygame.KEYUP:

Но вы не должны получать повторяться KEYDOWN сообщения, если вы не назвали pygame.key.set_repeat и установить ненулевое значение повтора.

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

+0

Исправьте меня, если я ошибаюсь, но не KEYUP просто означает, что ключ вверх? а не то, что он выпущен? Если я прав, это ничего не решает. Он просто пропустит все этапы, когда ключ останется. Может быть, я делаю что-то не так? – eukoloko

+0

Нет, вы должны получить только одно событие KEYUP, когда ключ будет выпущен. Вы получаете только несколько событий KEYDOWN в качестве ключевого механизма повторения. Если бы это было так, как вы предполагаете, вы постоянно получали сообщения KEYUP для всех ключей, которые вы не нажали. –

+0

Не знаю, что я делаю неправильно. Я использую событие key.up, но все же получаю ту же проблему. Я использовал точный шаблон i, указанный выше, с KEYDOWN, замененным на KEYUP. Все еще пропуская стадии. Спасибо за помощь. – eukoloko

0

Вы можете использовать событие key up, как указано выше, или прекратить реагировать на событие keydown после нескольких тиков после его выпуска.

+0

Как мне перестать реагировать на событие keydown для нескольких тиков? – eukoloko

+0

Как это: 'ticks_to_ignore = 0, если Event.type == pygame.KEYDOWN и ticks_to_ignore == 0: ticks_to_ignore = 10 # Процесс события # В другом месте в главном цикле , если ticks_to_ignore> 0: ticks_to_ignore - = 1' Но это немного уродливый взлом, клавиатура, вероятно, будет проще и понятнее для игрока. – Synedraacus

1

При нажатии кнопок на клавиатуре нажата или отпущена pygame.KEDOWN или pygame.KEYUP событие появляется только те, на очереди событий

Как вы это сделали, вам нужно установить глобальную переменную GameStage, которая указывает на текущую игру состояние:

GameStage = 0 ## outside while loop 

После этого мы запускаем наш основной цикл игры и получать все события формируют даже очереди, используя функцию pygame.event.get(), которая считывает и удаляет событие s из очереди:

while True: 
    #get all events from the event queue 
    for ev in pygame.event.get(): 

Если событие чтения представляет собой ключ-вниз событие логика программы обновляет GameStage переменную, аналогичную так называемой state-machine:

if ev.type == pygame.KEYDOWN: 
    if ev.key == pygame.K_a:    
     if GameStage == 0: 
      GameStage += 1 
      #do something 

     elif GameStage == 1: 
      GameStage += 1 
      #do something great 

     # and so on ;) 

Полный программный блок выглядит следующим образом:

#global variable GameStage for state-machine 
GameStage = 0 

#main game loop 
while True: 
    #get all events from the event queue 
    for ev in pygame.event.get(): 
     if ev.type == pygame.KEYDOWN: 
      if ev.key == pygame.K_a:    
       if GameStage == 0: 
        GameStage += 1 
        #do something 

       elif GameStage == 1: 
        GameStage += 1 
        #do something great 

       elif GameStage == 2: 
        GameStage += 1 
        #do something great again 

       elif GameStage == 3: 
        #this is the last stage, so you cloud go back to stage #0 
        GameStage = 0 

       #for debugging print current GameStage 
       print(GameStage) 

Только при нажатии - независимо от того, как долго вы удерживаете - aGameStage будет обновляться только один раз.

Надеется, что это помогает :)

Как отмечалось @sloth, это можно изменить называть pygame.key.set_repeat(), который будет генерировать несколькоpygame.KEYDOWN события, когда клавиши в нажатом положении.

+1

'... событие появляется только в очереди событий': это, как правило, верно, но только если вы не включаете повторение ключа с помощью' pygame.key.set_repeat' (что плохо в большинстве случаев). – sloth

+0

@sloth: достаточно честно :) Я добавлю, что это может быть проблемой. – elegent

Смежные вопросы