Как реализовать игровой цикл Pygame? - PullRequest
0 голосов
/ 04 марта 2019

Я хочу написать лучший игровой цикл на Python, используя pygame.time.Clock(), и я понимаю концепцию сохранения времени и отсоединения рендеринга от основного игрового цикла, чтобы лучше использовать тики.Я также понимаю про временную задержку рендеринга, чтобы он отображал правильное количество движения, но единственные примеры, которые я нашел, написаны на C #, и хотя я сначала подумал, что довольно просто преобразовать в Python, он не ведет себя.

Я понял, что Clock() Pygame уже отрабатывает миллисекунды между двумя последними вызовами .tick, и я попытался адаптировать найденный мной пример кода, но мне действительно нужно увидеть работающийПример написан на Python.Вот что я придумала до сих пор:

FPS = 60
MS_PER_UPDATE = 1000 / FPS
lag = 0.0
clock = pygame.time.Clock()
running = True

# Do an initial tick so the loop has 2 previous ticks.
clock.tick(FPS)

while running:
    clock.tick(FPS)
    lag += clock.get_time()
    user_input()

    while lag >= MS_PER_UPDATE:
        update()
        lag -= MS_PER_UPDATE

    render(lag / MS_PER_UPDATE)

Я не уверен, стоит ли все это в Pygame, или он уже позаботился в некоторых из своих time функций.?Моя игра работает на ноутбуке медленнее (ожидаемо), но я подумал, что это может выровнять FPS между моим основным ПК и ноутбуком, отключив рендеринг.У кого-нибудь есть опыт выполнения этих продвинутых игровых циклов в Pygame?Я просто хочу, чтобы все было как можно лучше ...

1 Ответ

0 голосов
/ 04 марта 2019

Просто возьмите время, необходимое для рендеринга последнего кадра (называемого дельта-временем) и передайте его игровым объектам, чтобы они могли решить, что делать (например, двигаться больше или меньше).

Вот суперпростой пример:

import pygame

class Actor(pygame.sprite.Sprite):
    def __init__(self, *args):
        super().__init__(*args)
        self.image = pygame.Surface((32, 32))
        self.rect = pygame.display.get_surface().get_rect()
        self.image.fill(pygame.Color('dodgerblue'))

    def update(self, events, dt):
        self.rect.move_ip((1 * dt / 5, 2 * dt / 5))
        if self.rect.x > 500: self.rect.x = 0
        if self.rect.y > 500: self.rect.y = 0

def main():
    pygame.init()
    screen = pygame.display.set_mode((500, 500))
    sprites = pygame.sprite.Group()
    Actor(sprites)
    clock = pygame.time.Clock()
    dt = 0
    while True:

        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        sprites.update(events, dt)

        screen.fill((30, 30, 30))
        sprites.draw(screen)
        pygame.display.update()

        dt = clock.tick(60)

if __name__ == '__main__':
    main()

Если ваша игра замедляется ниже 60 (или любого другого) FPS, dt становится больше, а Actor перемещается больше, чтобы наверстать упущенное время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...