added small game logic, cooking burger and serving customer

This commit is contained in:
2026-01-02 17:27:44 +00:00
parent 6218b4999a
commit 5bc69c97a1
4 changed files with 138 additions and 35 deletions

BIN
assets/models/customer.glb Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -4,14 +4,42 @@ fn main() {
App::new() App::new()
.add_plugins(DefaultPlugins) .add_plugins(DefaultPlugins)
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems(Update, (handle_click, move_to_target)) .add_systems(
Update,
(handle_click, move_to_target, fryer_cook, customer_serve),
)
.run(); .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)] #[derive(Component)]
struct Player { struct Player {
move_speed: f32, holding: Item,
height_offset: f32, progress: f32,
} }
#[derive(Component)] #[derive(Component)]
@@ -31,22 +59,7 @@ fn setup(
Transform::from_xyz(0.0, 25.0, -25.0).looking_at(Vec3::ZERO, Vec3::Y), Transform::from_xyz(0.0, 25.0, -25.0).looking_at(Vec3::ZERO, Vec3::Y),
)); ));
// Player
commands.spawn((
SceneRoot(asset_server.load("models/employee.glb#Scene0")),
//MeshMaterial3d(materials.add(Color::srgb(0.9, 0.83, 0.6))),
Transform::from_xyz(0.0, 1.5, 0.0).with_scale(Vec3::splat(0.5)),
Player {
move_speed: 10.0,
height_offset: 1.5,
},
MoveTarget {
position: Vec3::new(0.0, 0.0, 0.0),
},
));
// Light // Light
commands.insert_resource(AmbientLight { commands.insert_resource(AmbientLight {
color: Color::WHITE, color: Color::WHITE,
brightness: 200.0, // Subtle fill light so shadows aren't pitch black brightness: 200.0, // Subtle fill light so shadows aren't pitch black
@@ -67,27 +80,71 @@ fn setup(
)), )),
)); ));
/*commands.spawn((
PointLight {
intensity: 1000000.0,
shadows_enabled: true,
..default()
},
Transform::from_xyz(0.0, 10.0, 0.0),
));*/
// Plane // Plane
commands.spawn(( commands.spawn((
Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(50.0)))), Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(50.0)))),
MeshMaterial3d(materials.add(Color::srgb(0.3, 0.5, 0.3))), 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),
},
));
// 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( fn handle_click(
mouse_button: Res<ButtonInput<MouseButton>>, mouse_button: Res<ButtonInput<MouseButton>>,
windows: Query<&Window>, windows: Query<&Window>,
camera_query: Query<(&Camera, &GlobalTransform)>, camera_query: Query<(&Camera, &GlobalTransform)>,
mut target_query: Query<&mut MoveTarget>, mut target_query: Query<&mut MoveTarget, With<Player>>,
) { ) {
// Guard clause // Guard clause
if !mouse_button.just_pressed(MouseButton::Right) { if !mouse_button.just_pressed(MouseButton::Right) {
@@ -126,9 +183,9 @@ fn handle_click(
} }
} }
fn move_to_target(mut query: Query<(&mut Transform, &MoveTarget, &Player)>, time: Res<Time>) { fn move_to_target(mut query: Query<(&mut Transform, &MoveTarget, &Unit)>, time: Res<Time>) {
for (mut transform, target, player) in query.iter_mut() { for (mut transform, target, unit) in query.iter_mut() {
let adjusted_target = target.position + Vec3::Y * player.height_offset; let adjusted_target = target.position + Vec3::Y * unit.height_offset;
let direction = adjusted_target - transform.translation; let direction = adjusted_target - transform.translation;
let distance = direction.length(); let distance = direction.length();
@@ -137,16 +194,62 @@ fn move_to_target(mut query: Query<(&mut Transform, &MoveTarget, &Player)>, time
continue; continue;
} }
let move_amount = player.move_speed * time.delta_secs(); let move_amount = unit.move_speed * time.delta_secs();
// Snap // Snap
if distance < move_amount { if distance < move_amount {
transform.translation = adjusted_target; transform.translation = adjusted_target;
} else { } else {
transform.translation += direction.normalize() * move_amount; transform.translation += direction.normalize() * move_amount;
transform.look_at(adjusted_target, Vec3::Y);
}
}
}
let target_look = target.position + Vec3::Y * player.height_offset; fn fryer_cook(
transform.look_at(target_look, Vec3::Y); mut player: Query<(&mut Player, &Transform)>,
fryer: Query<(&Fryer, &Transform)>,
time: Res<Time>,
) {
for (mut player_data, player_transform) in player.iter_mut() {
if player_data.holding == Item::Burger {
continue;
}
for (fryer, fryer_transform) in fryer.iter() {
let distance = player_transform.translation - fryer_transform.translation;
if distance.length() < fryer.range {
player_data.progress += fryer.speed * time.delta_secs();
if player_data.progress > 100.0 {
player_data.holding = Item::Burger;
println!("YOU HAVE BURGER!!");
}
} else {
player_data.progress = 0.0;
}
}
}
}
fn customer_serve(
mut customer: Query<(&mut Customer, &mut MoveTarget, &Transform)>,
mut player: Query<(&mut Player, &Transform)>,
) {
for (mut player_data, player_transform) in player.iter_mut() {
if player_data.holding == Item::None {
continue;
}
for (mut customer_data, mut customer_target, customer_transform) in customer.iter_mut() {
if player_data.holding != customer_data.order {
continue;
}
let distance = player_transform.translation - customer_transform.translation;
if distance.length() < customer_data.range {
player_data.holding = Item::None;
customer_data.served = true;
customer_target.position = Vec3::new(20.0, 0.0, 0.0);
}
} }
} }
} }