demo demo
authorTomas Wenström <tomas.wenstrom@gmail.com>
Thu, 11 Mar 2021 18:39:21 +0000 (19:39 +0100)
committerTomas Wenström <tomas.wenstrom@gmail.com>
Thu, 11 Mar 2021 18:39:21 +0000 (19:39 +0100)
src/core/level/mod.rs
src/core/object/character.rs

index 47a4703..1d8c73a 100644 (file)
@@ -292,6 +292,10 @@ impl Wall {
        self.edge.angle()
     }
 
+    pub fn length(&self) -> f64 {
+       (self.edge.p1 - self.edge.p2).length()
+    }
+
     pub fn from_2d(&self, pos: &Point<f64>, vel: &Point<f64>) -> (f64, f64) {
        let pos = self.projection_of(*pos - self.edge.p1);
        let vel = self.projection_of(*vel);
index b2ec5cf..bf79700 100644 (file)
@@ -169,17 +169,73 @@ impl State for StandState {
 
     fn update(&mut self, body: &mut Body, _ctrl: &Controller, _objects: &mut Objects, _lvl: &Level, _dt: Duration) -> Option<Box<dyn State>> {
        if let Some(wall) = &body.standing_on {
+           body.vel += _ctrl.mov.to_point() * 0.2;
            let (mut pos, mut vel) = wall.from_2d(&body.pos, &body.vel);
-           vel *= 0.9;
+           vel *= 0.99;
            pos += vel;
-           let (p, v) = wall.to_2d(pos, vel);
-           body.pos = p;
-           body.vel = v;
+           if pos < 0.0 {
+               let w = wall.previous();
+               pos += w.length();
+               let (p, v) = w.to_2d(pos, vel);
+               body.pos = p;
+               body.vel = v;
+               body.standing_on = Some(w);
+           } else if pos > wall.length() {
+               let w = wall.next();
+               pos -= wall.length();
+               let (p, v) = w.to_2d(pos, vel);
+               body.pos = p;
+               body.vel = v;
+               body.standing_on = Some(w);
+           } else {
+               let (p, v) = wall.to_2d(pos, vel);
+               body.pos = p;
+               body.vel = v;
+           }
        }
 
        None
     }
 }
+
+////////// WALKING /////////////////////////////////////////////////////////////
+
+struct WalkTrigger;
+
+impl Trigger for WalkTrigger {
+    fn update(&mut self, body: &Body, ctrl: &Controller, _dt: Duration) -> Option<Box<dyn State>> {
+       if body.standing_on.is_some() && (ctrl.mov.x < -0.1 || ctrl.mov.x > 0.1) {
+           Some(Box::new(WalkState))
+       } else {
+           None
+       }
+    }
+}
+
+struct WalkState;
+
+impl State for WalkState {
+    fn enter(&mut self, body: &mut Body, ctrl: &Controller, _objects: &mut Objects) {
+       if let Some(wall) = &body.standing_on {
+           if ctrl.mov.to_point().length() < 0.1 {
+               body.vel = wall.normal().into();
+           } else {
+               body.vel = ctrl.mov.to_point();
+           }
+           body.vel *= 5.0;
+           body.pos += body.vel * 0.1;
+           body.standing_on = None;
+       }
+    }
+
+    fn update(&mut self, body: &mut Body, ctrl: &Controller, _objects: &mut Objects, lvl: &Level, _dt: Duration) -> Option<Box<dyn State>> {
+       body.vel += lvl.gravity;
+       body.pos += body.vel;
+
+       match ctrl.mov.x {
+           v if v < -0.9 && body.vel.x > -5.0 => { body.vel.x -= 0.5 }
+           v if v > 0.9 && body.vel.x < 5.0 => { body.vel.x += 0.5 }
+           _ => {}
        }
 
        None
@@ -205,12 +261,12 @@ struct JumpState;
 impl State for JumpState {
     fn enter(&mut self, body: &mut Body, ctrl: &Controller, _objects: &mut Objects) {
        if let Some(wall) = &body.standing_on {
-           if ctrl.mov.to_point().length() < 0.1 {
-               body.vel = wall.normal().into();
+           let direction = if ctrl.mov.to_point().length() < 0.1 {
+               wall.normal().into()
            } else {
-               body.vel = ctrl.mov.to_point();
-           }
-           body.vel *= 5.0;
+               ctrl.mov.to_point()
+           };
+           body.vel += direction * 5.0;
            body.pos += body.vel * 0.1;
            body.standing_on = None;
        }