bracket_terminal/consoles/text/
multi_tile_sprite.rs1use crate::prelude::{string_to_cp437, BTerm, DrawBatch, FontCharType, Tile, XpFile};
2use bracket_color::prelude::{ColorPair, RGBA};
3use bracket_geometry::prelude::Point;
4
5pub struct MultiTileSprite {
7 content: Vec<Tile>,
8 dimensions: Point,
9}
10
11impl MultiTileSprite {
12 pub fn from_string<S: ToString, T>(content: S, width: T, height: T) -> Self
14 where
15 T: Into<i32>,
16 {
17 let w: i32 = width.into();
18 let h: i32 = height.into();
19 let content_s = content.to_string();
20
21 let bytes = string_to_cp437(content_s);
22 let tiles = bytes
23 .into_iter()
24 .map(|glyph| Tile {
25 glyph,
26 fg: RGBA::from_f32(1.0, 1.0, 1.0, 1.0),
27 bg: RGBA::from_f32(0.0, 0.0, 0.0, 1.0),
28 })
29 .collect();
30
31 Self {
32 content: tiles,
33 dimensions: Point::new(w, h),
34 }
35 }
36
37 pub fn from_string_colored<S: ToString, T>(
39 content: S,
40 width: T,
41 height: T,
42 fg: &[RGBA],
43 bg: &[RGBA],
44 ) -> Self
45 where
46 T: Into<i32>,
47 {
48 let w: i32 = width.into();
49 let h: i32 = height.into();
50 let content_s = content.to_string();
51
52 let bytes = string_to_cp437(content_s);
53 let tiles = bytes
54 .into_iter()
55 .enumerate()
56 .map(|(i, glyph)| Tile {
57 glyph,
58 fg: fg[i],
59 bg: bg[i],
60 })
61 .collect();
62
63 Self {
64 content: tiles,
65 dimensions: Point::new(w, h),
66 }
67 }
68
69 pub fn from_xp(rex: &XpFile) -> Self {
71 let dimensions = Point::new(rex.layers[0].width, rex.layers[0].height);
72 let mut tiles: Vec<Tile> = vec![
73 Tile {
74 glyph: 0,
75 fg: RGBA::from_f32(1.0, 1.0, 1.0, 1.0),
76 bg: RGBA::from_f32(0.0, 0.0, 0.0, 1.0)
77 };
78 (dimensions.x * dimensions.y) as usize
79 ];
80
81 for layer in &rex.layers {
82 for y in 0..layer.height {
83 for x in 0..layer.width {
84 let cell = layer.get(x, y).unwrap();
85 if !cell.bg.is_transparent() {
86 let idx = (y * (dimensions.x as usize)) + (x as usize);
87 tiles[idx].glyph = cell.ch as FontCharType;
88 tiles[idx].fg = cell.fg.into();
89 tiles[idx].bg = cell.bg.into();
90 }
91 }
92 }
93 }
94
95 Self {
96 content: tiles,
97 dimensions,
98 }
99 }
100
101 pub fn render(&self, context: &mut BTerm, position: Point) {
103 let mut x = 0;
104 let mut y = 0;
105 for tile in self.content.iter() {
106 x += 1;
107 context.set(x + position.x, y + position.y, tile.fg, tile.bg, tile.glyph);
108 if x >= self.dimensions.x {
109 x = 0;
110 y += 1;
111 }
112 }
113 }
114
115 pub fn add_to_batch(&self, batch: &mut DrawBatch, position: Point) {
117 let mut pos = Point::zero();
118 for tile in self.content.iter() {
119 pos.x += 1;
120 batch.set(pos + position, ColorPair::new(tile.fg, tile.bg), tile.glyph);
121 if pos.x >= self.dimensions.x {
122 pos.x = 0;
123 pos.y += 1;
124 }
125 }
126 }
127}