Я скучаю по Python и Pygame, и мое первое, что я делаю, это простая игра Snake. Я пытаюсь сделать так, чтобы змея двигалась каждые 0,25 секунды. Вот часть моего кода, которая меняет:
while True:
check_for_quit()
clear_screen()
draw_snake()
draw_food()
check_for_direction_change()
move_snake() #How do I make it so that this loop runs at normal speed, but move_snake() only executes once every 0.25 seconds?
pygame.display.update()
Я хочу, чтобы все остальные функции выполнялись нормально, а move_snake() - только каждые 0,25 секунды. Я просмотрел его и нашел несколько ответов, но все они кажутся слишком сложными для тех, кто делает свой первый Python script.
Можно ли действительно получить пример того, как должен выглядеть мой код, а не просто сказать мне, какую функцию мне нужно использовать? Спасибо!
Существует несколько подходов, например, отслеживание системного времени или использование Clock
и подсчета тиков.
Но самый простой способ - использовать очередь событий и создать событие каждые x ms, используя pygame.time.set_timer()
:
pygame.time.set_timer()
многократно создает событие в очереди событий
set_timer(eventid, milliseconds) -> None
Задайте тип события, который будет отображаться в очереди событий, каждому заданному числу миллисекунд. Первое событие не появится до тех пор, пока не пройдет время.
Каждый тип события может иметь отдельный таймер, прикрепленный к нему. Лучше всего использовать значение между pygame.USEREVENT и pygame.NUMEVENTS.
Чтобы отключить таймер для события, установите для параметра миллисекунды значение 0.
Вот небольшой пример, где змея перемещается каждые 250 мс:
import pygame
pygame.init()
screen = pygame.display.set_mode((300, 300))
player, dir, size = pygame.Rect(100,100,20,20), (0, 0), 20
MOVEEVENT, t, trail = pygame.USEREVENT+1, 250, []
pygame.time.set_timer(MOVEEVENT, t)
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_w]: dir = 0, -1
if keys[pygame.K_a]: dir = -1, 0
if keys[pygame.K_s]: dir = 0, 1
if keys[pygame.K_d]: dir = 1, 0
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
if e.type == MOVEEVENT: # is called every 't' milliseconds
trail.append(player.inflate((-10, -10)))
trail = trail[-5:]
player.move_ip(*[v*size for v in dir])
screen.fill((0,120,0))
for t in trail:
pygame.draw.rect(screen, (255,0,0), t)
pygame.draw.rect(screen, (255,0,0), player)
pygame.display.flip()
Используйте Модуль часов Pygame, чтобы отслеживать время. В частности, метод tick
класса Clock
сообщит вам количество миллисекунд с момента последнего вызова tick
. Поэтому вы можете вызвать tick
один раз в начале (или в конце) каждой итерации в игровом цикле и сохранить его возвращаемое значение в переменной с именем dt
. Затем используйте dt
для обновления ваших переменных состояния игры, зависящих от времени.
time_elapsed_since_last_action = 0
clock = pygame.time.Clock()
while True: # game loop
# the following method returns the time since its last call in milliseconds
# it is good practice to store it in a variable called 'dt'
dt = clock.tick()
time_elapsed_since_last_action += dt
# dt is measured in milliseconds, therefore 250 ms = 0.25 seconds
if time_elapsed_since_last_action > 250:
snake.action() # move the snake here
time_elapsed_since_last_action = 0 # reset it to 0 so you can count again