From 3e8e6c56710a78216e0290bf194524429057f0c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Fri, 14 Jan 2022 19:09:42 +0000 Subject: [PATCH] add an example using UI & states to create a game menu (#2960) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit adds an example using UI for something more related to a game than the current UI examples. Example with a game menu: * new game - will display settings for 5 seconds before returning to menu * preferences - can modify the settings, with two sub menus * quit - will quit the game I wanted a more complex UI example before starting the UI rewrite to have ground for comparison Co-authored-by: François <8672791+mockersf@users.noreply.github.com> --- CREDITS.md | 4 + Cargo.toml | 4 + assets/models/AlienCake/README.md | 5 - assets/textures/Game Icons/exitRight.png | Bin 0 -> 384 bytes assets/textures/Game Icons/right.png | Bin 0 -> 368 bytes assets/textures/Game Icons/wrench.png | Bin 0 -> 637 bytes examples/README.md | 1 + examples/game/game_menu.rs | 820 +++++++++++++++++++++++ 8 files changed, 829 insertions(+), 5 deletions(-) delete mode 100644 assets/models/AlienCake/README.md create mode 100644 assets/textures/Game Icons/exitRight.png create mode 100644 assets/textures/Game Icons/right.png create mode 100644 assets/textures/Game Icons/wrench.png create mode 100644 examples/game/game_menu.rs diff --git a/CREDITS.md b/CREDITS.md index cefd08df93..b646a0662d 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -16,3 +16,7 @@ * Generic RPG Pack (CC0 license) by [Bakudas](https://twitter.com/bakudas) and [Gabe Fern](https://twitter.com/_Gabrielfer) * Environment maps (`.hdr` files) from [HDRIHaven](https://hdrihaven.com) (CC0 license) +* Alien from [Kenney's Space Kit](https://www.kenney.nl/assets/space-kit) (CC0 1.0 Universal) +* Cake from [Kenney's Food Kit](https://www.kenney.nl/assets/food-kit) (CC0 1.0 Universal) +* Ground tile from [Kenney's Tower Defense Kit](https://www.kenney.nl/assets/tower-defense-kit) (CC0 1.0 Universal) +* Game icons from [Kenney's Game Icons](https://www.kenney.nl/assets/game-icons) (CC0 1.0 Universal) diff --git a/Cargo.toml b/Cargo.toml index dd9e585c39..c451e83f06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -359,6 +359,10 @@ path = "examples/game/alien_cake_addict.rs" name = "breakout" path = "examples/game/breakout.rs" +[[example]] +name = "game_menu" +path = "examples/game/game_menu.rs" + # Input [[example]] name = "char_input_events" diff --git a/assets/models/AlienCake/README.md b/assets/models/AlienCake/README.md deleted file mode 100644 index 2cf86d3d8b..0000000000 --- a/assets/models/AlienCake/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Assets are from [Kenney](https://www.kenney.nl) - -- alien from [Space Kit](https://www.kenney.nl/assets/space-kit) -- cake from [Food Kit](https://www.kenney.nl/assets/food-kit) -- ground tile from [Tower Defense Kit](https://www.kenney.nl/assets/tower-defense-kit) diff --git a/assets/textures/Game Icons/exitRight.png b/assets/textures/Game Icons/exitRight.png new file mode 100644 index 0000000000000000000000000000000000000000..de78ab6f0f02523b296d723667143949cbeab8d7 GIT binary patch literal 384 zcmeAS@N?(olHy`uVBq!ia0vp^DImNS%G}r0G|-o z|HJ{Ha-hP1@~AC97GFt_U$B0Ez5o9E_UH50zn>q^U}?nt0x0vu)5S3);_%z+8+i{I z2sm8yIS_JYqMdgN1D8~lidaIkbfehPg^Y?_)|G57T@#K>E8eesC~wlUpWYKwt*`R- zubSY*rTOIi$x`XIhbprhPEMS>LFiJ=Ja(5`|DJC0SR~mqS>v(7v6D8B6_1_Nd8~Bo zq{(CDV<%N6EBSV`=}s_Hd+gJta>U}X>f)Z+66*JR=1ZtMvrS-E*Y}$@=Z>YI&y@O< zgDyXt1bs~Q|9G9F;#qdHqkOl3&y;+xrp`~iVFrP95gcl#`0Wn5oD5y)=eB7{eD?CG raqFV|zRf8~_c=A+Rk8ICLnZUc3ejV2ulW;!{$=oV^>bP0l+XkKN&B!b literal 0 HcmV?d00001 diff --git a/assets/textures/Game Icons/right.png b/assets/textures/Game Icons/right.png new file mode 100644 index 0000000000000000000000000000000000000000..3f2480f9a5465d9ff1a9869dadebfd96ae9847d1 GIT binary patch literal 368 zcmeAS@N?(olHy`uVBq!ia0vp^DImNS%G}T0G|-o z|F{8A2~e_Mb?rSMi>oBaFZjLvdHwbK^W*0;gb7!60Y#s9x;TbJ9DaL!Bkv&xp4P-H zw?r1V1?ik-2`tl1JbXUP%kx^Gnm&8Kqsa7sm)C1_p1*1PVQX~CMAtgcyyu4NdSs4E zBt7|}wzORZ#jXC9YBUGuTM|dYiH@36TE@=_rC5m h_qV%>{j~nXGVj^VH@k`s?*sam!PC{xWt~$(69Aegr)2;D literal 0 HcmV?d00001 diff --git a/assets/textures/Game Icons/wrench.png b/assets/textures/Game Icons/wrench.png new file mode 100644 index 0000000000000000000000000000000000000000..440e7edc41af9d033991f50595721ea70e2da744 GIT binary patch literal 637 zcmeAS@N?(olHy`uVBq!ia0vp^DImaMPIQTYS8sugaM7xs3ChLtow5n1k(v~i(Zq^ZZFZBql;Se^bnwA2o3)Hx)`+q+-9 z+hV1_9l_4G9aB%8m7BO!c4CyfUb#Z`)0~6}YY#~%JaO-QYWE~MvDfKshkg7D;p{1Q z`kp*)^>fzZI(p@7)TdKxPeg3sy5A}r_E1nOz;%bDY>425?D?Pk48@9pR>`pkf`eEKzg{MzhBpuSn3x)uew5+1(b{x(-o~H7oRK*?XLlCd>HoWB zr;u9A51nrtTYPq?rZygXvFFjj$l5hNyruk1&r)uP{(t4LQf>MbyWF1LkIWw~`#!nw q$0~vJCbQ;{+*okzlswt5EYG>e``Tg7SO0(sfWgz%&t;ucLK6V2UpT@5 literal 0 HcmV?d00001 diff --git a/examples/README.md b/examples/README.md index 81190f5886..02a10eabb4 100644 --- a/examples/README.md +++ b/examples/README.md @@ -182,6 +182,7 @@ Example | File | Description --- | --- | --- `alien_cake_addict` | [`game/alien_cake_addict.rs`](./game/alien_cake_addict.rs) | Eat the cakes. Eat them all. An example 3D game `breakout` | [`game/breakout.rs`](./game/breakout.rs) | An implementation of the classic game "Breakout" +`game_menu` | [`game/game_menu.rs`](./game/game_menu.rs) | A simple game menu ## Input diff --git a/examples/game/game_menu.rs b/examples/game/game_menu.rs new file mode 100644 index 0000000000..8bc0a155b3 --- /dev/null +++ b/examples/game/game_menu.rs @@ -0,0 +1,820 @@ +use bevy::prelude::*; + +// This example will display a simple menu using Bevy UI where you can start a new game, +// change some settings or quit. There is no actual game, it will just display the current +// settings for 5 seconds before going back to the menu. + +const TEXT_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); + +// Enum that will be used as a global state for the game +#[derive(Clone, Eq, PartialEq, Debug, Hash)] +enum GameState { + Splash, + Menu, + Game, +} + +// One of the two settings that can be set through the menu. It will be a resource in the app +#[derive(Debug, Component, PartialEq, Eq, Clone, Copy)] +enum DisplayQuality { + Low, + Medium, + High, +} + +// One of the two settings that can be set through the menu. It will be a resource in the app +#[derive(Debug, Component, PartialEq, Eq, Clone, Copy)] +struct Volume(u32); + +fn main() { + App::new() + .add_plugins(DefaultPlugins) + // Insert as resource the initial value for the settings resources + .insert_resource(DisplayQuality::Medium) + .insert_resource(Volume(7)) + .add_startup_system(setup) + // Declare the game state, and set its startup value + .add_state(GameState::Splash) + // Adds the plugins for each state + .add_plugin(splash::SplashPlugin) + .add_plugin(menu::MenuPlugin) + .add_plugin(game::GamePlugin) + .run(); +} + +// As there isn't an actual game, setup is just adding a `UiCameraBundle` +fn setup(mut commands: Commands) { + commands.spawn_bundle(UiCameraBundle::default()); +} + +mod splash { + use bevy::prelude::*; + + use super::{despawn_screen, GameState}; + + // This plugin will display a splash screen with Bevy logo for 1 second before switching to the menu + pub struct SplashPlugin; + + impl Plugin for SplashPlugin { + fn build(&self, app: &mut bevy::prelude::App) { + // As this plugin is managing the splash screen, it will focus on the state `GameState::Splash` + app + // When entering the state, spawn everything needed for this screen + .add_system_set(SystemSet::on_enter(GameState::Splash).with_system(splash_setup)) + // While in this state, run the `countdown` system + .add_system_set(SystemSet::on_update(GameState::Splash).with_system(countdown)) + // When exiting the state, despawn everything that was spawned for this screen + .add_system_set( + SystemSet::on_exit(GameState::Splash) + .with_system(despawn_screen::), + ); + } + } + + // Tag component used to tag entities added on the splash screen + #[derive(Component)] + struct OnSplashScreen; + + // Newtype to use a `Timer` for this screen as a resource + struct SplashTimer(Timer); + + fn splash_setup(mut commands: Commands, asset_server: Res) { + let icon = asset_server.load("branding/icon.png"); + // Display the logo + commands + .spawn_bundle(ImageBundle { + style: Style { + // This will center the logo + margin: Rect::all(Val::Auto), + // This will set the logo to be 200px wide, and auto adjust its height + size: Size::new(Val::Px(200.0), Val::Auto), + ..Default::default() + }, + image: UiImage(icon), + ..Default::default() + }) + .insert(OnSplashScreen); + // Insert the timer as a resource + commands.insert_resource(SplashTimer(Timer::from_seconds(1.0, false))); + } + + // Tick the timer, and change state when finished + fn countdown( + mut game_state: ResMut>, + time: Res