2025-11-27 19:49:04 -05:00
|
|
|
use bevy::prelude::*;
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
const MAX_SAILING_SPEED: f32 = 0.9;
|
|
|
|
|
const MAX_TURN_SPEED: f32 = 0.1;
|
|
|
|
|
|
|
|
|
|
#[derive(Component, Default)]
|
2025-11-27 19:49:04 -05:00
|
|
|
struct EntityPhysics {
|
|
|
|
|
x: f32,
|
|
|
|
|
y: f32,
|
|
|
|
|
speed: f32,
|
2025-11-28 10:16:58 -05:00
|
|
|
turn_speed: f32,
|
2025-11-27 19:49:04 -05:00
|
|
|
heading: f32,
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
#[derive(Component, Default)]
|
|
|
|
|
struct InputState {
|
|
|
|
|
x: f32,
|
|
|
|
|
y: f32,
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-27 19:49:04 -05:00
|
|
|
fn main() {
|
|
|
|
|
let mut app = App::new();
|
|
|
|
|
|
|
|
|
|
app.add_plugins(DefaultPlugins)
|
|
|
|
|
.add_systems(Startup, (hello_world, camera_setup, sprite_setup).chain())
|
|
|
|
|
.add_systems(Update, (handle_keys, player_physics).chain());
|
|
|
|
|
|
|
|
|
|
app.run();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn hello_world() {
|
|
|
|
|
println!("Hello, world!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn camera_setup(mut clear_color: ResMut<ClearColor>, mut commands: Commands) {
|
2025-11-28 10:30:18 -05:00
|
|
|
*clear_color = ClearColor(Color::linear_rgb(0.1, 0.4, 0.7));
|
2025-11-27 19:49:04 -05:00
|
|
|
|
|
|
|
|
commands.spawn(Camera2d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn sprite_setup(assets: Res<AssetServer>, mut commands: Commands) {
|
|
|
|
|
let sprite_handle = assets.load("sprite-0001.png");
|
|
|
|
|
|
|
|
|
|
commands.spawn((
|
|
|
|
|
Sprite {
|
|
|
|
|
image: sprite_handle,
|
|
|
|
|
..default()
|
|
|
|
|
},
|
2025-11-28 10:16:58 -05:00
|
|
|
EntityPhysics::default(),
|
|
|
|
|
InputState::default(),
|
2025-11-27 19:49:04 -05:00
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
fn handle_keys(mut q_player: Query<&mut InputState>, keys: Res<ButtonInput<KeyCode>>) {
|
2025-11-27 19:49:04 -05:00
|
|
|
if keys.just_pressed(KeyCode::KeyQ) {
|
|
|
|
|
info!("Quit.");
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
let Ok(mut input) = q_player.single_mut() else {
|
2025-11-27 19:49:04 -05:00
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
if keys.pressed(KeyCode::ArrowUp) {
|
|
|
|
|
input.y = 1.;
|
|
|
|
|
} else if keys.pressed(KeyCode::ArrowDown) {
|
|
|
|
|
input.y = -1.;
|
|
|
|
|
} else {
|
|
|
|
|
input.y = 0.;
|
2025-11-27 19:49:04 -05:00
|
|
|
}
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
if keys.pressed(KeyCode::ArrowRight) {
|
|
|
|
|
input.x = 1.;
|
|
|
|
|
} else if keys.pressed(KeyCode::ArrowLeft) {
|
|
|
|
|
input.x = -1.;
|
|
|
|
|
} else {
|
|
|
|
|
input.x = 0.;
|
2025-11-27 19:49:04 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
fn player_physics(mut q_player: Query<(&InputState, &mut EntityPhysics, &mut Transform)>) {
|
|
|
|
|
let Ok((input, mut physics, mut transform)) = q_player.single_mut() else {
|
2025-11-27 19:49:04 -05:00
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
|
2025-11-28 10:16:58 -05:00
|
|
|
if input.x < 0. {
|
|
|
|
|
physics.turn_speed -= 0.1;
|
|
|
|
|
} else if input.x > 0. {
|
|
|
|
|
physics.turn_speed += 0.1;
|
2025-11-28 10:30:18 -05:00
|
|
|
} else {
|
|
|
|
|
physics.turn_speed *= 0.99;
|
2025-11-28 10:16:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
physics.turn_speed = physics.turn_speed.clamp(-MAX_TURN_SPEED, MAX_TURN_SPEED);
|
|
|
|
|
physics.heading += physics.turn_speed * 0.1;
|
|
|
|
|
|
|
|
|
|
if input.y > 0. {
|
|
|
|
|
physics.speed += 0.1;
|
|
|
|
|
} else if input.y < 0. {
|
|
|
|
|
physics.speed -= 0.1;
|
|
|
|
|
} else {
|
2025-11-28 10:30:18 -05:00
|
|
|
physics.speed *= 0.999;
|
2025-11-28 10:16:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
physics.speed = physics.speed.clamp(-MAX_SAILING_SPEED, MAX_SAILING_SPEED);
|
|
|
|
|
|
2025-11-27 19:49:04 -05:00
|
|
|
let x_speed = physics.heading.sin() * physics.speed;
|
|
|
|
|
let y_speed = physics.heading.cos() * physics.speed;
|
|
|
|
|
|
|
|
|
|
physics.x += x_speed;
|
|
|
|
|
physics.y += y_speed;
|
|
|
|
|
|
|
|
|
|
transform.translation = Vec3 {
|
|
|
|
|
x: physics.x as f32,
|
|
|
|
|
y: physics.y as f32,
|
|
|
|
|
z: 0.,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
transform.rotation = Quat::from_axis_angle(
|
|
|
|
|
Vec3 {
|
|
|
|
|
x: 0.,
|
|
|
|
|
y: 0.,
|
|
|
|
|
z: -1.,
|
|
|
|
|
},
|
|
|
|
|
physics.heading,
|
|
|
|
|
);
|
|
|
|
|
}
|