83 lines
2.8 KiB
Rust
83 lines
2.8 KiB
Rust
use core::f32;
|
|
|
|
use avian2d::prelude::*;
|
|
use bevy::{
|
|
input::mouse::{AccumulatedMouseScroll, MouseScrollUnit},
|
|
math::curve::EaseFunction::SmoothStep,
|
|
prelude::*,
|
|
};
|
|
|
|
use super::objects::{Player, Radius};
|
|
|
|
/// Move the player character based on the keyboard input
|
|
pub fn move_player(
|
|
time: Res<Time>,
|
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
|
mut query: Single<(&mut LinearVelocity, &Radius), With<Player>>,
|
|
) {
|
|
let (ref mut velocity, radius) = *query;
|
|
|
|
let acceleration_energy = 150000.0;
|
|
// Although it would arguably be more accurate to divide by pi to get the actual mass (or include the density
|
|
// somehow), `acceleration_energy` is in arbitrary units so we can just pretend it's proper physics
|
|
let delta_v = acceleration_energy * time.delta_secs() / radius.0.powi(2);
|
|
|
|
let mut direction = Vec2::ZERO;
|
|
|
|
if keyboard_input.any_pressed([KeyCode::KeyW, KeyCode::ArrowUp]) {
|
|
direction.y += 1.0;
|
|
}
|
|
if keyboard_input.any_pressed([KeyCode::KeyS, KeyCode::ArrowDown]) {
|
|
direction.y -= 1.0;
|
|
}
|
|
if keyboard_input.any_pressed([KeyCode::KeyA, KeyCode::ArrowLeft]) {
|
|
direction.x -= 1.0;
|
|
}
|
|
if keyboard_input.any_pressed([KeyCode::KeyD, KeyCode::ArrowRight]) {
|
|
direction.x += 1.0;
|
|
}
|
|
|
|
// This would be easier if I could compare floats with 0 and still sleep at night
|
|
let circularize = if direction.x.abs() > 0.0 && direction.y.abs() > 0.0 {
|
|
f32::consts::FRAC_1_SQRT_2
|
|
} else {
|
|
1.0
|
|
};
|
|
|
|
// Kinda annoying I have to manually assign the fields here but I'll leave it in case I remember a better way later
|
|
velocity.x += direction.x * delta_v * circularize;
|
|
velocity.y += direction.y * delta_v * circularize;
|
|
}
|
|
|
|
/// Neatly exit game
|
|
pub fn quit(mut exit: MessageWriter<AppExit>) {
|
|
exit.write(AppExit::Success);
|
|
}
|
|
|
|
/// Follow the player character with the camera
|
|
pub fn move_camera(
|
|
time: Res<Time>,
|
|
mut camera: Single<&mut Transform, (Without<Player>, With<IsDefaultUiCamera>)>,
|
|
player: Single<&Transform, (With<Player>, Without<IsDefaultUiCamera>)>,
|
|
) {
|
|
camera.translation = camera.translation.lerp(
|
|
player.translation,
|
|
SmoothStep.sample_clamped(time.delta_secs() * 15.0),
|
|
);
|
|
}
|
|
|
|
/// Adjust the camera zoom based on the scroll wheel input
|
|
pub fn zoom_camera(
|
|
mut camera: Single<&mut Projection, With<IsDefaultUiCamera>>,
|
|
scroll: Res<AccumulatedMouseScroll>,
|
|
) -> Result {
|
|
let Projection::Orthographic(ref mut projection) = **camera else {
|
|
return Err("Default camera was not orthographic".into());
|
|
};
|
|
let scroll_type_multiplier = match scroll.unit {
|
|
MouseScrollUnit::Line => 0.1,
|
|
MouseScrollUnit::Pixel => 0.001,
|
|
};
|
|
projection.scale = (projection.scale - scroll.delta.y * scroll_type_multiplier).clamp(0.1, 4.0);
|
|
Ok(())
|
|
}
|