Re: pyglet1.2alpha tick or draw isn't called?

78 views
Skip to first unread message

Peter Enerccio

unread,
Dec 27, 2012, 9:51:46 AM12/27/12
to pyglet...@googlegroups.com
As far as I know, pyglet loop is event based, so it will only call draw when window is considered dirty.
I suggest making your own render loop, if you want performance over cpu usage (which you want for games for instance).


2012/12/22 Ricky Christie <seven.r...@gmail.com>
So I was trying out pyglet1.2alpha in my Snow Leopard.
Either the pyglet.clock.tick() method doesn't get called periodically or the draw method doesn't.
I wrote a code that should display incrementing number on each draw. It does increment but only after a long while.

import pyglet

class TestTick(object):
    def start(self):
        self.x = 1
        window = pyglet.window.Window()
        
        @window.event
        def on_draw():
            window.clear()
            self.x += 1
            label = pyglet.text.Label('Hello, world ' + str(self.x))
            label.draw()
            print('draw called')
        
        pyglet.app.run()

test = TestTick()
test.start()

Am I using it wrong here?

--
You received this message because you are subscribed to the Google Groups "pyglet-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/pyglet-users/-/w0NpkVNdZe0J.
To post to this group, send email to pyglet...@googlegroups.com.
To unsubscribe from this group, send email to pyglet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pyglet-users?hl=en.



--
Bc. Peter Vaňušanik
http://www.bishojo.tk

Tristam MacDonald

unread,
Dec 27, 2012, 11:26:03 AM12/27/12
to pyglet-users
On Sat, Dec 22, 2012 at 12:40 AM, Ricky Christie <seven.r...@gmail.com> wrote:
So I was trying out pyglet1.2alpha in my Snow Leopard.
Either the pyglet.clock.tick() method doesn't get called periodically or the draw method doesn't.
I wrote a code that should display incrementing number on each draw. It does increment but only after a long while.

import pyglet

class TestTick(object):
    def start(self):
        self.x = 1
        window = pyglet.window.Window()
        
        @window.event
        def on_draw():
            window.clear()
            self.x += 1
            label = pyglet.text.Label('Hello, world ' + str(self.x))
            label.draw()
            print('draw called')
        
        pyglet.app.run()

test = TestTick()
test.start()

Am I using it wrong here?

As Peter says, pyglet won't draw until it thinks there is a reason to (in your case, probably when you move the mouse).

If you want a constant redraw (such as for a game), then just register an empty update function: 

def update(dt):
    pass
pyglet.clock.schedule_interval(update, 1.0/30.0)

--
Tristam MacDonald
Software Development Engineer, Amazon.com

Ricky Christie

unread,
Dec 27, 2012, 11:16:16 PM12/27/12
to pyglet...@googlegroups.com
Much thanks guys - and happy holidays :D

Adam Bark

unread,
Mar 25, 2013, 8:21:30 PM3/25/13
to pyglet...@googlegroups.com
On 25/03/13 17:23, Peter B wrote:
> Pyglet 1.2 alpha DEFINITELY broke the scheduling. I see people asking
> the same thing, why the clock.set_fps_limit which previously worked is
> now no longer working as advertised, and the response seems to be Oh,
> just don't use it, and schedule everything on time intervals. Which is
> fine unless you WANT sometime to fire each frame.
>
> I'd appreciate some explanation of why this happened.
>
pyglet.clock.set_fps_limit is deprecated
http://pyglet.org/doc/api/pyglet.clock-module.html#set_fps_limit

If you want something to happen every frame possible then use
pyglet.clock.schedule with your update function as was mentioned earlier
in this thread. If you want to restrict the frame rate the correct way
to do that now is to use schedule_interval and a redraw will occur when
that happens assuming your monitor refresh rate is faster than the interval.

Peter B

unread,
Apr 10, 2013, 1:48:08 PM4/10/13
to pyglet...@googlegroups.com

Maybe I'm  misunderstanding something, but I specifically WANT to couple my game logic and drawing code. Are you telling me that this is no longer possible?

Adam Bark

unread,
Apr 10, 2013, 2:09:04 PM4/10/13
to pyglet...@googlegroups.com
What, specifically, are you trying to do? When you schedule something on_draw should be called afterwards by the event loop to draw the changes. If you want something more tightly coupled then you'll need to schedule something to make sure the screen gets refreshed and then run your logic from on_draw.

Peter B

unread,
Apr 10, 2013, 3:32:34 PM4/10/13
to pyglet...@googlegroups.com
I'm trying to make a retro arcade style 2d game, and part of that requires that I have discrete per-frame logic (rather than based on delta since last update). For example, almost every visible element is going to be constantly cycling through 2-4 frame animations. More significantly, I'd like to simulate slowdown when lots of elements are onscreen; dynamically changing the FPS limit seemed like an easy enough way to do this, since it directly adjusts the period limit used in clock.tick.

