diff options
author | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-03-20 19:54:41 +0200 |
---|---|---|
committer | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-03-20 19:54:41 +0200 |
commit | aff2c30b3fa025def54cc5a249ba539d514b2a07 (patch) | |
tree | 5802383c30bf1580e2d7ef4d3bdf91e799a73add /src | |
parent | 221434eafec46c6e1974d40f17893fee379cead8 (diff) | |
download | martian-rescue-rs-aff2c30b3fa025def54cc5a249ba539d514b2a07.tar.gz martian-rescue-rs-aff2c30b3fa025def54cc5a249ba539d514b2a07.tar.bz2 martian-rescue-rs-aff2c30b3fa025def54cc5a249ba539d514b2a07.zip |
feat: player controls
Diffstat (limited to 'src')
-rw-r--r-- | src/controllable.rs | 5 | ||||
-rw-r--r-- | src/controllable/player.rs | 96 | ||||
-rw-r--r-- | src/lunar/systems.rs | 20 | ||||
-rw-r--r-- | src/main.rs | 26 | ||||
-rw-r--r-- | src/setup.rs | 8 |
5 files changed, 128 insertions, 27 deletions
diff --git a/src/controllable.rs b/src/controllable.rs index feaeced..3fce2e0 100644 --- a/src/controllable.rs +++ b/src/controllable.rs @@ -1,5 +1,2 @@ mod player; -pub use player::{ - ControlledObject, - Player, -};
\ No newline at end of file +pub use player::*; diff --git a/src/controllable/player.rs b/src/controllable/player.rs index a87ef9d..fdc110e 100644 --- a/src/controllable/player.rs +++ b/src/controllable/player.rs @@ -1,10 +1,98 @@ -use bevy::{ecs::component::Component, text::Text2d}; +use avian2d::prelude::*; +use bevy::prelude::*; + +use crate::lunar::DestPlanet; #[derive(Component)] pub struct Player { - // pub display_name: Text2d, + pub velocity: f32, + pub display_name: Text2d, pub mass_kg: f32, } -pub struct ControlledObject { +pub struct ControlledObject {} +enum Direction { + Up, + Down, + Left, + Right, + None, +} +fn map_key_to_movement(key: &KeyCode) -> Direction { + match key { + KeyCode::KeyW => Direction::Up, + KeyCode::KeyS => Direction::Down, + KeyCode::KeyA => Direction::Left, + KeyCode::KeyD => Direction::Right, + _ => Direction::None, + } +} +pub fn check_transition_level( + mut commands: Commands, + player_transform: Query<&Transform, (With<Player>, Without<DestPlanet>)>, + moon_transform: Query<(Entity, &DestPlanet, &Transform), (With<DestPlanet>, Without<Player>)> +) { + let (moon_e, moon, moon_t) = moon_transform.single(); + let player_t = player_transform.single(); + let shroud_padding = 1. + moon.radius; + let bounds = ( + Vec2 { + x: moon_t.translation.x - shroud_padding, + y: moon_t.translation.y - shroud_padding, + }, + Vec2 { + x: moon_t.translation.x + shroud_padding, + y: moon_t.translation.y + shroud_padding, + } + ); + if player_t.translation.x > bounds.0.x && + player_t.translation.x < bounds.1.x && + player_t.translation.y > bounds.0.y && + player_t.translation.y < bounds.1.y { + info!("CAN TRANSITION TO NEXT LEVEL"); + commands.entity(moon_e).despawn(); + } +} +pub fn camera_follow_player( + mut camera_transform: Query<&mut Transform, (With<Camera2d>, Without<Player>)>, + player_transform: Query<&Transform, (With<Player>, Without<Camera>)>, +) { + let mut camera_t = camera_transform.single_mut(); + let player_t = player_transform.single(); + camera_t.translation = player_t.translation; +} +pub fn player_movements( + time: Res<Time>, + input: Res<ButtonInput<KeyCode>>, + mut ps: Query<(&Player, &Sprite, &mut ExternalForce), (With<Player>)>, +) { + let movements: Vec<Direction> = input.get_pressed().map(map_key_to_movement).collect(); + for (p, s, mut propulsion) in &mut ps { + let mut pvel_vec = Vec2 { x: 0., y: 0. }; + let pv = p.velocity; + movements.iter().for_each(|m| match m { + Direction::Up => pvel_vec.y = pv, + Direction::Down => pvel_vec.y = -pv, + Direction::Left => pvel_vec.x = -pv, + Direction::Right => pvel_vec.x = pv, + Direction::None => pvel_vec = Vec2 { x: 0., y: 0. }, + }); + let pvv = pvel_vec.normalize_or_zero(); + propulsion.apply_force(pvv * pv); + } +} +pub fn setup_player_with_controls(mut commands: Commands) { + commands.spawn(( + Player { + velocity: 20000.0, + display_name: Text2d("Main player".to_string()), + mass_kg: 100., + }, + RigidBody::Dynamic, + Transform::from_xyz(0., 70., 0.), + ExternalForce::ZERO.with_persistence(false), + Sprite::from_color(Color::BLACK, Vec2 { x: 10., y: 10. }), + Collider::rectangle(10., 10.), + + )); +} -}
\ No newline at end of file diff --git a/src/lunar/systems.rs b/src/lunar/systems.rs index 4cdebdc..81fbbf2 100644 --- a/src/lunar/systems.rs +++ b/src/lunar/systems.rs @@ -1,3 +1,5 @@ +use core::f32; + use bevy::prelude::*; use avian2d::prelude::*; use super::DestPlanet; @@ -21,26 +23,28 @@ pub fn update_lunar_transform( let new_transform = lunar_period_to_vec( lod.period, lod.orbital_radius).normalize_or_zero() * lod.orbital_radius; + // println!("lunar transform: {}", new_transform); moon_transform.translation = Vec3 {x: new_transform.x, y: new_transform.y, z: 0.0}; - lod.period = dt * lod.orbital_velocity; + lod.period += dt * lod.orbital_velocity; + lod.period = if lod.period <= 2. * f32::consts::PI { lod.period } else { 0. } } pub fn setup_moon(mut cmd: Commands) { let objective_planet = DestPlanet { // display_name: String::from("Objective Planet"), - planet_mass_kg: 50.0, - radius: 5.0, + planet_mass_kg: 50000.0, + radius: 30.0, }; - let lunar_radius = 900.0; + let lunar_radius = 225.0; let r = (&objective_planet).radius; let m = (&objective_planet).planet_mass_kg; let initial_transform = lunar_period_to_vec(0., 100.); cmd.spawn(( objective_planet, - LunarOrbitalData { period: 0., orbital_velocity: 1., orbital_radius: lunar_radius}, - RigidBody::Dynamic, + LunarOrbitalData { period: 0., orbital_velocity: 1.0, orbital_radius: lunar_radius}, + RigidBody::Static, Transform::from_xyz(initial_transform.x, initial_transform.y, 0.0), Sprite::from_color(Color::BLACK, Vec2 { x: 30., y: 30. }), - Collider::circle(r), + Collider::rectangle(r, r), Mass(m), )); -}
\ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index 319eabc..5e821f9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod controllable; use avian2d::prelude::*; use bevy::{prelude::*, winit::WinitSettings}; use controllable::Player; +use lunar::DestPlanet; fn main() { println!("Hello, world!"); App::new() @@ -16,15 +17,19 @@ fn main() { Startup, ( setup::setup_starting_planet, - setup::setup_init, + setup::setup_init, + controllable::setup_player_with_controls, lunar::setup_moon ) ) .add_systems( Update, ( - update_gravitational_forces, - lunar::update_lunar_transform + lunar::update_lunar_transform, + controllable::player_movements, + controllable::camera_follow_player, + controllable::check_transition_level, + update_gravitational_forces, ) ) .run(); @@ -49,7 +54,7 @@ fn calculate_force_vector( pos_actor: Vec2, pos_incident: Vec2, ) -> Vec2 { - let grav_const = 100.0; + let grav_const = 15.0; (grav_const * mass_actor * mass_incident / (pos_actor.distance_squared(pos_incident))) * Vec2 { x: pos_actor.x - pos_incident.x, @@ -63,17 +68,24 @@ fn calculate_force_vector( } fn update_gravitational_forces( mut query_planet: Query<(Entity, &StartPlanet, &Transform)>, + mut query_planet2: Query<(Entity, &DestPlanet, &Transform)>, mut query_object: Query<(Entity, &Player, &mut ExternalForce, &Transform)>, ) { let (_es, ps, ts) = query_planet.single_mut(); + let (_es, planet2, trans2) = query_planet2.single_mut(); let (_ed, player, mut exd, td) = query_object.single_mut(); - let f = calculate_force_vector( + let f0 = calculate_force_vector( ps.planet_mass_kg, player.mass_kg, ts.translation.xy(), td.translation.xy(), ); - info!("Force: {}, Transform: {}", f, td.translation); - exd.apply_force(f); + let f1 = calculate_force_vector( + planet2.planet_mass_kg, + player.mass_kg, + trans2.translation.xy(), + td.translation.xy()); + //info!("Force: {}, Transform: {}", f, td.translation); + exd.apply_force(f0).apply_force(f1); } diff --git a/src/setup.rs b/src/setup.rs index 6a6a5d0..b5fbf2a 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -7,7 +7,7 @@ pub fn setup_starting_planet(mut cmd: Commands) { let start_planet = StartPlanet { display_name: String::from("Earth 2"), planet_mass_kg: 15000.0, - radius: 10.0, + radius: 50.0, }; let collider_radius = (&start_planet).radius; let planet_mass_kg = (&start_planet).planet_mass_kg; @@ -15,12 +15,12 @@ pub fn setup_starting_planet(mut cmd: Commands) { start_planet, RigidBody::Static, Transform::from_xyz(0.0, 0.0, 0.0), - Sprite::from_color(Color::WHITE, Vec2 { x: 5.0, y: 5.0 }), - Collider::circle(collider_radius), + Sprite::from_color(Color::WHITE, Vec2 { x: 50.0, y: 50.0 }), + Collider::rectangle(collider_radius, collider_radius), Mass(planet_mass_kg), )); } pub fn setup_init(mut commands: Commands) { commands.spawn(Camera2d); println!("Setup initial things"); -}
\ No newline at end of file +} |