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}