use bevy::{ prelude::*, math::{vec3, vec2, const_vec2} }; use butsuri::prelude::*; use rand::{Rng, thread_rng}; const COLLIDER_SHAPE_SIZE: f32 = 25.; const AREA_SIZE: Vec2 = const_vec2!([300.; 2]); fn main() { App::new() .add_plugins(DefaultPlugins) .add_plugin(PhysicsPlugin::default()) .add_plugin(DebugPlugin) .add_startup_system(setup) .add_system(input) .add_system(out_of_bounds) .add_system(collision_reaction) .run(); } fn setup( mut commands: Commands ) { commands.spawn_bundle(OrthographicCameraBundle::new_2d()); for _ in 0..20 { commands.spawn_bundle(SpriteBundle { sprite: Sprite { custom_size: Some(Vec2::splat(COLLIDER_SHAPE_SIZE)), color: Color::TOMATO, ..Default::default() }, transform: Transform::from_translation(random_position()), ..Default::default() }) .insert(random_collier_shape()) .insert_bundle(Kinematic { velocity: Velocity { linear: random_velocity(), angular: 0.0, }, ..Default::default() }); } } fn input(input: Res>, mut query: Query<(&mut Transform, &mut Velocity)>) { if input.just_pressed(KeyCode::P) { for (mut transform, _) in query.iter_mut() { transform.translation = random_position(); } } if input.just_pressed(KeyCode::V) { for (_, mut velocity) in query.iter_mut() { velocity.linear = random_velocity(); } } } fn random_position() -> Vec3 { vec3( thread_rng().gen_range(-100.0..=100.0), thread_rng().gen_range(-100.0..=100.0), 0.0, ) } fn random_velocity() -> Vec2 { vec2( thread_rng().gen_range(-1.0..=1.0), thread_rng().gen_range(-1.0..=1.0), ).normalize() * thread_rng().gen_range(25. ..= 50.) } fn random_collier_shape() -> ColliderShape { match thread_rng().gen::() { true => ColliderShape::AABB(COLLIDER_SHAPE_SIZE, COLLIDER_SHAPE_SIZE), false => ColliderShape::Circle(COLLIDER_SHAPE_SIZE), } } fn out_of_bounds(mut query: Query<(&mut Transform, &mut Velocity)>) { for (mut transform, mut velocity) in query.iter_mut() { let horizontal = transform.translation.x > AREA_SIZE.x || transform.translation.x < -AREA_SIZE.x; let vertical = transform.translation.y > AREA_SIZE.x || transform.translation.y < -AREA_SIZE.y; if horizontal || vertical { velocity.linear = random_velocity(); transform.translation = random_position(); } } } fn collision_reaction ( mut collision_event: EventReader, mut query: Query<&mut Sprite>, ) { for mut sprite in query.iter_mut() { sprite.color = Color::BLUE } for &CollisionEvent(dst, _src) in collision_event.iter() { query.get_mut(dst).unwrap().color = Color::RED; } }