pyglet / pyglet

pyglet is a cross-platform windowing and multimedia library for Python, for developing games and other visually rich applications.
http://pyglet.org
BSD 3-Clause "New" or "Revised" License
1.9k stars 308 forks source link

Paused animated sprites do not display correct frame when changed with frame_index #906

Open Andrea-Oliveri opened 1 year ago

Andrea-Oliveri commented 1 year ago

Good Morning,

Issue: I have spotted undesirable behaviour of the Sprite class when using animations and pausing the animation. In my use case, I sometimes want to take the animated sprite and freeze it on a particular frame.

My attempt at doing so was:

sprite.paused = True
sprite.frame_index = DESIRED_FRAME_IDX

This piece of code freezes the animation indeed, but freezes it at the current frame. Despite changing sprite.frame_index, the texture which is then drawn on screen is that of the last frame before it was paused.

By reading the source code I have noticed this is due to Sprite._set_texture not getting called in the frame_index setter, and instead relying on the next _animate to make the change (except that this was unscheduled by the pause).

Proposed change:

@frame_index.setter
def frame_index(self, index):
    # Bound to available number of frames
    if self._animation is None:
        return
    self._frame_index = max(0, min(index, len(self._animation.frames)-1))

    # This is code adapted from _animate.    
    frame = self._animation.frames[self._frame_index]
    self._set_texture(frame.image.get_texture())

    if frame.duration is not None:
        self._next_dt = frame.duration

System Information: I am running the following on Windows, but this issue generalizes to any system as well as the latest commit on Github:

# Name                    Version                   Build  Channel
pyglet                    2.0.8                    pypi_0    pypi

Thank you for this great library. I remain at your disposal for further clarifications.

kingadami commented 4 months ago

Created a pull request to fix this issue.