import pygame from physics.TickData import TickData from sprite.BoundingBox import BoundingBox from sprite.PositionScale import PositionScale from sprite.Spritesheet import Spritesheet from ui_elements.KeyManager import KeyManager from ui_elements.UiElement import UiElement class Sprite(UiElement): def __init__(self, spritesheet: Spritesheet): super().__init__() self.spritesheet = spritesheet self.animation_state = list(self.spritesheet.animations.keys())[0] self.animation_frame = 0 self.animation_delay = 0 self.animated = True self.image = None self.is_collider = True def tick(self, tick_data: TickData): animation = self.spritesheet.animations[self.animation_state] if self.animated: self.animation_delay += tick_data.dt while self.animation_delay >= animation['delays'][self.animation_frame % len(animation['delays'])]: self.animation_delay -= animation['delays'][self.animation_frame % len(animation['delays'])] self.animation_frame = (self.animation_frame + 1) % len(animation['images']) self.image = animation['images'][self.animation_frame % len(animation['images'])] def set_animation_state(self, state: str): if state in self.spritesheet.animations: self.animation_state = state self.animation_delay = 0 self.tick(self.empty_tick_data()) def set_animation_frame(self, frame: int): self.animation_frame = frame self.tick(self.empty_tick_data()) def empty_tick_data(self) -> TickData: return TickData(0, [], KeyManager(), [], PositionScale()) def render_sprite_image(self) -> pygame.Surface: return self.image def get_bounding_box(self) -> BoundingBox: return BoundingBox( self.position_scale.position[0], self.position_scale.position[1], self.image.get_width() * self.position_scale.scale[0], self.image.get_height() * self.position_scale.scale[1] ) def dump(self, file): # re-attach all the images to a single surface and save it to a file width = 0 height = 0 for animation in self.spritesheet.animations.values(): max_height = 0 total_width = 0 for image in animation['images']: total_width += image.get_width() max_height = max(max_height, image.get_height()) width = max(width, total_width) height += max_height sheet = pygame.Surface((width, height)) x = 0 y = 0 for animation in self.spritesheet.animations.values(): max_height = 0 for image in animation['images']: sheet.blit(image, (x, y)) x += image.get_width() max_height = max(max_height, image.get_height()) y += max_height x = 0 pygame.image.save(sheet, file)