Skip to content

Commit

Permalink
Update all examples
Browse files Browse the repository at this point in the history
  • Loading branch information
Shatur committed Oct 19, 2024
1 parent 0d11781 commit 8af773c
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 126 deletions.
96 changes: 64 additions & 32 deletions examples/context_layering.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
//! One context applied on top of another and overrides some of the mappings.

use bevy::prelude::*;
mod player_box;

use std::f32::consts::FRAC_PI_4;

use bevy::{color::palettes::tailwind::INDIGO_600, prelude::*};
use bevy_enhanced_input::prelude::*;

use player_box::{PlayerBox, PlayerBoxBundle, PlayerBoxPlugin, PlayerColor, DEFAULT_SPEED};

fn main() {
App::new()
.add_plugins((DefaultPlugins, EnhancedInputPlugin, GamePlugin))
.add_plugins((
DefaultPlugins,
EnhancedInputPlugin,
PlayerBoxPlugin,
GamePlugin,
))
.run();
}

struct GamePlugin;

impl Plugin for GamePlugin {
fn build(&self, app: &mut App) {
app.add_input_context::<Player>()
app.add_input_context::<PlayerBox>()
.add_input_context::<Swimming>()
.add_systems(Startup, Self::spawn)
.observe(Self::move_character)
.observe(Self::jump)
.observe(Self::apply_movement)
.observe(Self::rotate)
.observe(Self::exit_water)
.observe(Self::enter_water)
.observe(Self::dive);
Expand All @@ -26,59 +37,80 @@ impl Plugin for GamePlugin {

impl GamePlugin {
fn spawn(mut commands: Commands) {
commands.spawn(Player);
commands.spawn(Camera2dBundle::default());
commands.spawn(PlayerBoxBundle::default());
}

fn move_character(trigger: Trigger<ActionEvent<Move>>) {
fn apply_movement(trigger: Trigger<ActionEvent<Move>>, mut players: Query<&mut Transform>) {
let event = trigger.event();
if let ActionEventKind::Fired { fired_secs, .. } = event.kind {
info!(
"moving with direction `{:?}` for `{fired_secs}` secs",
event.value
);
if event.kind.is_fired() {
let mut transform = players.get_mut(trigger.entity()).unwrap();
transform.translation += event.value.as_axis3d();
}
}

fn jump(trigger: Trigger<ActionEvent<Jump>>) {
fn rotate(trigger: Trigger<ActionEvent<Rotate>>, mut players: Query<&mut Transform>) {
let event = trigger.event();
if event.kind.is_started() {
info!("jumping in the air");
let mut transform = players.get_mut(trigger.entity()).unwrap();
transform.rotate_z(FRAC_PI_4);
}
}

fn enter_water(trigger: Trigger<ActionEvent<EnterWater>>, mut commands: Commands) {
fn enter_water(
trigger: Trigger<ActionEvent<EnterWater>>,
mut commands: Commands,
mut players: Query<&mut PlayerColor>,
) {
let event = trigger.event();
if event.kind.is_started() {
info!("entering water");
// Change color for visibility.
let mut color = players.get_mut(trigger.entity()).unwrap();
color.0 = INDIGO_600.into();

commands.entity(trigger.entity()).insert(Swimming);
}
}

fn dive(trigger: Trigger<ActionEvent<Dive>>) {
fn dive(trigger: Trigger<ActionEvent<Dive>>, mut players: Query<&mut Visibility>) {
let event = trigger.event();
if event.kind.is_started() {
info!("diving");
}

// Hide player while diving.
let target_visibility = match event.kind {
ActionEventKind::Started => Visibility::Hidden,
ActionEventKind::Completed { .. } => Visibility::Visible,
_ => return,
};

let mut visibility = players.get_mut(trigger.entity()).unwrap();
*visibility = target_visibility;
}

fn exit_water(trigger: Trigger<ActionEvent<ExitWater>>, mut commands: Commands) {
fn exit_water(
trigger: Trigger<ActionEvent<ExitWater>>,
mut commands: Commands,
mut players: Query<&mut PlayerColor>,
) {
let event = trigger.event();
if event.kind.is_fired() {
info!("exiting water");
let mut color = players.get_mut(trigger.entity()).unwrap();
color.0 = Default::default();

commands.entity(trigger.entity()).remove::<Swimming>();
}
}
}

#[derive(Component)]
struct Player;

impl InputContext for Player {
impl InputContext for PlayerBox {
fn context_instance(_world: &World, _entity: Entity) -> ContextInstance {
let mut ctx = ContextInstance::default();

ctx.bind::<Move>().with_wasd();
ctx.bind::<Jump>().with(KeyCode::Space);
ctx.bind::<Move>()
.with_wasd()
.with_modifier(Normalize)
.with_modifier(ScaleByDelta)
.with_modifier(Scalar::splat(DEFAULT_SPEED));
ctx.bind::<Rotate>().with(KeyCode::Space);
ctx.bind::<EnterWater>().with(KeyCode::Enter);

ctx
Expand All @@ -91,13 +123,13 @@ struct Move;

#[derive(Debug, InputAction)]
#[input_action(dim = Bool)]
struct Jump;
struct Rotate;

#[derive(Debug, InputAction)]
#[input_action(dim = Bool)]
struct EnterWater;

/// Context that overrides some actions from [`Player`].
/// Context that overrides some actions from [`PlayerBox`].
#[derive(Component)]
struct Swimming;

Expand All @@ -107,8 +139,8 @@ impl InputContext for Swimming {
fn context_instance(_world: &World, _entity: Entity) -> ContextInstance {
let mut ctx = ContextInstance::default();

// `Player` has lower priority, so `Dive` and `ExitWater` consume inputs first,
// preventing `Jump` and `EnterWater` from being triggered.
// `PlayerBox` has lower priority, so `Dive` and `ExitWater` consume inputs first,
// preventing `Rotate` and `EnterWater` from being triggered.
// The consuming behavior can be configured in the `InputAction` trait.
ctx.bind::<Dive>().with(KeyCode::Space);
ctx.bind::<ExitWater>().with(KeyCode::Enter);
Expand Down
64 changes: 41 additions & 23 deletions examples/context_sharing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,57 +2,70 @@
//! This could be used for games where you control multiple characters at the same time,
//! such as Binary Land for NES.

mod player_box;

use std::f32::consts::FRAC_PI_4;

use bevy::prelude::*;
use bevy_enhanced_input::prelude::*;

use player_box::{PlayerBox, PlayerBoxBundle, PlayerBoxPlugin, DEFAULT_SPEED};

fn main() {
App::new()
.add_plugins((DefaultPlugins, EnhancedInputPlugin, GamePlugin))
.add_plugins((
DefaultPlugins,
EnhancedInputPlugin,
PlayerBoxPlugin,
GamePlugin,
))
.run();
}

struct GamePlugin;

impl Plugin for GamePlugin {
fn build(&self, app: &mut App) {
app.add_input_context::<Player>()
app.add_input_context::<PlayerBox>()
.add_systems(Startup, Self::spawn)
.observe(Self::move_character)
.observe(Self::jump);
.observe(Self::apply_movement)
.observe(Self::rotate);
}
}

impl GamePlugin {
fn spawn(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());

// Spawn two entities with the same context.
commands.spawn(Player);
commands.spawn(Player);
commands.spawn(PlayerBoxBundle {
transform: Transform::from_translation(Vec3::X * 50.0),
..Default::default()
});
commands.spawn(PlayerBoxBundle {
transform: Transform::from_translation(-Vec3::X * 50.0),
..Default::default()
});
}

fn move_character(trigger: Trigger<ActionEvent<Move>>) {
fn apply_movement(trigger: Trigger<ActionEvent<Move>>, mut players: Query<&mut Transform>) {
let event = trigger.event();
let entity = trigger.entity();
if let ActionEventKind::Fired { fired_secs, .. } = event.kind {
info!(
"entity `{entity}` moving with direction `{:?}` for `{fired_secs}` secs",
event.value
);
if event.kind.is_fired() {
let mut transform = players.get_mut(trigger.entity()).unwrap();
transform.translation += event.value.as_axis3d();
}
}

fn jump(trigger: Trigger<ActionEvent<Jump>>) {
fn rotate(trigger: Trigger<ActionEvent<Rotate>>, mut players: Query<&mut Transform>) {
let event = trigger.event();
let entity = trigger.entity();
if event.kind.is_started() {
info!("entity `{entity}` jumping in the air");
let mut transform = players.get_mut(trigger.entity()).unwrap();
transform.rotate_z(FRAC_PI_4);
}
}
}

#[derive(Component)]
struct Player;

impl InputContext for Player {
impl InputContext for PlayerBox {
// By default all context instances are processed individually.
// This means if multiple entities spawned with the same mappings,
// actions from the first processed context may consume inputs.
Expand All @@ -63,8 +76,13 @@ impl InputContext for Player {
fn context_instance(_world: &World, _entity: Entity) -> ContextInstance {
let mut ctx = ContextInstance::default();

ctx.bind::<Move>().with_wasd();
ctx.bind::<Jump>().with(KeyCode::Space);
ctx.bind::<Move>()
.with_wasd()
.with_modifier(Normalize)
.with_modifier(ScaleByDelta)
.with_modifier(Scalar::splat(DEFAULT_SPEED));

ctx.bind::<Rotate>().with(KeyCode::Space);

ctx
}
Expand All @@ -76,4 +94,4 @@ struct Move;

#[derive(Debug, InputAction)]
#[input_action(dim = Bool)]
struct Jump;
struct Rotate;
Loading

0 comments on commit 8af773c

Please sign in to comment.