Python 当我运行我的脚本时,我在Pygame中获得了大约1fps。我的代码中是什么导致了这种情况?

Python 当我运行我的脚本时,我在Pygame中获得了大约1fps。我的代码中是什么导致了这种情况?,python,pygame,Python,Pygame,我的电脑并不古老,所以没有足够的处理能力不是原因。我认为这意味着这一定是由于我的代码中的某些东西需要很长时间才能执行造成的。我仔细研究了我的代码,但我不知道可能是什么原因导致了这种情况。如果有人能向我指出原因,我将不胜感激。我的代码分为4个模块: 地下城_craw.py import pygame, sys import game_function as gf from tilemap import Tilemap from player import Player def run_game

我的电脑并不古老,所以没有足够的处理能力不是原因。我认为这意味着这一定是由于我的代码中的某些东西需要很长时间才能执行造成的。我仔细研究了我的代码,但我不知道可能是什么原因导致了这种情况。如果有人能向我指出原因,我将不胜感激。我的代码分为4个模块:

地下城_craw.py

import pygame, sys

import game_function as gf
from tilemap import Tilemap
from player import Player

def run_game():
    # Start the game and create a screen object.
    pygame.init()
    screen_info = pygame.display.Info()
    screen = pygame.display.set_mode((screen_info.current_w, screen_info.current_h))
    pygame.display.set_caption('Dungeon Crawl')
    clock = pygame.time.Clock()

    # Create objects for classes.
    tilemap = Tilemap(screen)
    player = Player(screen)

    # Set the background color.
    bg_color = (255,255,255)

    # Game loop
    while True:
        gf.check_events(player)
        player.update()
        gf.update_screen(bg_color, screen, player)
        clock.tick(30)

run_game()_
import pygame, sys

from tilemap import Tilemap

def check_events(player):
    """Respond to keypresses and mouse events."""
    # Quit if the player closes out of the window.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_d:
                # Move the player to the right.
                player.moving_right = True

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_d:
                player.moving_right = False

def update_screen(bg_color, screen, player):
    """Update images on the screen and flip to the new screen."""
    # Create objects for classes.
    tilemap = Tilemap(screen)

    # Redraw the screen during each pass through the loop.
    screen.fill(bg_color)
    tilemap.draw_self(screen, player.x, player.y)
    player.blitme()

    # Make the most recently drawn screen visible.
    pygame.display.flip()
import pygame

class Player():

    def __init__(self, screen):
        # Load the hero image and the screen and get their rects.
        self.image = pygame.transform.scale2x(pygame.image.load('hero.bmp'))
        self.screen = screen
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Set position on screen.
        self.rect.centerx = 330
        self.rect.centery = 330

        # Set initial coordinates on the tilemap.
        self.x = 1000
        self.y = 1000

        # Movement flag
        self.moving_right = False

    def update(self):
        """Update the player's position based on the movement flags."""
        if self.moving_right:
            self.rect.centerx += 1

    def blitme(self):
        """Draw the player."""
        self.screen.blit(self.image, self.rect)
import pygame
from pygame import sprite

class Tilemap():

    def __init__(self, screen):
        # Set constants.
        BLACK = (0,0,0)
        LIGHTGREY = (200,200,200)
        DARKGREY = (100,100,100)

        NONE = 0
        FLOOR = 1
        WALL = 2

        # Link each structure to its color.
        self.colors =   {
                            NONE: BLACK,
                            FLOOR: LIGHTGREY,
                            WALL: DARKGREY
                        }

        # Decide which structures block movements.
        self.block_movement =   {
                                    NONE: 'n',
                                    FLOOR: 'n',
                                    WALL: 'y',
                                }

        # Create tilemap.
        tiles = []

        for x in range(0, 2000):
            tiles.append([])
            for y in range(0, 2000):
                tiles[x].append(NONE)

        for i in range(0, 10):
            tiles[1001][1000 + i] = WALL

        self.tiles = tiles

        # Set size of tiles and map height/width in tiles.
        self.TILESIZE = 60
        self.MAPHEIGHT = 11
        self.MAPWIDTH = 11

    def draw_self(self, screen, playerx, playery):
        """Draw the map."""
        for row in range(self.MAPHEIGHT):
            for column in range(self.MAPWIDTH):
                pygame.draw.rect(screen, self.colors[self.tiles[playerx + column][playery + row]], (column * self.TILESIZE, row * self.TILESIZE, self.TILESIZE, self.TILESIZE))
