Skip to content

Commit

Permalink
Merge branch 'main' into rigid-actor
Browse files Browse the repository at this point in the history
  • Loading branch information
Zac8668 authored Feb 4, 2024
2 parents 8774575 + 66c9ff6 commit 5bfb13b
Show file tree
Hide file tree
Showing 10 changed files with 333 additions and 228 deletions.
Binary file added assets/player/jetpack.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion src/actors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,9 @@ impl Plugin for ActorsPlugin {
app.add_systems(
FixedUpdate,
(
fill_actors.before(chunk_manager_update),
fill_actors
.before(chunk_manager_update)
.before(update_particles),
unfill_actors.after(chunk_manager_update),
update_actors.after(unfill_actors),
)
Expand Down
1 change: 0 additions & 1 deletion src/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ impl Chunk {
&self.get_values(materials),
CHUNK_LENGHT as u32,
CHUNK_LENGHT as u32,
(0., 0.),
)
}

Expand Down
145 changes: 95 additions & 50 deletions src/chunk_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,81 +218,116 @@ pub fn manager_setup(
pub fn add_colliders(
mut commands: Commands,
chunk_manager: Res<ChunkManager>,
chunks: Query<(Entity, &ChunkComponent)>,
rigidbodies: Query<(&Transform, &Rigidbody)>,
chunks: Query<(Entity, &ChunkComponent), Without<Collider>>,
materials: (Res<Assets<Materials>>, Res<MaterialsHandle>),
has_collider: Res<HasCollider>,
) {
let materials = materials.0.get(materials.1 .0.clone()).unwrap();
puffin::profile_function!();

let Some(materials) = materials.0.get(materials.1 .0.clone()) else {
return;
};

let mut rects = vec![];
if has_collider.0.is_empty() {
return;
}

for (ent, pos) in &chunks {
for rect in has_collider.0.iter() {
if rect.contains(pos.0) {
if let Some(chunk) = chunk_manager.chunks.get(&pos.0) {
let collider = chunk.get_collider(materials);

if let Some(collider) = collider {
commands
.entity(ent)
.insert(collider)
.insert(bevy_rapier2d::prelude::RigidBody::Fixed);
}
}

break;
}
}
}
}

pub fn remove_colliders(
mut commands: Commands,
chunks: Query<(Entity, &ChunkComponent), With<Collider>>,
has_collider: Res<HasCollider>,
) {
if has_collider.0.is_empty() {
return;
}

for (ent, pos) in &chunks {
let mut contains = false;
for rect in has_collider.0.iter() {
if rect.contains(pos.0) {
contains = true;
break;
}
}

if !contains {
//If none contains, remove collider and go to next chunk
//Remove collider
if let Some(mut entity) = commands.get_entity(ent) {
entity.remove::<Collider>();
entity.remove::<bevy_rapier2d::prelude::RigidBody>();
}
}
}
}

pub fn update_has_collider(
mut has_collider: ResMut<HasCollider>,
rigidbodies: Query<(&Transform, &Rigidbody)>,
) {
has_collider.0 = vec![];
for (transform, rigidbody) in &rigidbodies {
let l = std::f32::consts::SQRT_2 * (rigidbody.width as f32).max(rigidbody.height as f32);
let angle = -transform.rotation.to_euler(EulerRot::XYZ).2;
let mut center = transform.translation.xy();
center.y *= -1.;
center += vec2(rigidbody.width as f32, rigidbody.height as f32)
.rotate(Vec2::from_angle(angle))
/ 2.;

let l = std::f32::consts::SQRT_2 * (rigidbody.width as f32).max(rigidbody.height as f32);
let angle = std::f32::consts::FRAC_PI_4 + std::f32::consts::PI;
let mut top_left = transform.translation.xy();
top_left.y *= -1.;
let mut top_left = center;
top_left += vec2(angle.cos(), angle.sin()) * l / 2.;

let angle = std::f32::consts::FRAC_PI_4;
let mut down_right = transform.translation.xy();
down_right.y *= -1.;
let mut down_right = center;
down_right += vec2(angle.cos(), angle.sin()) * l / 2.;

/*{
//Some debug visualization
let mut top_left = top_left;
top_left.y *= -1.;
gizmos.circle_2d(top_left, 10., Color::RED);
gizmos.circle_2d(top_left, 5., Color::RED);
let mut down_right = down_right;
down_right.y *= -1.;
gizmos.circle_2d(down_right, 10., Color::BLACK);
gizmos.circle_2d(down_right, 5., Color::BLACK);
}*/

const LOADING_OFF: f32 = 1.5;
top_left -= vec2(CHUNK_LENGHT as f32, CHUNK_LENGHT as f32) * LOADING_OFF;
down_right += vec2(CHUNK_LENGHT as f32, CHUNK_LENGHT as f32) * LOADING_OFF;

top_left /= CHUNK_LENGHT as f32;
down_right /= CHUNK_LENGHT as f32;

const LOADING_OFF: i32 = 2;
let bounds_rect = IRect::new(
top_left.x as i32 - LOADING_OFF,
top_left.y as i32 - LOADING_OFF,
down_right.x as i32 + LOADING_OFF,
down_right.y as i32 + LOADING_OFF,
top_left.x as i32,
top_left.y as i32,
down_right.x as i32,
down_right.y as i32,
);

rects.push(bounds_rect);
}

if !rects.is_empty() {
'chunks: for (ent, pos) in &chunks {
for (i, rect) in rects.iter().enumerate() {
//If on bounds continue by breaking this loop
if rect.contains(pos.0) {
break;
} else if i == rects.len() - 1 {
//If none contains, remove collider and go to next chunk
//Remove collider
if let Some(mut entity) = commands.get_entity(ent) {
entity.remove::<Collider>();
entity.remove::<bevy_rapier2d::prelude::RigidBody>();
}
continue 'chunks;
}
}

if let Some(chunk) = chunk_manager.chunks.get(&pos.0) {
let collider = chunk.get_collider(materials);

if let Some(collider) = collider {
commands
.entity(ent)
.insert(collider)
.insert(CollisionGroups::new(WORLD_GROUP, RIGIDBODY_GROUP))
.insert(bevy_rapier2d::prelude::RigidBody::Fixed);
}
}
}
has_collider.0.push(bounds_rect);
}
}

Expand Down Expand Up @@ -672,6 +707,9 @@ fn clear_render_rect(mut dirty_rects: ResMut<DirtyRects>) {
dirty_rects.render = HashMap::new();
}

#[derive(Resource, Default)]
pub struct HasCollider(pub Vec<IRect>);

pub struct ChunkManagerPlugin;
impl Plugin for ChunkManagerPlugin {
fn build(&self, app: &mut App) {
Expand All @@ -682,12 +720,19 @@ impl Plugin for ChunkManagerPlugin {
)
.add_systems(
Update,
(update_manager_pos, add_colliders).run_if(in_state(GameState::Game)),
(
update_manager_pos,
add_colliders.after(update_has_collider),
remove_colliders.after(update_has_collider),
update_has_collider,
)
.run_if(in_state(GameState::Game)),
)
.add_systems(
PreUpdate,
clear_render_rect.run_if(in_state(GameState::Game)),
)
.init_resource::<HasCollider>()
.init_resource::<ChunkManager>()
.init_resource::<DirtyRects>();

Expand Down
4 changes: 4 additions & 0 deletions src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub const _CAMERA_SPEED: f32 = 10.;
pub const PLAYER_LAYER: f32 = 1.;
pub const PARTICLE_LAYER: f32 = 10.;
pub const AUTOMATA_LAYER: f32 = 100.;
pub const RIGIDBODY_LAYER: f32 = 1000.;

//Rapier2d collision groups
pub const RIGIDBODY_GROUP: Group = Group::GROUP_1;
Expand All @@ -62,3 +63,6 @@ pub const ACTOR_GROUP: Group = Group::GROUP_3;
pub const NORMAL_BUTTON: Color = Color::rgb(0.15, 0.15, 0.15);
pub const HOVERED_BUTTON: Color = Color::rgb(0.25, 0.25, 0.25);
pub const PRESSED_BUTTON: Color = Color::rgb(0.35, 0.75, 0.35);

//How much the rigidbody needs to be submerged to totally cut of gravity
//pub const STOP_RATE: f32 = 0.05;
Loading

0 comments on commit 5bfb13b

Please sign in to comment.