Я создаю игру в pygame 1.9.2. Это очень простая игра, в которой корабль движется между пятью колоннами плохих парней, которые атакуют, медленно двигаясь вниз. Я пытаюсь сделать так, чтобы корабль перемещался влево и вправо с помощью клавиш со стрелками влево и вправо. Вот мой код.:
keys=pygame.key.get_pressed() if keys[K_LEFT]: location-=1 if location==-1: location=0 if keys[K_RIGHT]: location+=1 if location==5: location=4
Это работает слишком хорошо. Корабль движется слишком быстро. Практически невозможно заставить его перемещаться только в одном месте, влево или вправо. Как я могу сделать так, чтобы корабль перемещался только один раз при каждом нажатии клавиши?
Переведено автоматически
Ответ 1
Вы можете получать события из pygame, а затем следить за KEYDOWN событием, вместо того чтобы смотреть на клавиши, возвращаемые get_pressed()(что выдает вам клавиши, которые в данный момент нажаты, тогда как KEYDOWN событие показывает вам, какие клавиши были нажаты в этом кадре).
Что происходит с вашим кодом прямо сейчас, так это то, что если ваша игра отрисовывается со скоростью 30 кадров в секунду, и вы удерживаете клавишу со стрелкой влево в течение половины секунды, вы обновляете местоположение 15 раз.
events = pygame.event.get() for event in events: if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: location -= 1 if event.key == pygame.K_RIGHT: location += 1
Чтобы поддерживать непрерывное перемещение при удерживании клавиши нажатой, вам пришлось бы установить какое-то ограничение, основанное либо на принудительной максимальной частоте кадров в игровом цикле, либо на счетчике, который позволяет вам перемещаться только каждые определенное количество тактов цикла.
move_ticker = 0 keys=pygame.key.get_pressed() if keys[K_LEFT]: if move_ticker == 0: move_ticker = 10 location -= 1 if location == -1: location = 0 if keys[K_RIGHT]: if move_ticker == 0: move_ticker = 10 location+=1 if location == 5: location = 4
Затем где-нибудь во время игрового цикла вы бы сделали что-то вроде этого:
if move_ticker > 0: move_ticker -= 1
Это позволит вам перемещаться только один раз каждые 10 кадров (поэтому, если вы переместитесь, тикер будет установлен на 10, и после 10 кадров это позволит вам перемещаться снова)
Ответ 2
pygame.key.get_pressed() возвращает список с состоянием каждой клавиши. Если клавиша нажата, состояние клавиши равно 1, в противном случае 0. Это снимок клавиш, в этот самый момент новое состояние клавиш должно непрерывно восстанавливаться в каждом кадре. Используйте pygame.key.get_pressed() для оценки текущего состояния кнопки и получения непрерывного движения:
whileTrue:
keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: x -= speed if keys[pygame.K_RIGHT]: x += speed if keys[pygame.K_UP]: y -= speed if keys[pygame.K_DOWN]: y += speed
This code can be simplified by subtracting "left" from "right" and "up" from "down":
whileTrue:
keys = pygame.key.get_pressed() x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * speed y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * speed
The keyboard events (see pygame.event module) occur only once when the state of a key changes. The KEYDOWN event occurs once every time a key is pressed. KEYUP occurs once every time a key is released. Use the keyboard events for a single action or movement:
whileTrue:
for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x -= speed if event.key == pygame.K_RIGHT: x += speed if event.key == pygame.K_UP: y -= speed if event.key == pygame.K_DOWN: y += speed
rect = pygame.Rect(0, 0, 20, 20) rect.center = window.get_rect().center vel = 5
run = True while run: clock.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False if event.type == pygame.KEYDOWN: print(pygame.key.name(event.key))
keys = pygame.key.get_pressed()
rect.x += (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel rect.y += (keys[pygame.K_DOWN] - keys[pygame.K_UP]) * vel
run = True while run: clock.tick(60) current_time = pygame.time.get_ticks() for event in pygame.event.get(): if event.type == pygame.QUIT: run = False
if event.type == pygame.KEYDOWN: bullet_list.insert(0, tank_rect.midright)
for i, bullet_pos inenumerate(bullet_list): bullet_list[i] = bullet_pos[0] + 5, bullet_pos[1] if bullet_surf.get_rect(center = bullet_pos).left > window.get_width(): del bullet_list[i:] break
window.fill((224, 192, 160)) window.blit(tank_surf, tank_rect) for bullet_pos in bullet_list: window.blit(bullet_surf, bullet_surf.get_rect(center = bullet_pos)) pygame.display.flip()
pygame.quit() exit()
Ответ 3
import pygame pygame.init() pygame.display.set_mode() whileTrue: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit(); #sys.exit() if sys is imported if event.type == pygame.KEYDOWN: if event.key == pygame.K_0: print("Hey, you pressed the key, '0'!") if event.key == pygame.K_1: print("Doing whatever")
Обратите внимание, что K_0 и K_1 - не единственные клавиши, чтобы просмотреть их все, обратитесь к документации pygame, в противном случае нажмите tab после ввода
pygame.
(обратите внимание на . after pygame) в незанятой программе. Обратите внимание, что буква K должна быть заглавной. Также обратите внимание, что если вы не зададите pygame размер дисплея (не указывайте никаких аргументов), то он автоматически будет использовать размер экрана / монитора компьютера. Приятного кодирования!