Commit | Line | Data |
---|---|---|
5d7eff9e TW |
1 | use core::level::{Level, IntersectResult::Intersection}; |
2 | use core::object::{Object, Objects, ObjectState}; | |
3 | use core::render::Renderer; | |
4 | use geometry::{Point, ToAngle}; | |
5 | use sdl2::rect::Rect; | |
6 | use sprites::SpriteManager; | |
7 | use time::Duration; | |
8 | ||
9 | ////////// BOLL //////////////////////////////////////////////////////////////// | |
10 | ||
11 | pub struct Boll { | |
12 | pos: Point<f64>, | |
13 | vel: Point<f64>, | |
14 | bounces: u8, | |
15 | } | |
16 | ||
17 | impl Boll { | |
18 | pub fn new(pos: Point<f64>, vel: Point<f64>, bounces: u8) -> Self { | |
19 | Boll { pos, vel, bounces } | |
20 | } | |
21 | } | |
22 | ||
23 | impl Object for Boll { | |
24 | ||
25 | fn update(&mut self, objects: &mut Objects, lvl: &Level, _dt: Duration) -> ObjectState { | |
26 | self.vel += lvl.gravity; | |
27 | self.pos += self.vel; | |
28 | ||
29 | if let Intersection(wall, pos) = lvl.intersect_walls(self.pos - self.vel, self.pos) { | |
30 | if self.bounces == 0 { | |
31 | return ObjectState::Dead | |
32 | } | |
33 | self.bounces -= 1; | |
34 | let mut a = wall.normal().mirror(self.vel.to_angle()); // TODO interpolera normalen mellan närliggande väggdelar? bollarna studsar väldigt "kantigt" nu | |
35 | 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 | |
36 | self.vel = Point::from(a) * self.vel.length() * 0.35; | |
37 | ||
38 | // create another boll | |
39 | use rand::distributions::{Distribution, Normal}; | |
40 | let mut rng = rand::thread_rng(); | |
41 | 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? | |
42 | use rand::Rng; | |
43 | objects.push(Box::new(Boll { | |
44 | vel: Point::from(a) * Normal::new(1.0, 0.25).sample(&mut rng) * self.vel.length() * rng.gen_range(0.25, 1.0), | |
45 | ..*self | |
46 | })); | |
47 | } | |
48 | ||
49 | ObjectState::Alive | |
50 | } | |
51 | ||
52 | fn render(&self, renderer: &mut Renderer, _sprites: &SpriteManager) { | |
53 | let block = _sprites.get("block"); | |
54 | let size = 4 + self.bounces * 6; | |
55 | 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)); | |
56 | // renderer.canvas().set_draw_color((0, self.bounces * 100, 255)); | |
57 | // renderer.canvas().draw_point((self.pos.x as i32, self.pos.y as i32)).unwrap(); | |
58 | } | |
59 | } |