main.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #[macro_use]
  2. extern crate specs_derive;
  3. #[macro_use]
  4. extern crate specs_system_macro;
  5. use ggez::GameError;
  6. use specs::prelude::*;
  7. #[derive(PartialEq, Clone, Copy, Debug)]
  8. enum TileType {
  9. Wall,
  10. Floor,
  11. }
  12. #[derive(Component)]
  13. pub struct Pos {
  14. x: usize,
  15. y: usize,
  16. }
  17. #[derive(Component)]
  18. pub struct Renderable {
  19. glyph: carpet::CP437,
  20. color: carpet::Color,
  21. }
  22. #[derive(Component)]
  23. pub struct MoveLeft;
  24. #[derive(Component)]
  25. pub struct Player;
  26. impl Player {
  27. fn get_entity(world: &mut specs::World) -> Entity {
  28. let storage = (&world.read_component::<Player>(), &world.entities());
  29. storage.join().next().expect("No entities tagged as Player").1
  30. }
  31. }
  32. #[derive(Component)]
  33. pub struct Motion {
  34. down: i8,
  35. right: i8,
  36. }
  37. impl Motion {
  38. fn move_player(world: &mut specs::World, down: i8, right: i8) {
  39. let player = Player::get_entity(world);
  40. world.write_component::<Motion>().insert(player, Motion { down, right }).unwrap();
  41. }
  42. }
  43. system_impl! {
  44. Draw(
  45. resource mut board: carpet::GameBoard<carpet::CP437>,
  46. renderable: Renderable,
  47. pos: Pos,
  48. ) {
  49. board.clear();
  50. for (p, r) in (&pos, &renderable).join() {
  51. board.set_with_color([p.x, p.y], r.glyph, r.color);
  52. }
  53. }
  54. }
  55. system! {
  56. Leftward (
  57. _left: MoveLeft,
  58. mut pos: Pos,
  59. ) {
  60. if pos.x == 0 {
  61. pos.x = 79;
  62. } else {
  63. pos.x -= 1;
  64. }
  65. }
  66. }
  67. system! {
  68. Move (
  69. mut motion: Motion,
  70. mut pos: Pos,
  71. ) {
  72. pos.x = (pos.x as i8 + motion.right) as usize;
  73. pos.y = (pos.y as i8 + motion.down) as usize;
  74. } finally {
  75. motion.clear();
  76. }
  77. }
  78. fn main() -> Result<(), GameError> {
  79. let mut game = carpet::GameBuilder::new()
  80. .name("game")
  81. .author("me")
  82. .resource_path({
  83. let base = std::env::var("CARGO_MANIFEST_DIR").unwrap();
  84. let mut path = std::path::PathBuf::from(base);
  85. path.push("resources");
  86. path
  87. })
  88. .tileset("/terminal8x8.jpg", [8, 8])
  89. .map_size(80, 50)
  90. .build()?;
  91. game.register::<Pos>();
  92. game.register::<Renderable>();
  93. game.register::<MoveLeft>();
  94. game.register::<Motion>();
  95. game.register::<Player>();
  96. game.world.print([1, 1], "Hello, world!");
  97. game.create_entity()
  98. .with(Pos { x: 40, y: 25 })
  99. .with(Player)
  100. .with(Renderable {
  101. glyph: carpet::CP437::from_char('A'),
  102. color: carpet::Color::Blue,
  103. })
  104. .build();
  105. for i in 0..10 {
  106. game.create_entity()
  107. .with(Pos { x: i * 7, y: 20 })
  108. .with(Renderable {
  109. glyph: carpet::CP437::from_char('X'),
  110. color: carpet::Color::Red,
  111. })
  112. .with(MoveLeft)
  113. .build();
  114. }
  115. game.on_key((carpet::VirtualKeyCode::W, carpet::KeyMods::NONE), |world| {
  116. Motion::move_player(world, -1, 0);
  117. });
  118. game.on_key((carpet::VirtualKeyCode::A, carpet::KeyMods::NONE), |world| {
  119. Motion::move_player(world, 0, -1);
  120. });
  121. game.on_key((carpet::VirtualKeyCode::S, carpet::KeyMods::NONE), |world| {
  122. Motion::move_player(world, 1, 0);
  123. });
  124. game.on_key((carpet::VirtualKeyCode::D, carpet::KeyMods::NONE), |world| {
  125. Motion::move_player(world, 0, 1);
  126. });
  127. game.run_with_systems(|world| {
  128. Draw.run_now(&world);
  129. Leftward.run_now(&world);
  130. Move.run_now(&world);
  131. })
  132. }