Pygame导致低FPS。如何改善性能?

时间:2018-02-02 01:37:28

标签: python python-3.x pygame

我正在使用带有pygame的一些射弹,并发现即使只有200行代码,游戏的运行速度也低于50 fps。 (除了正在运行的循环之外,没有一个很大的循环,而我的PC还是新的)

那么,这是因为pygame使用SDL吗?

如果是这样,使用像OpenGL这样的GPU会改善性能吗?

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 个答案:

答案 0 :(得分:5)

Images / pygame.Surfaces通常应使用pygame.Surface类的convertconvert_alpha方法进行转换。这将显着改善性能。

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的其他一些游戏框架。