diff --git a/src/level.rs b/src/level.rs index 207dd52..cbbf9e4 100644 --- a/src/level.rs +++ b/src/level.rs @@ -2,11 +2,14 @@ use bevy::prelude::*; use block::BlockBundle; +use crate::level::block::JumpCollisionBoxBundle; + pub mod block; pub struct Level { pub id: u32, pub blocks: Vec, + pub jump_collision_block_boxes: Vec, } impl Level { @@ -21,6 +24,7 @@ impl Level { trace!("Creating {} blocks for level", num_blocks); let mut blocks = Vec::with_capacity(num_blocks); + let mut jump_collision_block_boxes = Vec::with_capacity(num_blocks); for i in 0..num_blocks { let x = i as f32 * block::SIZE; let y = if i % 20 < 15 { @@ -31,9 +35,14 @@ impl Level { let translation = Vec3::new(x, y, 0.0); blocks.push(BlockBundle::new(translation)); + jump_collision_block_boxes.push(JumpCollisionBoxBundle::new(translation)); } - Self { id, blocks } + Self { + id, + blocks, + jump_collision_block_boxes, + } } } @@ -44,4 +53,7 @@ pub fn spawn_blocks(mut commands: Commands, level: Res) { for block in level.blocks.iter() { commands.spawn(block.clone()); } + for jump_collision_block_box in level.jump_collision_block_boxes.iter() { + commands.spawn(jump_collision_block_box.clone()); + } } diff --git a/src/level/block.rs b/src/level/block.rs index ae128d0..09e6eca 100644 --- a/src/level/block.rs +++ b/src/level/block.rs @@ -16,6 +16,16 @@ pub struct BlockBundle { block: Block, } +#[derive(Component, Clone, Default)] +pub struct JumpCollisionBox; + +#[derive(Bundle, Clone)] +pub struct JumpCollisionBoxBundle { + sprite_bundle: SpriteBundle, + collider: Collider, + jump_collision_box: JumpCollisionBox, +} + impl core::fmt::Debug for BlockBundle { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct( @@ -53,3 +63,29 @@ impl BlockBundle { } } } + +impl JumpCollisionBoxBundle { + pub fn new(translation: Vec3) -> Self { + // Add padding on left so wall clinging doesn't work + let translation = translation + Vec3::new(1.0, 0.0, 0.0); + + trace!( + "Creating jump collision box bundle (translation: {:?})", + translation + ); + + Self { + sprite_bundle: SpriteBundle { + transform: Transform { + translation, + ..default() + }, + visibility: Visibility::Hidden, + ..default() + }, + // Add padding so wall clinging doesn't work + collider: Collider::cuboid(SIZE - 2.0, SIZE - 2.0), + jump_collision_box: JumpCollisionBox, + } + } +} diff --git a/src/player.rs b/src/player.rs index 2e86920..2339e14 100644 --- a/src/player.rs +++ b/src/player.rs @@ -123,12 +123,39 @@ pub fn r#move( pub fn can_jump( mut collisions: EventReader, mut can_jump: ResMut, - player_query: Query>, - blocks_query: Query>, + query: Query<( + Entity, + Option<&crate::level::block::JumpCollisionBox>, + Option<&Player>, + )>, + // player_query: Query>, + // blocks_query: Query>, ) { + let player = query + .iter() + .filter(|(_, _, player)| player.is_some()) + .next() + .unwrap() + .0; for collision in collisions.iter() { - + let collision = collision.0; + + if player == collision.entity1 || player == collision.entity2 { + let other = if player == collision.entity1 { + collision.entity2 + } else { + collision.entity1 + }; + + if query.get(other).is_ok() { + can_jump.0 = true; + trace!("Player can jump."); + return; + } + } } + can_jump.0 = false; + trace!("Player can't jump."); } /// Add a force to the player in the given direction (to be used for grappling).