terrain.rs 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. use std::collections::HashMap;
  2. use ggez::{GameError, GameResult};
  3. use tiled::{Image as TiledImage, Layer, PropertyValue, Tileset};
  4. pub enum TerrainTileId {
  5. ShortGrass,
  6. MiddleGrass,
  7. HighGrass,
  8. Dirt,
  9. Mud,
  10. Concrete,
  11. BrickWall,
  12. }
  13. pub struct TerrainTile {
  14. pub id: TerrainTileId,
  15. pub tile_width: u32,
  16. pub tile_height: u32,
  17. pub relative_tile_width: f32,
  18. pub relative_tile_height: f32,
  19. pub tile_x: u32,
  20. pub tile_y: u32,
  21. pub opacity: f32,
  22. }
  23. impl TerrainTile {
  24. pub fn from_str_id(
  25. id: &str,
  26. tile_width: u32,
  27. tile_height: u32,
  28. relative_tile_width: f32,
  29. relative_tile_height: f32,
  30. tile_x: u32,
  31. tile_y: u32,
  32. ) -> Self {
  33. match id {
  34. "ShortGrass" => Self {
  35. id: TerrainTileId::ShortGrass,
  36. opacity: 0.0,
  37. tile_width,
  38. tile_height,
  39. relative_tile_width,
  40. relative_tile_height,
  41. tile_x,
  42. tile_y,
  43. },
  44. "MiddleGrass" => Self {
  45. id: TerrainTileId::MiddleGrass,
  46. opacity: 0.1,
  47. tile_width,
  48. tile_height,
  49. relative_tile_width,
  50. relative_tile_height,
  51. tile_x,
  52. tile_y,
  53. },
  54. "HighGrass" => Self {
  55. id: TerrainTileId::HighGrass,
  56. opacity: 0.2,
  57. tile_width,
  58. tile_height,
  59. relative_tile_width,
  60. relative_tile_height,
  61. tile_x,
  62. tile_y,
  63. },
  64. "Dirt" => Self {
  65. id: TerrainTileId::Dirt,
  66. opacity: 0.0,
  67. tile_width,
  68. tile_height,
  69. relative_tile_width,
  70. relative_tile_height,
  71. tile_x,
  72. tile_y,
  73. },
  74. "Mud" => Self {
  75. id: TerrainTileId::Mud,
  76. opacity: 0.1,
  77. tile_width,
  78. tile_height,
  79. relative_tile_width,
  80. relative_tile_height,
  81. tile_x,
  82. tile_y,
  83. },
  84. "Concrete" => Self {
  85. id: TerrainTileId::Concrete,
  86. opacity: 0.0,
  87. tile_width,
  88. tile_height,
  89. relative_tile_width,
  90. relative_tile_height,
  91. tile_x,
  92. tile_y,
  93. },
  94. "BrickWall" => Self {
  95. id: TerrainTileId::BrickWall,
  96. opacity: 1.0,
  97. tile_width,
  98. tile_height,
  99. relative_tile_width,
  100. relative_tile_height,
  101. tile_x,
  102. tile_y,
  103. },
  104. &_ => {
  105. // FIXME BS NOW: manage errors
  106. panic!("Unknown tile id {}", id)
  107. }
  108. }
  109. }
  110. }
  111. pub struct Terrain {
  112. pub tileset: Tileset,
  113. pub layer: Layer,
  114. pub image: TiledImage,
  115. // FIXME (u32, u32) -> GridPoint
  116. pub tiles: HashMap<(u32, u32), TerrainTile>,
  117. }
  118. impl Terrain {
  119. pub fn new(
  120. tileset: Tileset,
  121. layer: Layer,
  122. image: TiledImage,
  123. tiles: HashMap<(u32, u32), TerrainTile>,
  124. ) -> Self {
  125. Self {
  126. tileset,
  127. layer,
  128. image,
  129. tiles,
  130. }
  131. }
  132. }
  133. pub fn get_tile_from_terrain_tileset_with_id(
  134. terrain_tileset: &Tileset,
  135. id: u32,
  136. terrain_image_width: u32,
  137. terrain_image_height: u32,
  138. ) -> GameResult<TerrainTile> {
  139. for tile in terrain_tileset.tiles.iter() {
  140. if tile.id == id - terrain_tileset.first_gid {
  141. let str_id = match tile.properties.get("ID") {
  142. None => {
  143. return GameResult::Err(GameError::ResourceLoadError(format!(
  144. "Tile {} have no ID property",
  145. id
  146. )))
  147. }
  148. Some(property_value) => match property_value {
  149. PropertyValue::StringValue(str_id) => str_id.clone(),
  150. _ => {
  151. return GameResult::Err(GameError::ResourceLoadError(format!(
  152. "Tile {} must have String ID property value",
  153. id
  154. )))
  155. }
  156. },
  157. };
  158. let tile_width = terrain_tileset.tile_width;
  159. let tile_height = terrain_tileset.tile_height;
  160. let relative_tile_width = tile_width as f32 / terrain_image_width as f32;
  161. let relative_tile_height = tile_height as f32 / terrain_image_height as f32;
  162. let len_by_width = terrain_image_width / tile_width;
  163. let tile_y = tile.id / len_by_width;
  164. let tile_x = tile.id - (tile_y * len_by_width);
  165. return GameResult::Ok(TerrainTile::from_str_id(
  166. &str_id,
  167. tile_width,
  168. tile_height,
  169. relative_tile_width,
  170. relative_tile_height,
  171. tile_x,
  172. tile_y,
  173. ));
  174. }
  175. }
  176. return GameResult::Err(GameError::ResourceLoadError(format!(
  177. "No tile with {} found",
  178. id
  179. )));
  180. }