gdritter repos wenaglia / master src / sys / physics.rs
master

Tree @master (Download .tar.gz)

physics.rs @master

a3e0d9f
b77725a
 
37af6c0
862a3d2
3435b15
37af6c0
 
 
 
 
 
 
 
 
86edfda
37af6c0
 
862a3d2
 
86edfda
862a3d2
86edfda
862a3d2
 
37af6c0
 
 
 
 
86edfda
ad5e08d
862a3d2
 
86edfda
 
 
895328e
 
 
 
86edfda
895328e
 
 
 
86edfda
 
 
37af6c0
 
 
b77725a
 
862a3d2
b77725a
 
3435b15
b77725a
 
 
3435b15
 
 
 
 
 
b77725a
 
 
 
 
adc9cc3
 
b77725a
use crate::components::{Blocking, Collision, Position, Velocity, World};
use crate::game::MyGame;

use nalgebra::{Isometry2, Vector2};
use specs::{Join, RunNow};

struct Collide;

impl<'a> specs::System<'a> for Collide {
    type SystemData = (
        specs::Entities<'a>,
        specs::ReadStorage<'a, Position>,
        specs::ReadStorage<'a, Velocity>,
        specs::ReadStorage<'a, Blocking>,
        specs::WriteStorage<'a, Collision>,
        specs::WriteExpect<'a, World>,
    );

    fn run(
        &mut self,
        (entities, position, velocity, blocking, mut collisions, mut w): Self::SystemData,
    ) {
        let _: Vec<()> = (&entities, &position, &blocking)
            .join()
            .map(|(e, pos, bl)| {
                let np = if let Some(vel) = velocity.get(e) {
                    pos.moved(vel)
                } else {
                    pos.clone()
                };
                let obj = w.get_mut(bl.handle).unwrap();
                obj.set_position(Isometry2::new(Vector2::new(np.x, np.y), nalgebra::zero()));
            })
            .collect();
        w.update();
        for ev in w.proximity_events() {
            if ev.new_status == ncollide2d::query::Proximity::Intersecting {
                let e = w.collision_object(ev.collider1).unwrap().data();
                collisions.get_mut(*e).map(|r| r.has_collision = true);
                let e = w.collision_object(ev.collider2).unwrap().data();
                collisions.get_mut(*e).map(|r| r.has_collision = true);
            } else {
                let e = w.collision_object(ev.collider1).unwrap().data();
                collisions.get_mut(*e).map(|r| r.has_collision = false);
                let e = w.collision_object(ev.collider2).unwrap().data();
                collisions.get_mut(*e).map(|r| r.has_collision = false);
            }
        }
        w.clear_events();
    }
}

struct Physics;

impl<'a> specs::System<'a> for Physics {
    type SystemData = (
        specs::ReadStorage<'a, Velocity>,
        specs::ReadStorage<'a, Collision>,
        specs::WriteStorage<'a, Position>,
    );

    fn run(&mut self, (velocity, collision, mut position): Self::SystemData) {
        for (vel, col, pos) in (&velocity, &collision, &mut position).join() {
            if !col.has_collision {
                pos.x += vel.dx;
                pos.y += vel.dy;
            }
        }
    }
}

pub fn systems(game: &mut MyGame) {
    Collide.run_now(&game.world);
    Physics.run_now(&game.world);
}