Pygame отображает только часть спрайта для более высокой частоты кадров - PullRequest
0 голосов
/ 12 апреля 2019

Я тестирую группу спрайтов RenderUpdates, чтобы эффективно обновить экран (который позже будет использоваться для более сложной игры). Я проверяю это с простым случаем мяча, подпрыгивающего вокруг экрана. Но когда я использую его, на экране появляется только часть мяча. Передний край квадратный. Однако при приостановке анимации он показывает весь шар. Я сравнил это с очисткой всего экрана, а затем обновлением всего экрана. Это показывает весь шар правильно (см. Изображения ниже). Сначала я думал, что это проблема с RenderUpdates, но теперь я вижу, что это графическая проблема, связанная с частотой кадров, потому что, когда я уменьшаю частоту кадров, она показывает весь шар. Есть идеи о том, что происходит и как это исправить?

Прошу прощения за первое изображение. Я должен был сделать снимок с помощью своего телефона, потому что любое приложение для захвата экрана уменьшало бы частоту кадров, вызывая его появление в виде целого шара.

выше частота кадров

ниже частота кадров

Вот код для справки:

# import libraries
import pygame, sys
import numpy as np

# Define colors
BLACK = (0,0,0)
WHITE = (255,255,255)

# Screen parameters
SCALE = 2 # how much bigger the game will be compared to the original pong dim.
SCREEN_HEIGHT = 256*SCALE
SCREEN_WIDTH = 2*SCREEN_HEIGHT
FPS = 30*SCALE # how fast the screen updates (frames per second)

# Ball parameters
DIAMETER = 12*SCALE
BALL_VELOCITY = int(round(SCREEN_WIDTH/(2.5*FPS))) # crosses screen in 2.5 sec

# --- Ball class ---------------------------------------
class Ball(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self, self.containers)

        # create the physical surface of the ball
        self.image = pygame.Surface([DIAMETER,DIAMETER],pygame.SRCALPHA)
        pygame.draw.circle(self.image,WHITE, \
                (int(DIAMETER/2),int(DIAMETER/2)),int(DIAMETER/2))
        self.rect = self.image.get_rect()

        # velocity of ball
        self.velx = BALL_VELOCITY
        self.vely = BALL_VELOCITY

    # update is called every frame (moves the ball)
    def update(self):
        # Check if ball hits wall
        self.hit_wall()
        self.rect.x += self.velx
        self.rect.y += self.vely

    def hit_wall(self):
        # Check if ball hits left or right walls
        if self.rect.right + self.velx > SCREEN_WIDTH \
            or self.rect.left + self.velx < 0:
            self.velx = -self.velx # switches direction ball moves

        # Check if ball hits top or bottom walls
        if self.rect.bottom + self.vely > SCREEN_HEIGHT \
            or self.rect.top + self.vely < 0:
            self.vely = -self.vely # switches direction ball moves

# close the window and quits
def terminate():
    pygame.quit()
    sys.exit()

# --- Main Program -----------------------------------------------------
def main():
    # --- Setup --------------------------------------------
    pygame.init()

    # Set the width and heigth of the screen
    screen = pygame.display.set_mode([SCREEN_WIDTH,SCREEN_HEIGHT])

    # define background
    background = pygame.Surface([SCREEN_WIDTH,SCREEN_HEIGHT])
    background.fill(BLACK)

    # Write game title at the top of the screen
    pygame.display.set_caption("Pong")

    # Create group that contails all the sprites in the game
    all_sprites = pygame.sprite.RenderUpdates()

    # Containers for sprites
    Ball.containers = all_sprites

    # add the ball sprite using the Ball class above
    ball = Ball()

    # Create a clock to manage how fast the screen updates
    clock = pygame.time.Clock()

    # --- Main Program Loop ----------------------------------------------
    while True:
        # --- Event Processing
        for event in pygame.event.get():
            # user closed the screen (pressing x in top-right corner)
            if event.type == pygame.QUIT:
                terminate()

        # --- Update everything -------------------------------------------
        all_sprites.update()

        # --- Drawing code -----------------------------------------------
        # Clear screen
        all_sprites.clear(screen,background)

        # Draw all sprites
        dirty = all_sprites.draw(screen)

        # Draw the updates
        pygame.display.update(dirty)

        # Frames per second
        clock.tick(FPS)

# Begin Progam
if __name__ == '__main__':
    main()
else:
    terminate()
...