游戏功能.py

import pygame, sys

import game_function as gf
from tilemap import Tilemap
from player import Player

def run_game():
    # Start the game and create a screen object.
    pygame.init()
    screen_info = pygame.display.Info()
    screen = pygame.display.set_mode((screen_info.current_w, screen_info.current_h))
    pygame.display.set_caption('Dungeon Crawl')
    clock = pygame.time.Clock()

    # Create objects for classes.
    tilemap = Tilemap(screen)
    player = Player(screen)

    # Set the background color.
    bg_color = (255,255,255)

    # Game loop
    while True:
        gf.check_events(player)
        player.update()
        gf.update_screen(bg_color, screen, player)
        clock.tick(30)

run_game()_
import pygame, sys

from tilemap import Tilemap

def check_events(player):
    """Respond to keypresses and mouse events."""
    # Quit if the player closes out of the window.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_d:
                # Move the player to the right.
                player.moving_right = True

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_d:
                player.moving_right = False

def update_screen(bg_color, screen, player):
    """Update images on the screen and flip to the new screen."""
    # Create objects for classes.
    tilemap = Tilemap(screen)

    # Redraw the screen during each pass through the loop.
    screen.fill(bg_color)
    tilemap.draw_self(screen, player.x, player.y)
    player.blitme()

    # Make the most recently drawn screen visible.
    pygame.display.flip()
import pygame

class Player():

    def __init__(self, screen):
        # Load the hero image and the screen and get their rects.
        self.image = pygame.transform.scale2x(pygame.image.load('hero.bmp'))
        self.screen = screen
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Set position on screen.
        self.rect.centerx = 330
        self.rect.centery = 330

        # Set initial coordinates on the tilemap.
        self.x = 1000
        self.y = 1000

        # Movement flag
        self.moving_right = False

    def update(self):
        """Update the player's position based on the movement flags."""
        if self.moving_right:
            self.rect.centerx += 1

    def blitme(self):
        """Draw the player."""
        self.screen.blit(self.image, self.rect)
import pygame
from pygame import sprite

class Tilemap():

    def __init__(self, screen):
        # Set constants.
        BLACK = (0,0,0)
        LIGHTGREY = (200,200,200)
        DARKGREY = (100,100,100)

        NONE = 0
        FLOOR = 1
        WALL = 2

        # Link each structure to its color.
        self.colors =   {
                            NONE: BLACK,
                            FLOOR: LIGHTGREY,
                            WALL: DARKGREY
                        }

        # Decide which structures block movements.
        self.block_movement =   {
                                    NONE: 'n',
                                    FLOOR: 'n',
                                    WALL: 'y',
                                }

        # Create tilemap.
        tiles = []

        for x in range(0, 2000):
            tiles.append([])
            for y in range(0, 2000):
                tiles[x].append(NONE)

        for i in range(0, 10):
            tiles[1001][1000 + i] = WALL

        self.tiles = tiles

        # Set size of tiles and map height/width in tiles.
        self.TILESIZE = 60
        self.MAPHEIGHT = 11
        self.MAPWIDTH = 11

    def draw_self(self, screen, playerx, playery):
        """Draw the map."""
        for row in range(self.MAPHEIGHT):
            for column in range(self.MAPWIDTH):
                pygame.draw.rect(screen, self.colors[self.tiles[playerx + column][playery + row]], (column * self.TILESIZE, row * self.TILESIZE, self.TILESIZE, self.TILESIZE))
player.py

import pygame, sys

import game_function as gf
from tilemap import Tilemap
from player import Player

