Пигмент мерцающий спрайт - PullRequest
1 голос
/ 02 апреля 2020

Пока все в игре работает нормально, кроме спрайтов, мерцающих при движении. У спрайта есть след его последнего местоположения позади него. У меня только один pygame.display.update () и нет pygame.display.flip () , я говорю, что из-за ответов, которые я получил, когда искал проблему, говоря, что может вызвать проблему. Я использую pygame.sprite.Group.draw () и pygame.sprite.Group.clear () из моего производного группового класса. Вот ссылка https://youtu.be/Ayzy5prix84 на демонстрацию. Спасибо за вашу помощь заранее.

import pygame
pygame.init()


class Game():
    def __init__(self, name = "", width=600, height=400):
        self.name = name
        self.width = width
        self.height = height
        self.window = pygame.display.set_mode((width, height))
        pygame.display.set_caption(self.name)
        self.scenarios = {}
        self.active_scenario = None
    def update(self):
        self.scenarios[self.active_scenario].update(self.window)
    def draw(self):
        if self.scenarios != None:
            self.scenarios[self.active_scenario].draw(self.window)
    def add_scene(self, name, obj):
        if self.active_scenario == None:
            self.active_scenario = name
        self.scenarios[name] = obj

class Scenario:
    def __init__(self, background, menus = None, sprite_groups = None):
        self.background = background
        self.menus = menus
        self.sprite_groups = sprite_groups
        self.boundaries = self._set_boundaries()
    def _set_boundaries(self):
        boundaries = {}
        rect = self.background.image.get_rect()
        left = rect.left
        right = rect.right

        left_bound = Boundary((left,0, 1, rect.h))
        right_bound = Boundary((rect.w - 1,0, 1, rect.h))
        top_bound = Boundary((left,0, rect.w, 1))
        bottom_bound = Boundary((left,rect.h - 1, rect.w, 1))

        boundaries["left bound"] = left_bound
        boundaries["right bound"] = right_bound
        boundaries["top bound"] = top_bound
        boundaries["bottom bound"] = bottom_bound


        return boundaries
    def check_collision(self):
        for group in self.sprite_groups:
            for sprite in group.sprites():
                if sprite.rect.left < self.boundaries["left bound"].right:
                    sprite.rect.x = self.boundaries["left bound"].right 
                if sprite.rect.top < self.boundaries["top bound"].bottom:
                    sprite.rect.y = self.boundaries["top bound"].bottom
                if sprite.rect.right > self.boundaries["right bound"].left:
                    sprite.rect.x = self.boundaries["right bound"].left - sprite.rect.w
                if sprite.rect.bottom > self.boundaries["bottom bound"].top:
                    sprite.rect.y = self.boundaries["bottom bound"].top - sprite.rect.h
    def update_char(self):
        global key_dict
        #just finds the character sprite will change later this is a test of mechanics
        sprites = self.sprite_groups[0].sprites()
        character = sprites[0]


        if key_dict["up"] and not key_dict["down"]:
            character.rect.y -= character.speed
        if key_dict["down"] and not key_dict["up"]:
            character.rect.y += character.speed
        if key_dict["left"] and not key_dict["right"]:
            character.rect.x  -= character.speed
        if key_dict["right"] and not key_dict["left"]:
            character.rect.x  += character.speed



    def update(self, screen):
        self.update_char()
        self.check_collision()
        self.draw(screen)
    #draws the scenario to a surface then blit surface to main window named
    #screen
    def draw(self, screen):
        size = screen.get_size()
        surface = pygame.Surface((size[0], size[1]))
        self.background.draw(surface)
        if self.sprite_groups != None:
            for group in self.sprite_groups:
                group.clear(surface, self.background.image)
                group.draw(surface)
        screen.blit(surface, (0,0))


class Group(pygame.sprite.Group):
    def __init__(self, *sprites):
        pygame.sprite.Group.__init__(self, sprites)

class Sprite(pygame.sprite.Sprite):
    def __init__(self, image, *groups):
        pygame.sprite.Sprite.__init__(self, groups)
        self.image = pygame.image.load(image)
        self.rect = self.image.get_rect()
        self.left = self.rect.left
        self.right = self.rect.right
        self.top = self.rect.top
        self.bottom = self.rect.bottom

class Background:
    def __init__(self, image=None):
        self.image = pygame.image.load(image)
    def draw(self, screen):
        screen.blit(self.image, (0,0))


class Wall(Sprite):
    def __init__(self, *args):
        Sprite.__init__(self, args)

class Boundary:
    def __init__(self, rect, active=True):
        self.rect = pygame.Rect(rect)
        self.left = self.rect.left
        self.right = self.rect.right
        self.top = self.rect.top
        self.bottom = self.rect.bottom
        self.active = active

key_dict = {"left":False, "right":False, "up":False, "down":False}

game = Game("Key Finder")

ball = Sprite("../Sprites/Ball/Static.png")
ball.speed = 5
char_g = Group(ball)

sky = Background("Sky.png")
scene = Scenario(sky, sprite_groups = [char_g])
game.add_scene("Level 1", scene)


FPS = 60
clock = pygame.time.Clock()
running = True

while running:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                key_dict["up"] = True
            elif event.key == pygame.K_DOWN:
                key_dict["down"] = True
            elif event.key == pygame.K_LEFT:
                key_dict["left"] = True
            elif event.key == pygame.K_RIGHT:
                key_dict["right"] = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                key_dict["up"] = False
            elif event.key == pygame.K_DOWN:
                key_dict["down"] = False
            elif event.key == pygame.K_LEFT:
                key_dict["left"] = False
            elif event.key == pygame.K_RIGHT:
                key_dict["right"] = False

    game.update()
    pygame.display.update()
    clock.tick(FPS)

pygame.quit()

1 Ответ

1 голос
/ 02 апреля 2020

Вы слишком усложнили перерисовку сцены, которая может вызвать мерцание:

class Scenario: 
   # [...]
   def draw(self, screen):
       size = screen.get_size()
       surface = pygame.Surface((size[0], size[1]))
       self.background.draw(surface)
       if self.sprite_groups != None:
           for group in self.sprite_groups:
               group.clear(surface, self.background.image)
               group.draw(surface)
       screen.blit(surface, (0,0))

Создание поверхности с размером игрового окна (surface = pygame.Surface((size[0], size[1]))), в каждый кадр - это талия времени. На самом деле вы создаете поверхность с размером окна, рисуете эту поверхность и копируете поверхность в окно. Это вызывает огромную потерю производительности. Нарисуйте на поверхности, которая связана с окном напрямую. Обратите внимание, что вы не увидите изменения поверхности окна напрямую. Изменения сбрасываются один раз, когда вызывается pygame.display.update() или pygame.display.flip().
Поскольку вся сцена рисуется в каждом кадре, group.clear(surface, self.background.image) также является излишним. Обратите внимание: задний фон покрывает все окно, затем объекты сцены рисуются поверх фона.

Упростите drawScenario), чтобы решить проблему.

class Scenario:
    # [...]

    def draw(self, screen):
        self.background.draw(screen)
        if self.sprite_groups != None:
            for group in self.sprite_groups:
                group.draw(screen)

Если background не покрывает все окно, тогда вы должны очистить окно до self.background.draw(screen), screen.fill(0)

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