I was doing logic every frame through the scheduled update function, and relying on the "on_draw" method of pyglet.window to redraw after the scheduled functions completed- my assumption was that each invocation of "update" would be sandwiched between by two invocations of "on_draw", and vice versa. 

How should I organize my code? If I schedule my update function for every 1/60 seconds instead then I don't see how I'd be able to simulate slowdown without constant descheduling and rescheduling update at different speeds on each frame from within the update method.

Tristam MacDonald

unread,
Apr 10, 2013, 3:45:04 PM4/10/13
to pyglet-users
On Wed, Apr 10, 2013 at 3:32 PM, Peter B <peter.be...@gmail.com> wrote:
I'm trying to make a retro arcade style 2d game, and part of that requires that I have discrete per-frame logic (rather than based on delta since last update). For example, almost every visible element is going to be constantly cycling through 2-4 frame animations. More significantly, I'd like to simulate slowdown when lots of elements are onscreen; dynamically changing the FPS limit seemed like an easy enough way to do this, since it directly adjusts the period limit used in clock.tick.

I was doing logic every frame through the scheduled update function, and relying on the "on_draw" method of pyglet.window to redraw after the scheduled functions completed- my assumption was that each invocation of "update" would be sandwiched between by two invocations of "on_draw", and vice versa. 

How should I organize my code? If I schedule my update function for every 1/60 seconds instead then I don't see how I'd be able to simulate slowdown without constant descheduling and rescheduling update at different speeds on each frame from within the update method.

You can always write your own main loop...

As long as you call Window.dispatch_events() each frame, you should be able to manually call Window.clear() and Window.flip() as needed.

Peter B

unread,
Apr 10, 2013, 4:09:57 PM4/10/13
to pyglet...@googlegroups.com
Thanks, Tristram, I think I'll have to do that. 
Do you know of anyone who's done something similar with pyglet before (i.e. an application which uses its own custom event loop)? This will be the first application I write with pyglet and so I'm hoping to learn the idiomatic "pyglet" way to do a lot of these things without having to wade through the pyglet source to make sure I don't forget anything. 
Because I remember some pyglet documentation that mentioned the possibility of writing your own custom event loop, but warned against doing it unless you really know what you're doing. Having a reference to look at from someone who did know what they were doing would be very helpful.
Are there any other events I might need to manually dispatch, or any other methods i'd need to call each frame?

Adam Bark

unread,
Apr 10, 2013, 4:50:01 PM4/10/13
to pyglet...@googlegroups.com
Why don't you keep track of the time since you last moved your sprite and then only move/animate them when enough time has passed. Eg:

class MySprite(object):
    def update(dt):
        self.total_elapsed_time += dt
        if self.refresh_time + self.n_sprites_time < self.total_elapsed_time:
            self.move_and_animate()
            self.total_elapsed_time = 0

I hope that's clear.

Adam.

Peter B

unread,
Apr 10, 2013, 5:09:57 PM4/10/13
to pyglet...@googlegroups.com
Because I intend for runs through the game to be deterministic, recordable and replayable (by recording user input and feeding it back in).
I don't want to any game or drawing logic based on time. Certain events should happen every N frames, and watching for elapsed time allows things to slip through cracks (certain frames are "dropped" in a sense).

Adam Bark

unread,
Apr 10, 2013, 5:21:05 PM4/10/13
to pyglet...@googlegroups.com
It doesn't have to happen at a certain time it just happens whenever the next frame occurs after a set time has elapsed so nothing gets "dropped". It will do exactly the same as limiting the frame rate. Alternatively you could "schedule_once" your update function on each frame as long as you can determine how long it should be 'til the next frame.

Andre D

unread,
Apr 11, 2013, 11:17:07 AM4/11/13
to pyglet...@googlegroups.com
I do not understand why this is an issue, can you not schedule a tick for 1/LOGIC_TICKS_PER_SECOND which sets the current animation frame, then in the drawing code, just draw those currently selected frames?


--
You received this message because you are subscribed to the Google Groups "pyglet-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyglet-users...@googlegroups.com.

To post to this group, send email to pyglet...@googlegroups.com.

Andre D

unread,
Apr 11, 2013, 11:19:22 AM4/11/13
to pyglet...@googlegroups.com
That way you can draw at 10 or 100 fps even, but the logic still happens at the same rate.  Separating out the view and the logic layer is a good idea.
Reply all
Reply to author
Forward
0 new messages