physics.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. use crate::com::{Blocking, Collision, Position, Velocity};
  2. use crate::game::MyGame;
  3. use crate::types::World;
  4. use nalgebra::{Isometry2, Vector2};
  5. use specs::{Join, RunNow};
  6. struct Collide;
  7. impl<'a> specs::System<'a> for Collide {
  8. type SystemData = (
  9. specs::Entities<'a>,
  10. specs::ReadStorage<'a, Position>,
  11. specs::ReadStorage<'a, Velocity>,
  12. specs::ReadStorage<'a, Blocking>,
  13. specs::WriteStorage<'a, Collision>,
  14. specs::WriteExpect<'a, World>,
  15. );
  16. fn run(
  17. &mut self,
  18. (entities, position, velocity, blocking, mut collisions, mut w): Self::SystemData,
  19. ) {
  20. let _: Vec<()> = (&entities, &position, &blocking)
  21. .join()
  22. .map(|(e, pos, bl)| {
  23. let np = if let Some(vel) = velocity.get(e) {
  24. pos.moved(vel)
  25. } else {
  26. pos.clone()
  27. };
  28. let obj = w.get_mut(bl.handle).unwrap();
  29. *obj.data_mut() = Some(e);
  30. obj.set_position(
  31. Isometry2::new(Vector2::new(np.x, np.y), nalgebra::zero()));
  32. })
  33. .collect();
  34. w.update();
  35. for ev in w.proximity_events() {
  36. if ev.new_status == ncollide2d::query::Proximity::Intersecting {
  37. if let Some(e) = w.collision_object(ev.collider1).unwrap().data() {
  38. collisions.get_mut(*e).map(|r| r.has_collision = true);
  39. }
  40. if let Some(e) = w.collision_object(ev.collider2).unwrap().data() {
  41. collisions.get_mut(*e).map(|r| r.has_collision = true);
  42. }
  43. } else {
  44. if let Some(e) = w.collision_object(ev.collider1).unwrap().data() {
  45. collisions.get_mut(*e).map(|r| r.has_collision = false);
  46. }
  47. if let Some(e) = w.collision_object(ev.collider2).unwrap().data() {
  48. collisions.get_mut(*e).map(|r| r.has_collision = false);
  49. }
  50. }
  51. }
  52. w.clear_events();
  53. }
  54. }
  55. struct Intersection;
  56. impl<'a> specs::System<'a> for Intersection {
  57. type SystemData = (
  58. specs::Entities<'a>,
  59. specs::ReadStorage<'a, Position>,
  60. specs::ReadStorage<'a, Velocity>,
  61. specs::ReadStorage<'a, Blocking>,
  62. specs::WriteStorage<'a, Collision>,
  63. );
  64. fn run(&mut self, (entity, position, velocity, blocking, mut collision): Self::SystemData) {
  65. let mut spacemap = std::collections::HashMap::new();
  66. for (e, pos, _) in (&entity, &position, &blocking).join() {
  67. spacemap.insert(pos.to_grid(), e);
  68. }
  69. for (pos, vel, col) in (&position, &velocity, &mut collision).join() {
  70. if let Some(_) = spacemap.get(&pos.moved(vel).to_grid()) {
  71. col.has_collision = true;
  72. }
  73. }
  74. }
  75. }
  76. struct Physics;
  77. impl<'a> specs::System<'a> for Physics {
  78. type SystemData = (
  79. specs::ReadStorage<'a, Velocity>,
  80. specs::ReadStorage<'a, Collision>,
  81. specs::WriteStorage<'a, Position>,
  82. );
  83. fn run(&mut self, (velocity, collision, mut position): Self::SystemData) {
  84. for (vel, col, pos) in (&velocity, &collision, &mut position).join() {
  85. if !col.has_collision {
  86. pos.x += vel.dx;
  87. pos.y += vel.dy;
  88. }
  89. }
  90. }
  91. }
  92. struct ResetCollision;
  93. impl<'a> specs::System<'a> for ResetCollision {
  94. type SystemData = specs::WriteStorage<'a, Collision>;
  95. fn run(&mut self, mut collision: Self::SystemData) {
  96. for mut e in (&mut collision).join() {
  97. e.has_collision = false;
  98. }
  99. }
  100. }
  101. pub fn systems(game: &mut MyGame) {
  102. Collide.run_now(&game.world);
  103. // Intersection.run_now(&game.world.res);
  104. Physics.run_now(&game.world);
  105. // ResetCollision.run_now(&game.world);
  106. }