main.rs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. #[derive(PartialEq, Copy, Clone)]
  20. pub enum RunState { Paused, Running }
  21. pub struct State {
  22. pub ecs: World,
  23. pub systems: Dispatcher<'static, 'static>,
  24. pub runstate : RunState
  25. }
  26. impl GameState for State {
  27. fn tick(&mut self, ctx : &mut Rltk) {
  28. ctx.cls();
  29. if self.runstate == RunState::Running {
  30. self.systems.dispatch(&self.ecs);
  31. self.runstate = RunState::Paused;
  32. } else {
  33. self.runstate = player_input(self, ctx);
  34. }
  35. draw_map(&self.ecs, ctx);
  36. let positions = self.ecs.read_storage::<Position>();
  37. let renderables = self.ecs.read_storage::<Renderable>();
  38. let map = self.ecs.fetch::<Map>();
  39. for (pos, render) in (&positions, &renderables).join() {
  40. let idx = map.xy_idx(pos.x, pos.y);
  41. if map.visible_tiles[idx] { ctx.set(pos.x, pos.y, render.fg, render.bg, render.glyph) }
  42. }
  43. }
  44. }
  45. fn main() {
  46. let context = Rltk::init_simple8x8(80, 50, "Hello Rust World", "../resources");
  47. let mut gs = State {
  48. ecs: World::new(),
  49. systems : DispatcherBuilder::new()
  50. .with(VisibilitySystem{}, "visibility_system", &[])
  51. .with(MonsterAI{}, "monster_ai", &["visibility_system"])
  52. .build(),
  53. runstate : RunState::Running
  54. };
  55. gs.ecs.register::<Position>();
  56. gs.ecs.register::<Renderable>();
  57. gs.ecs.register::<Player>();
  58. gs.ecs.register::<Viewshed>();
  59. gs.ecs.register::<Monster>();
  60. gs.ecs.register::<Name>();
  61. let map : Map = Map::new_map_rooms_and_corridors();
  62. let (player_x, player_y) = map.rooms[0].center();
  63. gs.ecs
  64. .create_entity()
  65. .with(Position { x: player_x, y: player_y })
  66. .with(Renderable {
  67. glyph: rltk::to_cp437('@'),
  68. fg: RGB::named(rltk::YELLOW),
  69. bg: RGB::named(rltk::BLACK),
  70. })
  71. .with(Player{})
  72. .with(Viewshed{ visible_tiles : Vec::new(), range: 8, dirty: true })
  73. .with(Name{name: "Player".to_string() })
  74. .build();
  75. let mut rng = rltk::RandomNumberGenerator::new();
  76. for (i,room) in map.rooms.iter().skip(1).enumerate() {
  77. let (x,y) = room.center();
  78. let glyph : u8;
  79. let name : String;
  80. let roll = rng.roll_dice(1, 2);
  81. match roll {
  82. 1 => { glyph = rltk::to_cp437('g'); name = "Goblin".to_string(); }
  83. _ => { glyph = rltk::to_cp437('o'); name = "Orc".to_string(); }
  84. }
  85. gs.ecs.create_entity()
  86. .with(Position{ x, y })
  87. .with(Renderable{
  88. glyph,
  89. fg: RGB::named(rltk::RED),
  90. bg: RGB::named(rltk::BLACK),
  91. })
  92. .with(Viewshed{ visible_tiles : Vec::new(), range: 8, dirty: true })
  93. .with(Monster{})
  94. .with(Name{ name: format!("{} #{}", &name, i) })
  95. .build();
  96. }
  97. gs.ecs.insert(map);
  98. gs.ecs.insert(Point::new(player_x, player_y));
  99. rltk::main_loop(context, gs);
  100. }