use bevy::prelude::*; use crate::{ obstacle::Obstacle, player::{Player, move_player}, }; // Hitbox #[derive(Component)] pub struct Collider { pub size: Vec2, } #[derive(Resource, Default)] pub struct HasCollided(pub bool); // Check collision with Player pub fn check_collision_with_player( player: Single<(&Transform, &Collider, &mut Sprite), With>, obstacle: Query<(&Transform, &Collider), With>, mut has_collided: ResMut, ) { if has_collided.0 { return; } let (player_transform, player_collider, mut _player_sprite) = player.into_inner(); // Check whether or not each obstacles overlap the player for (collider_transform, collider_collider) in obstacle { if overlap( player_transform.translation.truncate(), player_collider.size / 2.0, collider_transform.translation.truncate(), collider_collider.size / 2.0, ) { // player_sprite.color = Color::srgb(1.0, 0.0, 0.0); // Change sprite color has_collided.0 = true; break; } } } // Test if there is an overlap between 2 boxes fn overlap(a_center: Vec2, a_half: Vec2, b_center: Vec2, b_half: Vec2) -> bool { let overlap_x = (a_center.x - b_center.x).abs() < (a_half.x + b_half.x); let overlap_y = (a_center.y - b_center.y).abs() < (a_half.y + b_half.y); overlap_x && overlap_y } pub struct CollisionPlugin; impl Plugin for CollisionPlugin { fn build(&self, app: &mut App) { app.init_resource::() .add_systems(Update, check_collision_with_player.after(move_player)); } }