use bevy::prelude::*; #[derive(Component)] struct Mover; fn main() { App::new() .insert_resource(Movement { dx: 0.0, dy: 0.0 }) .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, (input, decay, movement)) .run(); } fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(( Camera3dBundle { transform: Transform::from_xyz(0.0, 12.0, 18.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() }, Mover, )); commands.spawn(PointLightBundle { point_light: PointLight { shadows_enabled: true, ..default() }, transform: Transform::from_xyz(4.0, 8.0, 4.0), ..default() }); for x in 0..24 { for y in 0..24 { let x = x - 12; let y = y - 12; let z = if x == -12 || x == 11 || y == -12 || y == 11 || rand::random::() < 0.25 { 0.0 } else { -2.0 }; let rotation = match rand::random::() % 4 { 0 => 0.0, 1 => 0.5, 2 => 1.0, _ => 1.5, } * std::f32::consts::PI; commands.spawn(SceneBundle { scene: asset_server.load("test-cube.glb#Scene0"), transform: Transform::from_xyz((x * 2) as f32, z, (y * 2) as f32) .with_rotation(Quat::from_rotation_y(rotation)), ..default() }); } } } #[derive(Debug, Resource)] struct Movement { dx: f32, dy: f32, } impl Default for Movement { fn default() -> Movement { Movement { dx: 0.0, dy: 0.0 } } } const ACCEL: f32 = 0.002; fn input(keyboard: Res>, mut mvmt: ResMut) { if keyboard.pressed(KeyCode::ArrowUp) { mvmt.dy = (mvmt.dy - ACCEL).clamp(-0.5, 0.5); } if keyboard.pressed(KeyCode::ArrowDown) { mvmt.dy = (mvmt.dy + ACCEL).clamp(-0.5, 0.5); } if keyboard.pressed(KeyCode::ArrowLeft) { mvmt.dx = (mvmt.dx - ACCEL).clamp(-0.5, 0.5); } if keyboard.pressed(KeyCode::ArrowRight) { mvmt.dx = (mvmt.dx + ACCEL).clamp(-0.5, 0.5); } } fn decay(mut mvmt: ResMut) { if mvmt.dx.abs() < 0.001 { mvmt.dx = 0.0; } else { mvmt.dx *= 0.90; } if mvmt.dy.abs() < 0.001 { mvmt.dy = 0.0; } else { mvmt.dy *= 0.90; } } fn movement(mut query: Query<&mut Transform, With>, mvmt: Res, time: Res