use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, math::vec2, prelude::*, time::common_conditions::on_timer, window::PrimaryWindow, }; use bevy_spatial::{ AutomaticUpdate, SpatialAccess, SpatialStructure, TransformMode, kdtree::KDTree3, }; use std::ops::Deref; use std::time::Duration; #[derive(Component, Default)] struct NearestNeighbour; #[derive(Component)] struct MoveTowards; fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugins( AutomaticUpdate::::new() .with_spatial_ds(SpatialStructure::KDTree3) .with_frequency(Duration::from_secs(1)) .with_transform(TransformMode::Transform), ) .add_plugins(FrameTimeDiagnosticsPlugin::default()) .add_plugins(LogDiagnosticsPlugin::default()) .add_systems(Startup, setup) .add_systems( Update, ( mouseclick, log_num.run_if(on_timer(Duration::from_secs_f32(0.5))), move_to, ), ) .run(); } type NNTree = KDTree3; fn setup(mut commands: Commands) { commands.spawn(Camera2d); for x in -6..6 { for y in -6..6 { commands.spawn(( NearestNeighbour, Sprite { color: Color::srgb(0.7, 0.3, 0.5), custom_size: Some(Vec2::new(10.0, 10.0)), ..default() }, Transform { translation: Vec3::new((x * 100) as f32, (y * 100) as f32, 0.0), ..default() }, )); } } } fn mouseclick( mut commands: Commands, mouse_input: Res>, window: Single<&Window, With>, camera: Single<(&Camera, &GlobalTransform)>, ) { let (cam, cam_t) = camera.deref(); if mouse_input.pressed(MouseButton::Left) { if let Some(pos) = window.cursor_position() { for xoff in -1..=1 { for yoff in -1..=1 { commands.spawn(( MoveTowards, Sprite { color: Color::srgb(0.15, 0.15, 1.0), custom_size: Some(Vec2::new(10.0, 10.0)), ..default() }, Transform { translation: cam .viewport_to_world_2d( cam_t, pos + vec2(xoff as f32 * 16., yoff as f32 * 16.), ) .unwrap_or(Vec2::ZERO) .extend(1.0), ..default() }, )); } } } } } fn move_to( treeaccess: Res, time: Res