diff --git a/src/components.rs b/src/components.rs new file mode 100644 index 0000000..45054db --- /dev/null +++ b/src/components.rs @@ -0,0 +1,45 @@ +use bevy::prelude::*; + +#[derive(PartialEq)] +pub enum Item { + None, + Burger, +} + +#[derive(Component)] +pub struct Customer { + pub order: Item, + pub served: bool, + pub range: f32, +} + +#[derive(Component)] +pub struct Fryer { + pub range: f32, + pub speed: f32, +} + +#[derive(Component)] +pub struct Unit { + pub move_speed: f32, + pub height_offset: f32, +} + +#[derive(Component)] +pub struct Player { + pub holding: Item, + pub progress: f32, +} +#[derive(Component)] +pub struct ProgressBar { + pub width: f32, + pub player_height: f32, +} + +#[derive(Component)] +pub struct PlayerBurgerIndicator; + +#[derive(Component)] +pub struct MoveTarget { + pub position: Vec3, +} diff --git a/src/main.rs b/src/main.rs index 3d0b23f..f58493a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,9 @@ -use bevy::{light::NotShadowCaster, prelude::*}; +use bevy::prelude::*; + +mod components; +mod systems; + +use systems::{gameplay::*, movement::*, setup::*}; fn main() { App::new() @@ -17,335 +22,3 @@ fn main() { ) .run(); } - -#[derive(PartialEq)] -enum Item { - None, - Burger, -} - -#[derive(Component)] -struct Customer { - order: Item, - served: bool, - range: f32, -} - -#[derive(Component)] -struct Fryer { - range: f32, - speed: f32, -} - -#[derive(Component)] -struct Unit { - move_speed: f32, - height_offset: f32, -} - -#[derive(Component)] -struct Player { - holding: Item, - progress: f32, -} -#[derive(Component)] -struct ProgressBar { - width: f32, - player_height: f32, -} - -#[derive(Component)] -struct PlayerBurgerIndicator; - -#[derive(Component)] -struct MoveTarget { - position: Vec3, -} - -fn setup( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, - asset_server: Res, -) { - // Camera - commands.spawn(( - Camera3d::default(), - Transform::from_xyz(0.0, 25.0, -25.0).looking_at(Vec3::ZERO, Vec3::Y), - )); - - // Light - commands.insert_resource(AmbientLight { - color: Color::WHITE, - brightness: 200.0, // Subtle fill light so shadows aren't pitch black - ..default() - }); - - commands.spawn(( - DirectionalLight { - illuminance: 1000.0, - shadows_enabled: true, - ..default() - }, - Transform::from_rotation(Quat::from_euler( - EulerRot::XYZ, - -0.8, // Pitch down (looking down at scene) - 0.5, // Yaw (angle from side) - 0.0, // Roll (no rotation) - )), - )); - - // Plane - commands.spawn(( - Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(50.0)))), - MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))), - )); - - // Fryer - commands.spawn(( - Mesh3d(meshes.add(Cuboid::new(2.0, 1.75, 2.0))), - Transform::from_xyz(-10.0, 0.875, 0.0), - MeshMaterial3d(materials.add(Color::srgb(0.1, 0.1, 0.1))), - Fryer { - range: 3.0, - speed: 50.0, - }, - )); - - // Front Counter - commands.spawn(( - Mesh3d(meshes.add(Cuboid::new(2.0, 1.5, 10.0))), - Transform::from_xyz(10.0, 0.75, 0.0), - MeshMaterial3d(materials.add(Color::srgb(0.7, 0.7, 0.7))), - )); - - // Player - commands.spawn(( - SceneRoot(asset_server.load("models/employee.glb#Scene0")), - Transform::from_xyz(0.0, 1.5, 0.0).with_scale(Vec3::splat(0.5)), - Unit { - move_speed: 10.0, - height_offset: 1.5, - }, - Player { - holding: Item::None, - progress: 0.0, - }, - MoveTarget { - position: Vec3::new(0.0, 0.0, 0.0), - }, - // Burger indicator - children![( - SceneRoot(asset_server.load("models/burger.glb#Scene0")), - Transform::from_xyz(0.0, 7.1, 0.0).with_scale(Vec3::splat(0.9)), - Visibility::Hidden, - PlayerBurgerIndicator, - )], - )); - - // ProgressBar - commands.spawn(( - Mesh3d(meshes.add(Cuboid::new(4.0, 0.5, 0.1))), - MeshMaterial3d(materials.add(Color::srgb(0.0, 1.0, 0.0))), - Transform::from_xyz(0.0, 0.0, 0.0), - ProgressBar { - width: 1.0, - player_height: 4.0, - }, - NotShadowCaster, - )); - - // Customer - commands.spawn(( - SceneRoot(asset_server.load("models/customer.glb#Scene0")), - Transform::from_xyz(20.0, 1.5, 0.0).with_scale(Vec3::splat(0.5)), - Unit { - move_speed: 5.0, - height_offset: 1.5, - }, - Customer { - order: Item::Burger, - served: false, - range: 4.0, - }, - MoveTarget { - position: Vec3::new(12.0, 0.0, 0.0), - }, - )); -} - -fn handle_click( - mouse_button: Res>, - windows: Query<&Window>, - camera_query: Query<(&Camera, &GlobalTransform)>, - mut target_query: Query<&mut MoveTarget, With>, -) { - // Guard clause - if !mouse_button.just_pressed(MouseButton::Right) { - return; - } - - let Ok(window) = windows.single() else { - return; - }; - - let Some(cursor_position) = window.cursor_position() else { - return; - }; - - let Ok((camera, camera_transform)) = camera_query.single() else { - return; - }; - - let Ok(ray) = camera.viewport_to_world(camera_transform, cursor_position) else { - return; - }; - - // check for sky clicks - if ray.direction.y > 0.0 { - return; - } - - // Calculate the distance that the intercept with the ground occurs - let t = -ray.origin.y / ray.direction.y; - - // plug T into our formula - let intersection = ray.origin + ray.direction * t; - - for mut target in target_query.iter_mut() { - target.position = intersection; - } -} - -fn move_to_target(mut query: Query<(&mut Transform, &MoveTarget, &Unit)>, time: Res