main.rs 3.6 KB

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