This commit is contained in:
parent
fc95857824
commit
6a151397de
7 changed files with 21 additions and 1 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
@ -10,6 +10,7 @@
|
||||||
"despawn",
|
"despawn",
|
||||||
"Despawns",
|
"Despawns",
|
||||||
"lerp",
|
"lerp",
|
||||||
|
"PRNG",
|
||||||
"recip",
|
"recip",
|
||||||
"respawns",
|
"respawns",
|
||||||
"timestep",
|
"timestep",
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
use avian2d::prelude::*;
|
use avian2d::prelude::*;
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
/// Basic implementation of a physics object
|
||||||
#[derive(Component, Default)]
|
#[derive(Component, Default)]
|
||||||
#[require(Collider, Mesh2d, MeshMaterial2d<ColorMaterial>, Restitution = Restitution::new(1.0), RigidBody, TransformInterpolation, Transform)]
|
#[require(Collider, Mesh2d, MeshMaterial2d<ColorMaterial>, Restitution = Restitution::new(1.0), RigidBody, TransformInterpolation, Transform)]
|
||||||
struct GameObject;
|
struct GameObject;
|
||||||
|
|
||||||
|
/// A basic ball with which to interact
|
||||||
#[derive(Component, Default)]
|
#[derive(Component, Default)]
|
||||||
#[require(GameObject, RigidBody = RigidBody::Dynamic)]
|
#[require(GameObject, RigidBody = RigidBody::Dynamic)]
|
||||||
pub struct Ball;
|
pub struct Ball;
|
||||||
|
|
||||||
|
/// The controllable ball
|
||||||
#[derive(Component, Default)]
|
#[derive(Component, Default)]
|
||||||
#[require(Ball)]
|
#[require(Ball)]
|
||||||
pub struct Player;
|
pub struct Player;
|
||||||
|
|
||||||
|
/// The static objects bounding the playable area
|
||||||
#[derive(Component, Default)]
|
#[derive(Component, Default)]
|
||||||
#[require(GameObject, RigidBody = RigidBody::Static)]
|
#[require(GameObject, RigidBody = RigidBody::Static)]
|
||||||
pub struct Wall;
|
pub struct Wall;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rand::random;
|
use rand::random;
|
||||||
use wyrand::WyRand;
|
use wyrand::WyRand;
|
||||||
|
|
||||||
/// Initialize a `WyRand` using `rand`'s thread-local rng
|
/// Initialize a `WyRand` using `rand`'s thread-local random number generator
|
||||||
pub fn thread_rng() -> WyRand {
|
pub fn thread_rng() -> WyRand {
|
||||||
WyRand::new(random())
|
WyRand::new(random())
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use bevy::{
|
||||||
|
|
||||||
use super::objects::Player;
|
use super::objects::Player;
|
||||||
|
|
||||||
|
/// Move the player character based on the keyboard input
|
||||||
pub fn move_player(
|
pub fn move_player(
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
keyboard_input: Res<ButtonInput<KeyCode>>,
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
|
@ -31,10 +32,12 @@ pub fn move_player(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Neatly exit game
|
||||||
pub fn quit(mut exit: EventWriter<AppExit>) {
|
pub fn quit(mut exit: EventWriter<AppExit>) {
|
||||||
exit.write(AppExit::Success);
|
exit.write(AppExit::Success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Follow the player character with the camera
|
||||||
pub fn move_camera(
|
pub fn move_camera(
|
||||||
mut camera: Single<&mut Transform, (Without<Player>, With<IsDefaultUiCamera>)>,
|
mut camera: Single<&mut Transform, (Without<Player>, With<IsDefaultUiCamera>)>,
|
||||||
player: Single<&Transform, (With<Player>, Without<IsDefaultUiCamera>)>,
|
player: Single<&Transform, (With<Player>, Without<IsDefaultUiCamera>)>,
|
||||||
|
@ -42,6 +45,7 @@ pub fn move_camera(
|
||||||
camera.translation = camera.translation.lerp(player.translation, 0.05);
|
camera.translation = camera.translation.lerp(player.translation, 0.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adjust the camera zoom based on the scroll wheel input
|
||||||
pub fn zoom_camera(
|
pub fn zoom_camera(
|
||||||
mut camera: Single<&mut Projection, With<IsDefaultUiCamera>>,
|
mut camera: Single<&mut Projection, With<IsDefaultUiCamera>>,
|
||||||
scroll: Res<AccumulatedMouseScroll>,
|
scroll: Res<AccumulatedMouseScroll>,
|
||||||
|
|
|
@ -2,10 +2,12 @@ use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
|
/// Value with which to initialize the PRNG
|
||||||
#[derive(Clone, Resource)]
|
#[derive(Clone, Resource)]
|
||||||
pub struct Seed(u64);
|
pub struct Seed(u64);
|
||||||
|
|
||||||
impl From<String> for Seed {
|
impl From<String> for Seed {
|
||||||
|
/// Attempt to parse as an integer, fall back to hashing string
|
||||||
fn from(value: String) -> Self {
|
fn from(value: String) -> Self {
|
||||||
Self(value.parse::<u64>().unwrap_or_else(|_| {
|
Self(value.parse::<u64>().unwrap_or_else(|_| {
|
||||||
let mut state = DefaultHasher::new();
|
let mut state = DefaultHasher::new();
|
||||||
|
@ -16,6 +18,7 @@ impl From<String> for Seed {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Seed> for [u8; 8] {
|
impl From<Seed> for [u8; 8] {
|
||||||
|
/// Convert to a u8 array for ingestion by random number generator
|
||||||
fn from(value: Seed) -> Self {
|
fn from(value: Seed) -> Self {
|
||||||
value.0.to_le_bytes()
|
value.0.to_le_bytes()
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,15 @@ const BALL_COUNT: u8 = 32;
|
||||||
const BALL_SIZES: Range<f32> = 10.0..25.0;
|
const BALL_SIZES: Range<f32> = 10.0..25.0;
|
||||||
const DIMENSION_SIZES: Range<f32> = 500.0..2000.0;
|
const DIMENSION_SIZES: Range<f32> = 500.0..2000.0;
|
||||||
|
|
||||||
|
/// The size of the playable area (x, y)
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct PlayableArea(f32, f32);
|
pub struct PlayableArea(f32, f32);
|
||||||
|
|
||||||
|
/// The size of the player character
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct PlayerSize(f32);
|
pub struct PlayerSize(f32);
|
||||||
|
|
||||||
|
/// Initialize deterministic values
|
||||||
pub fn setup_pseudo_random(mut commands: Commands, mut rng: GlobalEntropy<WyRand>) {
|
pub fn setup_pseudo_random(mut commands: Commands, mut rng: GlobalEntropy<WyRand>) {
|
||||||
commands.insert_resource(PlayerSize(rng.random_range(BALL_SIZES)));
|
commands.insert_resource(PlayerSize(rng.random_range(BALL_SIZES)));
|
||||||
commands.insert_resource(PlayableArea(
|
commands.insert_resource(PlayableArea(
|
||||||
|
@ -38,6 +41,7 @@ pub fn setup_ui(mut commands: Commands) {
|
||||||
commands.spawn((Name::new("Camera"), Camera2d, IsDefaultUiCamera));
|
commands.spawn((Name::new("Camera"), Camera2d, IsDefaultUiCamera));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create the playable character
|
||||||
pub fn setup_player(
|
pub fn setup_player(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
@ -53,6 +57,7 @@ pub fn setup_player(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a random distribution of balls in the playable area
|
||||||
pub fn setup_balls(
|
pub fn setup_balls(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
@ -76,6 +81,7 @@ pub fn setup_balls(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create the 4 walls that enclose the playable area
|
||||||
pub fn setup_walls(
|
pub fn setup_walls(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
|
|
@ -10,6 +10,8 @@ use game::{
|
||||||
setup::{setup_balls, setup_player, setup_pseudo_random, setup_ui, setup_walls},
|
setup::{setup_balls, setup_player, setup_pseudo_random, setup_ui, setup_walls},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// The initial configuration passed to the game's setup functions.
|
||||||
|
/// Also functions as a Bevy plugin to pass the configuration into the app.
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(version, about)]
|
#[command(version, about)]
|
||||||
pub struct AppSettings {
|
pub struct AppSettings {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue