Pygame - clock.tick_busy_loop(fps)问题

时间:2015-11-25 07:30:45

标签: python pygame

所以我遇到了pygame的问题。我在两台Windows 10计算机上运行Pygame 1.9ish的Python 3.5-32位。在现代高速i7上,如果我尝试以60fps运行我的代码,它会以稳定的速度运行。但是,如果我在我的Core2Duo上运行它有点旧,它在60FPS下运行稳定...大约15秒,然后下降到45并且口吃。但是,如果我在Core2Duo上将FPS提高到120,它会一直运行并且很好。但随着它的运行设定在60或70左右,FPS在15秒后突然下降。

我无法解释为什么会这样。我已经切换到使用clock.tick_busy_loop(60)而不是clock.tick(60),因为这在所有计算机上都不可靠。

任何指针?我不明白为什么它在一台机器上运行良好且稳定,并且在另一台机器上15秒后失去速度。

#! /usr/bin/env python

"""
Modified from example by Sean J. McKiernan 'Mekire'
"""

import os
import sys
import random
import math
import ctypes #to fix stupid Windows fullscreen issue 
import pygame as pg


CAPTION = "Drag the Red Square"
SCREEN_WIDTH=1920
SCREEN_HEIGHT=1020
SCREEN_SIZE = (SCREEN_WIDTH,SCREEN_HEIGHT)
GRAVITY=0.1
PI=math.pi

class Planet(object):
"""
A class to represent our lovable purple planets.
"""


def __init__(self):
    """
    DEPRECATED: The argument pos corresponds to the center of our rectangle.
    """
    self.xPos=random.randint(0,SCREEN_WIDTH)
    self.yPos=random.randint(0,SCREEN_HEIGHT)
    self.densityFloat=random.uniform(1,2)
    self.radiusFloat=random.uniform(25,100)
    self.massFloat=GRAVITY*2.0*(self.radiusFloat**2)*self.densityFloat      
    self.text, self.text_rect = self.setup_font()
    self.radius=int(self.radiusFloat)
    self.planetSurface=pg.Surface((SCREEN_WIDTH,SCREEN_HEIGHT))
    #self.planetSurface.set_colorkey((0,0,0), pg.RLEACCEL)
    self.planetSurface.fill((255,0,0))
    self.circleDude, self.circleDude_rect=self.setup_circle()
    self.newX=0
    self.displacement=0
    self.playerSpeed=0.005

def setup_font(self):
    font = pg.font.SysFont('timesnewroman',30)
    message = "x-position: " + str(self.xPos) + " radiusFloat: " + str(round(self.radiusFloat,3))
    label = font.render(message,True, pg.Color("white"))
    label_rect = label.get_rect()
    return label, label_rect

def setup_circle(self):
    circle = pg.Surface((self.radius*2,self.radius*2))
    circle_rect = circle.get_rect()
    circle.fill((255,255,0))
    pg.draw.circle(circle, pg.Color("white"), (self.radius,self.radius),self.radius, 0)
    circle.set_colorkey((0,0,0), pg.RLEACCEL)

    return circle, circle_rect

def draw(self, surface, fpsMillis):
    """
    Blit image and text to the target surface.
    """

    timedelta=fpsMillis/1000.0

    localfont = pg.font.SysFont('timesnewroman',30)
    fontobj=localfont.render(str(timedelta),True,pg.Color("red"))
    #surface.blit(self.text,(0,0))
    #surface.blit(self.planetSurface,(0,0))
    surface.blit(fontobj,(500,500))


    #surface.blit(self.circleDude,(self.newX,self.yPos))        

    self.circleDude_rect.center = self.newX, self.yPos
    self.circleDude_rect.center=(self.newX,self.yPos)

    #self.newX += 50*timedelta


class App(object):
"""
A class to manage our event, game loop, and overall program flow.
"""
def __init__(self):
    """
    Get a reference to the screen (created in main); define necessary
    attributes; and create our player (draggable rect).
    """
    self.screen = pg.display.get_surface()
    self.screen_rect = self.screen.get_rect()
    self.clock = pg.time.Clock()
    self.fps = 120
    self.done = False
    self.keys = pg.key.get_pressed()
    self.planetOne = Planet()
    self.frameMilliseconds = 1

def event_loop(self):
    """
    This is the event loop for the whole program.
    Regardless of the complexity of a program, there should never be a need
    to have more than one event loop.
    """
    for event in pg.event.get():
        if event.type == pg.QUIT or self.keys[pg.K_ESCAPE]:
            self.done = True
        elif event.type == pg.MOUSEBUTTONDOWN and event.button == 1:
            self.player.check_click(event.pos)
        elif event.type == pg.MOUSEBUTTONUP and event.button == 1:
            self.player.click = False
        elif event.type in (pg.KEYUP, pg.KEYDOWN):
            self.keys = pg.key.get_pressed() 

def render(self):
    """
    All drawing should be found here.
    This is the only place that pygame.display.update() should be found.
    """
    self.screen.fill(pg.Color("black"))                     
    self.planetOne.draw(self.screen,self.frameMilliseconds)
    pg.display.update()

def main_loop(self):
    """
    This is the game loop for the entire program.
    Like the event_loop, there should not be more than one game_loop.
    """
    while not self.done:
        self.event_loop()
        self.render()
        self.frameMilliseconds=self.clock.tick_busy_loop(self.fps)


def main():
"""
Prepare our environment, create a display, and start the program.
"""
os.environ['SDL_VIDEO_CENTERED'] = '1'
pg.init()                                 #run init routines. duh. 

pg.display.set_caption(CAPTION)           #Set window caption to something  dank, homie
ctypes.windll.user32.SetProcessDPIAware() #STUPID windows is a pain in the ainairse - dpi scaling wrecks python
pg.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT),pg.FULLSCREEN) #Set display mood, wait, I mean mode. Mode.

App().main_loop()   #get into main loop.

pg.quit()           #quit pygame library, because that's a requirement apparently.

sys.exit()          #quit code.


if __name__ == "__main__":
main()

0 个答案:

没有答案