use core::level::{Level, IntersectResult::Intersection}; use core::object::{Object, Objects, ObjectState}; use core::render::Renderer; use geometry::{Point, ToAngle}; use sdl2::rect::Rect; use sprites::SpriteManager; use time::Duration; ////////// BOLL //////////////////////////////////////////////////////////////// pub struct Boll { pos: Point, vel: Point, bounces: u8, } impl Boll { pub fn new(pos: Point, vel: Point, bounces: u8) -> Self { Boll { pos, vel, bounces } } } impl Object for Boll { fn update(&mut self, objects: &mut Objects, lvl: &Level, _dt: Duration) -> ObjectState { self.vel += lvl.gravity; self.pos += self.vel; if let Intersection(wall, pos) = lvl.intersect_walls(self.pos - self.vel, self.pos) { if self.bounces == 0 { return ObjectState::Dead } 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 + 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; // create another boll use rand::distributions::{Distribution, Normal}; let mut rng = rand::thread_rng(); a += Normal::new(0.0, 0.1).sample(&mut rng).radians(); // TODO slumpen kan ge en vinkel som är under tangenten. vinkel-metoder på väggen istället kanske? use rand::Rng; objects.push(Box::new(Boll { vel: Point::from(a) * Normal::new(1.0, 0.25).sample(&mut rng) * self.vel.length() * rng.gen_range(0.25, 1.0), ..*self })); } ObjectState::Alive } fn render(&self, renderer: &mut Renderer, _sprites: &SpriteManager) { let block = _sprites.get("block"); let size = 4 + self.bounces * 6; renderer.blit(block, None, Rect::new(self.pos.x as i32 - size as i32 / 2, self.pos.y as i32 - size as i32 / 2, size as u32, size as u32)); // renderer.canvas().set_draw_color((0, self.bounces * 100, 255)); // renderer.canvas().draw_point((self.pos.x as i32, self.pos.y as i32)).unwrap(); } }