main.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. extern crate rltk;
  2. use rltk::{Console, GameState, Rltk, RGB, Point};
  3. extern crate specs;
  4. use specs::prelude::*;
  5. #[macro_use]
  6. extern crate specs_derive;
  7. mod components;
  8. pub use components::*;
  9. mod map;
  10. pub use map::*;
  11. mod player;
  12. use player::*;
  13. mod rect;
  14. pub use rect::Rect;
  15. mod visibility_system;
  16. use visibility_system::VisibilitySystem;
  17. mod monster_ai_system;
  18. use monster_ai_system::MonsterAI;
  19. rltk::add_wasm_support!();
  20. #[derive(PartialEq, Copy, Clone)]
  21. pub enum RunState { Paused, Running }
  22. pub struct State {
  23. pub ecs: World,
  24. pub runstate : RunState
  25. }
  26. impl State {
  27. fn run_systems(&mut self) {
  28. let mut vis = VisibilitySystem{};
  29. vis.run_now(&self.ecs);
  30. let mut mob = MonsterAI{};
  31. mob.run_now(&self.ecs);
  32. self.ecs.maintain();
  33. }
  34. }
  35. impl GameState for State {
  36. fn tick(&mut self, ctx : &mut Rltk) {
  37. ctx.cls();
  38. if self.runstate == RunState::Running {
  39. self.run_systems();
  40. self.runstate = RunState::Paused;
  41. } else {
  42. self.runstate = player_input(self, ctx);
  43. }
  44. draw_map(&self.ecs, ctx);
  45. let positions = self.ecs.read_storage::<Position>();
  46. let renderables = self.ecs.read_storage::<Renderable>();
  47. let map = self.ecs.fetch::<Map>();
  48. for (pos, render) in (&positions, &renderables).join() {
  49. let idx = map.xy_idx(pos.x, pos.y);
  50. if map.visible_tiles[idx] { ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph) }
  51. }
  52. }
  53. }
  54. fn main() {
  55. let context = Rltk::init_simple8x8(80, 50, "Hello Rust World", "resources");
  56. let mut gs = State {
  57. ecs: World::new(),
  58. runstate : RunState::Running
  59. };
  60. gs.ecs.register::<Position>();
  61. gs.ecs.register::<Renderable>();
  62. gs.ecs.register::<Player>();
  63. gs.ecs.register::<Viewshed>();
  64. gs.ecs.register::<Monster>();
  65. gs.ecs.register::<Name>();
  66. let map : Map = Map::new_map_rooms_and_corridors();
  67. let (player_x, player_y) = map.rooms[0].center();
  68. gs.ecs
  69. .create_entity()
  70. .with(Position { x: player_x, y: player_y })
  71. .with(Renderable {
  72. glyph: rltk::to_cp437('@'),
  73. fg: RGB::named(rltk::YELLOW),
  74. bg: RGB::named(rltk::BLACK),
  75. })
  76. .with(Player{})
  77. .with(Viewshed{ visible_tiles : Vec::new(), range: 8, dirty: true })
  78. .with(Name{name: "Player".to_string() })
  79. .build();
  80. let mut rng = rltk::RandomNumberGenerator::new();
  81. for (i,room) in map.rooms.iter().skip(1).enumerate() {
  82. let (x,y) = room.center();
  83. let glyph : u8;
  84. let name : String;
  85. let roll = rng.roll_dice(1, 2);
  86. match roll {
  87. 1 => { glyph = rltk::to_cp437('g'); name = "Goblin".to_string(); }
  88. _ => { glyph = rltk::to_cp437('o'); name = "Orc".to_string(); }
  89. }
  90. gs.ecs.create_entity()
  91. .with(Position{ x, y })
  92. .with(Renderable{
  93. glyph,
  94. fg: RGB::named(rltk::RED),
  95. bg: RGB::named(rltk::BLACK),
  96. })
  97. .with(Viewshed{ visible_tiles : Vec::new(), range: 8, dirty: true })
  98. .with(Monster{})
  99. .with(Name{ name: format!("{} #{}", &name, i) })
  100. .build();
  101. }
  102. gs.ecs.insert(map);
  103. gs.ecs.insert(Point::new(player_x, player_y));
  104. rltk::main_loop(context, gs);
  105. }