2012-05-14 3 views
2

저는 Pyglet에 익숙하지 않고 화면 주위에서 공을 움직이는 작은 프로그램을 작성했습니다. 지금은 60fps의 꾸준한 프레임 속도를 설정하는 데 어려움을 겪고 있습니다. Pyglet이 내 모니터의 재생 빈도 60Hz와 동기화되는 동안 Pyglet은 내 재생 빈도의 절반 (예 : 60Hz, 30fps)으로 내 fps를 설정합니다. 이 문제를 일으키는 내 코드에 문제가 있습니까?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() 
+0

'schedule_interval' 대신'pyglet.clock.schedule (update)'를 사용하면 개선 된 점이 있습니까? –

+0

차이가없는 것 같습니다. – FlowofSoul

+0

질문 당시, 1.1.1에는 프레임 레이트 관련 몇 가지 문제가 있었기 때문에 실행중인 Pyglet의 버전은 무엇입니까? – Torxed

답변

1

일부 시스템에서는 Pyglet이 올바르게 처리하지 않으므로 응용 프로그램 창의 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() 
+0

이것은 거의 작동하지만 시계를 사용할 수 없다는 것 외에는 한계가 있습니다. – Torxed

+0

따라서 vsync 부분이 참일 때,'vsync = True'로 설정하면 애플리케이션은 모니터 새로 고침으로 잠길 것입니다. 이것은 애플리케이션이 동기화 된 방식으로 새로 고침 될 때 발생할 수있는 화면 찢김을 줄이기위한 것입니다. 눈이 차이를 잡을 수 있습니다. 실제로 모니터가 새로 고침되고 화면이 끊어지면 업데이트가 발생하는 것과 같이 빠른 속도로 화면을 렌더링 할 때 화면이 싱크 또는 뒤떨어져 보일 것입니다. 그러나 시계는 적절한 refreshrate을 보여주지 않을 것입니다, 그것은 단지 당신에게 refreshrate 디스플레이의 환상을 줄 것입니다 :) – Torxed

+0

@ Torxed 어떤 제한? 나는 시계 아래에 일정을 잡는 데 사용해야한다고 생각했다. –

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()을 호출합니다. 그래픽 폴링을하지 않고 계속 진행하면됩니다. pyglet waits 설문 조사가 발생하면 pyglet.app.run()이 정상적으로 처리됩니다.