use std::{f32::consts::PI, ops::Range}; use avian2d::prelude::*; use bevy::{ color::palettes::{ css::WHITE, tailwind::{LIME_400, RED_400}, }, prelude::*, }; use bevy_rand::prelude::{GlobalEntropy, WyRand}; use rand::Rng; use wyrand::WyRand as LocalRng; use super::objects::{Ball, Player, Wall}; const BALL_COUNT: u8 = 32; const BALL_SIZES: Range = 10.0..25.0; const DIMENSION_SIZES: Range = 500.0..2000.0; #[derive(Resource)] pub struct PlayableArea(f32, f32); #[derive(Resource)] pub struct PlayerSize(f32); pub fn setup_pseudo_random(mut commands: Commands, mut rng: GlobalEntropy) { commands.insert_resource(PlayerSize(rng.random_range(BALL_SIZES))); commands.insert_resource(PlayableArea( rng.random_range(DIMENSION_SIZES), rng.random_range(DIMENSION_SIZES), )); } pub fn setup_ui(mut commands: Commands) { commands.spawn((Name::new("Camera"), Camera2d, IsDefaultUiCamera)); } pub fn setup_player( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, radius: Res, ) { let circle = Circle::new(radius.0); commands.spawn(( Player, Collider::from(circle), Mesh2d(meshes.add(circle)), MeshMaterial2d(materials.add(Color::from(LIME_400))), )); } pub fn setup_balls( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, region: Res, ) { let mut random = LocalRng::new(Default::default()); for _ in 0..BALL_COUNT { let circle = Circle::new(random.random_range(BALL_SIZES)); commands.spawn(( Ball, Collider::from(circle), Mesh2d(meshes.add(circle)), MeshMaterial2d(materials.add(Color::from(RED_400))), Transform::from_xyz( random.random_range( (-region.0 / 2.0 + circle.radius)..(region.0 / 2.0 - circle.radius), ), random.random_range( (-region.1 / 2.0 + circle.radius)..(region.1 / 2.0 - circle.radius), ), 0.0, ), )); } } pub fn setup_walls( mut commands: Commands, mut materials: ResMut>, mut meshes: ResMut>, region: Res, ) { let thickness = 20.0; for i in 0..4 { let (offset, length) = if i % 2 == 0 { (region.0, region.1 + thickness) } else { (region.1, region.0 + thickness) }; let mut transform = Transform::from_xyz(0.0, offset / 2.0, 0.0); transform.rotate_around( Vec3::ZERO, Quat::from_rotation_z(((i + 1) as f32) * PI / 2.0), ); commands.spawn(( Wall, Collider::rectangle(length, thickness), Mesh2d(meshes.add(Rectangle::new(length, thickness))), MeshMaterial2d(materials.add(Color::from(WHITE))), transform, )); } }