Skip to content

Commit

Permalink
feat: background and menu option rows
Browse files Browse the repository at this point in the history
  • Loading branch information
eerii committed Jul 13, 2024
1 parent 44cf25e commit b965537
Show file tree
Hide file tree
Showing 16 changed files with 279 additions and 135 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/examples.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ jobs:
uses: nixbuild/nix-quick-install-action@v28

- name: Use nix flake
uses: nicknovitski/nix-develop@v1
uses: nicknovitski/nix-develop@v1
with:
arguments: ".#web"

- name: Rust cache
uses: swatinem/rust-cache@v2
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ jobs:
uses: nixbuild/nix-quick-install-action@v28

- name: Use nix flake
uses: nicknovitski/nix-develop@v1
uses: nicknovitski/nix-develop@v1
with:
arguments: ".#web"

- name: Rust cache
uses: swatinem/rust-cache@v2
Expand Down Expand Up @@ -101,7 +103,7 @@ jobs:
uses: nixbuild/nix-quick-install-action@v28

- name: Use nix flake
uses: nicknovitski/nix-develop@v1
uses: nicknovitski/nix-develop@v1

- name: Rust cache
uses: swatinem/rust-cache@v2
Expand Down
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ cargo run

you can also play around with some of the included examples with `cargo run --example <name>`. and if you want to get started quickly, copy any example to `src/main.rs`!