def run_game():
    # Start the game and create a screen object.
    pygame.init()
    screen_info = pygame.display.Info()
    screen = pygame.display.set_mode((screen_info.current_w, screen_info.current_h))
    pygame.display.set_caption('Dungeon Crawl')
    clock = pygame.time.Clock()

    # Create objects for classes.
    tilemap = Tilemap(screen)
    player = Player(screen)

    # Set the background color.
    bg_color = (255,255,255)

    # Game loop
    while True:
        gf.check_events(player)
        player.update()
        gf.update_screen(bg_color, screen, player)
        clock.tick(30)

run_game()_
import pygame, sys

from tilemap import Tilemap

def check_events(player):
    """Respond to keypresses and mouse events."""
    # Quit if the player closes out of the window.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_d:
                # Move the player to the right.
                player.moving_right = True

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_d:
                player.moving_right = False

def update_screen(bg_color, screen, player):
    """Update images on the screen and flip to the new screen."""
    # Create objects for classes.
    tilemap = Tilemap(screen)

    # Redraw the screen during each pass through the loop.
    screen.fill(bg_color)
    tilemap.draw_self(screen, player.x, player.y)
    player.blitme()

    # Make the most recently drawn screen visible.
    pygame.display.flip()
import pygame

class Player():

    def __init__(self, screen):
        # Load the hero image and the screen and get their rects.
        self.image = pygame.transform.scale2x(pygame.image.load('hero.bmp'))
        self.screen = screen
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Set position on screen.
        self.rect.centerx = 330
        self.rect.centery = 330

        # Set initial coordinates on the tilemap.
        self.x = 1000
        self.y = 1000

        # Movement flag
        self.moving_right = False

    def update(self):
        """Update the player's position based on the movement flags."""
        if self.moving_right:
            self.rect.centerx += 1

    def blitme(self):
        """Draw the player."""
        self.screen.blit(self.image, self.rect)
import pygame
from pygame import sprite

class Tilemap():

    def __init__(self, screen):
        # Set constants.
        BLACK = (0,0,0)
        LIGHTGREY = (200,200,200)
        DARKGREY = (100,100,100)

        NONE = 0
        FLOOR = 1
        WALL = 2

        # Link each structure to its color.
        self.colors =   {
                            NONE: BLACK,
                            FLOOR: LIGHTGREY,
                            WALL: DARKGREY
                        }

        # Decide which structures block movements.
        self.block_movement =   {
                                    NONE: 'n',
                                    FLOOR: 'n',
                                    WALL: 'y',
                                }

        # Create tilemap.
        tiles = []

        for x in range(0, 2000):
            tiles.append([])
            for y in range(0, 2000):
                tiles[x].append(NONE)

        for i in range(0, 10):
            tiles[1001][1000 + i] = WALL

        self.tiles = tiles

        # Set size of tiles and map height/width in tiles.
        self.TILESIZE = 60
        self.MAPHEIGHT = 11
        self.MAPWIDTH = 11

    def draw_self(self, screen, playerx, playery):
        """Draw the map."""
        for row in range(self.MAPHEIGHT):
            for column in range(self.MAPWIDTH):
                pygame.draw.rect(screen, self.colors[self.tiles[playerx + column][playery + row]], (column * self.TILESIZE, row * self.TILESIZE, self.TILESIZE, self.TILESIZE))
tilemap.py

import pygame, sys

import game_function as gf
from tilemap import Tilemap
from player import Player

def run_game():
    # Start the game and create a screen object.
    pygame.init()
    screen_info = pygame.display.Info()
    screen = pygame.display.set_mode((screen_info.current_w, screen_info.current_h))
    pygame.display.set_caption('Dungeon Crawl')
    clock = pygame.time.Clock()

    # Create objects for classes.
    tilemap = Tilemap(screen)
    player = Player(screen)

    # Set the background color.
    bg_color = (255,255,255)

    # Game loop
    while True:
        gf.check_events(player)
        player.update()
        gf.update_screen(bg_color, screen, player)
        clock.tick(30)

run_game()_
import pygame, sys

from tilemap import Tilemap

