ryot_core/content/sprite/sprite_sheet.rs
1use crate::prelude::SpriteLayout;
2use glam::UVec2;
3use serde::{Deserialize, Serialize};
4
5/// This is the content of the Sprite Content. It contains the information needed
6/// to load the sprite sheet and individual sprites from it.
7/// A sprite sheet is defined by:
8/// - a sprite file (that can be compressed or not)
9/// - a sprite layout (1:1, 1:2, 2:1 or 2:2)
10/// - the ids of first and last sprites in the sheet, to determine which sprites are in the sheet
11#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
12pub struct SpriteSheet {
13 pub file: String,
14 #[serde(rename = "spritetype")]
15 pub layout: SpriteLayout,
16 #[serde(rename = "firstspriteid")]
17 pub first_sprite_id: u32,
18 #[serde(rename = "lastspriteid")]
19 pub last_sprite_id: u32,
20 pub area: u32,
21}
22
23impl SpriteSheet {
24 /// Checks if the sprite sheet contains the given sprite id
25 pub fn has_sprite(&self, sprite_id: u32) -> bool {
26 self.first_sprite_id <= sprite_id && self.last_sprite_id >= sprite_id
27 }
28
29 /// Returns the index of a given sprite id in the sprite sheet.
30 /// The index is the position of the sprite in the sprite sheet, starting from 0.
31 /// The index is used to calculate the position of the sprite in the sprite sheet.
32 /// If the sprite id is not in the sprite sheet, None is returned.
33 pub fn get_sprite_index(&self, sprite_id: u32) -> Option<usize> {
34 if self.has_sprite(sprite_id) {
35 Some((sprite_id - self.first_sprite_id) as usize)
36 } else {
37 None
38 }
39 }
40
41 /// Returns the size of a sprite in the sprite sheet.
42 /// The size is calculated based on the sprite layout and the sprite sheet config.
43 pub fn get_tile_size(&self, tile_size: &UVec2) -> UVec2 {
44 let width = self.layout.get_width(tile_size);
45 let height = self.layout.get_height(tile_size);
46 UVec2::new(width, height)
47 }
48}