有没有办法增加给予 python 程序的 CPU 权力? (Python 3.5, Mac)

Is there a way to increase the CPU power given to a python program? (Python 3.5, Mac)

我有这个程序,你是一场比赛,你必须躲避飘落的雪花。一旦你死了,屏幕上就会画出游戏结束的文字,而雪花会继续飘落。因为当时的过程更简单(没有键盘输入或移动火柴等),用于执行程序的 CPU 电量减少了大约 4%。但是,绘制文本需要更长的时间,因此雪花的速度都变慢了。

有没有办法告诉 python 在程序中使用更多可用的 CPU 功能以使其 运行 更快?

这是我使用的 drawText 方法:

def drawText(window, text, size, color, centerX, centerY):
    font=pygame.font.Font("DickensianChristmas.ttf", size)
    renderedText=font.render(str(text),True,color)
    textpos=renderedText.get_rect()
    textpos.centerx=centerX
    textpos.centery=centerY
    window.blit(renderedText, textpos)

这是运行正常的主要代码:

while True:
    ticks += 1
    window.fill((200,200,200))

    #Increase difficulty with time
    if ticks%increaseRate == 0:
        snowFrequency *= 0.925
        snowSpeed += 0.125
        speed += 0.15

    #Generate Speed Boost
    if randint(1,speedFrequency) == 1 and not(speedOnScreen):
        speedOnScreen = True
        speedX = randint(0,1180)
        speedY = -120

    #Generate Shield
    if randint(1,shieldFrequency) == 1 and not(shieldOnScreen):
        shieldOnScreen = True
        shieldX = randint(0,1180)
        shieldY = -120

    #Move, draw, pick up, and delete speed boost
    if speedOnScreen:
        speedY += snowSpeed
        window.blit(speedBoost, (speedX,speedY))
        if 700 > speedY > 472 and matchX+15 > speedX > matchX-120:
            speedStart = ticks
            speedOnScreen = False
        if speedY > 700:
            speedOnScreen = False

    #Move, draw, pick up, and delete shield
    if shieldOnScreen:
        shieldY += snowSpeed
        window.blit(shield, (shieldX,shieldY))
        if 700 > shieldY > 472 and matchX+15 > shieldX > matchX-107:
            shieldStart = ticks
            shieldOnScreen = False
        if shieldY > 700:
            shieldOnScreen = False

    #Sheilding effect
    if ticks > shieldStart+shieldDuration:
        invincible = False
    else:
        invincible = True
        window.blit(pygame.transform.scale(shield, (55,60)), (1240,0))
        pygame.draw.line(window,(0,0,0),(1270,75),(1270, 75+shieldDuration-(ticks-shieldStart)),25)

    #Speed Boost Effect
    if ticks > speedStart+speedDuration:
        speed = baseSpeed
        tilt = tiltAmount
    else:
        speed = baseSpeed*2
        tilt = tiltAmount*1.5
        window.blit(pygame.transform.scale(speedBoost, (60,60)), (0,0))
        pygame.draw.line(window,(0,0,0),(30,75),(30, 75+speedDuration-(ticks-speedStart)),25)

    #Draw Score
    drawText(window, score, 96, (0,0,0), 650, 50)

    #Make snowflakes
    if randint(1,round(snowFrequency)) == 1:
        #                  IMAGE                          X-COORDINATE     Y-COORDINATE
        snowflakes.append([snowflakeImages[randint(0,5)], randint(0,1234), -64])
    #Move snowflakes (different kinds move differently)
    for flake in snowflakes:
        if flake[0] == snowflake1:
            flake[2] += snowSpeed*0.8
            flake[1] += randint(-2,1)
        elif flake[0] == snowflake2:
            flake[2] += snowSpeed*0.8
            flake[1] += randint(-1,2)
        elif flake[0] == snowflake3 or flake[0] == snowflake4:
            flake[2] += snowSpeed*1.25
            flake[1] += randint(-1,1)
        else:
            flake[2] += snowSpeed
            flake[1] += randint(-2,2)
        #Draw snowflakes
        #           IMAGE      LOCATION
        window.blit(flake[0], (flake[1],flake[2]))
        #Remove snowflakes that go off screen and increase score
        if flake[2] > 700:
            snowflakes.remove(flake)
            score += 1

        #Compensate for matches rotation
        addDegrees = 0
        if degrees < 0:
            addDegrees = degrees
        #Collision detection
        if 631 > flake[2] > 528 and matchX+15+addDegrees > flake[1] > matchX-64-addDegrees:
            if invincible:
                snowflakes.remove(flake)
                score += 2
            else:
                gameOver(window, snowflakes)

    #Detect quit
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            done(window)

    #Match movement
    keys = pygame.key.get_pressed()
    if (keys[K_a] or keys[K_LEFT]):
        if degrees > -tilt:
            degrees -= tiltSpeed
        matchX -= speed
    if (keys[K_d] or keys[K_RIGHT]):
        if degrees < tilt:
            degrees += tiltSpeed
        matchX += speed
    if not (keys[K_a] or keys[K_LEFT] or keys[K_d] or keys[K_RIGHT]):
        if degrees > 0:
            degrees -= tiltSpeed
            matchX += tiltSpeed*2
        if degrees < 0:
            degrees += tiltSpeed

    #Draw match
    window.blit(pygame.transform.rotate(match, degrees),(matchX, 592))
    #Move oss-screen side-switching
    if matchX < 15:
        matchX += 1300
    elif matchX > 1285:
        matchX -= 1300
    #Update display
    pygame.display.update()