in order to have a development environment up and ready, run `nix develop` or use [`nix-direnv`](https://github.com/nix-community/nix-direnv) installed create a `.envrc` like this:

```sh
echo "use nix" > .envrc
```
if you have nix installed, running `nix develop` you get a shell with all the dependencies already installed.

### release 🌻

Expand Down
2 changes: 0 additions & 2 deletions Trunk.toml

This file was deleted.

15 changes: 0 additions & 15 deletions examples/dvd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use bevy::{
use hello_bevy::{
assets::{CoreAssets, ExampleAssets},
camera::GameCamera,
ui::menu::BACKGROUND_COLOR,
AppConfig, GamePlugin, GameState,
};

Expand Down Expand Up @@ -77,20 +76,6 @@ fn init_sample(
let size = Vec2::new(win.width(), win.height());
cmd.insert_resource(Bounds(size));

// Background
cmd.spawn((
SpriteBundle {
sprite: Sprite {
color: BACKGROUND_COLOR,
custom_size: Some(size),
..default()
},
transform: Transform::from_xyz(0., 0., -10.),
..default()
},
Background,
));

// Sprites
for velocity in [
Vec2::new(300., 250.),
Expand Down
36 changes: 16 additions & 20 deletions examples/jump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use bevy::{math::bounding::*, prelude::*};
use hello_bevy::{
assets::CoreAssets,
camera::GameCamera,
data::{GameOptions, Persistent},
input::{Action, ActionState},
ui::{menu::BACKGROUND_COLOR, widgets::BUTTON_COLOR},
AppConfig, GamePlugin, GameState,
};
use rand::Rng;
Expand Down Expand Up @@ -105,21 +105,12 @@ struct CameraFollow {
// Systems
// ·······

fn init_sample(mut cmd: Commands, assets: Res<CoreAssets>, cam: Query<Entity, With<GameCamera>>) {
// Background
cmd.spawn((
SpriteBundle {
sprite: Sprite {
color: BACKGROUND_COLOR,
custom_size: Some(LEVEL_SIZE),
..default()
},
transform: Transform::from_xyz(0., 0., -10.),
..default()
},
CameraFollow::default(),
));

fn init_sample(
mut cmd: Commands,
assets: Res<CoreAssets>,
options: Res<Persistent<GameOptions>>,
cam: Query<Entity, With<GameCamera>>,
) {
// Player
cmd.spawn((
SpriteBundle {
Expand All @@ -141,7 +132,7 @@ fn init_sample(mut cmd: Commands, assets: Res<CoreAssets>, cam: Query<Entity, Wi
cmd.spawn((
SpriteBundle {
sprite: Sprite {
color: BUTTON_COLOR,
color: options.accent_color,
custom_size: Some(Vec2::new(LEVEL_SIZE.x, 32.)),
..default()
},
Expand All @@ -158,7 +149,7 @@ fn init_sample(mut cmd: Commands, assets: Res<CoreAssets>, cam: Query<Entity, Wi
text: Text::from_section("0", TextStyle {
font: assets.font.clone(),
font_size: 150.,
color: BUTTON_COLOR.lighter(0.3),
color: options.base_color.lighter(0.3),
}),
transform: Transform::from_xyz(5.3, 0.3, -1.),
..default()
Expand Down Expand Up @@ -309,7 +300,12 @@ fn update_counter(mut counter: Query<(&mut Counter, &mut Text)>, player: Query<&
text.sections[0].value = counter.0.to_string();
}

fn spawn_platforms(mut cmd: Commands, mut info: ResMut<PlatformInfo>, player: Query<&Player>) {
fn spawn_platforms(
mut cmd: Commands,
options: Res<Persistent<GameOptions>>,
mut info: ResMut<PlatformInfo>,
player: Query<&Player>,
) {
let Ok(player) = player.get_single() else {
return;
};
Expand All @@ -323,7 +319,7 @@ fn spawn_platforms(mut cmd: Commands, mut info: ResMut<PlatformInfo>, player: Qu
cmd.spawn((
SpriteBundle {
sprite: Sprite {
color: BUTTON_COLOR,
color: options.accent_color,
custom_size: Some(PLATFORM_SIZE),
..default()
},
Expand Down
24 changes: 21 additions & 3 deletions src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
use bevy::prelude::*;

use crate::data::{GameOptions, Persistent};

/// The luminance of the background color
pub const BACKGROUND_LUMINANCE: f32 = 0.05;

// ······
// Plugin
// ······
Expand All @@ -13,7 +18,7 @@ pub struct CameraPlugin;

impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreStartup, init);
app.add_systems(Startup, init);
}
}

Expand All @@ -36,12 +41,25 @@ pub struct FinalCamera;
// ·······

/// Creates the main cameras before the game starts
fn init(mut cmd: Commands) {
fn init(mut cmd: Commands, options: Res<Persistent<GameOptions>>) {
let clear_color =
ClearColorConfig::Custom(options.base_color.with_luminance(BACKGROUND_LUMINANCE));

#[cfg(not(feature = "3d_camera"))]
let camera_bundle = Camera2dBundle { ..default() };
let camera_bundle = Camera2dBundle {
camera: Camera {
clear_color,
..default()
},
..default()
};

#[cfg(feature = "3d_camera")]
let camera_bundle = Camera3dBundle {
camera: Camera {
clear_color,
..default()
},
transform: Transform::from_xyz(0.0, 0.0, 10.0),
..default()
};
Expand Down
20 changes: 18 additions & 2 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct DataPlugin;

impl Plugin for DataPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Startup, init);
app.add_systems(PreStartup, init);
}
}

Expand All @@ -30,13 +30,29 @@ impl Plugin for DataPlugin {
/// Game options
/// Useful for accesibility and the settings menu
/// CHANGE: Add any configurable game options here
#[derive(Default, Resource, Serialize, Deserialize)]
#[derive(Resource, Serialize, Deserialize)]
pub struct GameOptions {
/// Base color of the game, used for backgrounds, etc
pub base_color: Color,
/// Accent color, meant to contrast with the base color
pub accent_color: Color,

/// Controlls if text to speech is enabled for menu navigation
#[cfg(feature = "tts")]
pub text_to_speech: bool,
}

impl Default for GameOptions {
fn default() -> Self {
Self {
base_color: Color::srgb(0.3, 0.5, 0.9),
accent_color: Color::srgb(0.3, 0.5, 0.9),
#[cfg(feature = "tts")]
text_to_speech: default(),
}
}
}

/// Save data
/// A place to save the player's progress
/// CHANGE: Add relevant save data here
Expand Down
3 changes: 2 additions & 1 deletion src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ pub struct UiPlugin;

impl Plugin for UiPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(SickleUiPlugin).add_systems(Startup, init);
app.add_plugins(SickleUiPlugin)
.add_systems(PostStartup, init);

#[cfg(feature = "menu")]
app.add_plugins(menu::MenuPlugin);
Expand Down
3 changes: 1 addition & 2 deletions src/ui/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ mod mappings;
mod options;

const UI_GAP: Val = Val::Px(16.);
/// Background color of the menu
pub const BACKGROUND_COLOR: Color = Color::srgba(0.0, 0.05, 0.1, 0.8);

// ······
// Plugin
Expand Down Expand Up @@ -92,6 +90,7 @@ enum MenuButton {
/// Indicates what is the state being refreshed
#[derive(Component)]
struct MenuRefreshState(MenuState);

// ·······
// Systems
// ·······
Expand Down
12 changes: 10 additions & 2 deletions src/ui/menu/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use sickle_ui::prelude::*;

use crate::{
assets::CoreAssets,
camera::BACKGROUND_LUMINANCE,
data::{GameOptions, Persistent},
ui::{
menu::{MenuButton, MenuState, BACKGROUND_COLOR, UI_GAP},
menu::{MenuButton, MenuState, UI_GAP},
widgets::{UiButtonWidget, UiTextWidget},
UiRootContainer,
},
Expand All @@ -24,6 +26,7 @@ pub(super) fn open(
mut cmd: Commands,
root: Query<Entity, With<UiRootContainer>>,
assets: Res<CoreAssets>,
options: Res<Persistent<GameOptions>>,
) {
let Ok(root) = root.get_single() else {
return;
Expand Down Expand Up @@ -55,5 +58,10 @@ pub(super) fn open(
})
.insert(StateScoped(MenuState::Main))
.style()
.background_color(BACKGROUND_COLOR);
.background_color(
options
.base_color
.with_luminance(BACKGROUND_LUMINANCE)
.with_alpha(0.8),
);
}
42 changes: 21 additions & 21 deletions src/ui/menu/mappings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ use sickle_ui::prelude::*;

use crate::{
assets::CoreAssets,
camera::BACKGROUND_LUMINANCE,
data::{GameOptions, Persistent},
input::Action,
ui::{
menu::{MenuButton, MenuState, BACKGROUND_COLOR, UI_GAP},
menu::{MenuButton, MenuState, UI_GAP},
navigation::FocusableHoverFill,
widgets::{UiButtonWidget, UiImageWidget, UiTextWidget},
widgets::{UiButtonWidget, UiImageWidget, UiOptionRowWidget, UiTextWidget},
UiRootContainer,
},
};
Expand All @@ -30,6 +32,7 @@ pub(super) fn open(
input_map: Query<&InputMap<Action>>,
asset_server: Res<AssetServer>,
assets: Res<CoreAssets>,
options: Res<Persistent<GameOptions>>,
) {
let Ok(root) = root.get_single() else {
return;
Expand All @@ -54,23 +57,19 @@ pub(super) fn open(
.iter()
.sorted_by_key(|(&a, _)| a.variant_name().to_string())
{
column.row(|row| {
row.style()
.width(Val::Percent(80.))
.justify_content(JustifyContent::Center)
.column_gap(Val::Px(4.));

row.text(
action.variant_name().into(),
assets.font.clone(),
)
.style()
.flex_grow(1.);

for map in maps {
row_mapping((**map).as_reflect(), row, &asset_server);
}
});
let mut row = column.option_row(
MenuButton::None,
action.variant_name().into(),
assets.font.clone(),
);

for map in maps {
row_mapping(
(**map).as_reflect(),
&mut row,
&asset_server,
);
}
}

column.button(MenuButton::ExitOrBack, |button| {
Expand All @@ -79,7 +78,7 @@ pub(super) fn open(
})
.insert(StateScoped(MenuState::Mappings))
.style()
.background_color(BACKGROUND_COLOR);
.background_color(options.base_color.with_luminance(BACKGROUND_LUMINANCE));
}

// ·······
Expand Down Expand Up @@ -115,11 +114,12 @@ fn row_mapping(map: &dyn Reflect, row: &mut UiBuilder<Entity>, asset_server: &As

for prompt in prompts {
// Dynamic loading to avoid having all icons in memory
row.button(MenuButton::None, |button| {
row.option_button(|button| {
button.image(asset_server.load(&prompt));
})
.insert(BorderRadius::all(Val::Px(16.)))
.insert(BorderColor::from(Srgba::NONE))
.insert(BackgroundColor::from(Srgba::NONE))
.insert(FocusableHoverFill)
.style()
.width(Val::Px(64.))
Expand Down
Loading

0 comments on commit b965537

Please sign in to comment.