最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - The reverse animation system isn't working - Stack Overflow

programmeradmin5浏览0评论

So, I've been working on this animation player kinda thing lately to make it reusable in future projects. After i attempted to implement the reverse feature, it just didn't work properly, i start from the last frame of the spritesheet, keeps going, reaches the first frame and boom suddenly it works for the rest of the time the project is run. Here is my code (if you have any questions about how it functions feel free to ask):

class Spritesheet:
    def __init__(self, filename, pos, scale, frame_h, frame_v, current_frame: Vector2):
        self.filename = filename
        self.pos = pos
        self.scale = scale
        self.frame = current_frame
        self.frame_h = frame_h
        self.frame_v = frame_v
        self.image = load_image(self.filename)
        self.texture = load_texture_from_image(self.image)
        self.rect = Rectangle(self.frame.x * self.image.width / self.frame_h, self.frame.y * self.image.height / self.frame_v, 
                              self.texture.width / self.frame_h, self.texture.height / self.frame_v)

    def draw(self):
        draw_texture_pro(
            self.texture, self.rect, 
            Rectangle(self.pos.x, self.pos.y, self.rect.width * self.scale, self.rect.height * self.scale), 
            Vector2(0, 0), 0, WHITE
        )
            
        
class Animation:
    def __init__(self, spritesheet, start_frame, end_frame, loop, 
                 vertical_anim: bool=False, speed: float = 10, 
                 reverse: bool = False):
        
        # Variables
        self.spritesheet = spritesheet
        self.start_frame = start_frame
        self.end_frame = end_frame
        self.loop = loop
        self.speed = speed
        self.reverse = reverse
        self.vertical_anim = vertical_anim
        
        
        self.frame_attr = 'y' if self.vertical_anim else 'x'
        self.initial_frame = self.end_frame if self.reverse else self.start_frame
        setattr(self.spritesheet.frame, self.frame_attr, self.initial_frame)
        
        self.current_frame = getattr(self.spritesheet.frame, self.frame_attr)

        self.frame_counter = 0

    def update(self):
        self.animate()
        
        self.current_frame = getattr(self.spritesheet.frame, self.frame_attr)
        print(self.initial_frame)
        
        self.spritesheet.rect.x = self.spritesheet.frame.x * (self.spritesheet.image.width / self.spritesheet.frame_h)
        self.spritesheet.rect.y = self.spritesheet.frame.y * (self.spritesheet.image.height / self.spritesheet.frame_v)
        
    def animate(self):
        if self.frame_counter >= (framerate / self.speed):
            step = -1 if self.reverse else 1
            new_frame = self.current_frame + step
            setattr(self.spritesheet.frame, self.frame_attr, new_frame)

            if self.is_finished():
                if self.loop:
                    # Reset to the correct loop start
                    new_frame = self.end_frame if self.reverse else self.start_frame
                    setattr(self.spritesheet.frame, self.frame_attr, new_frame)
                else:
                    # Ensure it stops at the correct frame
                    new_frame = self.start_frame if self.reverse else self.end_frame
                    setattr(self.spritesheet.frame, self.frame_attr, new_frame)

            self.current_frame = new_frame
            self.frame_counter = 0  # Reset counter

        self.frame_counter += 1





    def set_speed(self, new_speed):
        self.speed = new_speed

    def reset(self):
        setattr(self.spritesheet.frame, self.frame_attr, self.start_frame)
        self.frame_counter = 0

    def is_finished(self):
        if self.reverse:
            return self.current_frame <= self.start_frame  # Stop at start when reversing
        return self.current_frame >= self.end_frame 

    def draw(self):
        self.spritesheet.draw()

    def run(self):
        self.update()
        self.draw()

class AnimationPlayer:
    def __init__(self, animation_dict, default_animation):
        self.animation_dict = animation_dict
        self.current_animation = self.animation_dict[default_animation]

    def play(self, animation_name):
        if animation_name in self.animation_dict:
            self.current_animation = self.animation_dict[animation_name]
            self.current_animation.reset()  # Reset animation when switching

    def run(self):
        self.current_animation.update()  # Update animation frames
        self.current_animation.draw()    # Draw the updated frame

Here is the settings.py:

from pyray import *
from raylib import *
import math, os, sys, json

screen_width = 1280
screen_height = 720
framerate = 60

# Useful methods
def clamp(value, min_value, max_value):
    return max(min_value, min(value, max_value))

def lerp(start, end, t):
    return start + (end - start) * clamp(t, 0, 1)

def is_empty(obj):
    return isinstance(obj, (list, tuple, dict, set)) and len(obj) == 0

# Timer 
class Timer:
    def __init__(self, duration: int, repeat = False, autostart = False, func = None):
        self.duration = duration
        self.start_time = 0
        self.active = False
        self.repeat = repeat
        self.func = func
        
        if autostart:
            self.activate()

    def activate(self):
        self.active = True
        self.start_time = get_time()

    def deactivate(self):
        self.active = False
        self.start_time = 0
        if self.repeat:
            self.activate()

    def update(self):
        if self.active:
            if get_time() - self.start_time >= self.duration:
                if self.func and self.start_time: self.func()
                self.deactivate()

I've tried to set the start_frame to the end_frame and vice versa with this piece of code: self.start_frame, self.end_frame = self.end_frame, self.start_frame

But it just didn't work

发布评论

评论列表(0)

  1. 暂无评论