physics.rs 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. use crate::components::{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.set_position(Isometry2::new(Vector2::new(np.x, np.y), nalgebra::zero()));
  30. })
  31. .collect();
  32. w.update();
  33. for ev in w.proximity_events() {
  34. if ev.new_status == ncollide2d::query::Proximity::Intersecting {
  35. let e = w.collision_object(ev.collider1).unwrap().data();
  36. collisions.get_mut(*e).map(|r| r.has_collision = true);
  37. let e = w.collision_object(ev.collider2).unwrap().data();
  38. collisions.get_mut(*e).map(|r| r.has_collision = true);
  39. } else {
  40. let e = w.collision_object(ev.collider1).unwrap().data();
  41. collisions.get_mut(*e).map(|r| r.has_collision = false);
  42. let e = w.collision_object(ev.collider2).unwrap().data();
  43. collisions.get_mut(*e).map(|r| r.has_collision = false);
  44. }
  45. }
  46. w.clear_events();
  47. }
  48. }
  49. struct Physics;
  50. impl<'a> specs::System<'a> for Physics {
  51. type SystemData = (
  52. specs::ReadStorage<'a, Velocity>,
  53. specs::ReadStorage<'a, Collision>,
  54. specs::WriteStorage<'a, Position>,
  55. );
  56. fn run(&mut self, (velocity, collision, mut position): Self::SystemData) {
  57. for (vel, col, pos) in (&velocity, &collision, &mut position).join() {
  58. if !col.has_collision {
  59. pos.x += vel.dx;
  60. pos.y += vel.dy;
  61. }
  62. }
  63. }
  64. }
  65. pub fn systems(game: &mut MyGame) {
  66. Collide.run_now(&game.world);
  67. Physics.run_now(&game.world);
  68. }