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.width, text_rect.height)) 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)