Is there a way of detecting collision of Sprites in the bevy game engine?
Asked Answered
A

2

8

Currently im using the Position of two objects (comets and the ship) to detect if they collide.

fn collision_detection(
    comets: Query<&Transform, With<Comet>>,
    mut ships: Query<(&Transform, &mut ShipStatus), With<Ship>>,
) {
    for comet in comets.iter() {
        for (ship, mut status) in ships.iter_mut() {
            if comet.translation.x < ship.translation.x + 80.0 && comet.translation.y < ship.translation.y + 80.0
            && comet.translation.x > ship.translation.x - 80.0 && comet.translation.y > ship.translation.y - 80.0 {
                status.dead = true;
            }
        }
    }
}

But there has to be a better way of doing this.

Araxes answered 10/3, 2021 at 15:31 Comment(0)
P
6

Bevy doesn't have a complete collision system currently. Unless it has been expanded in the few months since the introductory page was created:

Physics

Many games require collision detection and physics. I'm planning on building a plug-able physics interface with nphysics / ncollide as the first backend.

Fortunately, this simple example is actually provided by bevy::sprite::collide_aabb::collide which does simple AABB collision detection.

use bevy::sprite::collide_aabb::collide;

let ship_size = Vec2::new(80.0, 80.0);
let comet_size = Vec2::new(0.0, 0.0);
for comet in comets.iter() {
    for (ship, mut status) in ships.iter_mut() {
        if collide(ship.translation, ship_size, comet.translation, comet_size).is_some() {
            status.dead = true;
        }
    }
}
Pathy answered 11/3, 2021 at 0:26 Comment(1)
Hi, cool answer! Is there a faster approach? currently it seems this should work in O(n*m), while there are data structures that allow faster collision detection, such as R-trees and the other structures derived from it. However, I struggle to see how this would be implemented in a bevy system that gets a simple iterator over the ships and comets...Somatoplasm
T
0

There's https://lib.rs/crates/bevy_spatial with KD-Tree nowadays.

Usage example from the info page:

use bevy_spatial::{AutomaticUpdate, KDTree3, TransformMode, SpatialAccess};

#[derive(Component, Default)]
struct TrackedByKDTree;

fn main() {
    App::new()
        .add_plugin(AutomaticUpdate::<TrackedByKDTree>::new()
            .with_frequency(Duration::from_secs_f32(0.3))
            .with_transform(TransformMode::GlobalTransform))
        .add_systems(Update, use_neighbour);
    // ...
}

type NNTree = KDTree3<TrackedByKDTree>; // type alias for later

// spawn some entities with the TrackedByKDTree component

fn use_neighbour(tree: Res<NNTree>){
    if let Some((pos, entity)) = tree.nearest_neighbour(Vec3::ZERO) {
        // pos: Vec3
        // do something with the nearest entity here
    }
}
Tranquilizer answered 29/10, 2023 at 12:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.