У меня проблема с pyGame (полный новичок здесь). Я тренируюсь с event.key и хотел бы отключить/отключить клавишу, которая будет нажата непрерывно. Я попытался это сделать и проверил этот сайт, но это не принесло многообещающих результатов. Вся вещь имеет место в
if event.key == pygame.K_UP and isJumping == False:
(полные строки 49 - 55)
## HOW TO UNPRESS K_UP IN CASE IT WAS PRESSED AND NOT RELEASED?
if event.key == pygame.K_UP and isJumping == False:
yChange -= 10
isJumping = True
elif event.key == pygame.K_UP and isJumping == True:
print("X")
Это работает отлично, если стрелка вверх нажимается один раз, но продолжает выполнение yChange в цикле, если он не был выпущен - это, конечно, совсем не желательно. Не могли бы вы мне помочь?
import pygame
pygame.init() # Initialize pyGame module
# Set screen dimensions
screenW = 800
screenH = 600
# Set color
AQUA = (155, 255, 255)
# Set FPS
FPS = 60
fpsClock = pygame.time.Clock()
# Set character
mainChar = pygame.image.load('p1_front.png')
mainCharX = screenH / 2 # char X position
mainCharY = screenW / 2 # char Y position
isJumping = False
xChange = 0
yChange = 0
MOVSPEED = 1
# Set backgrounds
mainBg = pygame.image.load('bg_castle.png')
mainBg = pygame.transform.scale(mainBg, (screenW, screenH))
# Set the window, param in a tuple is width / height
DISPLAYSURF = pygame.display.set_mode((screenW, screenH))
# Set window name (game title)
pygame.display.set_caption("Newbie training")
while True: # Main loop of the game
#set BG
DISPLAYSURF.blit(mainBg, (0,0))
# Events loop below
for event in pygame.event.get():
if event.type == pygame.QUIT: # Quit window when [x] is pressed
pygame.quit()
exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
xChange += MOVSPEED
elif event.key == pygame.K_LEFT:
xChange -= MOVSPEED
## HOW TO UNPRESS K_UP IN CASE IT WAS PRESSED AND NOT RELEASED?
if event.key == pygame.K_UP and isJumping == False:
yChange -= 10
isJumping = True
elif event.key == pygame.K_UP and isJumping == True:
print("X")
if event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT or event.key == pygame.K_LEFT:
xChange = 0
if event.key == pygame.K_UP:
yChange = 0
#print(event)
mainCharX += xChange
mainCharY += yChange
DISPLAYSURF.blit(mainChar, (mainCharX, mainCharY)) # Load character
pygame.display.update() #update window
fpsClock.tick(FPS) # FPS goes always after update
Кажется, вы не понимаете, как работает очередь событий и цикл событий. Когда вы нажимаете клавишу, в pygame.KEYDOWN
событий добавляется одно событие pygame.KEYDOWN
. Вызов pygame.event.get
опорожняет очередь событий и помещает все события в список, по которому вы перебираете цикл for event in pygame.event.get():
: for event in pygame.event.get():
Это означает, что pygame не знает, что вы все еще держите ключ, он только увидит, что вы нажали UP один раз. Он также заметит, что вы отпустите ключ и добавите событие pygame.KEYUP
в очередь.
В вашем случае вы уменьшаете переменную yChange
до -10
при нажатии клавиши UP. В цикле while mainCharY
будет mainCharY
на -10
каждый кадр, и символ будет двигаться вверх. Как только вы отпустите ключ, yChange
сбрасывается на 0
и символ игрока останавливается.
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
yChange = 0
Чтобы реализовать прыжки в вашей игре, вы должны добавить константу GRAVITY, которую вы добавляете к своей скорости y, чтобы каждый кадр ускорялся вниз. Когда персонаж коснется земли, установите для y-velocity значение 0 и переменную (on_ground
или что-то подобное) в значение True
, чтобы вы знали, что игрок может прыгать. Когда игрок нажимает клавишу перехода, вы можете установить у-скорость на отрицательное значение, и спрайт начнет двигаться вверх, пока GRAVITY снова не опустит его. Вот полный пример.
Если вы хотите, чтобы игрок мог прыгать на 10 'единиц' на прессу, тогда остановитесь на месте, вы можете просто установить yChange на 0 каждый кадр после добавления его в mainCharY.
Однако, если вы ищете более надежную систему прыжков (нажата кнопка, игрок перемещается вверх на несколько кадров, затем останавливается и падает назад) требуется больше.
Чтобы дать вам представление: что, если в конце каждого фрейма была какая-то логика, проверяющая, если mainCharY> 0 (игрок не на земле) и, если это так, вычитает некоторое число из yChange (как если бы гравитация вытягивала их)?
В приведенном выше случае ваш код должен избегать повторной проблемы с прессой. Возможно, было бы проще просто проверить (mainCharY> 0) вместо использования переменной isJumping.
Я не думаю, что это вообще возможно, что pygame может пропустить ключевое событие.
Я думаю, проблема заключается в том, что вы не устанавливаете isJumping
на false в любом месте, что останавливает изменение yChange
навсегда после первого нажатия. Если я правильно это интерпретирую, следующий код должен работать:
if event.type == pygame.KEYDOWN:
... # Your other code
if event.key == pygame.K_UP and not isJumping: # "== False" is not necessary
yChange -= 10
isJumping = True
if event.type == pygame.KEYUP:
... # Your other code
if event.key == pygame.K_UP and isJumping:
yChange = 0
isJumping = False # <-- This is the addition to the code
Одна вещь, о которой нужно помнить, заключается в том, что эта система прыжков не будет выглядеть очень естественной. Посмотрите на ответ @SamHolloway, чтобы получить больше разъяснений по этому вопросу.