Я пытаюсь разработать простую игру, созданную с помощью Pygame (библиотека Python).
У меня есть sprite
объект, player
и я перемещаю его с помощью клавиш со стрелками. Если я не двигаю мышь, спрайт движется нормально, но когда я двигаю мышь, спрайт движется быстрее (например, х2 или х3). player
Объект находится внутри charsGroup
вар.
Я запускал игру в W7 и в Ubuntu. То же самое происходит в обеих ОС.
У меня есть больше сущностей, которые двигаются как NPC и пули, но они не затрагиваются, только игрок. Учитывая это, я думаю, что проблема может быть связана с системой перемещения игрока (клавиши со стрелками).
Вот update()
метод player
объекта:
def update(self):
for event in pygame.event.get():
key = pygame.key.get_pressed()
mouseX, mouseY = pygame.mouse.get_pos()
if event.type == pygame.MOUSEBUTTONDOWN:
self.bulletsGroup.add(Bullet(pygame.image.load("bullet.png"),
self.rect.x + (self.image.get_width()/2),
self.rect.y + (self.image.get_height()/2),
mouseX, mouseY, 50, 50))
if key[pygame.K_RIGHT]:
if not self.checkCollision():
self.rect.x += 10
else:
self.rect.x -= 10
if key[pygame.K_LEFT]:
if not self.checkCollision():
self.rect.x -= 10
else:
self.rect.x += 10
if key[pygame.K_UP]:
if not self.checkCollision():
self.rect.y -= 10
else:
self.rect.y += 10
if key[pygame.K_DOWN]:
if not self.checkCollision():
self.rect.y += 10
else:
self.rect.y -= 10
А вот цикл while:
while True:
if PLAYER.healthBase <= 0:
GAMEOVER = True
if not GAMEOVER:
mapTilesGroup.draw(SCREEN)
charsGroup.update()
charsGroup.draw(SCREEN)
npcsGroup.update()
npcsGroup.draw(SCREEN)
drawBullets()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if GAMEOVER:
myfont = pygame.font.SysFont("monospace", 30)
label = myfont.render("GAME OVER!", 1, (255, 255, 0))
SCREEN.blit(label, (400, 300))
freq.tick(0)
pygame.display.flip()
Я не знаю, что еще вам нужно, чтобы помочь мне, но все, что вам нужно (больше информации или кода), просто попросите об этом!
BULLET_IMAGE = pygame.image.load("bullet.png")
а затем позжеself.bulletsGroup.add(Bullet(BULLET_IMAGE...
Ответы:
tl; dr не смешивайте цикл событий с циклом игры .
Когда вы двигаете мышью, игра получает множество
pygame.MOUSEMOTION
событий. Вы на самом деле не используете эти события для обновления вашей позиции мыши, хотя вы получаете текущее состояние мыши, используяpygame.mouse.get_pos()
. Это неэффективно, но это не проблема.Проблема в том, что вы обновляете позицию игрока внутри цикла событий !
Вот что должно произойти:
Вот что делает ваш код:
При перемещении мыши цикл обработки будет выполняться много раз за кадр. Но когда вы проверяете, какие клавиши нажаты
pygame.key.get_pressed()
, они остаются нажатыми , пока вы не отпустите, некоторое время спустя. Таким образом, поскольку ваш цикл событий проходит через события перемещения мыши, он будет повторно применять движения игрока несколько раз.Решение простое: вывести игрока за пределы цикла событий.
источник
pygame.mouse.get_pos()
это неэффективно? Какие у меня есть альтернативы?pygame.mouse.get_pos()
получает последнюю позицию мыши, независимо от очереди событий, поэтому нет необходимости помещать ее в цикл событий. Альтернативой может быть обработка каждогоpygame.MOUSEMOTION
самостоятельно, но если вам не нужно каждое событие (например, вы пишете программу рисования), подойдет последняя позиция.Вот еще несколько мыслей, чтобы дополнить существующий ответ .
В Gaffer On Games есть отличная статья об игровых циклах, на которую есть ссылки повсюду.
Ваш игровой цикл должен иметь разные независимые этапы: Input, Update, Render.
Например, вы можете читать входные данные 30 раз в секунду (или в режиме реального времени для лучшей скорости отклика), делать 30 обновлений в секунду и отображать 60 кадров в секунду, или любые другие значения, которые хорошо подходят для вашей игры.
источник