-use teststate::TestState;
use AppState;
-use common::{Point, ToAngle};
use core::app::StateChange;
use core::controller::Controller;
use core::controller::ControllerManager;
use core::level::{Level, LevelGenerator, Wall, IntersectResult::Intersection};
use core::render::Renderer;
+use geometry::{Point, ToAngle};
use point;
use sdl2::event::Event;
-use sdl2::joystick::PowerLevel;
use sdl2::keyboard::Keycode;
use sdl2::rect::Rect;
use sprites::SpriteManager;
use std::cell::RefCell;
use std::rc::Rc;
+use teststate::TestState;
use time::Duration;
////////// GAMESTATE ///////////////////////////////////////////////////////////
ctrl: Rc<RefCell<Controller>>,
pos: Point<f64>,
vel: Point<f64>,
+ standing_on: Option<Wall>,
}
impl Character {
ctrl,
pos: point!(300.0, 300.0),
vel: point!(0.0, 0.0),
+ standing_on: None,
}
}
}
fn update(&mut self, objects: &mut Objects, lvl: &Level, dt: Duration) -> ObjectState {
let ctrl = self.ctrl.borrow();
- let x = (self.pos.x / lvl.grid.scale.width as f64).min(lvl.grid.size.width as f64 - 1.0).max(0.0) as usize;
- let y = (self.pos.y / lvl.grid.scale.height as f64).min(lvl.grid.size.height as f64 - 1.0).max(0.0) as usize;
- self.vel += lvl.gravity;
- if lvl.grid.cells[x][y] {
- if self.vel.y > 0.0 && !(ctrl.mov.down() && ctrl.jump.is_pressed) {
- self.vel.y = 0.0;
- self.vel.x *= 0.9;
- self.pos.y -= 1.0;
- }
-
- if !ctrl.mov.down() {
+ match &self.standing_on {
+ Some(wall) => {
if ctrl.jump.is_pressed && !ctrl.jump.was_pressed {
- self.vel.y = -5.0;
+ if ctrl.mov.to_point().length() < 0.1 {
+ self.vel = wall.normal().into();
+ } else {
+ self.vel = ctrl.mov.to_point();
+ }
+ self.vel *= 5.0;
+ self.pos += self.vel * 0.1;
+ self.standing_on = None;
+ } else {
+ self.vel *= 0.9;
+ }
+ },
+ None => {
+ self.vel += lvl.gravity;
+ self.pos += self.vel;
+
+ match ctrl.mov.x {
+ v if v < -0.9 && self.vel.x > -5.0 => { self.vel.x -= 0.5 }
+ v if v > 0.9 && self.vel.x < 5.0 => { self.vel.x += 0.5 }
+ _ => {}
+ }
+
+ if let Intersection(wall, pos) = lvl.intersect_walls(self.pos - self.vel, self.pos) {
+ self.standing_on = Some(wall);
+ self.pos = pos;
+ self.vel = point!(0.0, 0.0);
}
}
}
- self.pos += self.vel;
if ctrl.shoot.is_pressed {
use rand::distributions::{Distribution, Normal};
let direction = if ctrl.aim.to_point().length() > 0.1 { ctrl.aim.to_point() } else { ctrl.mov.to_point() };
for _i in 0..100 {
objects.push(Box::new(Boll {
- pos: self.pos,
+ pos: self.pos + point!(0.0, -16.0), // half the height of mario
vel: direction * (10.0 + rand::random::<f64>()) + point!(normal.sample(&mut rand::thread_rng()), normal.sample(&mut rand::thread_rng())) + self.vel,
bounces: 2,
}));
self.vel -= direction * 0.1;
}
- if ctrl.start.is_pressed && !ctrl.start.was_pressed {
- match ctrl.device.power_level() {
- Ok(PowerLevel::Unknown) => { println!("power level unknown"); }
- Ok(PowerLevel::Empty) => { println!("power level empty"); }
- Ok(PowerLevel::Low) => { println!("power level low"); }
- Ok(PowerLevel::Medium) => { println!("power level medium"); }
- Ok(PowerLevel::Full) => { println!("power level full"); }
- Ok(PowerLevel::Wired) => { println!("power level wired"); }
- Err(_) => {}
- };
- }
-
- match ctrl.mov.x {
- v if v < -0.9 && self.vel.x > -5.0 => { self.vel.x -= 0.5 }
- v if v > 0.9 && self.vel.x < 5.0 => { self.vel.x += 0.5 }
- _ => {}
- }
-
Alive
}
}
self.bounces -= 1;
let mut a = wall.normal().mirror(self.vel.to_angle()); // TODO interpolera normalen mellan närliggande väggdelar? bollarna studsar väldigt "kantigt" nu
- self.pos = pos;
+ self.pos = pos + Point::from(wall.normal()) * 0.1; // får bollen att inte åka igenom väggen av misstag p.g.a nedan slumpvinkel
self.vel = Point::from(a) * self.vel.length() * 0.35;
- self.pos += self.vel; // TODO det här kan få bollen att åka igenom en närliggande vägg utan att kollisionstestas, men behövs just nu för att inte kollidera med samma vägg bakifrån
// create another boll
use rand::distributions::{Distribution, Normal};