diff --git a/game/assets/cry.png b/game/assets/cry.png new file mode 100644 index 0000000000000000000000000000000000000000..3e759581714c6b7180e696c9988275f1249e5b4e Binary files /dev/null and b/game/assets/cry.png differ diff --git a/game/assets/sound/boss_music.ogg b/game/assets/sound/boss_music.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6957472871481abace2578abf1a41bce00230bde Binary files /dev/null and b/game/assets/sound/boss_music.ogg differ diff --git a/game/assets/sound/combat.mp3 b/game/assets/sound/combat.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..3e313b8ac79e2ee266b7b5a56048c2d03cedac25 Binary files /dev/null and b/game/assets/sound/combat.mp3 differ diff --git a/game/assets/sound/combat.ogg b/game/assets/sound/combat.ogg new file mode 100644 index 0000000000000000000000000000000000000000..01ff18806147fb5bc6355d577e34a0e1555f770b Binary files /dev/null and b/game/assets/sound/combat.ogg differ diff --git a/game/assets/sound/combat.wav b/game/assets/sound/combat.wav new file mode 100644 index 0000000000000000000000000000000000000000..86908f6b10991cba637bbd0c600ccd5356855ea7 Binary files /dev/null and b/game/assets/sound/combat.wav differ diff --git a/game/assets/sound/gameover.ogg b/game/assets/sound/gameover.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1713da5c8ab0818043e6a9cf13d336a5d7e12f53 Binary files /dev/null and b/game/assets/sound/gameover.ogg differ diff --git a/game/assets/sound/menu.ogg b/game/assets/sound/menu.ogg new file mode 100644 index 0000000000000000000000000000000000000000..c4f84031bf3c938deb0b1110c0fb7fa033fecb1c Binary files /dev/null and b/game/assets/sound/menu.ogg differ diff --git a/game/assets/sound/pokemon.ogg b/game/assets/sound/pokemon.ogg new file mode 100644 index 0000000000000000000000000000000000000000..30639b3afc3d9bac8a746e3b3a9c5145231c7c4b Binary files /dev/null and b/game/assets/sound/pokemon.ogg differ diff --git a/game/assets/sound/victoire.ogg b/game/assets/sound/victoire.ogg new file mode 100644 index 0000000000000000000000000000000000000000..314d7ff760025c6345bcb4bcbd1baa083cd18bb3 Binary files /dev/null and b/game/assets/sound/victoire.ogg differ diff --git a/game/assets/trophy.png b/game/assets/trophy.png new file mode 100644 index 0000000000000000000000000000000000000000..e550b80935c5d26f99803cc34722d1420bd55fd5 Binary files /dev/null and b/game/assets/trophy.png differ diff --git a/game/src/audio.rs b/game/src/audio.rs new file mode 100644 index 0000000000000000000000000000000000000000..339cb767b0046f78196c08e29c8979bae9ee172f --- /dev/null +++ b/game/src/audio.rs @@ -0,0 +1,85 @@ +use bevy::{prelude::*}; + +use super::{despawn_screen, GameState}; + +pub struct AudioPlugin; + +impl Plugin for AudioPlugin { + fn build(&self, app: &mut App) { + app + .add_systems(OnEnter(GameState::Victory), audio_win) + .add_systems(OnExit(GameState::Victory), despawn_screen::<AudioMenu>) + .add_systems(OnEnter(GameState::GameOver), audio_defeat) + .add_systems(OnExit(GameState::GameOver), despawn_screen::<AudioMenu>) + .add_systems(OnEnter(GameState::Menu), audio_menu) + .add_systems(OnExit(GameState::Menu), despawn_screen::<AudioMenu>) + .add_systems(OnEnter(GameState::Game), audio_game) + .add_systems(OnExit(GameState::Game), despawn_screen::<AudioMenu>) + .add_systems(OnEnter(GameState::Fight), audio_fight) + .add_systems(OnExit(GameState::Fight), despawn_screen::<AudioMenu>); + + } +} + +#[derive(Component)] +struct AudioMenu; + +fn audio_win(mut commands: Commands, asset_server: Res<AssetServer>) { + commands + .spawn(( + AudioBundle { + source: asset_server.load("sound/victoire.ogg"), + //connecter le volum avec le settings + ..default() + }, + AudioMenu, + )); +} + +fn audio_defeat (mut commands: Commands, asset_server: Res<AssetServer>) { + commands + .spawn(( + AudioBundle { + source: asset_server.load("sound/gameover.ogg"), + //connecter le volum avec le settings + ..default() + }, + AudioMenu, + )); +} + +fn audio_menu (mut commands: Commands, asset_server: Res<AssetServer>) { + commands + .spawn(( + AudioBundle { + source: asset_server.load("sound/menu.ogg"), + //connecter le volum avec le settings + ..default() + }, + AudioMenu, + )); +} + +fn audio_game (mut commands: Commands, asset_server: Res<AssetServer>) { + commands + .spawn(( + AudioBundle { + source: asset_server.load("sound/pokemon.ogg"), + //connecter le volum avec le settings + ..default() + }, + AudioMenu, + )); +} + +fn audio_fight (mut commands: Commands, asset_server: Res<AssetServer>) { + commands + .spawn(( + AudioBundle { + source: asset_server.load("sound/boss_music.ogg"), + //connecter le volum avec le settings + ..default() + }, + AudioMenu, + )); +} \ No newline at end of file diff --git a/game/src/defeat.rs b/game/src/defeat.rs new file mode 100644 index 0000000000000000000000000000000000000000..cbd73af7e4c947558b98c9c3ec510c523d236d9f --- /dev/null +++ b/game/src/defeat.rs @@ -0,0 +1,91 @@ +use bevy::prelude::*; + +use super::{despawn_screen, GameState, TEXT_COLOR,}; + +pub struct GameOverPlugin; + +impl Plugin for GameOverPlugin { + fn build(&self, app: &mut App) { + app + .add_systems(OnEnter(GameState::GameOver), defeat_setup) + .add_systems(Update, countdown.run_if(in_state(GameState::GameOver))) + .add_systems(OnExit(GameState::GameOver),despawn_screen::<OnDefeatScreen>); + } +} + +#[derive(Component)] +struct OnDefeatScreen; + +#[derive(Resource, Deref, DerefMut)] +struct WinTimer(Timer); + +fn defeat_setup(mut commands: Commands, asset_server: Res<AssetServer>) { + let cry_img = asset_server.load("cry.png"); + commands + .spawn(( + NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + ..default() + }, + ..default() + }, + OnDefeatScreen, + )) + .with_children(|parent| { + parent + .spawn(NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + flex_direction: FlexDirection::Column, + align_items: AlignItems::Center, + ..default() + }, + background_color: Color::BLACK.into(), + ..default() + }) + .with_children(|parent| { + // Display the Victory + parent.spawn( + TextBundle::from_section( + "GAME OVER\n", + TextStyle { + font_size: 80.0, + color: TEXT_COLOR, + ..default() + }, + ) + .with_style(Style { + margin: UiRect::all(Val::Px(50.0)), + ..default() + }), + ); + }) + .with_children(|parent|{ + parent.spawn( + ImageBundle{ + style: Style { + width: Val::Px(500.0), + ..default() + }, + image: UiImage::new(cry_img), + ..default() + }); + }); + }); + commands.insert_resource(WinTimer(Timer::from_seconds(10.0, TimerMode::Once))); +} + +fn countdown( + mut game_state: ResMut<NextState<GameState>>, + time: Res<Time>, + mut timer: ResMut<WinTimer>, +) { + if timer.tick(time.delta()).finished() { + game_state.set(GameState::Menu); + } +} \ No newline at end of file diff --git a/game/src/fight.rs b/game/src/fight.rs deleted file mode 100644 index 221a2511788e52e6553e12bc60f921e0ee27bb85..0000000000000000000000000000000000000000 --- a/game/src/fight.rs +++ /dev/null @@ -1,5 +0,0 @@ -use bevy::prelude::*; - -use super::{despawn_screen, GameState, }; - -pub struct MenuPlugin; \ No newline at end of file diff --git a/game/src/game.rs b/game/src/game.rs index f03124b35b61bd978d873f10fe954f459f8fc300..fd14fc18248792c267aaba63bbd691b04981c506 100644 --- a/game/src/game.rs +++ b/game/src/game.rs @@ -111,6 +111,7 @@ use super::{despawn_screen, GameState, TEXT_COLOR, color: TEXT_COLOR, ..default() }; + let texture = asset_server.load("eleve.png"); commands .spawn( @@ -338,11 +339,8 @@ use super::{despawn_screen, GameState, TEXT_COLOR, } fn attack_system( - mut commands: Commands, - asset_server: Res<AssetServer>, mut player_query: Query<&Transform, With<Player>>, mut enemy_query: Query<&Transform, With<Enemy>>, - combat_text_query: Query<Entity, With<CombatText>>, // Query to handle existing combat texts mut game_state: ResMut<NextState<GameState>>, ) { // Check if the player is near an enemy to show the combat text @@ -352,35 +350,10 @@ use super::{despawn_screen, GameState, TEXT_COLOR, if player_transform.translation.distance(enemy_transform.translation) < 60.0 { // Adjust this value based on the size of your collision box in_combat = true; - game_state.set(GameState::Fight); + game_state.set(GameState::GameOver); break; } - } - let has_combat_text = combat_text_query.iter().next().is_some(); - - if in_combat && !has_combat_text { - // Display the combat text - commands.spawn(TextBundle { - text: Text { - sections: vec![TextSection { - value: "Combat".to_string(), - style: TextStyle { - font: asset_server.load("FiraSans-Bold.ttf"), // Adjust this font path - font_size: 40.0, - color: Color::WHITE, - }, - }], - ..Default::default() - }, - ..Default::default() - }) - .insert(CombatText); - } else if !in_combat && has_combat_text { - // Remove the combat text - for entity in combat_text_query.iter() { - commands.entity(entity).despawn(); - } - } + } } } diff --git a/game/src/main.rs b/game/src/main.rs index 4845c85a726ca0177365d205cdcb316da35f358a..b027dd2d33de11c859513e358647899525d3ff19 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -10,10 +10,6 @@ const HOVERED_BUTTON: Color = Color::rgb(0.25, 0.25, 0.25); const HOVERED_PRESSED_BUTTON: Color = Color::rgb(0.25, 0.65, 0.25); const PRESSED_BUTTON: Color = Color::rgb(0.35, 0.75, 0.35); -mod splash; -mod game; -mod menu; - // Enum that will be used as a global state for the game #[derive(Clone, Copy, Default, Eq, PartialEq, Debug, Hash, States)] enum GameState { @@ -61,11 +57,25 @@ fn main() { .add_state::<GameState>() .add_systems(Startup, setup) // Adds the plugins for each state - .add_plugins((splash::SplashPlugin, menu::MenuPlugin, game::GamePlugin)) + .add_plugins(( + splash::SplashPlugin, + menu::MenuPlugin, + game::GamePlugin, + win::WinPlugin, + defeat::GameOverPlugin, + audio::AudioPlugin)) //.add_plugins(splash::SplashPlugin) .run(); } +mod splash; +mod game; +mod menu; +mod win; +mod defeat; +mod audio; + + fn setup(mut commands: Commands) { commands.spawn(Camera2dBundle::default()); } diff --git a/game/src/menu.rs b/game/src/menu.rs index 7c4f7dd8278ab301a9a55c72c47f03895ec0e4ac..bde2e75def29ece95b05efba3ef8448f757102ef 100644 --- a/game/src/menu.rs +++ b/game/src/menu.rs @@ -96,6 +96,9 @@ use bevy::{app::AppExit, prelude::*}; #[derive(Component)] struct SelectedOption; + #[derive(Component)] + struct AudioMenu; + // All actions that can be triggered from a button click #[derive(Component)] enum MenuButtonAction { @@ -177,8 +180,6 @@ use bevy::{app::AppExit, prelude::*}; ..default() }; - //let window = window_query.get_single().unwrap(); - commands .spawn(( NodeBundle { diff --git a/game/src/player.rs b/game/src/player.rs deleted file mode 100644 index db1fdf6870c1d5d35b3944e5a7f89ed496902f62..0000000000000000000000000000000000000000 --- a/game/src/player.rs +++ /dev/null @@ -1,43 +0,0 @@ -use bevy::prelude::*; - -pub struct PlayerHistory { - pub target_position: Vec2, - pub new_position: Vec2, - pub timer: Timer, -} - -impl PlayerHistory { - pub fn update_position(&mut self, new_position: Vec3) { - self.target_position = self.new_position; - self.new_position = new_position; - } -} - -#[derive(Component)] -struct Enemy; - - -#[derive(Component)] -struct CollisionBox { - width: f32, - height: f32, -} - - -pub struct PlayerPlugin; - -impl Plugin for PlayerPlugin { - fn build(&self, app: &mut App) { - app.insert_resource(PlayerHistory{ - trarget_position: Vec2::ZERO, - new_position: Vec2::ZERO, - timer: Timer::new(Duration::from_secs_f32(0.2)), - }) - . - .add_systems(Update, character_movement) - .add_systems(Startup,spawn_enemies) - .add_systems(Update,attack_system) - - } - -} diff --git a/game/src/win.rs b/game/src/win.rs new file mode 100644 index 0000000000000000000000000000000000000000..291e6e52443fa52f14038bb92b3336e8f2da130e --- /dev/null +++ b/game/src/win.rs @@ -0,0 +1,91 @@ +use bevy::prelude::*; + +use super::{despawn_screen, GameState, TEXT_COLOR,}; + +pub struct WinPlugin; + +impl Plugin for WinPlugin { + fn build(&self, app: &mut App) { + app + .add_systems(OnEnter(GameState::Victory), win_setup) + .add_systems(Update, countdown.run_if(in_state(GameState::Victory))) + .add_systems(OnExit(GameState::Victory),despawn_screen::<OnWinScreen>); + } +} + +#[derive(Component)] +struct OnWinScreen; + +#[derive(Resource, Deref, DerefMut)] +struct WinTimer(Timer); + +fn win_setup(mut commands: Commands, asset_server: Res<AssetServer>) { + let trophy_img = asset_server.load("trophy.png"); + commands + .spawn(( + NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Center, + justify_content: JustifyContent::Center, + ..default() + }, + ..default() + }, + OnWinScreen, + )) + .with_children(|parent| { + parent + .spawn(NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + flex_direction: FlexDirection::Column, + align_items: AlignItems::Center, + ..default() + }, + background_color: Color::BLACK.into(), + ..default() + }) + .with_children(|parent| { + // Display the Victory + parent.spawn( + TextBundle::from_section( + "Victory\n", + TextStyle { + font_size: 80.0, + color: TEXT_COLOR, + ..default() + }, + ) + .with_style(Style { + margin: UiRect::all(Val::Px(50.0)), + ..default() + }), + ); + }) + .with_children(|parent|{ + parent.spawn( + ImageBundle{ + style: Style { + width: Val::Px(200.0), + ..default() + }, + image: UiImage::new(trophy_img), + ..default() + }); + }); + }); + commands.insert_resource(WinTimer(Timer::from_seconds(10.0, TimerMode::Once))); +} + +fn countdown( + mut game_state: ResMut<NextState<GameState>>, + time: Res<Time>, + mut timer: ResMut<WinTimer>, +) { + if timer.tick(time.delta()).finished() { + game_state.set(GameState::Menu); + } +} \ No newline at end of file