Улучшить производительность при выполнении Pygame? - PullRequest
0 голосов
/ 04 января 2019

Моя пигмейка работает слишком медленно.Без использования класса oop он работал отлично, но теперь с использованием oop он очень медленный.

Я протестировал помещение этого отдельного файла класса в основной файл, но результат был таким же.

import pygame
from snake import Snake

pygame.init()
surf_width = 800
surf_height = 600
clock = pygame.time.Clock()

dis_surf = pygame.display.set_mode((surf_width, surf_height))
pygame.display.set_caption("snake game")
run = True
def game_loop():
    x = 255
    y = 255
    x_change = 0
    y_change = 0
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        dis_surf.fill((255, 255, 255))
        game = Snake(dis_surf, x, y, x_change, y_change)
        x = game.x
        y = game.y

другойfile: import pygame

class Snake():
    def __init__(self, dis_surf, x, y, x_change, y_change):
        self.dis_surf = dis_surf
        self.x = x
        self.y = y
        self.width = 20
        self.height = 20
        self.x_change = x_change
        self.y_change = y_change
        self.vel = 5
        self.draw()

    def draw(self):
        pygame.draw.rect(self.dis_surf, (0, 255, 0), (self.x, self.y, self.width, self.height))
        self.run()
        pygame.display.update()

    def run(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.x_change = self.vel
                    self.y_change = 0
                elif event.key == pygame.K_LEFT:
                    self.x_change = -self.vel
                    self.y_change = 0
                elif event.key == pygame.K_UP:
                    self.y_change = -self.vel
                    self.x_change = 0
                elif event.key == pygame.K_DOWN:
                    self.y_change = self.vel
                    self.x_change = 0
            print(event)
        self.x += self.x_change
        self.y += self.y_change


        x_change = game.x_change
        y_change = game.y_change
        pygame.display.update()
        clock.tick(60)

game_loop()

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Если вы хотите использовать ООП в Pygame, используйте класс Sprite в Pygame.Это сделано именно для этой цели.

Ваш код должен выглядеть следующим образом (я пытался изменить не слишком много):

import pygame

pygame.init()
surf_width = 800
surf_height = 600
clock = pygame.time.Clock()

screen = pygame.display.set_mode((surf_width, surf_height))
pygame.display.set_caption("snake game")


class Snake(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((20, 20))
        self.image.fill(pygame.Color('orange'))
        self.rect = self.image.get_rect(topleft=pos)
        self.x_change = 0
        self.y_change = 0
        self.vel = 5

    def update(self, events):
        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.x_change = self.vel
                    self.y_change = 0
                elif event.key == pygame.K_LEFT:
                    self.x_change = -self.vel
                    self.y_change = 0
                elif event.key == pygame.K_UP:
                    self.y_change = -self.vel
                    self.x_change = 0
                elif event.key == pygame.K_DOWN:
                    self.y_change = self.vel
                    self.x_change = 0

        self.rect.move_ip(self.x_change, self.y_change)

def main():
    snake = Snake((0, 0))
    snakes = pygame.sprite.Group(snake)
    while True:
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                return

        snakes.update(events)
        screen.fill((30, 30, 30))
        snakes.draw(screen)
        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()        

Убедитесь, что только pygame.display.flip() и pygame.event.get() вызовите только один разкаждый кадр.

Если вы хотите обрабатывать события в других частях вашего кода, просто сохраните события текущего фрейма в переменной и передайте их.Использование Group делает это простым.

Посмотрите, как мы четко отделили логику игры:

Основной цикл выполняет только три действия, которые он должен делать,Обработка событий, обновление состояния игры и рисование на экране.Он делает это, не «зная, что на самом деле происходит» в игре.

Спрайт Snake реагирует только тогда, когда об этом говорит главный цикл (когда вызывается его метод update), и ему все равнооткуда происходят события и как и где они отображаются.

0 голосов
/ 04 января 2019

Несколько вещей не так.

1) Вы создаете новый Snake класс каждой игровой петли , когда вы делаете game = Snake() внутрипока цикл.В сочетании с номером 2 это ваша главная проблема.Я переместил эту строку за пределы цикла while для вас.

2) Вы звоните run() внутри __init__.Это то, что вы никогда не должны делать в конструкторе. Обычно конструкторы следует использовать только для задания начальных данных.Это также внесло значительный вклад в проблему номер 1, потому что это происходило на каждом игровом цикле.Я убрал звонок self.run() внутри __init__ для тебя.

3) pygame.display.update() вызывали дважды.Не причина вашей проблемы, но все же ненужная.

Сделано несколько небольших исправлений для вас.

import pygame

pygame.init()
surf_width = 800
surf_height = 600
clock = pygame.time.Clock()

dis_surf = pygame.display.set_mode((surf_width, surf_height))
pygame.display.set_caption("snake game")
run = True

def game_loop():
    x = 255
    y = 255
    x_change = 0
    y_change = 0
    game = Snake(dis_surf, x, y, x_change, y_change)
    while run:
        dis_surf.fill((255, 255, 255))
        game.draw()

class Snake():
    def __init__(self, dis_surf, x, y, x_change, y_change):
        self.dis_surf = dis_surf
        self.x = x
        self.y = y
        self.width = 20
        self.height = 20
        self.x_change = x_change
        self.y_change = y_change
        self.vel = 5

    def draw(self):
        pygame.draw.rect(self.dis_surf, (0, 255, 0), (self.x, self.y, self.width, self.height))
        self.run()

    def run(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.x_change = self.vel
                    self.y_change = 0
                elif event.key == pygame.K_LEFT:
                    self.x_change = -self.vel
                    self.y_change = 0
                elif event.key == pygame.K_UP:
                    self.y_change = -self.vel
                    self.x_change = 0
                elif event.key == pygame.K_DOWN:
                    self.y_change = self.vel
                    self.x_change = 0
        self.x += self.x_change
        self.y += self.y_change
        pygame.display.update()
        clock.tick(60)

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