|
|
|
|
@ -1,3 +1,4 @@
|
|
|
|
|
use bevy::asset::{AssetPath, HandleTemplate};
|
|
|
|
|
use engine::*;
|
|
|
|
|
|
|
|
|
|
const TILE: &str = "tileGrey_01.png";
|
|
|
|
|
@ -72,7 +73,6 @@ fn main() {
|
|
|
|
|
Update,
|
|
|
|
|
toggle_state_entities::<AudioPlayback>.run_if(state_changed::<AudioPlayback>),
|
|
|
|
|
)
|
|
|
|
|
.add_observer(on_add_ui_button)
|
|
|
|
|
.add_observer(on_add_coordinates)
|
|
|
|
|
.run();
|
|
|
|
|
}
|
|
|
|
|
@ -86,7 +86,7 @@ enum AudioPlayback {
|
|
|
|
|
Play,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Component, PartialEq, Default, FromTemplate)]
|
|
|
|
|
#[derive(Debug, Component, PartialEq, Default)]
|
|
|
|
|
#[require(Visibility, Transform)]
|
|
|
|
|
enum UiButton {
|
|
|
|
|
Power,
|
|
|
|
|
@ -117,51 +117,41 @@ impl UiButton {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn on_add_ui_button(
|
|
|
|
|
trigger: On<Add, UiButton>,
|
|
|
|
|
mut commands: Commands,
|
|
|
|
|
query: Query<&UiButton>,
|
|
|
|
|
server: Res<AssetServer>,
|
|
|
|
|
) {
|
|
|
|
|
let button = query.get(trigger.entity).unwrap();
|
|
|
|
|
commands
|
|
|
|
|
.entity(trigger.entity)
|
|
|
|
|
.insert((
|
|
|
|
|
Button,
|
|
|
|
|
Hovered::default(),
|
|
|
|
|
Outline {
|
|
|
|
|
width: Val::Px(5.0),
|
|
|
|
|
color: Color::NONE,
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
fn ui_button(
|
|
|
|
|
button: UiButton,
|
|
|
|
|
) -> impl Scene {
|
|
|
|
|
let color: Color = WHITE.with_alpha(0.5).into();
|
|
|
|
|
bsn! {
|
|
|
|
|
Button
|
|
|
|
|
Hovered
|
|
|
|
|
Outline {
|
|
|
|
|
width: Val::Px(5.0),
|
|
|
|
|
color: Color::NONE,
|
|
|
|
|
}
|
|
|
|
|
Node {
|
|
|
|
|
top: Val::Px(2.5),
|
|
|
|
|
left: Val::Px(2.5),
|
|
|
|
|
margin: UiRect::all(Val::Px(2.5)),
|
|
|
|
|
}
|
|
|
|
|
BackgroundColor(GRAY)
|
|
|
|
|
ImageNode {
|
|
|
|
|
image: HandleTemplate::Path(TILE),
|
|
|
|
|
color,
|
|
|
|
|
}
|
|
|
|
|
Children [
|
|
|
|
|
Node {
|
|
|
|
|
top: Val::Px(2.5),
|
|
|
|
|
left: Val::Px(2.5),
|
|
|
|
|
margin: UiRect::all(Val::Px(2.5)),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
BackgroundColor(GRAY.into()),
|
|
|
|
|
align_self: AlignSelf::Center,
|
|
|
|
|
justify_self: JustifySelf::Center,
|
|
|
|
|
width: Val::Percent(100.0),
|
|
|
|
|
height: Val::Percent(100.0),
|
|
|
|
|
}
|
|
|
|
|
ImageNode {
|
|
|
|
|
image: server.load(TILE),
|
|
|
|
|
color: WHITE.with_alpha(0.5).into(),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
children![(
|
|
|
|
|
Node {
|
|
|
|
|
align_self: AlignSelf::Center,
|
|
|
|
|
justify_self: JustifySelf::Center,
|
|
|
|
|
width: Val::Percent(100.0),
|
|
|
|
|
height: Val::Percent(100.0),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
ImageNode {
|
|
|
|
|
image: server.load(button.icon()),
|
|
|
|
|
..default()
|
|
|
|
|
},
|
|
|
|
|
)],
|
|
|
|
|
))
|
|
|
|
|
.observe(responsive_button_over)
|
|
|
|
|
.observe(responsive_button_out);
|
|
|
|
|
image: HandleTemplate::Path(AssetPath::parse(button.icon())),
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
on(responsive_button_over)
|
|
|
|
|
on(responsive_button_out)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn the_camera() -> impl Scene {
|
|
|
|
|
@ -180,27 +170,27 @@ fn the_ui() -> impl Scene {
|
|
|
|
|
}
|
|
|
|
|
Transform
|
|
|
|
|
Children [
|
|
|
|
|
UiButton::Power
|
|
|
|
|
ui_button(UiButton::Power)
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut writer: MessageWriter<AppExit>| {
|
|
|
|
|
writer.write(AppExit::Success);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::Pause
|
|
|
|
|
ui_button(UiButton::Pause)
|
|
|
|
|
SimulationPlayback::Run
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>| {
|
|
|
|
|
// Set simulation state
|
|
|
|
|
next.set(SimulationPlayback::Pause);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::Play
|
|
|
|
|
ui_button(UiButton::Play)
|
|
|
|
|
SimulationPlayback::Pause
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>| {
|
|
|
|
|
// Set simulation state
|
|
|
|
|
next.set(SimulationPlayback::Run);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::Step
|
|
|
|
|
ui_button(UiButton::Step)
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<SimulationPlayback>>| {
|
|
|
|
|
next.set(SimulationPlayback::Step);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::ZoomOut
|
|
|
|
|
ui_button(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) => {
|
|
|
|
|
@ -209,7 +199,7 @@ fn the_ui() -> impl Scene {
|
|
|
|
|
_ => todo!(),
|
|
|
|
|
});
|
|
|
|
|
}),
|
|
|
|
|
UiButton::ZoomIn
|
|
|
|
|
ui_button(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) => {
|
|
|
|
|
@ -218,15 +208,15 @@ fn the_ui() -> impl Scene {
|
|
|
|
|
_ => todo!(),
|
|
|
|
|
});
|
|
|
|
|
}),
|
|
|
|
|
UiButton::MuteAudio
|
|
|
|
|
ui_button(UiButton::MuteAudio)
|
|
|
|
|
AudioPlayback::Play
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<AudioPlayback>>| {
|
|
|
|
|
next.set(AudioPlayback::Play);
|
|
|
|
|
next.set(AudioPlayback::Mute);
|
|
|
|
|
}),
|
|
|
|
|
UiButton::PlayAudio
|
|
|
|
|
ui_button(UiButton::PlayAudio)
|
|
|
|
|
AudioPlayback::Mute
|
|
|
|
|
on(|_: On<Pointer<Press>>, mut next: ResMut<NextState<AudioPlayback>>| {
|
|
|
|
|
next.set(AudioPlayback::Mute);
|
|
|
|
|
next.set(AudioPlayback::Play);
|
|
|
|
|
}),
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
@ -235,7 +225,7 @@ fn the_ui() -> impl Scene {
|
|
|
|
|
#[derive(Default, Debug, Resource)]
|
|
|
|
|
struct NextCoordinates(Coordinates);
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Default, Clone, PartialEq, Hash, Eq, Component)]
|
|
|
|
|
#[derive(Debug, Default, Clone, PartialEq, Hash, Eq, Component, FromTemplate)]
|
|
|
|
|
#[require(Visibility, Transform)]
|
|
|
|
|
struct Coordinates {
|
|
|
|
|
x: isize,
|
|
|
|
|
@ -383,7 +373,7 @@ fn grid_gizmo(mut gizmos: Gizmos, coordinates: Res<NextCoordinates>) {
|
|
|
|
|
gizmos.rect_2d(isometry, Vec2::ONE * SCALE, PURPLE)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Component, Debug, PartialEq, Hash, Eq)]
|
|
|
|
|
#[derive(Component, Debug, PartialEq, Hash, Eq, FromTemplate)]
|
|
|
|
|
struct Cell;
|
|
|
|
|
|
|
|
|
|
// When left mouse clicked, spawn a cell at GridPosition
|
|
|
|
|
@ -522,12 +512,19 @@ enum Lifecycle {
|
|
|
|
|
Dead(Entity),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn new_cell(Coordinates { x, y }: Coordinates) -> impl Scene {
|
|
|
|
|
bsn! {
|
|
|
|
|
Coordinates { x, y }
|
|
|
|
|
Cell
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn cell_lifecycle(mut reader: MessageReader<Lifecycle>, mut commands: Commands) {
|
|
|
|
|
reader.read().for_each(|msg| match msg {
|
|
|
|
|
Lifecycle::Alive(c) => {
|
|
|
|
|
debug!("creating {:?}", c);
|
|
|
|
|
// TODO: Safeguard: ensure no other cell there?
|
|
|
|
|
commands.spawn((c.clone(), Cell));
|
|
|
|
|
commands.spawn_scene(new_cell(c.clone()));
|
|
|
|
|
}
|
|
|
|
|
Lifecycle::Dead(e) => {
|
|
|
|
|
commands.entity(*e).despawn();
|
|
|
|
|
|