split off asteroid generation and spawning
This commit is contained in:
parent
5c50ac33e3
commit
68cc65a2eb
128
src/world.rs
128
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::<RingMaterial>::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<AsteroidData>);
|
||||
|
||||
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<Assets<RingMaterial>>,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
// 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<AsteroidDatabase>,
|
||||
) {
|
||||
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<Time>,
|
||||
mut timer: ResMut<AsteroidUpdateTimer>,
|
||||
mut db: ResMut<AsteroidDatabase>,
|
||||
mut commands: Commands,
|
||||
asset_server: Res<AssetServer>,
|
||||
) {
|
||||
if !timer.0.tick(time.delta()).just_finished() {
|
||||
return;
|
||||
}
|
||||
|
||||
for asteroid in &mut db.0 {
|
||||
if asteroid.is_spawned {
|
||||
continue;
|
||||
}
|
||||
asteroid.is_spawned = true;
|
||||
let asset = match asteroid.class {
|
||||
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(asteroid.x, asteroid.y, asteroid.z),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_cheats(
|
||||
key_input: Res<ButtonInput<KeyCode>>,
|
||||
mut q_player: Query<(&Transform, &mut Position, &mut LinearVelocity), With<actor::PlayerCamera>>,
|
||||
|
|
Loading…
Reference in a new issue