130 lines
3.9 KiB
Rust
130 lines
3.9 KiB
Rust
use bevy::{
|
|
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
|
|
input::keyboard::Key,
|
|
prelude::{
|
|
children, default, px, warn, App, AssetServer, Assets, ButtonInput, Camera3d, ClearColor,
|
|
Color, Commands, DefaultPlugins, Entity, FontSize, GlobalAmbientLight, IntoScheduleConfigs,
|
|
Mesh, Mesh3d, MeshMaterial3d, Node, Plane3d, PositionType, Query, Res, ResMut,
|
|
StandardMaterial, Startup, Text, TextFont, Transform, Update, Vec2, Vec3, Visibility,
|
|
Window, With,
|
|
},
|
|
};
|
|
use rstar::RTree;
|
|
use toids::{
|
|
handle_inputs, init_naybs, setup_channels, spawn_background, turkey_time, update_buddies,
|
|
update_naybs, update_pos, update_vel, BackgroundHandle, Config, LookAt, Naybs, Paused,
|
|
Positions,
|
|
};
|
|
|
|
fn main() {
|
|
let config: toids::Config = argh::from_env();
|
|
App::new()
|
|
.add_plugins(DefaultPlugins)
|
|
.add_plugins((
|
|
FrameTimeDiagnosticsPlugin::default(),
|
|
LogDiagnosticsPlugin::default(),
|
|
))
|
|
.insert_resource(config)
|
|
.insert_resource(Paused::default())
|
|
.insert_resource(Positions::default())
|
|
.insert_resource(ClearColor(Color::srgb(0.64, 0.745, 0.937))) // a nice light blue
|
|
.insert_resource(GlobalAmbientLight {
|
|
color: Color::WHITE,
|
|
brightness: 150.0,
|
|
affects_lightmapped_meshes: true,
|
|
..Default::default()
|
|
})
|
|
.insert_resource(Naybs {
|
|
index: RTree::new(),
|
|
positions: None,
|
|
})
|
|
.insert_resource(LookAt::default())
|
|
.add_systems(
|
|
Startup,
|
|
(setup_channels, setup, init_naybs, spawn_background).chain(),
|
|
)
|
|
.add_systems(
|
|
Update,
|
|
(update_pos, update_buddies, update_vel)
|
|
.chain()
|
|
.run_if(should_run),
|
|
)
|
|
.add_systems(
|
|
Update,
|
|
(handle_inputs, close_on_esc, update_naybs.after(update_pos)),
|
|
)
|
|
//.add_systems(Update, update_gizmos)
|
|
.run();
|
|
}
|
|
|
|
fn setup(
|
|
mut commands: Commands,
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
mut materials: ResMut<Assets<StandardMaterial>>,
|
|
mut positions: ResMut<Positions>,
|
|
config: Res<Config>,
|
|
models: Res<AssetServer>,
|
|
) {
|
|
let rand = &mut rand::rng();
|
|
|
|
commands.spawn((
|
|
Transform::from_xyz(0., 5.0, 25.).looking_at(Vec3::new(0.0, 5.0, 0.0), Vec3::Y),
|
|
Camera3d::default(),
|
|
));
|
|
// plane
|
|
commands.spawn((
|
|
Mesh3d(meshes.add(Mesh::from(Plane3d::new(Vec3::Y, Vec2::splat(500.0))))),
|
|
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.9, 0.3))),
|
|
Visibility::Visible,
|
|
Transform::default(),
|
|
));
|
|
|
|
for _ in 0..config.toids {
|
|
turkey_time(&mut commands, rand, &models, &mut positions);
|
|
}
|
|
|
|
// instructions
|
|
commands.spawn((
|
|
Visibility::Visible,
|
|
Node {
|
|
position_type: PositionType::Absolute,
|
|
top: px(12.0),
|
|
left: px(12.0),
|
|
..default()
|
|
},
|
|
children![(
|
|
Text::new("Up and down for camera forward and back; hold shift to change height.\nLeft or right to move left or right.\nPress 'SPACE' to pause, 'ESC' to quit."),
|
|
TextFont {
|
|
font_size: FontSize::Px(20.0),
|
|
..default()
|
|
},
|
|
)],
|
|
));
|
|
}
|
|
|
|
fn close_on_esc(
|
|
mut commands: Commands,
|
|
windows: Query<Entity, With<Window>>,
|
|
input: Res<ButtonInput<Key>>,
|
|
handle: ResMut<BackgroundHandle>,
|
|
) {
|
|
let background_gone = handle.as_ref().is_finished();
|
|
if background_gone {
|
|
warn!("background is gone, shutting down");
|
|
}
|
|
|
|
let exited = background_gone || input.just_pressed(Key::Escape);
|
|
if !exited {
|
|
return;
|
|
}
|
|
|
|
drop(handle);
|
|
|
|
for window in windows.iter() {
|
|
commands.entity(window).despawn();
|
|
}
|
|
}
|
|
|
|
fn should_run(paused: Res<Paused>) -> bool {
|
|
!**paused
|
|
}
|