Я думаю, что Pygame немного менее умна, чем вы ожидаете. В вашем while
l oop вы перемещаете своего персонажа, но все, что вы делаете, когда вы «перемещаете» этого персонажа, обновляет число на этом объекте. Вы не говорите Pygame, что что-то изменилось, и вы не перерисовываете экран. Это не достаточно умно, чтобы знать, чтобы сделать это самостоятельно. Существуют фреймворки, которые будут отслеживать ваши значения и пытаться обновить отображение, чтобы синхронизироваться с ними (в основном для веб-разработки), но это не то, как работает pygame.
Вместо этого видеоигры в реальном времени обычно следуют этому шаблону :
while running:
handle_events() # check which keys have been pressed
loop() # handle, physics, AI, logic, etc
render() # re-draw a new version of the screen based on the new state of the world
Подробнее см. в этом руководстве .
В вашем случае это может выглядеть так:
pygame.key.set_repeat(100, 100)
character = Bruh(35, 367)
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_DOWN:
character.moveUp()
elif event.key == K_UP:
character.moveDown()
elif event.key == K_LEFT:
character.moveLeft()
elif event.key == K_RIGHT:
character.moveRight()
screen.fill((0, 0, 0))
drawLevel1(screen)
character.draw(screen)
pygame.display.update()
На самом деле, хотя, это не отличный способ делать вещи. Строка pygame.key.set_repeat(100, 100)
означает, что вы будете получать событие KEYDOWN
только каждые 100 мс (10 раз / сек c). Но while
l oop будет работать намного больше, чем это. Это означает, что движение вашего персонажа будет происходить только со скоростью 10FPS, но вы будете сжигать ресурсы, чтобы запустить игру намного быстрее.
Вместо этого я бы сделал что-то вроде этого:
# make a clock to help us run at a consistent framerate
clock = pygame.time.Clock()
# a dictionary to help us keep track of which keys are currently held down
keys_down = {
K_DOWN: False,
K_UP: False,
K_LEFT: False,
K_RIGHT: False,
}
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
# when the user presses a key, we keep track of the fact
# that that key is down until they release it
if event.key in keys_down:
keys_down[event.key] = True
elif event.type == KEYUP:
# when the user releases a key, it's not down anymore
if event.key in keys_down:
keys_down[event.key] = False
# This code will run *every loop*, regardless of
# whether the user has pressed or released a key recently
if keys_down[K_DOWN]:
character.moveDown()
if keys_down[K_UP]:
character.moveUp()
if keys_down[K_LEFT]:
character.moveLeft()
if keys_down[K_RIGHT]:
character.moveRight()
# Then, clear the screen and re-draw everything in the scene
screen.fill((0, 0, 0))
# drawLevel1(screen)
character.draw(screen)
pygame.display.update()
# clock.tick gets the number of `ticks` (milliseconds) since the
# last time it was called. If you specify a number like tick(30),
# then it will also wait an amount of time equal to 30 minus that
# number. Effectively it will limit you to 30fps.
clock.tick(30)
На самом деле, даже это не идеально. На самом деле, вы должны бежать как можно быстрее и обновлять игровую логику c, чтобы учесть частоту кадров (т.е. двигаться дальше каждый кадр, если у вас меньше кадров в секунду), чтобы ваш персонаж всегда двигался с постоянной скоростью, даже если вы получаете окунуться в частоту кадров. Более того, пусть ваша логика c и рендеринг работают асинхронно. Однако мы разберемся с некоторыми сложными вещами.
Редактировать:
Как указал @Kingsley, в Pygame встроена эта функциональность. Приведенный выше пример можно упростить следующим образом:
import pygame
from pygame.locals import *
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
# This line handles all the KEYUP and KEYDOWN events
# instead of doing it manually
keys_down = pygame.key.get_pressed()
if keys_down[K_DOWN]:
character.moveDown()
if keys_down[K_UP]:
character.moveUp()
if keys_down[K_LEFT]:
character.moveLeft()
if keys_down[K_RIGHT]:
character.moveRight()
screen.fill((0, 0, 0))
drawLevel1(screen)
character.draw(screen)
pygame.display.update()
clock.tick(30)