Very simple 2d/3d toggle button

It's buggy as hell, but it works. Improvements come with icing.
bevy0.12
Elijah Voigt 2 years ago
parent 087b427506
commit a58151ee52

3
.gitignore vendored

@ -17,3 +17,6 @@
**/*.ini
trace-*.json
*.blend
*.blend1

BIN
assets/images/2d-icon.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/images/3d-icon.png (Stored with Git LFS)

Binary file not shown.

@ -18,6 +18,7 @@ mkShell rec {
vulkan-loader # Rendering
xorg.libXcursor xorg.libXi xorg.libXrandr # To use the x11 feature
libxkbcommon wayland # To use the wayland feature
gimp
];
LD_LIBRARY_PATH = lib.makeLibraryPath buildInputs;

@ -1,9 +1,3 @@
// TODO: Camera Animations
// Intro animation
// Turn changing animations
// TODO: Pickup/put-down sound in 3d
// TODO: Background during menu
use crate::{
game::{Board, BoardIndex, Piece, Side},
prelude::*,
@ -65,7 +59,9 @@ impl Plugin for Display3dPlugin {
(
activate::<Display3d>,
set_piece_texture,
opening_animation.run_if(run_once()),
opening_animation
.run_if(run_once())
.run_if(in_state(GameState::Play)),
),
)
.add_systems(OnExit(DisplayState::Display3d), deactivate::<Display3d>)
@ -74,6 +70,9 @@ impl Plugin for Display3dPlugin {
(
activate::<Display3d>.run_if(in_state(DisplayState::Display3d)),
set_piece_texture,
opening_animation
.run_if(run_once())
.run_if(in_state(DisplayState::Display3d)),
),
);
}
@ -209,7 +208,7 @@ fn hydrate_camera(
let gltf = gltfs.get(&assets_map.models).expect("Load GLTF content");
// Set it to the default position by starting the initial animation
if let Ok(mut player) = players.get_mut(entity) {
info!("Animations: {:?}", gltf.named_animations.keys());
debug!("Animations: {:?}", gltf.named_animations.keys());
// GameCamIntro1, GameCamIntro2, GameCamSide1>2, GameCamSide2>1
let animation = match state.get() {
game::TurnState::SideA => gltf.named_animations.get("GameCamIntro1"),

@ -11,6 +11,7 @@ mod hit;
mod loading;
mod menu;
mod prelude;
mod ui;
use std::time::Duration;
@ -40,7 +41,6 @@ fn main() {
app.add_systems(
Update,
(
toggle_display_mode.run_if(on_event::<KeyboardInput>()),
// TODO: Run this other times too so we ensure a camera is always active
toggle_display_camera.run_if(state_changed::<DisplayState>()),
toggle_display_camera.run_if(state_changed::<GameState>()),
@ -70,6 +70,7 @@ fn main() {
app.add_plugins(loading::LoadingPlugin);
app.add_plugins(menu::MenuPlugin);
app.add_plugins(audio::AudioPlugin);
app.add_plugins(ui::UiPlugin);
app.run();
}
@ -83,7 +84,7 @@ pub enum GameState {
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Default, States, Component)]
pub enum DisplayState {
pub(crate) enum DisplayState {
#[default]
Display2d,
Display3d,
@ -141,24 +142,6 @@ fn debug_state<S: States>(state: Res<State<S>>) {
info!("State change {:?}", *state);
}
fn toggle_display_mode(
mut events: EventReader<KeyboardInput>,
display_state: Res<State<DisplayState>>,
mut next_state: ResMut<NextState<DisplayState>>,
) {
events
.iter()
.filter(
|KeyboardInput {
key_code, state, ..
}| (*key_code, *state) == (Some(KeyCode::Space), ButtonState::Pressed),
)
.for_each(|_| match display_state.get() {
DisplayState::Display2d => next_state.set(DisplayState::Display3d),
DisplayState::Display3d => next_state.set(DisplayState::Display2d),
})
}
fn toggle_display_camera(
state: Res<State<DisplayState>>,
mut cameras: Query<(&mut Camera, &DisplayState)>,

@ -160,7 +160,7 @@ fn handle_menu_quit(
fn interactive_button(
mut events: Query<(&mut BackgroundColor, &Interaction), (With<Button>, Changed<Interaction>)>,
mut window: Query<&mut Window, With<PrimaryWindow>>,
mut writer: EventWriter<crate::audio::AudioEvent>,
mut writer: EventWriter<audio::AudioEvent>,
) {
events
.iter_mut()
@ -176,7 +176,7 @@ fn interactive_button(
Interaction::Pressed => {
window.single_mut().cursor.icon = CursorIcon::Grab;
bg_color.0.set_a(1.0);
writer.send(crate::audio::AudioEvent::MenuSelect)
writer.send(audio::AudioEvent::MenuSelect)
}
});
}

@ -0,0 +1,88 @@
use crate::prelude::*;
pub(crate) struct UiPlugin;
impl Plugin for UiPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, initialize);
app.add_systems(OnExit(GameState::Loading), sync_display_mode);
app.add_systems(
Update,
(
toggle_display_mode.run_if(any_component_changed::<Interaction>),
sync_display_mode.run_if(state_changed::<DisplayState>()),
),
);
}
}
#[derive(Debug, Component)]
struct UiRoot;
fn initialize(mut commands: Commands) {
commands
.spawn((
NodeBundle {
style: Style {
padding: UiRect::all(Val::Px(10.0)),
position_type: PositionType::Absolute,
right: Val::Px(5.0),
bottom: Val::Px(5.0),
..default()
},
background_color: Color::WHITE.with_a(0.5).into(),
..default()
},
UiRoot,
))
.with_children(|parent| {
parent.spawn((
ButtonBundle {
style: Style {
padding: UiRect::all(Val::Px(10.0)),
..default()
},
visibility: Visibility::Visible,
..default()
},
DisplayState::Display2d,
));
});
}
/// When button is clicked, switch display state to that state and hide the other option.
/// Display2d -> Click -> Display2d mode & Display3d butto
fn toggle_display_mode(
events: Query<(&Interaction, &DisplayState), (Changed<Interaction>, With<Button>)>,
mut next_state: ResMut<NextState<DisplayState>>,
) {
events
.iter()
.for_each(|(interaction, display_state)| match interaction {
Interaction::Pressed => match display_state {
DisplayState::Display2d => next_state.set(DisplayState::Display2d),
DisplayState::Display3d => next_state.set(DisplayState::Display3d),
},
_ => (),
});
}
/// Syncs the display button with the UI
/// Runs every time the DisplayState changes
fn sync_display_mode(
mut query: Query<(&mut UiImage, &mut DisplayState), With<Button>>,
state: Res<State<DisplayState>>,
server: Res<AssetServer>,
) {
query.iter_mut().for_each(|(mut image, mut display_state)| {
let (texture, target_state) = match state.get() {
DisplayState::Display2d => (server.load("images/3d-icon.png"), DisplayState::Display3d),
DisplayState::Display3d => (server.load("images/2d-icon.png"), DisplayState::Display2d),
};
*image = UiImage {
texture,
..default()
};
*display_state = target_state;
});
}
Loading…
Cancel
Save