1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use crate::Project;
#[derive(Clone, Default, Debug)]
pub struct Point(pub usize, pub usize);
impl From<(usize, usize)> for Point {
fn from(tup: (usize, usize)) -> Self {
Point(tup.0, tup.1)
}
}
pub fn grid_point_to_coord(point: Point, grid_width: usize) -> usize {
point.0 + point.1 * grid_width
}
pub fn grid_coord_to_point(coord: usize, grid_width: usize) -> Point {
let grid_y = coord / grid_width;
Point(coord - grid_y * grid_width, coord / grid_width)
}
pub fn tile_id_to_atlas_pixel(
tile_id: usize,
atlas_width: usize,
grid_width: usize,
padding: usize,
spacing: usize,
) -> Point {
let grid_x = tile_id - atlas_width * (tile_id / atlas_width);
let grid_y = tile_id / atlas_width;
Point(
padding + grid_x * (grid_width + spacing),
padding + grid_y * (grid_width + spacing),
)
}
#[derive(Clone, Debug)]
pub struct RenderCell {
pub is_empty: bool,
pub tile_id: usize,
pub atlas_pos: Point,
}
#[derive(Debug)]
pub struct RenderGrid {
pub tiles: Vec<RenderCell>,
pub tile_size: Point,
pub grid_size: Point,
}
impl RenderGrid {
pub fn new(num_cells: usize, tile_size: Point, grid_size: Point) -> Self {
RenderGrid {
tiles: vec![
RenderCell {
is_empty: true,
tile_id: 0,
atlas_pos: Point::default(),
};
num_cells
],
tile_size,
grid_size,
}
}
pub fn get_tile(&self, x: usize, y: usize) -> &RenderCell {
let coord_id = grid_point_to_coord((x, y).into(), self.grid_size.0);
&self.tiles[coord_id]
}
pub fn rows(&self) -> std::slice::Chunks<'_, RenderCell> {
self.tiles.chunks(self.grid_size.0)
}
}
pub trait ToRenderGrid {
fn to_merged_render_grid(&self, level: usize) -> Result<RenderGrid, anyhow::Error>;
}
impl ToRenderGrid for Project {
fn to_merged_render_grid(&self, level: usize) -> Result<RenderGrid, anyhow::Error> {
if self.levels.len() < level {
panic!("Level not found in the parsed map");
}
let level = &self.levels[level];
let first_layer = &level.layer_instances[0];
let cell_count = first_layer.grid_width * first_layer.grid_height;
let mut grid = RenderGrid::new(
cell_count,
Point(16, 16),
Point(first_layer.grid_width, first_layer.grid_height),
);
level.layer_instances.iter().rev().for_each(|layer| {
layer.auto_tiles.iter().for_each(|rule| {
rule.tiles.iter().for_each(|tile| {
grid.tiles[tile.coord_id].is_empty = false;
grid.tiles[tile.coord_id].tile_id = tile.tile_id;
grid.tiles[tile.coord_id].atlas_pos.0 = tile.tile_x;
grid.tiles[tile.coord_id].atlas_pos.1 = tile.tile_y;
})
});
layer.grid_tiles.iter().for_each(|tile| {
grid.tiles[tile.coord_id].is_empty = false;
grid.tiles[tile.coord_id].tile_id = tile.tile_id;
grid.tiles[tile.coord_id].atlas_pos.0 = tile.tile_x;
grid.tiles[tile.coord_id].atlas_pos.1 = tile.tile_x;
})
});
Ok(grid)
}
}