https://blubberquark.tumblr.com/post/630054903238262784/why-pygame-is-slow
Pygame to biblioteka, a nie silnik gry. Użytkownik ma swobodę projektowania pętli gry (game loop), rysowania na ekranie, korzystania z własnych algorytmów i struktur danych. Samemu należy np. wykrywać kolizje obiektów. Można przypadkowo zaimplementować coś mało wydajnie.
Generalnie nie należy za wcześnie zabierać się za optymalizację kodu. Najpierw należy się upewnić, co jest faktyczną przyczyną powolnej pracy. Czasem problem tkwi w niewłaściwych strukturach danych, niewłaściwych algorytmach użytych w grze.
Jeżeli kod działa stabilnie dla 60 FPS, to nie ma sensu zajmować się optymalizacją.
Można przyspieszyć odświeżanie pikseli na ekranie. Zamiast użyć pygame.display.flip(), które przerysowuje cały ekran, można przekazać do odświeżenia tylko te prostokąty ekranu, w których piksele rzeczywiście się zmieniły. Używa się pygame.display.update(dirty_rects) z listą obiektów Rect.
Jednym z powodów spowolnienia gry może być ładowanie plików w każdym obiegu pętli while.
Czasem może się pojawić potrzeba stworzenia na ekranie obiektu działającego jak przycisk, którego naciśnięcie myszą powoduje wykonanie pewnej akcji. Podany przykład pokazuje, jak można zbudować przyciski na bazie klasy Sprite. Przyciski będą zmieniać tło ekranu.
import sys
import pygame
# COLORS
black = (0, 0, 0)
gray = (128, 128, 128)
white = (255, 255, 255)
red = (255, 0, 0)
green = (0, 255, 0)
blue = (0, 0, 255)
yellow = (255, 255, 0)
# Object class
class Button(pygame.sprite.Sprite):
def __init__(self, text, font_size):
#pygame.sprite.Sprite.__init__(self)
super().__init__()
font = pygame.font.Font(None, font_size) # load the pygame default font
text_surf = font.render(text, True, black) # czarne fonty
text_rect = text_surf.get_rect()
self.image = pygame.Surface(text_rect.size)
self.image.fill(white) # białe tło przycisku
self.image.blit(text_surf, text_rect)
self.rect = self.image.get_rect() # lub text_rect
# INITIALIZE THE GAME
pygame.init() # to zawsze na starcie
size = (width, height) = (500, 500)
screen = pygame.display.set_mode(size) # display Surface
pygame.display.set_caption('Buttons')
# CLOCK
FPS = 60 # frames per second setting
clock = pygame.time.Clock()
red_button = Button("Red", 50)
red_button.rect.center = (width // 4, height // 4)
blue_button = Button("Blue", 50)
blue_button.rect.center = (3*width // 4, height // 4)
green_button = Button("Green", 50)
green_button.rect.center = (width // 4, 3*height // 4)
yellow_button = Button("Yellow", 50)
yellow_button.rect.center = (3*width // 4, 3*height // 4)
buttons = pygame.sprite.Group()
buttons.add(red_button, blue_button, green_button, yellow_button)
screen_bg = black # początkowy kolor ekranu
# MAIN GAME LOOP
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT: # QUIT Event, pygame.locals.QUIT
pygame.quit() # deactivates the Pygame library
sys.exit(0)
elif event.type == pygame.MOUSEBUTTONDOWN:
if red_button.rect.collidepoint(event.pos):
screen_bg = red
print("red button pressed ...")
if blue_button.rect.collidepoint(event.pos):
screen_bg = blue
print("blue button pressed ...")
if green_button.rect.collidepoint(event.pos):
screen_bg = green
print("green button pressed ...")
if yellow_button.rect.collidepoint(event.pos):
screen_bg = yellow
print("yellow button pressed ...")
# DRAWING
screen.fill(screen_bg) # na nowo malujemy ekran
buttons.draw(screen) # rysujemy przyciski
pygame.display.flip()
clock.tick(FPS)