我读到了关于pygame陷入困境的其他问题,我所能找到的只是限制FPS,我试过但是它仍然在停滞不前,我已经尝试了一切,但最后我认为这只是因为我的代码效率低或者什么,任何帮助将不胜感激。
这是一个性能视频,因为我确定你们都不想真正下载这个,
https://www.youtube.com/watch?v=vmZaxb0zQR0
当它第一次启动它的速度比它应该的慢时,视频中的0:12是它应该以它应该的速度运行,并且在0:50它再次陷入停滞。
我试着到处寻找它可能是什么,我一无所获,坦率地说,发布这个来源是尴尬的
main.py
import sys, pygame
import random
import time
from resources import _time_
from pygame.locals import *
debug = True
start = time.time()
pygame.mixer.pre_init(44100, -16, 2, 2048)
pygame.init()
size = width, height = 800, 600
speed = [1, 1]
ai_speed = [1, 1]
black = (0, 0, 0)
text_color = (255, 255, 255)
dad_count = 0
#values change to True if appropriate key is pressed
keys = [False, False, False, False]
#set title and screen width and height
pygame.display.set_caption("Dad Explorer v0.02")
screen = pygame.display.set_mode(size)
clock = pygame.time.Clock()
screen_rect = screen.get_rect()
#set boundary variables
b_height = height - 26
b_width = width - 25
newdad = False
#load our beautiful sounds
loop = pygame.mixer.music.load("sound/loop.wav")
intro = pygame.mixer.Sound("sound/intro.wav")
alarm1 = pygame.mixer.Sound("sound/klaxon_alert1.wav")
beeps = pygame.mixer.Sound("sound/beeps.wav")
beeps.set_volume(0.1)
defeated = pygame.mixer.Sound("sound/defeatednormal.wav")
defeated.set_volume(0.5)
yell = pygame.mixer.Sound("sound/yell.wav")
yell.set_volume(0.7)
#spawn objects at random coordinates
playerspawn = (random.randrange(b_width), random.randrange(b_height))
enemyspawn = (random.randrange(b_width), random.randrange(b_height))
#player
player = pygame.image.load("images/smug.gif")
player_rect = player.get_rect()
player_rect[:2] = playerspawn
#enemy
enemy = pygame.image.load("images/dad.png")
enemy_rect = enemy.get_rect()
enemy_rect[:2] = enemyspawn
#loop music
pygame.mixer.music.set_volume(0.2)
pygame.mixer.music.play(-1)
#pre set collision to false
collision = False
#fpsCounter = text_font.render("FPS: {}".format(pygame.time.Clock()))
while 1:
respawn = (random.randrange(b_width), random.randrange(b_height))
#display text on the screen
text_font = pygame.font.SysFont("monospace", 14)
player_label = text_font.render("-- Player --", 1, text_color)
player_velocity = text_font.render("Velocity: {}".format(speed), 1, text_color)
player_position = text_font.render("Position: {}".format((player_rect.x, player_rect.y)), 1, text_color)
text_debug = text_font.render("Debug: {}".format(debug), 1, text_color)
time_label = text_font.render("Time wasted: {}".format(_time_()), 1, text_color)
dad_kills = text_font.render("{} Dads defeated".format(dad_count), 1, text_color)
enemy_label = text_font.render("-- Enemy --", 1, text_color)
enemy_velocity = text_font.render("Velocity: {}".format(ai_speed), 1, text_color)
enemy_currentpos = text_font.render("Position: {}".format(enemy_rect[:2]), 1, text_color)
#move the enemy
enemy_rect = enemy_rect.move(ai_speed)
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key==K_UP:
keys[0]=True
elif event.key==K_LEFT:
keys[1]=True
elif event.key==K_DOWN:
keys[2]=True
elif event.key==K_RIGHT:
keys[3]=True
if event.key == K_r:
#press r to reset player position
if debug == True:
player_rect[:2] = [100, 100]
speed = [1, 1]
else:
pass
if event.type == pygame.KEYUP:
if event.key==pygame.K_UP:
keys[0]=False
elif event.key==pygame.K_LEFT:
keys[1]=False
elif event.key==pygame.K_DOWN:
keys[2]=False
elif event.key==pygame.K_RIGHT:
keys[3]=False
#set enemy boundaries
if enemy_rect.left < 0 or enemy_rect.right > width:
ai_speed[0] = -ai_speed[0]
if enemy_rect.top < 0 or enemy_rect.bottom > height:
ai_speed[1] = -ai_speed[1]
#set player boundaries
if not screen_rect.contains(player_rect):
if player_rect.right > screen_rect.right:
player_rect.right = screen_rect.right
if player_rect.bottom > screen_rect.bottom:
player_rect.bottom = screen_rect.bottom
if player_rect.left < screen_rect.left:
player_rect.left = screen_rect.left
if player_rect.top < screen_rect.top:
player_rect.top = screen_rect.top
#check for collision
new_collision = enemy_rect.colliderect(player_rect)
if not collision and new_collision:
print "alarm"
dad_count += 1
defeated.play()
newdad = True
if dad_count == 1:
enemy = pygame.image.load("images/maddad.png")
yell.play()
elif collision and not new_collision:
print "done colliding"
beeps.play()
collision = new_collision
screen.fill(black) #display background
screen.blit(player, player_rect) #display player object and player movement
if newdad is True:
enemy_rect[:2] = respawn
ai_speed = [random.randrange(-5, 5), random.randrange(-5, 5)]
screen.blit(enemy, enemy_rect)
newdad = False
else:
screen.blit(enemy, enemy_rect)
#player data
screen.blit(player_label, (5, 10))
screen.blit(player_velocity, (5, 30))
screen.blit(player_position, (5, 50))
screen.blit(text_debug, (5, 70))
screen.blit(time_label, (5, b_height))
screen.blit(dad_kills, (5, b_height - 30))
#AI data
screen.blit(enemy_label, (5, 120))
screen.blit(enemy_velocity, (5, 140))
screen.blit(enemy_currentpos, (5, 160))
if keys[0]:
speed[1] = -2
elif keys[2]:
speed[1] = 2
else:
speed[1] = 0
if keys[1]:
speed[0] = -2
elif keys[3]:
speed[0] = 2
else:
speed[0] = 0
player_rect.move_ip(speed[0], speed[1])
pygame.display.flip()
clock.tick(150)
resources.py (跟踪播放的时间)
import random
import time, datetime
from random import choice
start_datetime = datetime.datetime.now()
def _time_():
delta = datetime.datetime.now() - start_datetime
days = delta.days
hours = delta.seconds / 3600
minutes = (delta.seconds / 60) % 60
seconds = delta.seconds % 60
runningtime = []
if days > 0:
runningtime.append("{} day{}".format(days, "" if days == 1 else "s"))
if hours > 0:
runningtime.append("{} hour{}".format(hours, "" if hours == 1 else "s"))
if minutes > 0:
runningtime.append("{} minute{}".format(minutes, "" if minutes == 1 else "s"))
if seconds > 0:
runningtime.append("{} second{}".format(seconds, "" if seconds == 1 else "s"))
if len(runningtime) < 2:
time = " and ".join(runningtime)
else:
time = ", ".join(runningtime[:-1]) + ", and " + runningtime[-1]
return time
答案 0 :(得分:3)
我认为你的问题是字体渲染。字体渲染是一项非常昂贵的操作,您应该始终缓存并重新使用这些渲染表面。
此外,您在主循环的每次迭代中都会加载字体。只需加载一次。
游戏非常简单,但我建议帧率为60(根据我的经验,这是一个很好的价值,YMMV)。
缓存的示例可能如下所示:
...
text_font = pygame.font.SysFont("monospace", 14)
cache={}
def get_msg(msg):
if not msg in cache:
cache[msg] = text_font.render(msg, 1 , text_color)
return cache[msg]
while 1:
respawn = (random.randrange(b_width), random.randrange(b_height))
player_label = get_msg("-- Player --")
player_velocity = get_msg("Velocity: {}".format(speed))
player_position = get_msg("Position: {}".format((player_rect.x, player_rect.y)))
text_debug = get_msg("Debug: {}".format(debug))
time_label = get_msg("Time wasted: {}".format(_time_()))
dad_kills = get_msg("{} Dads defeated".format(dad_count))
...
这应该提高你的帧率并防止减速。
作为旁注,而不是:
#set player boundaries
if not screen_rect.contains(player_rect):
if player_rect.right > screen_rect.right:
player_rect.right = screen_rect.right
if player_rect.bottom > screen_rect.bottom:
player_rect.bottom = screen_rect.bottom
if player_rect.left < screen_rect.left:
player_rect.left = screen_rect.left
if player_rect.top < screen_rect.top:
player_rect.top = screen_rect.top
只需使用:
#set player boundaries
player_rect.clamp_ip(screen_rect)
您的代码还存在其他一些小问题,但这个问题/答案已经出了问题。