Я тестирую группу спрайтов 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()