use bevy::prelude::*;
use crate::consts::{
APP_VERSION,
SELECTED_COLOR,
TITLE,
TITLE_COLOR,
UNSELECTED_COLOR,
VERSION_COLOR,
};
use crate::events::NumplesEvent;
use crate::fonts::TitleFont;
use crate::game::Level;
use crate::gameover::GameOverCheck;
use crate::gameplay::{Gameplay, MustResetClock, Paused};
use crate::persistence::Persistence;
use crate::states::GameState;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Component)]
pub struct TitleScene;
impl TitleScene {
pub fn load_title_scene(
mut commands: Commands,
title_font: Res<TitleFont>,
mut game_over: ResMut<GameOverCheck>,
) {
game_over.0 = false;
commands.spawn((
Self,
Text::new(TITLE.to_string()),
TextFont {
font: title_font.font().clone_weak(),
font_size: 48.0,
..default()
},
TextShadow::default(),
TextColor(TITLE_COLOR.clone()),
TextLayout::new_with_justify(JustifyText::Center),
Node {
position_type: PositionType::Absolute,
top: Val::Px(0.0),
width: Val::Percent(100.0),
..default()
},
));
commands.spawn((
Self,
Text::new(APP_VERSION.to_string()),
TextFont {
font: title_font.clone_weak(),
font_size: 18.0,
..default()
},
TextColor(VERSION_COLOR),
TextLayout::new_with_justify(JustifyText::Right),
Node {
position_type: PositionType::Absolute,
top: Val::Px(50.0),
width: Val::Percent(83.5),
..default()
},
));
let mut y = 100. / 6.;
for level in Level::levels() {
let level_number: u8 = level.into();
commands
.spawn((
Self,
level,
Text::new(format!("{}. {}", level_number, level.to_string())),
TextFont {
font: title_font.font().clone_weak(),
font_size: 32.0,
..default()
},
TextColor(UNSELECTED_COLOR.clone()),
TextLayout::new_with_justify(JustifyText::Center),
Node {
position_type: PositionType::Absolute,
align_items: AlignItems::Center,
top: Val::Percent(y),
width: Val::Percent(100.0),
height: Val::Percent(12.0),
..default()
},
))
.observe(Self::pointer_over_observer)
.observe(Self::pointer_out_observer)
.observe(Self::pointer_click_observer)
;
y += 100. / 8.;
}
commands
.spawn((
Self,
Text::new("C-o. Load Board"),
TextFont {
font: title_font.font().clone_weak(),
font_size: 32.0,
..default()
},
TextColor(UNSELECTED_COLOR.clone()),
TextLayout::new_with_justify(JustifyText::Center),
Node {
position_type: PositionType::Absolute,
align_items: AlignItems::Center,
top: Val::Percent(y),
width: Val::Percent(100.0),
height: Val::Percent(12.0),
..default()
},
))
.observe(Self::pointer_over_observer)
.observe(Self::pointer_out_observer)
.observe(Self::load_file_observer)
;
}
fn pointer_over_observer(
mut trigger: Trigger<Pointer<Over>>,
mut query: Query<(&Self, &mut TextColor, &mut BackgroundColor)>,
) {
if let Ok((_, mut text_color, mut bg)) = query.get_mut(trigger.target()) {
text_color.0 = SELECTED_COLOR.clone();
bg.0 = Color::Srgba(Srgba { red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0 });
}
trigger.propagate(false);
}
fn pointer_out_observer(
mut trigger: Trigger<Pointer<Out>>,
mut query: Query<(&Self, &mut TextColor, &mut BackgroundColor)>,
) {
if let Ok((_, mut text_color, mut bg)) = query.get_mut(trigger.target()) {
text_color.0 = UNSELECTED_COLOR.clone();
bg.0 = Color::Srgba(Srgba { red: 1.0, green: 1.0, blue: 1.0, alpha: 0.0 });
}
trigger.propagate(true);
}
fn pointer_click_observer(
mut trigger: Trigger<Pointer<Click>>,
query: Query<(&Self, &Level)>,
mut event_writer: EventWriter<NumplesEvent>,
) {
if let Ok((_, &level)) = query.get(trigger.target()) {
event_writer.write(NumplesEvent::StartGame(level));
}
trigger.propagate(false);
}
fn load_file_observer(
mut trigger: Trigger<Pointer<Click>>,
mut persistence: ResMut<Persistence>,
) {
persistence.load = true;
trigger.propagate(false);
}
pub fn unload_title_scene(
mut commands: Commands,
entities: Query<Entity, With<Self>>,
) {
for entity in &entities {
commands.entity(entity).despawn();
}
}
pub fn event_handle(
mut commands: Commands,
mut events: EventReader<NumplesEvent>,
mut next_state: ResMut<NextState<GameState>>,
mut paused: ResMut<Paused>,
) {
for event in events.read() {
match event {
NumplesEvent::StartGame(level) => {
commands.spawn((Gameplay, *level));
commands.spawn(MustResetClock);
paused.0 = false;
next_state.set(GameState::Playing);
}
_ => (),
}
}
}
}