From 5f3f6945bc02961fb2ce09217eb047f6783afc37 Mon Sep 17 00:00:00 2001 From: Isaac Turci <78173025+Zac8668@users.noreply.github.com> Date: Thu, 11 Jan 2024 11:52:41 -0300 Subject: [PATCH 1/4] Fixed input frame dependent bug --- src/actors.rs | 19 +++------ src/animation.rs | 2 +- src/particles.rs | 4 +- src/player.rs | 104 ++++++++++++++++++++++++++++++++++++----------- 4 files changed, 89 insertions(+), 40 deletions(-) diff --git a/src/actors.rs b/src/actors.rs index 1b21847..37953f7 100644 --- a/src/actors.rs +++ b/src/actors.rs @@ -9,7 +9,7 @@ pub struct Actor { } //Called before simulations -pub fn add_actors( +pub fn fill_actors( mut chunk_manager: ResMut, actors: Query<&Actor>, mut dirty_rects: ResMut, @@ -33,7 +33,7 @@ pub fn add_actors( } //Called after simulation, before actor update -pub fn remove_actors( +pub fn unfill_actors( mut chunk_manager: ResMut, actors: Query<&Actor>, materials: (Res>, Res), @@ -246,18 +246,9 @@ impl Plugin for ActorsPlugin { app.add_systems( FixedUpdate, ( - add_actors - .before(chunk_manager_update) - .before(remove_actors) - .before(update_actors), - remove_actors - .after(chunk_manager_update) - .after(add_actors) - .before(update_actors), - update_actors - .after(remove_actors) - .after(add_actors) - .after(chunk_manager_update), + fill_actors.before(chunk_manager_update), + unfill_actors.after(chunk_manager_update), + update_actors.after(unfill_actors), ), ); } diff --git a/src/animation.rs b/src/animation.rs index 7856e0e..dbdf306 100644 --- a/src/animation.rs +++ b/src/animation.rs @@ -34,6 +34,6 @@ fn animate_sprite( pub struct AnimationPlugin; impl Plugin for AnimationPlugin { fn build(&self, app: &mut App) { - app.add_systems(FixedUpdate, animate_sprite.after(update_player_sprite)); + app.add_systems(FixedUpdate, animate_sprite.after(update_player)); } } diff --git a/src/particles.rs b/src/particles.rs index b5eb5e1..860b10e 100644 --- a/src/particles.rs +++ b/src/particles.rs @@ -241,8 +241,8 @@ impl Plugin for ParticlesPlugin { app.add_systems( FixedUpdate, ( - hydrate_particles.before(update_particles), - update_particles.after(chunk_manager_update), + hydrate_particles.after(update_player), + update_particles.before(chunk_manager_update), ), ); } diff --git a/src/player.rs b/src/player.rs index 046af63..057de14 100644 --- a/src/player.rs +++ b/src/player.rs @@ -112,7 +112,7 @@ pub fn player_setup( /// Updates player pub fn update_player( - input: (ResMut>, EventReader), + input: (Res, EventReader), mut player: Query<(&mut Actor, &mut Player, &mut AnimationIndices)>, chunk_manager: ResMut, materials: (Res>, Res), @@ -120,7 +120,7 @@ pub fn update_player( mut zoom: ResMut, ) { let (mut actor, mut player, mut anim_idxs) = player.single_mut(); - let (keys, mut scroll_evr) = input; + let (inputs, mut scroll_evr) = input; let materials = materials.0.get(materials.1 .0.clone()).unwrap(); // Gravity @@ -134,7 +134,7 @@ pub fn update_player( } // Movement - let x = -(keys.pressed(KeyCode::A) as u8 as f32) + keys.pressed(KeyCode::D) as u8 as f32; + let x = inputs.right - inputs.left; actor.vel.x = x * RUN_SPEED; let on_ground = on_ground(&chunk_manager, &actor, materials); @@ -153,7 +153,7 @@ pub fn update_player( } // Jump - if keys.just_pressed(KeyCode::Space) { + if inputs.jump_just_pressed { if on_ground { actor.vel.y -= JUMP_MAG; player.state = PlayerState::Jumping(time.elapsed_seconds_wrapped_f64()); @@ -165,7 +165,7 @@ pub fn update_player( //Jump higher when holding space if let PlayerState::Jumping(jump_start) = player.state { - if keys.pressed(KeyCode::Space) + if inputs.jump_pressed && time.elapsed_seconds_wrapped_f64() - jump_start < TIME_JUMP_PRESSED { actor.vel.y -= PRESSED_JUMP_MAG @@ -175,7 +175,7 @@ pub fn update_player( // Jetpack let mut new_up = false; if let PlayerState::Jetpack(_) = player.state { - if player.fuel > 0. && keys.pressed(KeyCode::Space) { + if player.fuel > 0. && inputs.jump_pressed { actor.vel.y = (actor.vel.y - JETPACK_FORCE).clamp(-JETPACK_MAX, f32::MAX); player.fuel -= FUEL_COMSUMPTON; new_up = true; @@ -211,13 +211,13 @@ pub fn update_player( } //Change shooting atoms - if keys.just_pressed(KeyCode::Key1) { + if inputs.numbers[0] { player.atom_id = 2; - } else if keys.just_pressed(KeyCode::Key2) { + } else if inputs.numbers[1] { player.atom_id = 3; - } else if keys.just_pressed(KeyCode::Key3) { + } else if inputs.numbers[2] { player.atom_id = 4; - } else if keys.just_pressed(KeyCode::Key4) { + } else if inputs.numbers[3] { player.atom_id = 5; } } @@ -228,18 +228,14 @@ pub fn tool_system( mut camera: Query<(&Camera, &GlobalTransform), Without>, tool_front_ent: Query>, querys: (Query<&Window>, Query<(&mut TextureAtlasSprite, &Player)>), - resources: ( - ResMut, - ResMut, - Res>, - ), + resources: (ResMut, ResMut, Res), materials: (Res>, Res), ) { let (mut tool_transform, tool_gtransform, mut tool_sprite) = tool.single_mut(); let (camera, camera_gtransform) = camera.single_mut(); let (window, mut player) = querys; let (mut textatlas_sprite, player) = player.single_mut(); - let (mut chunk_manager, mut dirty_rects, mouse) = resources; + let (mut chunk_manager, mut dirty_rects, inputs) = resources; let Ok(window) = window.get_single() else { return; }; @@ -271,8 +267,8 @@ pub fn tool_system( let tool_front = center_vec_y_flipped + tool_slope * 5.; let mut pos_to_update = vec![]; - if mouse.pressed(MouseButton::Right) { - let new_tool_front = tool_front + tool_slope * 2.; + if inputs.push { + let new_tool_front = tool_front + tool_slope * 3.5; let n = 6; for i in 0..=n { @@ -299,7 +295,7 @@ pub fn tool_system( } } } - } else if mouse.pressed(MouseButton::Left) { + } else if inputs.pull { let center_bound = tool_front + tool_slope * TOOL_DISTANCE; let bound1 = (center_bound + bound_slope * TOOL_RANGE).as_ivec2(); @@ -343,18 +339,80 @@ pub fn update_player_sprite(mut query: Query<(&mut Transform, &Actor), With>); +pub fn get_input( + keys: Res>, + mouse_buttons: Res>, + mut inputs: ResMut, +) { + //Jump + if keys.just_pressed(KeyCode::Space) { + inputs.jump_just_pressed = true; + inputs.jump_pressed = true; + } else if inputs.jump_pressed { + inputs.jump_pressed = true; + } + + //Movement + if keys.pressed(KeyCode::A) { + inputs.left = 1.; + } + if keys.pressed(KeyCode::D) { + inputs.right = 1.; + } + + //Tool + if mouse_buttons.pressed(MouseButton::Left) { + inputs.pull = true; + } + if mouse_buttons.pressed(MouseButton::Right) { + inputs.push = true; + } + + //Numbers, to select atoms + if keys.just_pressed(KeyCode::Key1) { + inputs.numbers[0] = true; + } else if keys.just_pressed(KeyCode::Key2) { + inputs.numbers[1] = true; + } else if keys.just_pressed(KeyCode::Key3) { + inputs.numbers[2] = true; + } else if keys.just_pressed(KeyCode::Key4) { + inputs.numbers[3] = true; + } +} + +pub fn clear_input(mut inputs: ResMut) { + *inputs = Inputs::default(); +} + +#[derive(Resource, Default)] +pub struct Inputs { + left: f32, + right: f32, + + pull: bool, + push: bool, + + jump_pressed: bool, + jump_just_pressed: bool, + + numbers: [bool; 4], +} + pub struct PlayerPlugin; impl Plugin for PlayerPlugin { fn build(&self, app: &mut App) { app.add_systems( FixedUpdate, ( - update_player.after(chunk_manager_update), - update_player_sprite, - tool_system.after(chunk_manager_update), + update_player.before(update_actors), + update_player_sprite.after(update_actors), + tool_system.before(chunk_manager_update), + clear_input.after(update_player).after(tool_system), ), ) - .insert_resource(SavingTask::default()) + .add_systems(PreUpdate, get_input) + .init_resource::() + .init_resource::() .add_systems(PostStartup, player_setup.after(manager_setup)); } } From 0b1d6285358b1181f68afd4a4dba3cf6aca7b411 Mon Sep 17 00:00:00 2001 From: Isaac Turci <78173025+Zac8668@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:44:04 -0300 Subject: [PATCH 2/4] Polishing --- src/chunk.rs | 18 ++++++++++-------- src/consts.rs | 4 ++-- src/player.rs | 14 ++++++++++++-- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/chunk.rs b/src/chunk.rs index dc0dfa7..e1ab739 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -1,5 +1,4 @@ use bevy::render::render_resource::*; -use std::cmp::Ordering; use std::collections::HashSet; use crate::prelude::*; @@ -26,21 +25,24 @@ impl Chunk { pub fn new(texture: Handle, index: IVec2) -> Chunk { let mut atoms = [Atom::default(); CHUNK_LEN]; - match index.y.cmp(&2) { - Ordering::Less => {} - Ordering::Equal => { + match index.y { + i32::MIN..=0 => {} + 1 => { for (i, atom) in atoms.iter_mut().enumerate() { let id = match i { 0..=511 => 6, - 512..=2815 => 7, - _ => 4, + _ => 7, }; *atom = Atom::new(id); } } - - Ordering::Greater => { + 2 => { + for atom in &mut atoms { + *atom = Atom::new(4); + } + } + 3..=i32::MAX => { for atom in &mut atoms { *atom = Atom::new(8); } diff --git a/src/consts.rs b/src/consts.rs index aa7ae12..f3aef9f 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -22,10 +22,10 @@ pub const JETPACK_MAX: f32 = 3.; pub const JUMP_MAG: f32 = 9.; pub const PRESSED_JUMP_MAG: f32 = 0.6; pub const TIME_JUMP_PRESSED: f64 = 0.8; -pub const RUN_SPEED: f32 = 3.5; +pub const RUN_SPEED: f32 = 2.5; pub const TOOL_DISTANCE: f32 = 32.; -pub const TOOL_RANGE: f32 = 12.; +pub const TOOL_RANGE: f32 = 16.; pub const ZOOM_LOWER_BOUND: f32 = 0.15; pub const ZOOM_UPPER_BOUND: f32 = 0.30; diff --git a/src/player.rs b/src/player.rs index 057de14..83d3812 100644 --- a/src/player.rs +++ b/src/player.rs @@ -302,8 +302,18 @@ pub fn tool_system( let bound2 = (center_bound + -bound_slope * TOOL_RANGE).as_ivec2(); for bound_vec in Line::new(bound1, bound2 - bound1) { - for vec in Line::new(tool_front.as_ivec2(), bound_vec - tool_front.as_ivec2()) { + for vec in Line::new( + (tool_front - 4. * tool_slope).as_ivec2(), + bound_vec - (tool_front - 4. * tool_slope).as_ivec2(), + ) { let chunk_pos = global_to_chunk(vec); + if (vec.distance_squared((tool_front - 6. * tool_slope).as_ivec2()) as f32) + .sqrt() + < 6. + { + continue; + } + if let Some(atom) = chunk_manager.get_mut_atom(chunk_pos) { if !materials[atom.id].is_void() && !materials[atom.id].is_object() { commands.spawn(Particle { @@ -348,7 +358,7 @@ pub fn get_input( if keys.just_pressed(KeyCode::Space) { inputs.jump_just_pressed = true; inputs.jump_pressed = true; - } else if inputs.jump_pressed { + } else if keys.pressed(KeyCode::Space) { inputs.jump_pressed = true; } From a8330e5f1aecc347db80b1249c8de688ef8f7e09 Mon Sep 17 00:00:00 2001 From: Isaac Turci <78173025+Zac8668@users.noreply.github.com> Date: Fri, 12 Jan 2024 12:16:24 -0300 Subject: [PATCH 3/4] Better particle performance --- src/chunk_manager.rs | 2 +- src/consts.rs | 4 ++-- src/main.rs | 1 + src/particles.rs | 30 ++++++++++++++++++------------ 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/chunk_manager.rs b/src/chunk_manager.rs index e72835d..88acad3 100644 --- a/src/chunk_manager.rs +++ b/src/chunk_manager.rs @@ -9,7 +9,7 @@ use smallvec::SmallVec; use crate::prelude::*; /// Updates and do the chunks logic -#[derive(Default, Resource, Clone)] +#[derive(Default, Resource)] pub struct ChunkManager { pub chunks: HashMap, pub pos: IVec2, diff --git a/src/consts.rs b/src/consts.rs index f3aef9f..b9583bd 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -40,8 +40,8 @@ pub const GRAVITY: u8 = 1; pub const TERM_VEL: u8 = 10; pub const FRAMES_SLEEP: u8 = 1; //Has to be even -pub const LOAD_WIDTH: i32 = 20; -pub const LOAD_HEIGHT: i32 = 12; +pub const LOAD_WIDTH: i32 = 32; +pub const LOAD_HEIGHT: i32 = 18; pub const _CAMERA_SPEED: f32 = 10.; diff --git a/src/main.rs b/src/main.rs index eefb014..76881ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,6 +34,7 @@ mod prelude { pub use std::fs::File; pub use std::io::Write; pub use std::io::{BufReader, BufWriter}; + pub use std::sync::{Arc, RwLock}; pub use crate::materials::Material; } diff --git a/src/particles.rs b/src/particles.rs index 860b10e..ae7f5b8 100644 --- a/src/particles.rs +++ b/src/particles.rs @@ -73,12 +73,13 @@ pub fn update_particles( let compute_pool = ComputeTaskPool::get(); compute_pool.scope(|deferred_scope| { - let chunks = &chunk_manager.chunks.clone(); let manager_pos = &chunk_manager.pos.clone(); + let chunk_manager = Arc::new(RwLock::new(&mut chunk_manager)); let (particles_send, particles_recv) = async_channel::unbounded::(); let particle_send = &particles_send; + let chunk_manager_deffered = Arc::clone(&chunk_manager); deferred_scope.spawn(async move { while let Ok(update) = particles_recv.recv().await { if update.remove { @@ -86,20 +87,26 @@ pub fn update_particles( continue; } - if let Some(atom) = chunk_manager.get_mut_atom(update.chunk_pos) { + let mut change_atom = false; + if let Some(atom) = chunk_manager_deffered.read().unwrap().get_atom(&update.chunk_pos) { if materials[atom.id].is_void() { - *atom = update.atom; - commands.entity(update.ent).despawn(); - - update_dirty_rects(&mut dirty_rects.render, update.chunk_pos); - update_dirty_rects_3x3(&mut dirty_rects.current, update.chunk_pos); + change_atom = true; } } + + if change_atom { + let atom = &mut chunk_manager_deffered.write().unwrap()[update.chunk_pos]; + *atom = update.atom; + commands.entity(update.ent).despawn(); + + update_dirty_rects(&mut dirty_rects.render, update.chunk_pos); + update_dirty_rects_3x3(&mut dirty_rects.current, update.chunk_pos); + } } }); particles - .iter_mut() + .par_iter_mut() .for_each(|(mut particle, mut transform, ent)| { let mut dest_pos = transform.translation.xy(); dest_pos.y *= -1.; @@ -140,10 +147,9 @@ pub fn update_particles( let chunk_pos = global_to_chunk(pos); let prev_chunk_pos = global_to_chunk(prev_pos); - let atom = chunks.get(&chunk_pos.chunk).unwrap().atoms - [chunk_pos.atom.d1()]; - let prev_atom = chunks.get(&prev_chunk_pos.chunk).unwrap().atoms - [prev_chunk_pos.atom.d1()]; + let atom = chunk_manager.read().unwrap().get_atom(&chunk_pos).unwrap().clone(); + let prev_atom = + chunk_manager.read().unwrap().get_atom(&prev_chunk_pos).unwrap().clone(); if particle.state == PartState::Normal && !materials[atom.id].is_void() From 7ca9d03b27362be3d1c9ca0df12351306c06c36d Mon Sep 17 00:00:00 2001 From: Isaac Turci <78173025+Zac8668@users.noreply.github.com> Date: Fri, 12 Jan 2024 12:19:02 -0300 Subject: [PATCH 4/4] Cargo fmt --- src/particles.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/particles.rs b/src/particles.rs index ae7f5b8..0ebe375 100644 --- a/src/particles.rs +++ b/src/particles.rs @@ -88,7 +88,11 @@ pub fn update_particles( } let mut change_atom = false; - if let Some(atom) = chunk_manager_deffered.read().unwrap().get_atom(&update.chunk_pos) { + if let Some(atom) = chunk_manager_deffered + .read() + .unwrap() + .get_atom(&update.chunk_pos) + { if materials[atom.id].is_void() { change_atom = true; } @@ -147,9 +151,13 @@ pub fn update_particles( let chunk_pos = global_to_chunk(pos); let prev_chunk_pos = global_to_chunk(prev_pos); - let atom = chunk_manager.read().unwrap().get_atom(&chunk_pos).unwrap().clone(); - let prev_atom = - chunk_manager.read().unwrap().get_atom(&prev_chunk_pos).unwrap().clone(); + let atom = + *chunk_manager.read().unwrap().get_atom(&chunk_pos).unwrap(); + let prev_atom = *chunk_manager + .read() + .unwrap() + .get_atom(&prev_chunk_pos) + .unwrap(); if particle.state == PartState::Normal && !materials[atom.id].is_void()