Pygame cause low FPS. How to improve performance?

I worked with some shells with pygame and found out that even with 200 lines of code, the game ran at a speed of less than 50 frames per second. (There is no big loop, except for the loop cycle, and my computer is quite new)

So is this because pygame uses SDL?

If so, does a GPU like OpenGL use performance?

Main.py

#Eemport
import pygame as pyg,sys,background, player, wall
from pygame.locals import *

#Screen
screen_size_width = 1280
screen_size_height = 720
screen_size = (screen_size_width,screen_size_height)

#Initialization
pyg.init()
screen = pyg.display.set_mode(screen_size)
pyg.display.set_caption("Collision and better physics")

#Set clock
Clock = pyg.time.Clock()

#Set Background
Background = background.background("beach.jpg",screen_size)

#Set Player
player_size_width = 128
player_size_height = 128
player_location_x = 640
player_location_y = 360

player_size = (player_size_width,player_size_height)
player_location = (player_location_x,player_location_y)

player_speed = 5

Player = player.player("crab.png",player_size,player_location)

#Set input
keys = {'right': False, 'left': False, 'up': False, 'down': False}
nextlocation = [0,0]

#make wall
walls = []
walls.append(wall.wall((600,100),(340,600)))

#Running loop
running = True
while running:

    #Read input
    for event in pyg.event.get():
        if event.type == QUIT:
            pyg.quit()
            sys.exit()

        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                pyg.quit()
                sys.exit()
            if event.key == K_UP:
                keys['up'] = True
            if event.key == K_DOWN:
                keys['down'] = True
            if event.key == K_LEFT:
                keys['left'] = True
            if event.key == K_RIGHT:
                keys['right'] = True
        if event.type == KEYUP:
            if event.key == K_UP:
                keys['up'] = False
            if event.key == K_DOWN:
                keys['down'] = False
            if event.key == K_LEFT:
                keys['left'] = False
            if event.key == K_RIGHT:
                keys['right'] = False

    #Update values
    #1. Player Value
    if keys['right']:
        Player.move(player_speed,0,walls)
    if keys['left']:
        Player.move(-player_speed,0,walls)
    if keys['up']:
        Player.move(0,player_speed,walls)
    if keys['down']:
        Player.move(0,-player_speed,walls)




    #Draw on screen Be aware of priority!!!
    Background.draw_image(screen)
    for wall in walls:
        pyg.draw.rect(screen, (255,255,255),wall.rect)
    Player.draw_image(screen)
    Clock.tick()
    print(Clock.get_fps(),Player.rect.x,Player.rect.y)

    #Update display
    pyg.display.update()

Wall.py

import pygame as pyg
from pygame.locals import *

class wall(object):
    """
    This class represents walls
    No action
    """
    def __init__(self,size,location):
        self.width = size[0]
        self.height = size[1]
        self.locationx = location[0]
        self.locationy = location[1]

        self.rect = pyg.Rect(self.locationx,self.locationy,self.width,self.height)

background.py

import pygame as pyg
from pygame.locals import *

class background(object):
    """
    This class represents the background
    action - draw
    """

    def __init__(self,image_file,screen_size):
        self.screen_size = screen_size
        self.image = pyg.image.load(image_file)
        self.image = pyg.transform.scale(self.image,self.screen_size)
        self.rect = pyg.Rect((0,0),self.screen_size)

    def draw_image(self,screen):
        screen.blit(self.image,self.rect)

    def load_new_image(self,image_file):
        self.image = pyg.image.load(image_file)

player.py

import pygame as pyg
from pygame.locals import *

class player(object):
    """
    This class represents the player
    contains actions for the player

    """
    def __init__(self,image_file,image_size,location):
        #image
        self.image = pyg.image.load(image_file)
        self.image = pyg.transform.scale(self.image,image_size)
        self.image_size = image_size
        #Rect
        self.rect = pyg.Rect(location,image_size)

    def move(self, dx, dy,walls):
        self.rect.x += dx
        collide_wall = self.rect.collidelist(walls)
        if collide_wall != -1:
            if dx > 0:
                self.rect.right = walls[collide_wall].rect.left
            else:
                self.rect.left = walls[collide_wall].rect.right
        self.rect.y -= dy
        collide_wall = self.rect.collidelist(walls)
        if collide_wall != -1:
            if dy > 0:
                self.rect.bottom = walls[collide_wall].rect.top
            else:
                self.rect.top = walls[collide_wall].rect.bottom

    def draw_image(self,screen):     #Draw image on screen
        screen.blit(self.image,self.rect)

    def load_new_image(self,image_file):      #loads new image
        self.image = pyg.image.load(image_file)
        self.image = pyg.transform.scale(self.image, self.image_size)

    def current_location(self):
        return (self.rect.x , self.rect.y)
+4
source share
1 answer

Images / pygame.Surfaces should usually be converted using the convertor convert_alphaclass pygame.Surface. This will greatly improve performance.

IMAGE = pygame.image.load('an_image.png').convert()
IMAGE2 = pygame.image.load('an_image_with_transparency.png').convert_alpha()

, , . pygame.image.load .


, OpenGL pygame, , , , OpenGL.

, Python.

+5

Source: https://habr.com/ru/post/1693048/


All Articles