Вопрос по python – FPS с Pyglet половина частоты обновления монитора

2

Я новичок в работе с Pyglet, и я написал небольшую программу, которая перемещает шарик по экрану. Сейчас у меня возникают трудности с установлением постоянной частоты кадров 60 кадров в секунду. В то время как Pyglet должен синхронизироваться с частотой обновления моего монитора 60 Гц, Pyglet устанавливает мои fps на половину моей частоты обновления (например, при 60 Гц, 30 fps). Что-то не так в моем коде, который вызывает это?

import pyglet
import physicalobject
import random
from pyglet.window import mouse

pyglet.resource.path = ['./resources']
pyglet.resource.reindex()

ball_image = pyglet.resource.image("ball2.png")

#sets clock format
fps_display = pyglet.clock.ClockDisplay(format='%(fps).2f fps')

def center_image(image):
    image.anchor_x = image.width/2
    image.anchor_y = image.height/2

center_image(ball_image)
ball = physicalobject.PhysicalObject(img=ball_image, x = 400, y = 300)
ball.scale = .2
ball.velocity_x = random.randint(-4,4)*150
ball.velocity_y = random.randint(-4,4)*150

#Calls update function to set new ball position based on velocity
def update(dt):
     ball.update(dt)

@window.event
def on_mouse_drag(x, y, dx, dy, button, modifiers):
     ball.x = x
     ball.y = y
     ball.velocity_x = dx * 20
     ball.velocity_y = dy * 20

@window.event
def on_draw():
     window.clear()
     ball.draw()
     fps_display.draw()

def main():
     pyglet.clock.schedule_interval(update, 1/120.0)
     pyglet.app.run()

if __name__ == '__main__':
     main()
Видите ли вы улучшение, если вы используетеpyglet.clock.schedule(update) вместоschedule_interval? robots.jpg
Во время вопроса, какую версию Pyglet вы использовали, потому что у 1.1.1 были некоторые проблемы с частотой кадров. Torxed
Кажется, это не имеет значения. FlowofSoul

Ваш Ответ

2   ответа
1

import pyglet
from time import time, sleep

class Window(pyglet.window.Window):
    def __init__(self, refreshrate):
        super(Window, self).__init__(vsync = False)
        self.frames = 0
        self.framerate = pyglet.text.Label(text='Unknown', font_name='Verdana', font_size=8, x=10, y=10, color=(255,255,255,255))
        self.last = time()
        self.alive = 1
        self.refreshrate = refreshrate

    def on_draw(self):
        self.render()

    def render(self):
        self.clear()
        if time() - self.last >= 1:
            self.framerate.text = str(self.frames)
            self.frames = 0
            self.last = time()
        else:
            self.frames += 1
        self.framerate.draw()
        self.flip()

    def on_close(self):
        self.alive = 0

    def run(self):
        while self.alive:
            self.render()
            event = self.dispatch_events()
            sleep(1.0/self.refreshrate)

win = Window(23) # set the fps
win.run()

Также попробуйте установитьvsync = True и удалениеsleep(1.0/self.refreshrate)это заблокирует частоту обновления вашего монитора.

Кроме того, обратите внимание, что я не используюpyglet.app.run() чтобы заблокировать процесс рендеринга, я звонюself.dispatch_events() вместо этого ... он ничего не делает, кроме как позволить графическому & quot; poll & quot; и двигаться дальше, без него .. Pyglet ждет опроса, которыйpyglet.app.run() обычно делает.

1

вам нужно отключить vsync окна вашего приложения, чтобы заставить его работать. Вот пример сценария, который вы можете запустить, чтобы понять, как он работает:

import pyglet

# Show FPS
fps = pyglet.clock.ClockDisplay()

# The game window
class Window(pyglet.window.Window):
    def __init__(self):
        super(Window, self).__init__(vsync = False)
        # Run "self.update" 128 frames a second and set FPS limit to 128.
        pyglet.clock.schedule_interval(self.update, 1.0/128.0)
        pyglet.clock.set_fps_limit(128)

    # You need the dt argument there to prevent errors,
    # it does nothing as far as I know.
    def update(self, dt): 
        pass

    def on_draw(self):
        pyglet.clock.tick() # Make sure you tick the clock!
        self.clear()
        fps.draw()

# Create a window and run
win = Window()
pyglet.app.run()
Это работает, почти ... за исключением того, что вы не можете использовать часы ... У него есть ограничения.
@ Торксед Какие ограничения? Я был под впечатлением от часовshould использоваться для планирования событий.
Таким образом, часть vsync верна, если вы установитеvsync = True тогда приложение будет вынуждено заблокировать обновление монитора, это должно уменьшить разрыв экрана, который может произойти, если приложение обновляется таким синхронизированным образом, что глаз может заметить различия. Это означает, что оно будет отображаться несинхронно или запаздывает, когда на самом деле это просто ваш экран рендеринга так быстро и с таким интервалом, что обновления происходят, когда монитор обновляется, то есть разрыв экрана. Но часы не будут показывать правильное обновление, это просто создаст иллюзию обновления обновления :)

Похожие вопросы