这是游戏结束后运行变慢的代码:

while True:
    window.fill((200,200,200))
    window.blit(burntOut4, (matchX,592))
    drawText(window, score, 96, (0,0,0), 650, 50)
    drawText(window, "GAME OVER!", 120, (0,0,0), 650, 350)
    if beatHS:
        drawText(window, "NEW HIGHSCORE!", 80, (0,0,0), 650, 450)
    else:
        drawText(window, "HIGHSCORE: "+highScore, 80, (0,0,0), 650, 450)
    if randint(1,round(snowFrequency)) == 1:
        snowflakes.append([snowflakeImages[randint(0,5)], randint(0,1234), -64])
    for flake in snowflakes:
        if flake[0] == snowflake1:
            flake[2] += snowSpeed*0.8
            flake[1] += randint(-2,1)
        elif flake[0] == snowflake2:
            flake[2] += snowSpeed*0.8
            flake[1] += randint(-1,2)
        elif flake[0] == snowflake3 or flake[0] == snowflake4:
            flake[2] += snowSpeed*1.25
            flake[1] += randint(-1,1)
        else:
            flake[2] += snowSpeed
            flake[1] += randint(-2,2)
        window.blit(flake[0], (flake[1],flake[2]))
        if flake[2] > 700:
            snowflakes.remove(flake)
    pygame.display.update()
    for event in pygame.event.get():
        if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
            pygame.quit()
            sys.exit(0)

我已经通过注释掉它来验证是文本绘图减慢了速度。是否也可以更有效地绘制文本而不是使用更多 CPU?

我认为一旦开始在屏幕上绘制文本,绘制所有雪花的处理能力就会有点高。将图像传输到表面比将表面传输到表面要慢得多。所以有很多雪花(除了文本),所有的 blitting 都在加起来。

例如(在游戏循环外):

enemy_rect = get_image("enemy.png").get_rect()
enemy_surface = pygame.Surface((enemy_rect.width, enemy_rect.height), pygame.SRCALPHA)
enemy_surface.fill((0, 0, 0, 0))
enemy_surface.blit(get_image("enemy_reveal_camo.png"), enemy_rect)

所以现在当 blit 到屏幕时(在游戏循环内):

screen.blit(enemy_surface, (x, y))

快于:

enemy = get_image("enemy.png")  # outside game loop

screen.blit(enemy, (x, y))  # inside game loop

这可能无法完全解决您的问题,但有助于提高绘图效率。您实际上是在预先绘制图像。至少值得一试,当我在屏幕上绘制一堆单独的图像时,它对我的​​游戏产生了奇迹。

如果您还想提高文本绘制的效率,请将字体加载和渲染拉到游戏循环之外。因此,您可以预渲染文本,并在代码内部更新位置。就像图像一样,您可以将文本预先绘制到游戏循环之外的表面,因为它是静态放置的。

总是在游戏循环之外尽可能多地预绘制。