spritesheet_generator/
spritesheet.rs

1use std::collections::{BTreeMap, HashMap};
2use serde::{Serialize, Serializer};
3
4use texture_packer;
5
6#[derive(Serialize, Deserialize, Clone, Debug)]
7pub struct Screen {
8    pub x: f32,
9    pub y: f32,
10    pub w: f32,
11    pub h: f32,
12}
13
14#[derive(Serialize, Deserialize, Clone, Debug)]
15pub struct Frame {
16    pub x: u32,
17    pub y: u32,
18    pub w: u32,
19    pub h: u32,
20    pub screen: Screen,
21}
22
23#[derive(Serialize, Deserialize, Clone, Debug)]
24pub struct Spritesheet {
25    #[serde(serialize_with = "ordered_map")]
26    pub frames: HashMap<String, Frame>,
27}
28
29fn ordered_map<S>(value: &HashMap<String, Frame>, serializer: S) -> Result<S::Ok, S::Error>
30where
31S: Serializer,
32{
33    let ordered: BTreeMap<_, _> = value.iter().collect();
34    ordered.serialize(serializer)
35}
36
37pub fn to_atlas(
38    frames: &HashMap<String, texture_packer::Frame>,
39    image_width: u32,
40    image_height: u32,
41) -> Spritesheet {
42    let frames_map = frames
43        .iter()
44        .map(|(name, frame)| (
45                name.clone(),
46                Frame {
47                    x: frame.frame.x,
48                    y: frame.frame.y,
49                    w: frame.frame.w,
50                    h: frame.frame.h,
51                    screen: Screen {
52                        x: 1. / (image_width as f32 / frame.frame.x as f32),
53                        y: 1. / (image_height as f32 / frame.frame.y as f32),
54                        w: 1. / (image_width as f32 / frame.frame.w as f32),
55                        h: 1. / (image_height as f32 / frame.frame.h as f32),
56                    }
57                }
58            )
59        )
60        .collect();
61
62    return Spritesheet { frames: frames_map };
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn should_convert_to_atlas() {
71        let mut converted_frames: HashMap<String, texture_packer::Frame> = HashMap::new();
72        converted_frames.insert(
73            "test1".to_string(),
74            texture_packer::Frame {
75                key: "test1".to_string(),
76                frame: texture_packer::Rect{ x: 0, y: 0, w: 10, h: 50},
77                source: texture_packer::Rect{ x: 0, y: 0, w: 10, h: 50},
78                rotated: false,
79                trimmed: false,
80            }
81        );
82        let atlas = to_atlas(&converted_frames, 100, 100);
83
84        let mut created_frames: HashMap<String, Frame> = HashMap::new();
85        created_frames.insert(
86            "test1".to_string(),
87            Frame {
88                x: 0, y: 0, w: 10, h: 50, screen: Screen { x: 0., y: 0., w: 0.1, h: 0.5 }
89            }
90        );
91        created_frames.insert(
92            "test2".to_string(),
93            Frame {
94                x: 1, y: 1, w: 1, h: 1, screen: Screen { x: 0., y: 0., w: 0., h: 0. }
95            }
96        );
97
98        let converted = atlas.frames.get("test1").unwrap();
99        let created = created_frames.get("test1").unwrap();
100
101        assert_eq!(converted.x, created.x);
102        assert_eq!(converted.y, created.y);
103        assert_eq!(converted.w, created.w);
104        assert_eq!(converted.h, created.h);
105        assert_eq!(converted.screen.x, created.screen.x);
106        assert_eq!(converted.screen.y, created.screen.y);
107        assert_eq!(converted.screen.w, created.screen.w);
108        assert_eq!(converted.screen.h, created.screen.h);
109    }
110}