Pygame程序滞后多个精灵(~170)

时间:2018-04-27 19:17:40

标签: python performance pygame

首先,我已事先在stackoverflow上研究了这个主题,但我想了解更多相关信息,以便我提出一个新问题。

所以基本上,我一直在Pygame 1.9.3工作,并且我成功地制作了一个带图形的简单2D游戏。我正在使用Sprite类,因此我经常使用Group()方法。我使用groupName.draw(屏幕)将我的图形绘制到屏幕上。

我的游戏的一个组成部分是与地形互动的能力,例如移除瓷砖和放置瓷砖。每个图块都是我的块Sprite Group的一部分,它被绘制到屏幕上。

然而,随着块图块数量的增加,我的程序开始明显滞后。以下我试图解决这个问题:

  • 对我所有已加载的图片使用.convert_alpha()
  • 仅加载图像
  • 更改目标FPS(使用60 atm)
  • 更改我的程序,以便在环境发生变化时仅调用blockGroup.draw()命令。基本上,如果环境发生变化,我会重新绘制块,截取我的窗口,然后将此图像blit直到环境再次发生变化(正如预期的那样,这会导致截屏时出现延迟)

然而,我的比赛仍然滞后。

当然,如果我增加块精灵的大小(意味着我在加载它们各自的图像时如何调整它们的大小),我最终可以放置更多的块而不会出现延迟,因为总共有更少的精灵,但这是不适合我想要完成的事情。

此外,我已经实施了2个与这个地形互动的NPC团队。因此,我的程序需要检查主游戏循环中的大量碰撞是可以理解的,但是,除非我加入一个约30个NPC的团队(我目前正在工作),否则我不希望我的程序滞后只有10名NPC,每队5名。)

当我的程序开始滞后时,我计算了精灵的总数(将每组中的所有精灵加起来)为170.

所以,最后,我的问题:如果我计划同时使用多个精灵(多个〜170)的程序,那么pygame根本不会因速度而被裁掉吗? / strong>

我相信我已经使用了很好的实现方法,比如删除它们各自组后的精灵以及上面的简要列表。

我已经请求提供一些代码,所以这里有一些重要的部分。

主游戏循环:

# Main Game Loop
while gameRunning:
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        gameRunning = False

    keys = pygame.key.get_pressed()
    if keys[LEFT_KEY]:
        player1.goLeft()

    if keys[RIGHT_KEY]:
        player1.goRight()

    if keys[JUMP_KEY]:
        player1.jump()

    if keys[DOWN_KEY]:
        player1.ducking = True

    if keys[SPRINT_KEY] and player1.movementKeyPressed:
        player1.startSprinting()

    if keys[SHOW_SCORES_KEY]:
        Screen.DISPLAY_SCORES = True

    # KEYUP EVENT
    elif event.type == pygame.KEYUP:
        if event.key == LEFT_KEY or event.key == RIGHT_KEY or event.key == SPRINT_KEY:
            player1.stopMovingX()
            player1.isSprinting = False

        if event.key == DOWN_KEY:
            player1.ducking = False

        if event.key == SHOW_SCORES_KEY:
            Screen.DISPLAY_SCORES = False

    # MOUSE
    if event.type == pygame.MOUSEBUTTONDOWN:
        # Left Click
        if event.button == ATTACK_KEY:
            player1.attack()

        # Right Click
        elif event.button == PLACE_BLOCK_KEY:
            player1.requestToPlaceBlock()

# Clear the screen
Screen.gameScreen.fill(Colors.WHITE)

# Update Sprites
EntityLists.npcGroup.update()
EntityLists.redTeamGroup.update()
EntityLists.blackTeamGroup.update()
EntityLists.corpseGroup.update()

# Update Blocks
EntityLists.blockGroup.update()

#
print(len(EntityLists.blockGroup) + len(EntityLists.redTeamGroup) + len(EntityLists.blackTeamGroup) +
      len(EntityLists.npcGroup) + len(EntityLists.wallGroup))

if Screen.takeScreenShot:
    # Blit background first
    Screen.gameScreen.blit(background, (0, 0))
    # Draw blocks and wall next
    EntityLists.wallGroup.draw(Screen.gameScreen)
    EntityLists.blockGroup.draw(Screen.gameScreen)

    # Next, take screenshot
    pygame.image.save(Screen.gameScreen, "BACKGROUND_AND_BLOCKS.png")
    backgroundAndBlocks = pygame.image.load('BACKGROUND_AND_BLOCKS.png')
    # Reset variable
    Screen.takeScreenShot = False

# Blit
Screen.gameScreen.blit(backgroundAndBlocks, (0, 0))

# Draw Entities
EntityLists.npcGroup.draw(Screen.gameScreen)
EntityLists.redTeamGroup.draw(Screen.gameScreen)
EntityLists.corpseGroup.draw(Screen.gameScreen)
EntityLists.blackTeamGroup.draw(Screen.gameScreen)

# Player names
Screen.drawNames()

# Draw Death Messages
Screen.displayDeathMessages()

# Draw scores if viable
if Screen.DISPLAY_SCORES:
    Screen.displayScores()

# Update screen
pygame.display.flip()

# FPS
clock.tick(Screen.TARGET_FPS)

pygame.quit()

非常感谢您的时间。

1 个答案:

答案 0 :(得分:0)

我正在开发pygame,当您不使用Spritesheets .... try并使用Spritesheets时,延迟会很明显,那样您就只能上传包含所有Sprite一次的单个图像。

如果您的主角有20个不同的图像(帧),包括闲置,跑步,步行,跳跃,射击等,并且您不使用Spritesheet,会发生什么?

Pygame需要在每个循环中一张一张地上传所有这些图像,从而产生延迟。

相反,spritesheet是一个单独的图像,包含所有带有(x,y,width,height)每个sprite的sprite,因此pygame在需要该特定sprite框架时知道每个sprite的边界。

尝试使用Spritesheets,它将使您的游戏运行流畅,处理能力降低,图形卡使用量减少,发热量降低。

100张图像,每张图像重100kb ...这很多,但是一张spritesheet图片仅重100kb .... hmmm

如果您的游戏只有5个精灵,则在没有滞后的情况下使用图像,但是如果游戏中包含滞后的图像以上并且存在滞后,请使用精灵表,这还可以使您的工作更有条理,并且在您需要打包时向上,将其转换为.exe或其他任何东西,它将减轻重量。

注意:我在不久前发布了我的答案,但我只是想补充一下,当您加载图像时,请尝试一次将其加载到 init 方法中,并在update方法中引用它们。不要在循环内“ pygame.image.load(filename)”,它会滞后。

祝你好运。