|
|
|
|
@ -1,13 +1,3 @@
|
|
|
|
|
// TODO: Rearchitected so it's Cell and Coordiantes not Cell { position { coordiantes } }
|
|
|
|
|
|
|
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
|
|
use bevy::{
|
|
|
|
|
audio::Volume,
|
|
|
|
|
input::mouse::{AccumulatedMouseMotion, MouseMotion},
|
|
|
|
|
picking::hover::Hovered,
|
|
|
|
|
platform::collections::HashMap,
|
|
|
|
|
};
|
|
|
|
|
use engine::*;
|
|
|
|
|
|
|
|
|
|
const TILE: &str = "tileGrey_01.png";
|
|
|
|
|
@ -22,10 +12,12 @@ fn main() {
|
|
|
|
|
.init_resource::<NextCoordinates>()
|
|
|
|
|
.init_resource::<CellAssets>()
|
|
|
|
|
.init_resource::<Panning>()
|
|
|
|
|
.insert_resource(ClearColor(WHITE.into()))
|
|
|
|
|
.init_state::<SimulationPlayback>()
|
|
|
|
|
.init_state::<AudioPlayback>()
|
|
|
|
|
.add_message::<Lifecycle>()
|
|
|
|
|
.add_systems(Startup, setup)
|
|
|
|
|
.add_systems(Startup, the_camera.spawn())
|
|
|
|
|
.add_systems(Startup, the_ui.spawn())
|
|
|
|
|
.add_systems(Startup, load_audio_tones)
|
|
|
|
|
.add_systems(Startup, load_materials)
|
|
|
|
|
.add_systems(Startup, load_meshes)
|
|
|
|
|
@ -87,14 +79,14 @@ fn main() {
|
|
|
|
|
|
|
|
|
|
const SCALE: f32 = 100.0;
|
|
|
|
|
|
|
|
|
|
#[derive(States, Debug, Default, Hash, PartialEq, Eq, Clone, Component)]
|
|
|
|
|
#[derive(States, Debug, Default, Hash, PartialEq, Eq, Clone, Component, FromTemplate)]
|
|
|
|
|
enum AudioPlayback {
|
|
|
|
|
#[default]
|
|
|
|
|
Mute,
|
|
|
|
|
Play,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Component, PartialEq)]
|
|
|
|
|
#[derive(Debug, Component, PartialEq, Default, FromTemplate)]
|
|
|
|
|
#[require(Visibility, Transform)]
|
|
|
|
|
enum UiButton {
|
|
|
|
|
Power,
|
|
|
|
|
@ -105,6 +97,8 @@ enum UiButton {
|
|
|
|
|
ZoomIn,
|
|
|
|
|
PlayAudio,
|
|
|
|
|
MuteAudio,
|
|
|
|
|
#[default]
|
|
|
|
|
None,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl UiButton {
|
|
|
|
|
@ -118,6 +112,7 @@ impl UiButton {
|
|
|
|
|
Self::ZoomIn => "zoomIn.png",
|
|
|
|
|
Self::PlayAudio => "audioOn.png",
|
|
|
|
|
Self::MuteAudio => "audioOff.png",
|
|
|
|
|
Self::None => todo!(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -169,82 +164,71 @@ fn on_add_ui_button(
|
|
|
|
|
.observe(responsive_button_out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn setup(mut commands: Commands) {
|
|
|
|
|
commands.spawn((
|
|
|
|
|
Camera2d,
|
|
|
|
|
Camera {
|
|
|
|
|
clear_color: ClearColorConfig::Custom(WHITE.into()),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
commands
|
|
|
|
|
.spawn((
|
|
|
|
|
Node {
|
|
|
|
|
top: Val::Px(0.0),
|
|
|
|
|
left: Val::Px(0.0),
|
|
|
|
|
height: Val::Px(40.0),
|
|
|
|
|
width: Val::Percent(100.0),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
Transform::default(),
|
|
|
|
|
))
|
|
|
|
|
.with_children(|parent| {
|
|
|
|
|
parent.spawn(UiButton::Power).observe(shutdown);
|
|
|
|
|
// TODO: Reset button
|
|
|
|
|
parent
|
|
|
|
|
.spawn((UiButton::Pause, SimulationPlayback::Run))
|
|
|
|
|
.observe(pause_sim);
|
|
|
|
|
parent
|
|
|
|
|
.spawn((UiButton::Play, SimulationPlayback::Pause))
|
|
|
|
|
.observe(play_sim);
|
|
|
|
|
parent.spawn(UiButton::Step).observe(step_sim);
|
|
|
|
|
parent.spawn(UiButton::ZoomOut).observe(zoom_out);
|
|
|
|
|
parent.spawn(UiButton::ZoomIn).observe(zoom_in);
|
|
|
|
|
// TODO: Mute/Unmute Toggle
|
|
|
|
|
parent
|
|
|
|
|
.spawn((UiButton::MuteAudio, AudioPlayback::Play))
|
|
|
|
|
.observe(mute_audio);
|
|
|
|
|
parent
|
|
|
|
|
.spawn((UiButton::PlayAudio, AudioPlayback::Mute))
|
|
|
|
|
.observe(play_audio);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
fn shutdown(_trigger: On<Pointer<Press>>, mut writer: MessageWriter<AppExit>) {
|
|
|
|
|
writer.write(AppExit::Success);
|
|
|
|
|
}
|
|
|
|
|
fn play_sim(_trigger: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>) {
|
|
|
|
|
// Set simulation state
|
|
|
|
|
next.set(SimulationPlayback::Run);
|
|
|
|
|
}
|
|
|
|
|
fn pause_sim(_trigger: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>) {
|
|
|
|
|
// Set simulation state
|
|
|
|
|
next.set(SimulationPlayback::Pause);
|
|
|
|
|
fn the_camera() -> impl Scene {
|
|
|
|
|
bsn! {
|
|
|
|
|
Camera2d
|
|
|
|
|
}
|
|
|
|
|
fn step_sim(_trigger: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>) {
|
|
|
|
|
next.set(SimulationPlayback::Step);
|
|
|
|
|
}
|
|
|
|
|
fn zoom_out(_trigger: On<Pointer<Press>>, mut projection: Query<&mut Projection>) {
|
|
|
|
|
projection.iter_mut().for_each(|mut p| match *p {
|
|
|
|
|
Projection::Orthographic(ref mut o) => {
|
|
|
|
|
o.scale /= 0.5;
|
|
|
|
|
}
|
|
|
|
|
_ => todo!(),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
fn zoom_in(_trigger: On<Pointer<Press>>, mut projection: Query<&mut Projection>) {
|
|
|
|
|
projection.iter_mut().for_each(|mut p| match *p {
|
|
|
|
|
Projection::Orthographic(ref mut o) => {
|
|
|
|
|
o.scale *= 0.5;
|
|
|
|
|
}
|
|
|
|
|
_ => todo!(),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
fn play_audio(_trigger: On<Pointer<Press>>, mut next: ResMut<NextState<AudioPlayback>>) {
|
|
|
|
|
next.set(AudioPlayback::Play);
|
|
|
|
|
}
|
|
|
|
|
fn mute_audio(_trigger: On<Pointer<Press>>, mut next: ResMut<NextState<AudioPlayback>>) {
|
|
|
|
|
next.set(AudioPlayback::Mute);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn the_ui() -> impl Scene {
|
|
|
|
|
bsn! {
|
|
|
|
|
Node {
|
|
|
|
|
top: Val::Px(0.0),
|
|
|
|
|
left: Val::Px(0.0),
|
|
|
|
|
height: Val::Px(40.0),
|
|
|
|
|
width: Val::Percent(100.0),
|
|
|
|
|
}
|
|
|
|
|
Transform
|
|
|
|
|
Children [
|
|
|
|
|
UiButton::Power
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut writer: MessageWriter<AppExit>| {
|
|
|
|
|
writer.write(AppExit::Success);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::Pause
|
|
|
|
|
SimulationPlayback::Run
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>| {
|
|
|
|
|
// Set simulation state
|
|
|
|
|
next.set(SimulationPlayback::Pause);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::Play
|
|
|
|
|
SimulationPlayback::Pause
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>| {
|
|
|
|
|
// Set simulation state
|
|
|
|
|
next.set(SimulationPlayback::Run);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::Step
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>| {
|
|
|
|
|
next.set(SimulationPlayback::Step);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::ZoomOut
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut projection: Query<&mut Projection>| {
|
|
|
|
|
projection.iter_mut().for_each(|mut p| match *p {
|
|
|
|
|
Projection::Orthographic(ref mut o) => {
|
|
|
|
|
o.scale /= 0.5;
|
|
|
|
|
}
|
|
|
|
|
_ => todo!(),
|
|
|
|
|
});
|
|
|
|
|
}),
|
|
|
|
|
UiButton::ZoomIn
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut projection: Query<&mut Projection>| {
|
|
|
|
|
projection.iter_mut().for_each(|mut p| match *p {
|
|
|
|
|
Projection::Orthographic(ref mut o) => {
|
|
|
|
|
o.scale *= 0.5;
|
|
|
|
|
}
|
|
|
|
|
_ => todo!(),
|
|
|
|
|
});
|
|
|
|
|
}),
|
|
|
|
|
UiButton::MuteAudio
|
|
|
|
|
AudioPlayback::Play
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<AudioPlayback>>| {
|
|
|
|
|
next.set(AudioPlayback::Play);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::PlayAudio
|
|
|
|
|
AudioPlayback::Mute
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<AudioPlayback>>| {
|
|
|
|
|
next.set(AudioPlayback::Mute);
|
|
|
|
|
}),
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -433,7 +417,8 @@ fn assert_cell_uniqueness(q: Query<(Entity, &Coordinates), With<Cell>>) {
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(States, Debug, Default, Hash, PartialEq, Eq, Clone, Component)]
|
|
|
|
|
#[derive(States, Debug, Default, Hash, PartialEq, Eq, Clone, Component, FromTemplate)]
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
enum SimulationPlayback {
|
|
|
|
|
#[default]
|
|
|
|
|
Pause,
|
|
|
|
|
@ -663,7 +648,7 @@ fn control_volume(state: ResMut<State<AudioPlayback>>, mut sinks: Query<&mut Aud
|
|
|
|
|
sinks.iter_mut().for_each(|mut sink| {
|
|
|
|
|
sink.set_volume(volume);
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
AudioPlayback::Mute => sinks.iter_mut().for_each(|mut sink| {
|
|
|
|
|
sink.set_volume(Volume::SILENT);
|
|
|
|
|
}),
|
|
|
|
|
|