Pygame cause for low FPS. How can the performance

2020-02-14 05:57发布

I was working with some projectiles with pygame and found out that even with just 200 lines of code, the game ran with under 50 fps. (There isn't a big loop, except the running loop, and my PC is fairly new)

So, is this because pygame uses SDL?

If so, would using GPU like OpenGL improve the 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)

1条回答
趁早两清
2楼-- · 2020-02-14 06:30

Images/pygame.Surfaces should usually be converted with the convert or convert_alpha methods of the pygame.Surface class. This will improve the performance dramatically.

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

Also, load your images only once when the program starts and reuse them in your program. Loading them from the hard disk with pygame.image.load again is slow and should be avoided.


If you need even more speed, you can use OpenGL in conjunction with pygame, but that means rewriting your rendering code and of course you would have to learn OpenGL first.

Alternatively, you could check out some of the other game frameworks for Python.

查看更多
登录 后发表回答