main.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #[macro_use] extern crate itertools;
  2. use ggez::{Context, ContextBuilder, GameResult};
  3. use ggez::event::{self, EventHandler};
  4. use ggez::graphics;
  5. use std::path::Path;
  6. #[allow(dead_code)]
  7. mod consts {
  8. pub const SPEED: u32 = 2;
  9. pub const TILE_SIZE: u32 = 24;
  10. pub const HALF_TILE: u32 = TILE_SIZE / 2;
  11. pub const QUARTER_TILE: u32 = TILE_SIZE / 4;
  12. pub const BOARD_WIDTH: usize = 16;
  13. pub const BOARD_HEIGHT: usize = 12;
  14. pub const SCALE: u32 = 3;
  15. pub const TILED_TRUE: tiled::PropertyValue =
  16. tiled::PropertyValue::BoolValue(true);
  17. }
  18. #[derive(Debug)]
  19. struct Board {
  20. tiles: Vec<Option<Tile>>,
  21. entities: Vec<Option<Tile>>,
  22. decoration: Vec<Option<Tile>>,
  23. }
  24. impl Board {
  25. fn from_file(path: &Path) -> Board {
  26. let tiled::Map {
  27. tilesets,
  28. layers,
  29. ..
  30. } = tiled::parse_file(path).unwrap();
  31. let read_layer = |idx: usize| {
  32. layers[idx].tiles.iter()
  33. .flat_map(|row| row)
  34. .map(|&n| if n > 0 {
  35. Some(Tile::from_tileset(n, &tilesets[0]))
  36. } else {
  37. None
  38. })
  39. .collect()
  40. };
  41. let tiles = read_layer(0);
  42. let entities = read_layer(1);
  43. let decoration = read_layer(2);
  44. Board {
  45. tiles,
  46. entities,
  47. decoration,
  48. }
  49. }
  50. fn draw() {
  51. }
  52. }
  53. #[derive(Debug, Clone)]
  54. struct Tile {
  55. action: Action,
  56. sprite: (u8, u8),
  57. pass: bool,
  58. }
  59. impl Tile {
  60. fn from_tileset(n: u32, tileset: &tiled::Tileset) -> Tile {
  61. let x = (n - 1) % 32;
  62. let y = (n - x - 1) / 32;
  63. let pass = tileset.tiles[n as usize].properties.get("pass").eq(
  64. &Some(&consts::TILED_TRUE));
  65. Tile {
  66. action: Action::NoAction,
  67. sprite: (x as u8, y as u8),
  68. pass: pass,
  69. }
  70. }
  71. fn draw(&self, (y, x): (usize, usize)) -> graphics::DrawParam {
  72. let (tx, ty) = self.sprite;
  73. graphics::DrawParam {
  74. src: graphics::Rect {
  75. x: (1.0 / 32.0) * tx as f32,
  76. y: (1.0 / 32.0) * ty as f32,
  77. w: 1.0 / 32.0,
  78. h: 1.0 / 32.0,
  79. },
  80. dest: ggez::nalgebra::Point2::new(
  81. x as f32 * 24.0, y as f32 * 24.0),
  82. ..Default::default()
  83. }
  84. }
  85. }
  86. #[derive(Debug, Clone)]
  87. enum Action {
  88. NoAction,
  89. }
  90. struct MyGame {
  91. board: Board,
  92. sprites: graphics::spritebatch::SpriteBatch,
  93. }
  94. impl EventHandler for MyGame {
  95. fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
  96. Ok(())
  97. }
  98. fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
  99. use ggez::graphics as g;
  100. use ggez::nalgebra as n;
  101. g::set_background_color(ctx, g::BLACK);
  102. g::clear(ctx);
  103. for layer in [ &self.board.tiles, &self.board.entities, &self.board.decoration ].iter() {
  104. for (pt, t) in iproduct!((0..consts::BOARD_HEIGHT),
  105. (0..consts::BOARD_WIDTH)).zip(
  106. layer.iter()) {
  107. if let Some(t) = t {
  108. self.sprites.add(t.draw(pt));
  109. }
  110. }
  111. }
  112. g::draw(ctx, &self.sprites, n::Point2::new(0.0, 0.0), 0.0)?;
  113. self.sprites.clear();
  114. g::present(ctx);
  115. Ok(())
  116. }
  117. }
  118. fn main() -> Result<(), ggez::error::GameError> {
  119. // Make a Context and an EventLoop.
  120. let board = Board::from_file(&Path::new("assets/main.tmx"));
  121. let mut ctx = ContextBuilder::new("game", "me")
  122. .add_resource_path({
  123. let base = std::env::var("CARGO_MANIFEST_DIR").unwrap();
  124. let mut path = std::path::PathBuf::from(base);
  125. path.push("assets");
  126. path
  127. })
  128. .build()?;
  129. let image = graphics::Image::new(&mut ctx, "/spritesheet.png")?;
  130. let sprites = graphics::spritebatch::SpriteBatch::new(image);
  131. let mut my_game = MyGame {
  132. board,
  133. sprites,
  134. };
  135. event::run(&mut ctx, &mut my_game)
  136. }