X-Git-Url: http://www.dolda2000.com/gitweb/?a=blobdiff_plain;f=src%2Fcore%2Fobject%2Fcharacter.rs;fp=src%2Fcore%2Fobject%2Fcharacter.rs;h=8632ee2a0c13a626ea17e134db3cc81367775dc4;hb=5d7eff9e9c0f585e9c4d57907f2e72003d39c757;hp=0000000000000000000000000000000000000000;hpb=09cd68feac9813b82f0c73e7c0429ddf0f719117;p=kaka%2Frust-sdl-test.git diff --git a/src/core/object/character.rs b/src/core/object/character.rs new file mode 100644 index 0000000..8632ee2 --- /dev/null +++ b/src/core/object/character.rs @@ -0,0 +1,118 @@ +use core::controller::Controller; +use core::object::boll::Boll; +use core::level::{Level, Wall, IntersectResult::Intersection}; +use core::object::{Object, Objects, ObjectState}; +use core::render::Renderer; +use geometry::Point; +use point; +use sdl2::rect::Rect; +use sprites::SpriteManager; +use std::cell::RefCell; +use std::rc::Rc; +use time::Duration; + +////////// CHARACTER /////////////////////////////////////////////////////////// + +pub struct Character { + ctrl: Rc>, + pos: Point, + vel: Point, + standing_on: Option, +} + +impl Character { + pub fn new(ctrl: Rc>) -> Self { + Character { + ctrl, + pos: point!(300.0, 300.0), + vel: point!(0.0, 0.0), + standing_on: None, + } + } +} + +impl Object for Character { + fn update(&mut self, objects: &mut Objects, lvl: &Level, dt: Duration) -> ObjectState { + let ctrl = self.ctrl.borrow(); + + match &self.standing_on { + Some(wall) => { + if ctrl.jump.is_pressed && !ctrl.jump.was_pressed { + 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); + } + } + } + + if ctrl.shoot.is_pressed { + use rand::distributions::{Distribution, Normal}; + let normal = Normal::new(0.0, 0.1); + 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::new( + self.pos + point!(0.0, -16.0), // half the height of mario + direction * (10.0 + rand::random::()) + point!(normal.sample(&mut rand::thread_rng()), normal.sample(&mut rand::thread_rng())) + self.vel, + 2, + ))); + } + ctrl.rumble(1.0, dt); + self.vel -= direction * 0.1; + } + + ObjectState::Alive + } + + fn render(&self, renderer: &mut Renderer, sprites: &SpriteManager) { + let block = sprites.get("mario"); + let size = 32; + renderer.blit(block, None, Rect::new(self.pos.x as i32 - size as i32 / 2, self.pos.y as i32 - size as i32, size, size)); + + let ctrl = &self.ctrl.borrow(); + let l = 300.0; + let pos = (self.pos.x as i32, self.pos.y as i32); + // // axis values + // let p = (self.pos + ctrl.aim.to_axis_point() * l).to_i32().into(); + // renderer.draw_line(pos, p, (0, 255, 0)); + // draw_cross(renderer, p); + // values limited to unit vector + let p = (self.pos + ctrl.aim.to_point() * l).to_i32().into(); + renderer.draw_line(pos, p, (255, 0, 0)); + draw_cross(renderer, p); + let p = (self.pos + ctrl.mov.to_point() * l).to_i32().into(); + renderer.draw_line(pos, p, (0, 255, 0)); + draw_cross(renderer, p); + // // circle values + // let p = (self.pos + Point::from(ctrl.aim.a) * l).to_i32().into(); + // renderer.draw_line(pos, p, (0, 0, 255)); + // draw_cross(renderer, p); + } +} + +fn draw_cross(renderer: &mut Renderer, p: (i32, i32)) { + renderer.canvas().draw_line((p.0 - 5, p.1), (p.0 + 5, p.1)).unwrap(); + renderer.canvas().draw_line((p.0, p.1 - 5), (p.0, p.1 + 5)).unwrap(); +}