def check_events(player):
    """Respond to keypresses and mouse events."""
    # Quit if the player closes out of the window.
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_d:
                # Move the player to the right.
                player.moving_right = True

        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_d:
                player.moving_right = False

def update_screen(bg_color, screen, player):
    """Update images on the screen and flip to the new screen."""
    # Create objects for classes.
    tilemap = Tilemap(screen)

    # Redraw the screen during each pass through the loop.
    screen.fill(bg_color)
    tilemap.draw_self(screen, player.x, player.y)
    player.blitme()

    # Make the most recently drawn screen visible.
    pygame.display.flip()
import pygame

class Player():

    def __init__(self, screen):
        # Load the hero image and the screen and get their rects.
        self.image = pygame.transform.scale2x(pygame.image.load('hero.bmp'))
        self.screen = screen
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        # Set position on screen.
        self.rect.centerx = 330
        self.rect.centery = 330

        # Set initial coordinates on the tilemap.
        self.x = 1000
        self.y = 1000

        # Movement flag
        self.moving_right = False

    def update(self):
        """Update the player's position based on the movement flags."""
        if self.moving_right:
            self.rect.centerx += 1

    def blitme(self):
        """Draw the player."""
        self.screen.blit(self.image, self.rect)
import pygame
from pygame import sprite

class Tilemap():

    def __init__(self, screen):
        # Set constants.
        BLACK = (0,0,0)
        LIGHTGREY = (200,200,200)
        DARKGREY = (100,100,100)

        NONE = 0
        FLOOR = 1
        WALL = 2

        # Link each structure to its color.
        self.colors =   {
                            NONE: BLACK,
                            FLOOR: LIGHTGREY,
                            WALL: DARKGREY
                        }

        # Decide which structures block movements.
        self.block_movement =   {
                                    NONE: 'n',
                                    FLOOR: 'n',
                                    WALL: 'y',
                                }

        # Create tilemap.
        tiles = []

        for x in range(0, 2000):
            tiles.append([])
            for y in range(0, 2000):
                tiles[x].append(NONE)

        for i in range(0, 10):
            tiles[1001][1000 + i] = WALL

        self.tiles = tiles

        # Set size of tiles and map height/width in tiles.
        self.TILESIZE = 60
        self.MAPHEIGHT = 11
        self.MAPWIDTH = 11

    def draw_self(self, screen, playerx, playery):
        """Draw the map."""
        for row in range(self.MAPHEIGHT):
            for column in range(self.MAPWIDTH):
                pygame.draw.rect(screen, self.colors[self.tiles[playerx + column][playery + row]], (column * self.TILESIZE, row * self.TILESIZE, self.TILESIZE, self.TILESIZE))

每次更新屏幕时,都会创建一个新的
Tilemap
。在初始值设定项中,您有以下代码:

for x in range(0, 2000):
    tiles.append([])
    for y in range(0, 2000):
        tiles[x].append(NONE)
这意味着您不必要地重新创建了
Tilemap
,使用了一个嵌套的for循环,该循环迭代
2000*2000=4000000次(每帧!),只是为了创建一个二维列表。此列表不需要每帧创建一次;它只需要在游戏中的每个场景之前创建。我相信这是导致性能问题的原因


我猜您希望将dungeon\u crawl.py中的
tilemap
变量传递到函数
gf.update\u screen
,而不是在函数开始时重新创建它。

每次更新屏幕时,您都会创建一个新的
tilemap
。在初始值设定项中,您有以下代码:

for x in range(0, 2000):
    tiles.append([])
    for y in range(0, 2000):
        tiles[x].append(NONE)
这意味着您不必要地重新创建了
Tilemap
,使用了一个嵌套的for循环,该循环迭代
2000*2000=4000000次(每帧!),只是为了创建一个二维列表。此列表不需要每帧创建一次;它只需要在游戏中的每个场景之前创建。我相信这是导致性能问题的原因

我的猜测是,您希望将dungeon\u craw.py中的
tilemap
变量传递到函数
gf.update\u屏幕中,而不是在函数开始时重新创建它