Compare commits
4 Commits
1ce9945f05
..
trash
| Author | SHA1 | Date | |
|---|---|---|---|
| 04d5d30bd5 | |||
| c92d6a3f00 | |||
| dd49731ea8 | |||
| e27180a4b3 |
+180
-74
@@ -9,24 +9,23 @@
|
|||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
use sdl2::keyboard::Scancode;
|
//use sdl2::keyboard::Scancode;
|
||||||
use std::collections::HashSet;
|
//use std::collections::HashSet;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use sdl2::rect::Point;
|
use sdl2::rect::Point;
|
||||||
use sdl2::rect::Rect;
|
use sdl2::rect::Rect;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
|
||||||
const WINDOW_HEIGHT:i32 = 600;
|
const WINDOW_HEIGHT:i32 = 800;
|
||||||
const WINDOW_WIDTH:i32 = 800;
|
const WINDOW_WIDTH:i32 = 1000;
|
||||||
const BIRD_SPEED:i32 = 2;
|
const MAX_BIRD_SPEED:i32 = 40;
|
||||||
const MAX_BIRD_SPEED:i32 = 15;
|
const BIRDS_COUNT:i32 = 200;
|
||||||
const BIRDS_COUNT:i32 = 500;
|
|
||||||
const BIRD_SIZE:i32 = 15;
|
const BIRD_SIZE:i32 = 15;
|
||||||
|
|
||||||
const VISION_RANGE:i32 = 150;
|
const VISION_RANGE:i32 = 10;
|
||||||
const COHERENCE_RATE:i32 = 1;
|
const COHERENCE_RATE:i32 = 1;
|
||||||
const SEPRATION_RATE:i32 = 1;
|
const SEPRATION_RATE:i32 = 1;
|
||||||
const ALIGNEMENT_RATE:i32 = 2;
|
const ALIGNEMENT_RATE:i32 = 1;
|
||||||
const NEIGHBOUR_TRESHOLD:i32 = 10;
|
const NEIGHBOUR_TRESHOLD:i32 = 10;
|
||||||
|
|
||||||
pub struct Bird{
|
pub struct Bird{
|
||||||
@@ -41,9 +40,14 @@ impl Simulation{
|
|||||||
pub fn render(&mut self,ctx:&mut sdl2::render::Canvas<sdl2::video::Window>){
|
pub fn render(&mut self,ctx:&mut sdl2::render::Canvas<sdl2::video::Window>){
|
||||||
ctx.set_draw_color(Color::RGB(0x6D, 0x6D, 0x64));
|
ctx.set_draw_color(Color::RGB(0x6D, 0x6D, 0x64));
|
||||||
ctx.clear();
|
ctx.clear();
|
||||||
ctx.set_draw_color(Color::RGB(0x33, 0x33, 0x33));
|
|
||||||
for bird in self.birds.iter(){
|
for bird in self.birds.iter(){
|
||||||
|
ctx.set_draw_color(Color::RGB(0x33, 0x33, 0x33));
|
||||||
ctx.fill_rect(bird.shape).expect("Rusty Boids");
|
ctx.fill_rect(bird.shape).expect("Rusty Boids");
|
||||||
|
ctx.set_draw_color(Color::RGB(0xe7, 0x4c, 0x3c));
|
||||||
|
let start_pos = Point::new(bird.shape.x + bird.shape.width() as i32 / 2,bird.shape.y + bird.shape.height() as i32 /2);
|
||||||
|
let end_pos = Point::new(start_pos.x + bird.velocity.x * 2,start_pos.y + bird.velocity.y * 2);
|
||||||
|
ctx.draw_line(start_pos,end_pos).expect("Could nor draw vector line");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn apply_coherence(&mut self){
|
pub fn apply_coherence(&mut self){
|
||||||
@@ -76,33 +80,37 @@ impl Simulation{
|
|||||||
let posy = bird.shape.y;
|
let posy = bird.shape.y;
|
||||||
let average = averages[i as usize];
|
let average = averages[i as usize];
|
||||||
|
|
||||||
|
let mut added_velocity:Point = Point::new(0,0);
|
||||||
|
|
||||||
if posx > average.x{
|
if posx > average.x{
|
||||||
if bird.velocity.x - COHERENCE_RATE < -MAX_BIRD_SPEED{
|
added_velocity.x -= COHERENCE_RATE;
|
||||||
bird.velocity.x = -MAX_BIRD_SPEED;
|
|
||||||
}else{
|
|
||||||
bird.velocity.x -= COHERENCE_RATE;
|
|
||||||
}
|
|
||||||
}else if posx < average.x{
|
}else if posx < average.x{
|
||||||
if bird.velocity.x + COHERENCE_RATE > MAX_BIRD_SPEED{
|
added_velocity.x += COHERENCE_RATE;
|
||||||
bird.velocity.x = MAX_BIRD_SPEED;
|
|
||||||
}else{
|
|
||||||
bird.velocity.x += COHERENCE_RATE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if posy > average.y{
|
if posy > average.y{
|
||||||
if bird.velocity.y - COHERENCE_RATE < -MAX_BIRD_SPEED{
|
added_velocity.y -= COHERENCE_RATE;
|
||||||
bird.velocity.y = -MAX_BIRD_SPEED;
|
|
||||||
}else{
|
|
||||||
bird.velocity.y -= COHERENCE_RATE;
|
|
||||||
}
|
|
||||||
}else if posy < average.y{
|
}else if posy < average.y{
|
||||||
if bird.velocity.y + COHERENCE_RATE > MAX_BIRD_SPEED{
|
added_velocity.y += COHERENCE_RATE;
|
||||||
bird.velocity.y = MAX_BIRD_SPEED;
|
|
||||||
}else{
|
|
||||||
bird.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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -136,75 +144,175 @@ impl Simulation{
|
|||||||
let posy = bird.shape.y;
|
let posy = bird.shape.y;
|
||||||
let average = averages[i as usize];
|
let average = averages[i as usize];
|
||||||
|
|
||||||
if posx > average.x{
|
let mut added_velocity:Point = Point::new(0,0);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if posy > average.y{
|
if posx > average.x{
|
||||||
if bird.velocity.y + SEPRATION_RATE > MAX_BIRD_SPEED{
|
added_velocity.x -= SEPRATION_RATE;
|
||||||
bird.velocity.y = MAX_BIRD_SPEED;
|
}else if posx < average.x{
|
||||||
}else{
|
added_velocity.x += SEPRATION_RATE;
|
||||||
bird.velocity.y += SEPRATION_RATE;
|
}
|
||||||
}
|
|
||||||
}else if posy < average.y{
|
if posy > average.y{
|
||||||
if bird.velocity.y - SEPRATION_RATE < -MAX_BIRD_SPEED{
|
added_velocity.y -= SEPRATION_RATE;
|
||||||
bird.velocity.y = -MAX_BIRD_SPEED;
|
}else if posy < average.y{
|
||||||
}else{
|
added_velocity.y += SEPRATION_RATE;
|
||||||
bird.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){
|
pub fn apply_alignement(&mut self){
|
||||||
|
// first we calculate all the averages for every birds
|
||||||
|
let mut averages:Vec<Point> = 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){
|
pub fn update(&mut self){
|
||||||
self.apply_coherence();
|
self.apply_coherence();
|
||||||
self.apply_separation();
|
|
||||||
self.apply_alignement();
|
self.apply_alignement();
|
||||||
|
self.apply_separation();
|
||||||
|
|
||||||
for bird in &mut self.birds{
|
for bird in &mut self.birds{
|
||||||
|
check_velocity(bird);
|
||||||
let mut posx = bird.shape.x;
|
let mut posx = bird.shape.x;
|
||||||
let mut posy = bird.shape.y;
|
let mut posy = bird.shape.y;
|
||||||
let width:i32 = bird.shape.width() as i32;
|
let width:i32 = bird.shape.width() as i32;
|
||||||
let height:i32 = bird.shape.height() as i32;
|
let height:i32 = bird.shape.height() as i32;
|
||||||
//let left_wall = WINDOW_WIDTH - width;
|
|
||||||
//let bottom_wall = WINDOW_HEIGHT- height;
|
|
||||||
|
|
||||||
if posx + bird.velocity.x > WINDOW_WIDTH - width{
|
let push_back = 1;
|
||||||
posx = 0;
|
let soft_border_margin = 30;
|
||||||
//bird.velocity.x -= bird.velocity.x / 2;
|
let left_soft_border = 0 + soft_border_margin;
|
||||||
|
let right_soft_border = WINDOW_WIDTH - soft_border_margin;
|
||||||
|
let top_soft_border = 0 + soft_border_margin;
|
||||||
|
let bottom_soft_border = WINDOW_HEIGHT -soft_border_margin;
|
||||||
|
|
||||||
|
|
||||||
|
if posx + bird.velocity.x > WINDOW_WIDTH - width || posx + bird.velocity.x < 0{
|
||||||
|
bird.velocity.x = 0;
|
||||||
}
|
}
|
||||||
if posx + bird.velocity.x < 0{
|
if posy + bird.velocity.y > WINDOW_HEIGHT - height || posy + bird.velocity.y < 0{
|
||||||
posx = WINDOW_WIDTH - bird.shape.width() as i32;
|
bird.velocity.y = 0;
|
||||||
//bird.velocity.x += bird.velocity.x / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if posy + bird.velocity.y > WINDOW_HEIGHT - height{
|
if posx + bird.velocity.x > right_soft_border && bird.velocity.x <= 0{
|
||||||
posy = 0;
|
//the bird is coming from the border so we accelerate it
|
||||||
//bird.velocity.y -= bird.velocity.y / 2;
|
bird.velocity.x -= push_back;
|
||||||
|
}else{
|
||||||
|
bird.velocity.x += push_back;
|
||||||
}
|
}
|
||||||
if posy + bird.velocity.y < 0{
|
if posx - bird.velocity.x < left_soft_border && bird.velocity.x >= 0{
|
||||||
posy = WINDOW_HEIGHT - bird.shape.height() as i32;
|
//the bird is coming from the border so we accelerate it
|
||||||
//bird.velocity.x += bird.velocity.x / 2;
|
bird.velocity.x += push_back;
|
||||||
|
}else{
|
||||||
|
bird.velocity.x -= push_back;
|
||||||
|
}
|
||||||
|
|
||||||
|
if posy + bird.velocity.y > bottom_soft_border && bird.velocity.y <= 0{
|
||||||
|
//the bird is coming from the border so we accelerate it
|
||||||
|
bird.velocity.y -= push_back;
|
||||||
|
}else{
|
||||||
|
bird.velocity.y += push_back;
|
||||||
|
}
|
||||||
|
if posy - bird.velocity.y < top_soft_border && bird.velocity.y >= 0{
|
||||||
|
//the bird is coming from the border so we accelerate it
|
||||||
|
bird.velocity.y += push_back;
|
||||||
|
}else{
|
||||||
|
bird.velocity.y -= push_back;
|
||||||
}
|
}
|
||||||
|
|
||||||
posx += bird.velocity.x;
|
posx += bird.velocity.x;
|
||||||
posy += bird.velocity.y;
|
posy += bird.velocity.y;
|
||||||
|
|
||||||
bird.shape.set_x(posx);
|
bird.shape.set_x(posx);
|
||||||
bird.shape.set_y(posy);
|
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<sdl2::video::Window>,event_pump:&mut sdl2::EventPump,game:&mut Simulation){
|
pub fn main_loop(canvas: &mut sdl2::render::Canvas<sdl2::video::Window>,event_pump:&mut sdl2::EventPump,game:&mut Simulation){
|
||||||
'running: loop {
|
'running: loop {
|
||||||
@@ -217,12 +325,10 @@ pub fn main_loop(canvas: &mut sdl2::render::Canvas<sdl2::video::Window>,event_pu
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MAIN LOOP
|
// MAIN LOOP
|
||||||
game.update();
|
game.update();
|
||||||
game.render(canvas);
|
game.render(canvas);
|
||||||
// MAIN LOOP
|
// MAIN LOOP
|
||||||
|
|
||||||
canvas.present();
|
canvas.present();
|
||||||
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
|
||||||
}
|
}
|
||||||
@@ -230,7 +336,7 @@ pub fn main_loop(canvas: &mut sdl2::render::Canvas<sdl2::video::Window>,event_pu
|
|||||||
pub fn generate_birds() -> Vec<Bird>{
|
pub fn generate_birds() -> Vec<Bird>{
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut birds = Vec::with_capacity(BIRDS_COUNT as usize);
|
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 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));
|
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});
|
birds.push(Bird{shape:rectangle,velocity:velocity});
|
||||||
|
|||||||
Reference in New Issue
Block a user