PyGame многопоточность display.update не гладкая

Я делаю игру на python и pygame, и, поскольку моя игра включает в себя очень много спрайтов, я решил использовать отдельный поток для каждого вражеского \ персонажа, который запускает метод _mainloop. Я только начал с этого, и у меня возникла проблема. Я делаю базовый класс, который рисует крупье и пока может перемещаться по координатам X. он работает почти идеально, но проблема в том, что я думаю, что, поскольку крупье рисуется в методе класса _mainloop, и отображение обновляется в основном цикле обработки событий, из-за чего крупье иногда выглядит намного толще, что является немного странно. Я не хочу обновлять дисплей в _mainloop, потому что на экране будет около FPS * врагов + игроков, что может работать примерно до 500 pygame.display.updates в секунду, что немного перебор. Если кто-нибудь знает лучший способ сделать это, вы можете мне сказать? пожалуйста?
Я прочитал это:
Многопоточность Pygame
Многопоточность с Pygame
это не имеет отношения к моему вопросу. Я действительно ничего не мог найти на нем. Вот мой код:

from random import randint
import threading

from pygame.locals import *
import pygame as pg

FPS = 60
CLOCK = pg.time.Clock()
COLOURS = {
    'beige': (232, 202, 145),
    'green': (0, 128, 0),
    'blue': (0, 0, 128),
    'red': (128, 0, 0),
    'dark red': (255, 0, 0),
    'dark blue': (0, 0, 255),
    'dark green': (0, 255, 0),
    'black': (0, 0, 0),
    'aqua': (0, 255, 255),
    'white': (255, 255, 255),
    'teal': (0, 128, 128),
    'purple': (128, 128, 0),
    'dark purple': (255, 255, 0),
    'yellow': (255, 255, 0),
    'silver': (192, 192, 192),
    'gold': (192, 192, 96),
    'gray': (211, 211, 211),
}

class CharacterImage:
    """
    this is a sprite that at this point, should really
    just be able to move around.
    """

    # lots of methods and properties and stuff
    ...

    def build_image(self, surface):
        """
        constructs and draws the stickman to the 
        screen.
        """
        # really big function
        ...

    def move_to(self, pos: 'x', surface, pixels=1):
        """
        moves the character image by pixels
        towards the destination.
        INCOMPLETE: only X coordinates are supported
        """

        current = self.topleft[0]
        direction = 'b' if pos < current else 'f'
        current_pos = current - pixels if direction == 'b' else current + pixels
        self.update_coords((current_pos, self.topleft[1]))
        self.build_image(surface)
        return current_pos

    def start_thread(self, pos, surface, pixels=1):
        a = threading.Thread(target=lambda: self._mainloop(pos, surface, pixels), daemon=True)
        self.mainthread = a
        a.start()

    def _mainloop(self, pos, surface, pixels, *args, **kwargs):
        new_pos = pos
        while self.topleft != new_pos:
            new_pos = self.move_to(pos, surface, pixels, *args, **kwargs)
            CLOCK.tick(FPS)


class WeaponDummy:
    ... # random code


def main():
    a = pg.display.set_mode((800, 400))
    testsurf = pg.surface.Surface((2, 2))
    testsurf.fill(COLOURS['green'])
    s = CharacterImage('test', WeaponDummy(testsurf), (10, 300))
    d = CharacterImage('test', WeaponDummy(testsurf), (10, 320))
    s.build_image(a)
    d.build_image(a)
    d.start_thread(880, a)
    s.start_thread(880, a)

    while True:

        for i in pg.event.get():
            if i.type == QUIT:
                pg.quit()
                raise Exception

        pg.display.update()
        a.fill(COLOURS['black'])

        print('updated')
        CLOCK.tick(FPS)

if __name__ == '__main__':
    main()

если вам нужен полный код, который можно запустить, вы можете получить его здесь

любая помощь будет оценена по достоинству. большое спасибо!

Я запустил ваш код и не заметил никаких визуальных ошибок. Я заметил, что фигура полностью исчезла с экрана, прежде чем консоль зарегистрировала «обновлено» один раз. pg.display.update() и CLOCK.tick(FPS) также не стреляют, пока не отойдут. Это имеет смысл для вас, исходя из того, как написан ваш код, не так ли? Это желательно?

Ben Quigley 17.04.2018 05:57

Очень странно, что консоль вошла в updated только после того, как персонаж ушел. со мной это не так. То, что персонаж ушел за экран, - это всего лишь небольшая проблема с областью вокруг pos = new_pos. я могу это исправить. Что касается визуальных ошибок, просто они кажутся немного мерцающими, и я нахожу это раздражающим, но если вы думаете, что это даже не заметно, то, вероятно, это нормально. Благодарность!

Michael 17.04.2018 19:00
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
193
0

Другие вопросы по теме