|
|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
|
|
|
|
|
use bevy::{prelude::*, window::WindowResized};
|
|
|
|
|
use bevy_prototype_lyon::prelude::*;
|
|
|
|
|
use rand::prelude::*;
|
|
|
|
|
use crate::agent::Agent;
|
|
|
|
|
|
|
|
|
|
#[derive(Component)]
|
|
|
|
|
struct GridLine;
|
|
|
|
|
@ -14,6 +16,7 @@ struct WorldPluginState
|
|
|
|
|
grid_height: f32,
|
|
|
|
|
top_margin: f32,
|
|
|
|
|
|
|
|
|
|
num_agents: i32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct WorldPlugin
|
|
|
|
|
@ -21,6 +24,8 @@ pub struct WorldPlugin
|
|
|
|
|
pub grid_width: f32,
|
|
|
|
|
pub grid_height: f32,
|
|
|
|
|
pub top_margin: f32,
|
|
|
|
|
|
|
|
|
|
pub num_agents: i32,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Plugin for WorldPlugin
|
|
|
|
|
@ -40,6 +45,7 @@ impl Plugin for WorldPlugin
|
|
|
|
|
grid_width: self.grid_width,
|
|
|
|
|
grid_height: self.grid_height,
|
|
|
|
|
top_margin: self.top_margin,
|
|
|
|
|
num_agents: self.num_agents,
|
|
|
|
|
})
|
|
|
|
|
.add_systems(Update, on_resize)
|
|
|
|
|
.add_systems(Startup, setup);
|
|
|
|
|
@ -54,20 +60,71 @@ fn setup(mut commands: Commands, settings: Res<WorldPluginState>)
|
|
|
|
|
let cell_width = settings.window_width / (settings.grid_width - 1.0);
|
|
|
|
|
let cell_height = (settings.window_height - settings.top_margin) / (settings.grid_height - 1.0);
|
|
|
|
|
let line_size = 2.0;
|
|
|
|
|
let half_screen_width = settings.window_width / 2.0;
|
|
|
|
|
let half_screen_height = (settings.window_height - settings.top_margin) / 2.0;
|
|
|
|
|
// let half_screen_width = settings.window_width / 2.0;
|
|
|
|
|
// let half_screen_height = (settings.window_height - settings.top_margin) / 2.0;
|
|
|
|
|
// for i in 0..settings.grid_width as i32
|
|
|
|
|
// {
|
|
|
|
|
// let point_a = Vec2::new(i as f32 * cell_width - half_screen_width, -half_screen_height - settings.top_margin);
|
|
|
|
|
// let point_b = Vec2::new(i as f32 * cell_width - half_screen_width, half_screen_height - settings.top_margin);
|
|
|
|
|
// add_line(&mut commands, point_a, point_b, line_size);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// for i in 0..settings.grid_height as i32
|
|
|
|
|
// {
|
|
|
|
|
// let point_a = Vec2::new(-half_screen_width, i as f32 * cell_height - half_screen_height - settings.top_margin);
|
|
|
|
|
// let point_b = Vec2::new(half_screen_width, i as f32 * cell_height - half_screen_height - settings.top_margin);
|
|
|
|
|
// add_line(&mut commands, point_a, point_b, line_size);
|
|
|
|
|
// }
|
|
|
|
|
draw_grid(&mut commands, &settings);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Generate new agents
|
|
|
|
|
info!("Generating Agents...");
|
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
|
for i in 0..settings.num_agents
|
|
|
|
|
{
|
|
|
|
|
// new Agent with random grid index
|
|
|
|
|
let x: i32 = rng.gen_range(0..settings.grid_width as i32);
|
|
|
|
|
let y: i32 = rng.gen_range(0..settings.grid_height as i32);
|
|
|
|
|
let agent = Agent::new(x, y);
|
|
|
|
|
|
|
|
|
|
// convert index to screen coords
|
|
|
|
|
let screen_x = x as f32 * cell_width + cell_width / 2.0;
|
|
|
|
|
let screen_y = y as f32 * cell_height + cell_height / 2.0;
|
|
|
|
|
|
|
|
|
|
// spawn agents in random grid locations
|
|
|
|
|
let circle = shapes::Circle{radius: cell_width / 2.0 - line_size, center: Vec2::new(screen_x, screen_y)};
|
|
|
|
|
|
|
|
|
|
commands.spawn((ShapeBundle{
|
|
|
|
|
path: GeometryBuilder::build_as(&circle),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
Fill::color(Color::GREEN),
|
|
|
|
|
agent,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn draw_grid(commands: &mut Commands, settings: &Res<WorldPluginState>)
|
|
|
|
|
{
|
|
|
|
|
let cell_width = settings.window_width / (settings.grid_width - 1.0);
|
|
|
|
|
let cell_height = (settings.window_height - settings.top_margin) / (settings.grid_height - 1.0);
|
|
|
|
|
let line_size = 2.0;
|
|
|
|
|
// let half_screen_width = settings.window_width / 2.0;
|
|
|
|
|
// let half_screen_height = (settings.window_height - settings.top_margin) / 2.0;
|
|
|
|
|
for i in 0..settings.grid_width as i32
|
|
|
|
|
{
|
|
|
|
|
let point_a = Vec2::new(i as f32 * cell_width - half_screen_width, -half_screen_height - settings.top_margin);
|
|
|
|
|
let point_b = Vec2::new(i as f32 * cell_width - half_screen_width, half_screen_height - settings.top_margin);
|
|
|
|
|
add_line(&mut commands, point_a, point_b, line_size);
|
|
|
|
|
let point_a = Vec2::new(i as f32 * cell_width, 0.0);
|
|
|
|
|
let point_b = Vec2::new(i as f32 * cell_width, settings.window_height - settings.top_margin);
|
|
|
|
|
add_line(commands, point_a, point_b, line_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for i in 0..settings.grid_height as i32
|
|
|
|
|
{
|
|
|
|
|
let point_a = Vec2::new(-half_screen_width, i as f32 * cell_height - half_screen_height - settings.top_margin);
|
|
|
|
|
let point_b = Vec2::new(half_screen_width, i as f32 * cell_height - half_screen_height - settings.top_margin);
|
|
|
|
|
add_line(&mut commands, point_a, point_b, line_size);
|
|
|
|
|
let point_a = Vec2::new(0.0, i as f32 * cell_height);
|
|
|
|
|
let point_b = Vec2::new(settings.window_width, i as f32 * cell_height);
|
|
|
|
|
add_line(commands, point_a, point_b, line_size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -78,6 +135,7 @@ fn add_line(commands: &mut Commands, point_a: Vec2, point_b: Vec2, line_size: f3
|
|
|
|
|
commands.spawn((
|
|
|
|
|
ShapeBundle {
|
|
|
|
|
path: GeometryBuilder::build_as(&line),
|
|
|
|
|
//transform: Transform::from_translation(Vec3::new(0., 0., -1.0)),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
Stroke::new(Color::BLACK, line_size),
|
|
|
|
|
@ -87,18 +145,25 @@ fn add_line(commands: &mut Commands, point_a: Vec2, point_b: Vec2, line_size: f3
|
|
|
|
|
|
|
|
|
|
fn on_resize(mut commands: Commands, mut settings: ResMut<WorldPluginState>, mut resize_reader: EventReader<WindowResized>, mut grid: Query<(Entity, &GridLine)> )
|
|
|
|
|
{
|
|
|
|
|
let mut has_event = false;
|
|
|
|
|
for e in resize_reader.iter()
|
|
|
|
|
{
|
|
|
|
|
// When resolution is being changed
|
|
|
|
|
// info!("new window size: {:.1} x {:.1}", e.width, e.height);
|
|
|
|
|
settings.window_width = e.width;
|
|
|
|
|
settings.window_height = e.height;
|
|
|
|
|
has_event = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if has_event
|
|
|
|
|
{
|
|
|
|
|
for (entity, line) in &grid
|
|
|
|
|
{
|
|
|
|
|
commands.entity(entity).despawn();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
setup(commands, settings.into());
|
|
|
|
|
draw_grid(&mut commands, &settings.into());
|
|
|
|
|
info!("Redrawing");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|