tiled_json_rs/
utils.rs

1use crate::{layer::Layer, map::Map, TileLayer, TileRect, TileSet, Vec2};
2use std::fs::File;
3use std::io::Error;
4use std::path::Path;
5
6impl Map {
7    pub fn load_from_file(path: &Path) -> Result<Self, Error> {
8        let file = File::open(path)?;
9        let set = serde_json::from_reader(file)?;
10        Ok(set)
11    }
12
13    pub fn load_from_str(s: &str) -> Result<Layer, Error> {
14        let set = serde_json::from_str(s)?;
15        Ok(set)
16    }
17
18    /// Returns the image path for the image the tile is using
19    pub fn tileset_image_path(&self, tile_gid: u32) -> Option<&Path> {
20        for set in &self.tile_sets {
21            if tile_gid >= set.first_gid
22                && tile_gid < set.tile_count + set.first_gid
23            {
24                return Some(set.image.as_path());
25            }
26        }
27        None
28    }
29
30    /// Return the name of the tileset the tile is from
31    pub fn tileset_name(&self, tile_gid: u32) -> Option<&str> {
32        for set in &self.tile_sets {
33            if tile_gid >= set.first_gid
34                && tile_gid < set.tile_count + set.first_gid
35            {
36                return Some(&set.name);
37            }
38        }
39        None
40    }
41
42    /// Returns the position and dimensions of the tile GID on its associated image.
43    /// Used for drawing tiles, eg; using SDL2 to blit this tile from an image surface.
44    pub fn tile_position_on_image(&self, mut tile_gid: u32) -> TileRect {
45        let mut tileset = &self.tile_sets[0];
46        for set in &self.tile_sets {
47            if tile_gid >= set.first_gid
48                && tile_gid < set.tile_count + set.first_gid
49            {
50                tileset = set;
51                tile_gid -= set.first_gid;
52                break;
53            }
54        }
55        tileset.tile_position_on_image(tile_gid)
56    }
57
58    /// Returns the tile position in pixels on the current map
59    pub fn tile_position_on_map(&self, count: u32, tile_gid: u32) -> Vec2<u32> {
60        let mut tileset = &self.tile_sets[0];
61        for set in &self.tile_sets {
62            if tile_gid >= set.first_gid
63                && tile_gid < set.tile_count + set.first_gid
64            {
65                tileset = set;
66                break;
67            }
68        }
69        let x = count % self.width * tileset.tile_width;
70        let y = count / self.width * tileset.tile_width;
71        Vec2 { x, y }
72    }
73}
74
75impl TileSet {
76    /// Returns the tile position and extents for it's location
77    /// on the source image. Useful for creating textures/blits.
78    pub fn tile_position_on_image(&self, local_id: u32) -> TileRect {
79        let min_x = local_id % self.columns * self.tile_width;
80        let min_y = local_id / self.columns * self.tile_width;
81        TileRect {
82            x: min_x as i32,
83            y: min_y as i32,
84            width: self.tile_width,
85            height: self.tile_height,
86        }
87    }
88}
89
90impl TileLayer {
91    /// Returns the tiles position in tile column/row. To get a pixel dimension
92    /// multiply this by the tile dimensions
93    pub fn tile_position_on_layer(&self, count: u32) -> Vec2<u32> {
94        let x = count % self.width;
95        let y = count / self.width;
96        Vec2 { x, y }
97    }
98}