有没有办法增加给予 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
这可能无法完全解决您的问题,但有助于提高绘图效率。您实际上是在预先绘制图像。至少值得一试,当我在屏幕上绘制一堆单独的图像时,它对我的游戏产生了奇迹。
如果您还想提高文本绘制的效率,请将字体加载和渲染拉到游戏循环之外。因此,您可以预渲染文本,并在代码内部更新位置。就像图像一样,您可以将文本预先绘制到游戏循环之外的表面,因为它是静态放置的。
总是在游戏循环之外尽可能多地预绘制。
我有这个程序,你是一场比赛,你必须躲避飘落的雪花。一旦你死了,屏幕上就会画出游戏结束的文字,而雪花会继续飘落。因为当时的过程更简单(没有键盘输入或移动火柴等),用于执行程序的 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
这可能无法完全解决您的问题,但有助于提高绘图效率。您实际上是在预先绘制图像。至少值得一试,当我在屏幕上绘制一堆单独的图像时,它对我的游戏产生了奇迹。
如果您还想提高文本绘制的效率,请将字体加载和渲染拉到游戏循环之外。因此,您可以预渲染文本,并在代码内部更新位置。就像图像一样,您可以将文本预先绘制到游戏循环之外的表面,因为它是静态放置的。
总是在游戏循环之外尽可能多地预绘制。