diff --git a/src/main.rs b/src/main.rs index a973cd1..93abbf9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,21 +9,20 @@ use sdl2::pixels::Color; use sdl2::event::Event; use sdl2::keyboard::Keycode; -use sdl2::keyboard::Scancode; -use std::collections::HashSet; +//use sdl2::keyboard::Scancode; +//use std::collections::HashSet; use std::time::Duration; use sdl2::rect::Point; use sdl2::rect::Rect; use rand::Rng; -const WINDOW_HEIGHT:i32 = 600; -const WINDOW_WIDTH:i32 = 800; -const BIRD_SPEED:i32 = 2; -const MAX_BIRD_SPEED:i32 = 15; +const WINDOW_HEIGHT:i32 = 800; +const WINDOW_WIDTH:i32 = 1000; +const MAX_BIRD_SPEED:i32 = 40; const BIRDS_COUNT:i32 = 200; const BIRD_SIZE:i32 = 15; -const VISION_RANGE:i32 = 100; +const VISION_RANGE:i32 = 10; const COHERENCE_RATE:i32 = 1; const SEPRATION_RATE:i32 = 1; const ALIGNEMENT_RATE:i32 = 1; @@ -81,33 +80,37 @@ impl Simulation{ let posy = bird.shape.y; let average = averages[i as usize]; + let mut added_velocity:Point = Point::new(0,0); + if posx > average.x{ - if bird.velocity.x - COHERENCE_RATE < -MAX_BIRD_SPEED{ - bird.velocity.x = -MAX_BIRD_SPEED; - }else{ - bird.velocity.x -= COHERENCE_RATE; - } + added_velocity.x -= COHERENCE_RATE; }else if posx < average.x{ - if bird.velocity.x + COHERENCE_RATE > MAX_BIRD_SPEED{ - bird.velocity.x = MAX_BIRD_SPEED; - }else{ - bird.velocity.x += COHERENCE_RATE; - } + added_velocity.x += COHERENCE_RATE; } if posy > average.y{ - if bird.velocity.y - COHERENCE_RATE < -MAX_BIRD_SPEED{ - bird.velocity.y = -MAX_BIRD_SPEED; - }else{ - bird.velocity.y -= COHERENCE_RATE; - } + added_velocity.y -= COHERENCE_RATE; }else if posy < average.y{ - if bird.velocity.y + COHERENCE_RATE > MAX_BIRD_SPEED{ - bird.velocity.y = MAX_BIRD_SPEED; - }else{ - bird.velocity.y += COHERENCE_RATE; - } + added_velocity.y += COHERENCE_RATE; } + + if added_velocity.x > COHERENCE_RATE / 3{ + added_velocity.x = COHERENCE_RATE / 3; + } + if added_velocity.x < -COHERENCE_RATE / 3{ + added_velocity.x = -COHERENCE_RATE / 3; + } + + if added_velocity.y > COHERENCE_RATE / 3{ + added_velocity.y = COHERENCE_RATE / 3; + } + if added_velocity.y < -COHERENCE_RATE / 3{ + added_velocity.y = -COHERENCE_RATE / 3; + } + + bird.velocity.x += added_velocity.x; + bird.velocity.y += added_velocity.y; + } } @@ -141,43 +144,107 @@ impl Simulation{ let posy = bird.shape.y; let average = averages[i as usize]; - if posx > average.x{ - if bird.velocity.x + SEPRATION_RATE > MAX_BIRD_SPEED{ - bird.velocity.x = MAX_BIRD_SPEED; - }else{ - bird.velocity.x += SEPRATION_RATE; - } - }else if posx < average.x{ - if bird.velocity.x - SEPRATION_RATE < -MAX_BIRD_SPEED{ - bird.velocity.x = -MAX_BIRD_SPEED; - }else{ - bird.velocity.x -= SEPRATION_RATE; - } - } + let mut added_velocity:Point = Point::new(0,0); - if posy > average.y{ - if bird.velocity.y + SEPRATION_RATE > MAX_BIRD_SPEED{ - bird.velocity.y = MAX_BIRD_SPEED; - }else{ - bird.velocity.y += SEPRATION_RATE; - } - }else if posy < average.y{ - if bird.velocity.y - SEPRATION_RATE < -MAX_BIRD_SPEED{ - bird.velocity.y = -MAX_BIRD_SPEED; - }else{ - bird.velocity.y -= SEPRATION_RATE; - } - } + if posx > average.x{ + added_velocity.x -= SEPRATION_RATE; + }else if posx < average.x{ + added_velocity.x += SEPRATION_RATE; + } + + if posy > average.y{ + added_velocity.y -= SEPRATION_RATE; + }else if posy < average.y{ + added_velocity.y += SEPRATION_RATE; + } + + if added_velocity.x > MAX_BIRD_SPEED / 3{ + added_velocity.x = MAX_BIRD_SPEED / 3; + } + if added_velocity.x < -MAX_BIRD_SPEED / 3{ + added_velocity.x = -MAX_BIRD_SPEED / 3; + } + + if added_velocity.y > MAX_BIRD_SPEED / 3{ + added_velocity.y = MAX_BIRD_SPEED / 3; + } + if added_velocity.y < -MAX_BIRD_SPEED / 3{ + added_velocity.y = -MAX_BIRD_SPEED / 3; + } + + bird.velocity.x += added_velocity.x; + bird.velocity.y += added_velocity.y; } } pub fn apply_alignement(&mut self){ + // first we calculate all the averages for every birds + let mut averages:Vec = Vec::with_capacity(BIRDS_COUNT as usize); + for i in 0..BIRDS_COUNT{ + let mut sum = Point::new(0,0); + let target = &self.birds[i as usize]; + let mut x_offset:i32; + let mut y_offset:i32; + let mut neighbours_count = 0; + for bird in &self.birds{ + x_offset = (target.shape.x - bird.shape.x).abs(); + y_offset = (target.shape.y - bird.shape.y).abs(); + if x_offset <= VISION_RANGE && y_offset <= VISION_RANGE{ + sum.x += bird.velocity.x; + sum.y += bird.velocity.y; + neighbours_count += 1; + } + } + let average = Point::new(sum.x / neighbours_count as i32,sum.y / neighbours_count as i32); + averages.push(average); + } + + for i in 0..BIRDS_COUNT{ + //now we need to steer torwards it + let bird = &mut self.birds[i as usize]; + let posx = bird.shape.x; + let posy = bird.shape.y; + let average = averages[i as usize]; + let mut added_velocity:Point = Point::new(0,0); + + if posx > average.x{ + added_velocity.x -= ALIGNEMENT_RATE; + }else if posx < average.x{ + added_velocity.x += ALIGNEMENT_RATE; + } + + if posy > average.y{ + added_velocity.y -= ALIGNEMENT_RATE; + }else if posy < average.y{ + added_velocity.y += ALIGNEMENT_RATE; + } + + if added_velocity.x > MAX_BIRD_SPEED / 3{ + added_velocity.x = MAX_BIRD_SPEED / 3; + } + if added_velocity.x < -MAX_BIRD_SPEED / 3{ + added_velocity.x = -MAX_BIRD_SPEED / 3; + } + + if added_velocity.y > MAX_BIRD_SPEED / 3{ + added_velocity.y = MAX_BIRD_SPEED / 3; + } + if added_velocity.y < -MAX_BIRD_SPEED / 3{ + added_velocity.y = -MAX_BIRD_SPEED / 3; + } + + bird.velocity.x += added_velocity.x; + bird.velocity.y += added_velocity.y; + + } } pub fn update(&mut self){ self.apply_coherence(); - self.apply_separation(); self.apply_alignement(); + self.apply_separation(); + for bird in &mut self.birds{ + check_velocity(bird); let mut posx = bird.shape.x; let mut posy = bird.shape.y; let width:i32 = bird.shape.width() as i32; @@ -223,26 +290,29 @@ impl Simulation{ }else{ bird.velocity.y -= push_back; } + + posx += bird.velocity.x; + posy += bird.velocity.y; - if bird.velocity.y > MAX_BIRD_SPEED{ - bird.velocity.y = MAX_BIRD_SPEED; - }else if bird.velocity.y < -MAX_BIRD_SPEED{ - bird.velocity.y = -MAX_BIRD_SPEED; - } - if bird.velocity.x > MAX_BIRD_SPEED{ - bird.velocity.x = MAX_BIRD_SPEED; - }else if bird.velocity.x < -MAX_BIRD_SPEED{ - bird.velocity.x = -MAX_BIRD_SPEED; - } - - - posx += bird.velocity.x / 2; - posy += bird.velocity.y / 2; bird.shape.set_x(posx); bird.shape.set_y(posy); + + //bird.velocity = Point::new(0,0); } } } +pub fn check_velocity(bird:&mut Bird){ + if bird.velocity.y > MAX_BIRD_SPEED{ + bird.velocity.y = MAX_BIRD_SPEED; + }else if bird.velocity.y < -MAX_BIRD_SPEED{ + bird.velocity.y = -MAX_BIRD_SPEED; + } + if bird.velocity.x > MAX_BIRD_SPEED{ + bird.velocity.x = MAX_BIRD_SPEED; + }else if bird.velocity.x < -MAX_BIRD_SPEED{ + bird.velocity.x = -MAX_BIRD_SPEED; + } +} pub fn main_loop(canvas: &mut sdl2::render::Canvas,event_pump:&mut sdl2::EventPump,game:&mut Simulation){ 'running: loop { @@ -255,12 +325,10 @@ pub fn main_loop(canvas: &mut sdl2::render::Canvas,event_pu _ => {} } } - // MAIN LOOP game.update(); game.render(canvas); // MAIN LOOP - canvas.present(); ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); } @@ -268,7 +336,7 @@ pub fn main_loop(canvas: &mut sdl2::render::Canvas,event_pu pub fn generate_birds() -> Vec{ let mut rng = rand::thread_rng(); let mut birds = Vec::with_capacity(BIRDS_COUNT as usize); - for bird in 0..BIRDS_COUNT{ + for _bird in 0..BIRDS_COUNT{ let rectangle = Rect::new(rng.gen_range(0..WINDOW_WIDTH - BIRD_SIZE),rng.gen_range(0..WINDOW_HEIGHT - BIRD_SIZE),BIRD_SIZE as u32, BIRD_SIZE as u32); let velocity = Point::new(rng.gen_range(-MAX_BIRD_SPEED..MAX_BIRD_SPEED), rng.gen_range(-MAX_BIRD_SPEED..MAX_BIRD_SPEED)); birds.push(Bird{shape:rectangle,velocity:velocity});