diff options
author | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-03-30 21:47:05 +0300 |
---|---|---|
committer | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-03-30 21:47:05 +0300 |
commit | 9bdbfd49580275f0f82fecb74bc2946c1854a651 (patch) | |
tree | 624c27999b8e00eb7b422e4e531214df11b6673c | |
parent | aff2c30b3fa025def54cc5a249ba539d514b2a07 (diff) | |
download | martian-rescue-rs-9bdbfd49580275f0f82fecb74bc2946c1854a651.tar.gz martian-rescue-rs-9bdbfd49580275f0f82fecb74bc2946c1854a651.tar.bz2 martian-rescue-rs-9bdbfd49580275f0f82fecb74bc2946c1854a651.zip |
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | flake.lock | 8 | ||||
-rw-r--r-- | flake.nix | 2 | ||||
-rw-r--r-- | src/controllable/player.rs | 15 | ||||
-rw-r--r-- | src/lunar/systems.rs | 27 | ||||
-rw-r--r-- | src/main.rs | 65 | ||||
-rw-r--r-- | src/setup.rs | 4 |
7 files changed, 93 insertions, 30 deletions
@@ -2,9 +2,7 @@ name = "martian-rescue-rs" version = "0.1.0" edition = "2024" - [dependencies] avian2d = "0.2.1" bevy = "0.15.3" -bevy_rapier2d = "0.29.0" bevy_render = "0.15.3" @@ -220,16 +220,16 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1742384350, - "narHash": "sha256-AXB3q9l0eKp1fyQFBOSgFxGJ7sIWklE4F0OWN9FnZlI=", + "lastModified": 1743095683, + "narHash": "sha256-gWd4urRoLRe8GLVC/3rYRae1h+xfQzt09xOfb0PaHSk=", "owner": "nixos", "repo": "nixpkgs", - "rev": "7dc58b828587d2f392964b1f5bd31da8f21fe3cd", + "rev": "5e5402ecbcb27af32284d4a62553c019a3a49ea6", "type": "github" }, "original": { "owner": "nixos", - "ref": "master", + "ref": "nixos-unstable", "repo": "nixpkgs", "type": "github" } @@ -1,6 +1,6 @@ { inputs = { - nixpkgs.url = "github:nixos/nixpkgs/master"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; systems.url = "github:nix-systems/default"; devenv.url = "github:cachix/devenv"; devenv.inputs.nixpkgs.follows = "nixpkgs"; diff --git a/src/controllable/player.rs b/src/controllable/player.rs index fdc110e..91f3d5a 100644 --- a/src/controllable/player.rs +++ b/src/controllable/player.rs @@ -1,7 +1,7 @@ use avian2d::prelude::*; use bevy::prelude::*; -use crate::lunar::DestPlanet; +use crate::{lunar::DestPlanet, Stickable, TouchdownGoal}; #[derive(Component)] pub struct Player { @@ -27,13 +27,14 @@ fn map_key_to_movement(key: &KeyCode) -> Direction { } } pub fn check_transition_level( - mut commands: Commands, + mut has_touched_down: ResMut<TouchdownGoal>, player_transform: Query<&Transform, (With<Player>, Without<DestPlanet>)>, moon_transform: Query<(Entity, &DestPlanet, &Transform), (With<DestPlanet>, Without<Player>)> ) { + if has_touched_down.reached {return;} let (moon_e, moon, moon_t) = moon_transform.single(); let player_t = player_transform.single(); - let shroud_padding = 1. + moon.radius; + let shroud_padding = 0.1 + moon.radius; let bounds = ( Vec2 { x: moon_t.translation.x - shroud_padding, @@ -49,13 +50,16 @@ pub fn check_transition_level( 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(); + // has_touched_down.reached = true; + // commands.entity(moon_e).despawn(); } } pub fn camera_follow_player( + goal: Res<TouchdownGoal>, mut camera_transform: Query<&mut Transform, (With<Camera2d>, Without<Player>)>, player_transform: Query<&Transform, (With<Player>, Without<Camera>)>, ) { + if goal.reached {return;} let mut camera_t = camera_transform.single_mut(); let player_t = player_transform.single(); camera_t.translation = player_t.translation; @@ -63,8 +67,10 @@ pub fn camera_follow_player( pub fn player_movements( time: Res<Time>, input: Res<ButtonInput<KeyCode>>, + goal: Res<TouchdownGoal>, mut ps: Query<(&Player, &Sprite, &mut ExternalForce), (With<Player>)>, ) { + if goal.reached { return; } 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. }; @@ -89,6 +95,7 @@ pub fn setup_player_with_controls(mut commands: Commands) { }, RigidBody::Dynamic, Transform::from_xyz(0., 70., 0.), + Stickable {}, ExternalForce::ZERO.with_persistence(false), Sprite::from_color(Color::BLACK, Vec2 { x: 10., y: 10. }), Collider::rectangle(10., 10.), diff --git a/src/lunar/systems.rs b/src/lunar/systems.rs index 81fbbf2..e9aed52 100644 --- a/src/lunar/systems.rs +++ b/src/lunar/systems.rs @@ -2,6 +2,10 @@ use core::f32; use bevy::prelude::*; use avian2d::prelude::*; +use crate::StartPlanet; +use crate::Stickable; +use crate::TouchdownGoal; + use super::DestPlanet; use super::LunarOrbitalData; pub fn lunar_period_to_vec(angular_pos: f32, radius: f32) -> Vec2 { @@ -11,20 +15,28 @@ pub fn lunar_period_to_vec(angular_pos: f32, radius: f32) -> Vec2 { } pub fn update_lunar_transform( time: Res<Time>, + goal: Res<TouchdownGoal>, mut lunar_query: Query<( &DestPlanet, &mut LunarOrbitalData, &mut Transform, + &mut LinearVelocity, &RigidBody - ), With<DestPlanet>>, + ), (With<DestPlanet>, Without<StartPlanet>)>, + mut solar_query: Query<( + &Transform + ), (With<StartPlanet>, Without<DestPlanet>)>, ) { - let (_moon_planet, mut lod, mut moon_transform, _moon_body) = lunar_query.single_mut(); + if goal.reached {return;} + let (_moon_planet, mut lod, mut moon_transform, mut moon_vel, _moon_body) = lunar_query.single_mut(); + let (solar_transform) = solar_query.single_mut(); let dt = time.delta_secs(); 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}; + // moon_transform.translation = Vec3 {x: new_transform.x, y: new_transform.y, z: 0.0}; + moon_vel.0 = (new_transform - moon_transform.translation.xy() + solar_transform.translation.xy()) * 100.0 * dt; + println!("lunar transform: {}", moon_transform.translation); lod.period += dt * lod.orbital_velocity; lod.period = if lod.period <= 2. * f32::consts::PI { lod.period } else { 0. } } @@ -34,15 +46,18 @@ pub fn setup_moon(mut cmd: Commands) { planet_mass_kg: 50000.0, radius: 30.0, }; - let lunar_radius = 225.0; + let lunar_radius = 300.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.0, orbital_radius: lunar_radius}, - RigidBody::Static, + RigidBody::Dynamic, Transform::from_xyz(initial_transform.x, initial_transform.y, 0.0), + LockedAxes::ROTATION_LOCKED, + LinearVelocity::ZERO, + Stickable {}, Sprite::from_color(Color::BLACK, Vec2 { x: 30., y: 30. }), Collider::rectangle(r, r), Mass(m), diff --git a/src/main.rs b/src/main.rs index 5e821f9..e1a3645 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,36 +1,43 @@ +mod controllable; mod lunar; mod setup; -mod controllable; use avian2d::prelude::*; use bevy::{prelude::*, winit::WinitSettings}; use controllable::Player; use lunar::DestPlanet; +#[derive(Resource)] +struct TouchdownGoal { + reached: bool, +} fn main() { println!("Hello, world!"); App::new() .add_plugins(DefaultPlugins) .insert_resource(ClearColor(Color::srgb(0.5, 0.5, 0.9))) .insert_resource(WinitSettings::game()) + .insert_resource(TouchdownGoal { reached: false }) .add_plugins(PhysicsPlugins::default()) .add_systems( Startup, ( - setup::setup_starting_planet, + setup::setup_starting_planet, setup::setup_init, controllable::setup_player_with_controls, - lunar::setup_moon - ) + lunar::setup_moon, + ), ) .add_systems( - Update, + Update, ( lunar::update_lunar_transform, controllable::player_movements, controllable::camera_follow_player, controllable::check_transition_level, update_gravitational_forces, - ) + handle_collision, + remove_all_if_goal, + ), ) .run(); } @@ -47,7 +54,37 @@ struct StartPlanet { planet_mass_kg: f32, radius: f32, } - +#[derive(Component)] +struct Stickable {} +fn handle_collision( + mut commands: Commands, + mut collision_events: EventReader<CollisionStarted>, + mut goal: ResMut<TouchdownGoal>, + query: Query<(Entity, &Stickable, Option<&RigidBody>)>, +) { + for event in collision_events.read() { + // Identify the entities involved in the collision + if let Some((entity, _, _)) = query.iter().find(|(e, _, _)| *e == event.0) { + if let Some((entity2, _, _)) = query.iter().find(|(e2, _, _)| *e2 == event.1) { + // Set the dynamic object to a kinematic state to make it stick + commands.entity(entity).insert(RigidBody::Kinematic); + commands.entity(entity2).insert(RigidBody::Kinematic); + goal.reached = true; + } + } + } +} +fn remove_all_if_goal( + mut commands: Commands, + query: Query<Entity>, + goal: Res<TouchdownGoal> +) { + if goal.reached { + for e in &query { + commands.entity(e).despawn(); + } + } +} fn calculate_force_vector( mass_actor: f32, mass_incident: f32, @@ -67,10 +104,14 @@ fn calculate_force_vector( }.normalize() * 50000.0*/ } fn update_gravitational_forces( + has_touched_down: Res<TouchdownGoal>, mut query_planet: Query<(Entity, &StartPlanet, &Transform)>, mut query_planet2: Query<(Entity, &DestPlanet, &Transform)>, mut query_object: Query<(Entity, &Player, &mut ExternalForce, &Transform)>, ) { + if has_touched_down.reached { + return; + } 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(); @@ -81,11 +122,11 @@ fn update_gravitational_forces( td.translation.xy(), ); let f1 = calculate_force_vector( - planet2.planet_mass_kg, - player.mass_kg, - trans2.translation.xy(), - td.translation.xy()); + 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 b5fbf2a..64d7447 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,5 +1,5 @@ use avian2d::prelude::{Collider, Mass, RigidBody}; -use bevy::{color::Color, core_pipeline::core_2d::Camera2d, ecs::system::Commands, math::Vec2, sprite::Sprite, transform::components::Transform}; +use bevy::{color::Color, core_pipeline::core_2d::Camera2d, ecs::system::Commands, math::Vec2, sprite::Sprite, text::{Text2d, Text2dBundle}, transform::components::Transform}; use crate::StartPlanet; @@ -22,5 +22,7 @@ pub fn setup_starting_planet(mut cmd: Commands) { } pub fn setup_init(mut commands: Commands) { commands.spawn(Camera2d); + commands.spawn((Text2d::new("Game - if you call it one. W A S D to move.\nLeave your planet to land on the moon,\nbut be careful of gravity pulling you."), Transform::from_xyz(0., 70., 1.))); + println!("Setup initial things"); } |