|  | @@ -1,21 +1,25 @@
 | 
	
		
			
				|  |  |  use bevy::prelude::*;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  #[derive(Component)]
 | 
	
		
			
				|  |  | -struct Rotator;
 | 
	
		
			
				|  |  | +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, rotate)
 | 
	
		
			
				|  |  | +        .add_systems(Update, (input, decay, movement))
 | 
	
		
			
				|  |  |          .run();
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
 | 
	
		
			
				|  |  | -    commands.spawn(Camera3dBundle {
 | 
	
		
			
				|  |  | -        transform: Transform::from_xyz(0.0, 12.0, 18.0).looking_at(Vec3::ZERO, Vec3::Y),
 | 
	
		
			
				|  |  | -        ..default()
 | 
	
		
			
				|  |  | -    });
 | 
	
		
			
				|  |  | +    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 {
 | 
	
	
		
			
				|  | @@ -51,8 +55,59 @@ fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -fn rotate(mut query: Query<&mut Transform, With<Rotator>>, time: Res<Time>) {
 | 
	
		
			
				|  |  | +#[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<ButtonInput<KeyCode>>, mut mvmt: ResMut<Movement>) {
 | 
	
		
			
				|  |  | +    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<Movement>) {
 | 
	
		
			
				|  |  | +    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<Mover>>, mvmt: Res<Movement>, time: Res<Time>) {
 | 
	
		
			
				|  |  | +    if time.delta_seconds() == 0.0 {
 | 
	
		
			
				|  |  | +        return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      for mut transform in &mut query {
 | 
	
		
			
				|  |  | -        transform.rotate_y(time.delta_seconds() / 2.);
 | 
	
		
			
				|  |  | +        transform.translation += Vec3::new(
 | 
	
		
			
				|  |  | +            mvmt.dx / time.delta_seconds(),
 | 
	
		
			
				|  |  | +            0.0,
 | 
	
		
			
				|  |  | +            mvmt.dy / time.delta_seconds(),
 | 
	
		
			
				|  |  | +        );
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |