sep-pm-platformer/project/sprite/Sprite.py

86 lines
2.8 KiB
Python
Raw Normal View History

2023-03-24 17:41:48 +01:00
import pygame
from physics.TickData import TickData
2023-03-25 15:41:32 +01:00
from sprite.BoundingBox import BoundingBox
from sprite.PositionScale import PositionScale
from sprite.Spritesheet import Spritesheet
2023-03-26 09:51:11 +02:00
from ui_elements.UiElement import UiElement
2023-03-25 15:41:32 +01:00
2023-03-24 17:41:48 +01:00
2023-03-26 09:51:11 +02:00
class Sprite(UiElement):
2023-03-25 15:41:32 +01:00
def __init__(self, spritesheet: Spritesheet):
2023-03-26 09:51:11 +02:00
super().__init__()
2023-03-24 17:41:48 +01:00
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
2023-03-25 15:41:32 +01:00
self.is_collider = True
def tick(self, tick_data: TickData):
2023-03-24 17:41:48 +01:00
animation = self.spritesheet.animations[self.animation_state]
if self.animated:
self.animation_delay += tick_data.dt
2023-03-24 17:41:48 +01:00
2023-03-25 15:41:32 +01:00
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'])
2023-03-24 17:41:48 +01:00
2023-03-25 15:41:32 +01:00
self.image = animation['images'][self.animation_frame % len(animation['images'])]
2023-03-24 17:41:48 +01:00
2023-03-25 15:41:32 +01:00
def set_animation_state(self, state: str):
2023-03-24 17:41:48 +01:00
if state in self.spritesheet.animations:
self.animation_state = state
self.animation_delay = 0
self.tick(TickData(0, [], [], [], PositionScale()))
2023-03-24 17:41:48 +01:00
2023-03-25 15:41:32 +01:00
def set_animation_frame(self, frame: int):
2023-03-24 17:41:48 +01:00
self.animation_frame = frame
self.tick(TickData(0, [], [], [], PositionScale()))
2023-03-24 17:41:48 +01:00
2023-03-26 09:51:11 +02:00
def render_sprite_image(self) -> pygame.Surface:
return self.image
2023-03-24 17:41:48 +01:00
2023-03-25 15:41:32 +01:00
def get_bounding_box(self) -> BoundingBox:
return BoundingBox(
self.position_scale.position[0],
self.position_scale.position[1],
2023-03-25 17:18:43 +01:00
self.image.get_width() * self.position_scale.scale[0],
self.image.get_height() * self.position_scale.scale[1]
2023-03-25 15:41:32 +01:00
)
2023-03-24 17:41:48 +01:00
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
2023-03-25 15:41:32 +01:00
for image in animation['images']:
2023-03-24 17:41:48 +01:00
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
2023-03-25 15:41:32 +01:00
for image in animation['images']:
2023-03-24 17:41:48 +01:00
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)