diff --git a/src/world.rs b/src/world.rs index a895f26..a24cf75 100644 --- a/src/world.rs +++ b/src/world.rs @@ -6,6 +6,7 @@ use bevy_xpbd_3d::prelude::*; use bevy_xpbd_3d::plugins::sync::SyncConfig; use std::f32::consts::PI; +const ASTEROID_UPDATE_INTERVAL: f32 = 1.0; // seconds const ASTEROID_SIZE: f32 = 100.0; const STARS_MAX_MAGNITUDE: f32 = 5.5; @@ -30,11 +31,16 @@ pub struct WorldPlugin; impl Plugin for WorldPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, setup); + app.add_systems(Startup, generate_asteroids); app.add_systems(Update, handle_cheats); + app.add_systems(Update, spawn_despawn_asteroids); app.add_plugins(PhysicsPlugins::default()); app.add_plugins(MaterialPlugin::::default()); //app.add_plugins(PhysicsDebugPlugin::default()); app.insert_resource(Gravity(DVec3::splat(0.0))); + app.insert_resource(AsteroidUpdateTimer( + Timer::from_seconds(ASTEROID_UPDATE_INTERVAL, TimerMode::Repeating))); + app.insert_resource(AsteroidDatabase(Vec::new())); // Disable bevy_xpbd's position->transform sync because we have a // custom syncing function. @@ -46,6 +52,18 @@ impl Plugin for WorldPlugin { } } +#[derive(Resource)] struct AsteroidUpdateTimer(Timer); +#[derive(Resource)] struct AsteroidDatabase(Vec); + +struct AsteroidData { + is_spawned: bool, + class: u8, + size: f32, + x: f64, + y: f64, + z: f64, +} + #[derive(Asset, TypePath, AsBindGroup, Debug, Clone)] pub struct RingMaterial { alpha_mode: AlphaMode, @@ -74,48 +92,6 @@ pub fn setup( mut materials_custom: ResMut>, asset_server: Res, ) { - // Generate a bunch of asteriods - let maxdist = 4; - let pi = PI as f64; - let player_x: f64 = -300000.0; - let player_y: f64 = 0.0; - let player_z: f64 = -500000.0; - for i in -maxdist..maxdist { - for j in -maxdist..maxdist { - for k in -maxdist..maxdist { - let offset: f64 = 500.0; - let dist: f64 = 8e3; - let wobble: f64 = dist/2.0; - let (i, j, k) = (i as f64, j as f64, k as f64); - let asset = match ((i+j+k) as i32) % 2 { - 0 => ASSET_ASTEROID1, - _ => ASSET_ASTEROID2, - }; - commands.spawn(( - actor::Actor::default(), - RigidBody::Dynamic, - AngularVelocity(DVec3::new(0.1, 0.1, 0.03)), - LinearVelocity(DVec3::new(0.0, 0.0, 0.35)), - Collider::sphere(1.0), - SceneBundle { - transform: Transform { - scale: Vec3::splat(ASTEROID_SIZE), - ..default() - }, - scene: asset_server.load(asset), - ..default() - }, - Rotation::from(Quat::from_rotation_y(-PI / 3.)), - Position::from_xyz( - player_x + offset + dist * i + wobble * (j+k/pi).sin() * (k+j/pi).cos(), - player_y + offset + dist * j + wobble * (k+i/pi).sin() * (i+k/pi).cos(), - player_z + offset + dist * k + wobble * (i+j/pi).sin() * (j+i/pi).cos(), - ), - )); - } - } - } - // Generate starmap let sphere_handle = meshes.add(Sphere::new(1.0)); let mut starcount = 0; @@ -181,6 +157,74 @@ pub fn setup( )); } +fn generate_asteroids( + mut db: ResMut, +) { + let maxdist = 4; + let pi = PI as f64; + let player_x: f64 = -300000.0; + let player_y: f64 = 0.0; + let player_z: f64 = -500000.0; + for i in -maxdist..maxdist { + for j in -maxdist..maxdist { + for k in -maxdist..maxdist { + let offset: f64 = 500.0; + let dist: f64 = 8e3; + let wobble: f64 = dist/2.0; + let (i, j, k) = (i as f64, j as f64, k as f64); + db.0.push(AsteroidData { + is_spawned: false, + x: player_x + offset + dist * i + wobble * (j+k/pi).sin() * (k+j/pi).cos(), + y: player_y + offset + dist * j + wobble * (k+i/pi).sin() * (i+k/pi).cos(), + z: player_z + offset + dist * k + wobble * (i+j/pi).sin() * (j+i/pi).cos(), + size: ASTEROID_SIZE, + class: (((i+j+k) as i32) % 2) as u8, + }); + } + } + } +} + +fn spawn_despawn_asteroids( + time: Res