generated from 2ndbeam/bevy-template
feat: Player attacking
- Added BpmTimer.accuracy method - Added Weapon.attack_offset method - Replaced beats_remaining with timer in Attacking and Awaiting - AttackArea spawning on Attacking end
This commit is contained in:
parent
95276c070b
commit
fb1923fe53
9 changed files with 107 additions and 58 deletions
|
|
@ -1,6 +1,8 @@
|
|||
//! Player systems
|
||||
|
||||
use crate::timer::TickEvent;
|
||||
use bevy_trait_query::One;
|
||||
|
||||
use crate::timer::BpmTimer;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -17,19 +19,33 @@ pub fn handle_input(
|
|||
&mut KinematicCharacterController,
|
||||
&mut Sprite,
|
||||
Option<&mut AttackGraph>,
|
||||
Option<One<&dyn Weapon>>,
|
||||
Option<&states::Free>,
|
||||
Option<&states::Choosing>,
|
||||
Option<&states::Attacking>,
|
||||
Option<&states::Awaiting>,
|
||||
Option<&mut states::Attacking>,
|
||||
Option<&mut states::Awaiting>,
|
||||
)>,
|
||||
|
||||
timer_query: Query<&BpmTimer>,
|
||||
) {
|
||||
let Some(timer) = timer_query.iter().next() else {
|
||||
error!("No BpmTimer provided");
|
||||
return;
|
||||
};
|
||||
|
||||
let bpm = timer.get_bpm();
|
||||
|
||||
for (
|
||||
// Basic things
|
||||
player_id,
|
||||
player,
|
||||
action_state,
|
||||
mut controller,
|
||||
mut sprite,
|
||||
// Weapon
|
||||
maybe_attack_graph,
|
||||
maybe_weapon,
|
||||
// States
|
||||
maybe_free,
|
||||
maybe_choosing,
|
||||
maybe_attacking,
|
||||
|
|
@ -46,18 +62,13 @@ pub fn handle_input(
|
|||
} else if let Some(states::Choosing { log }) = maybe_choosing &&
|
||||
let Some(mut attack_graph) = maybe_attack_graph {
|
||||
if let Some(next_state) = attack_graph.next(*log) {
|
||||
let accuracy = timer.accuracy();
|
||||
let next_attack = match *log {
|
||||
PlayerInput::LightAttack => {
|
||||
states::Attacking {
|
||||
phys: next_state,
|
||||
beats_remaining: 1,
|
||||
}
|
||||
states::Attacking::new(next_state, accuracy, 1., bpm)
|
||||
},
|
||||
PlayerInput::HeavyAttack => {
|
||||
states::Attacking {
|
||||
phys: next_state,
|
||||
beats_remaining: 2,
|
||||
}
|
||||
states::Attacking::new(next_state, accuracy, 2., bpm)
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
|
@ -65,35 +76,28 @@ pub fn handle_input(
|
|||
} else {
|
||||
commands.entity(player_id).insert(Done::Failure);
|
||||
}
|
||||
} else if let Some(states::Attacking { phys, beats_remaining }) = maybe_attacking {
|
||||
println!("{phys:#?}");
|
||||
if *beats_remaining == 0 {
|
||||
commands.entity(player_id).insert(Done::Success);
|
||||
}
|
||||
} else if let Some(states::Awaiting { beats_remaining, .. }) = maybe_awaiting {
|
||||
if *beats_remaining == 0 {
|
||||
commands.entity(player_id).insert(Done::Success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(mut attacking) = maybe_attacking {
|
||||
attacking.timer.tick(time.delta());
|
||||
|
||||
// TODO: change beats_remaining to more accurate counting
|
||||
/// Observer that updates temporal states on timer tick
|
||||
pub fn on_timer_tick(
|
||||
_: On<TickEvent>,
|
||||
player_query: Query<(
|
||||
Option<&mut states::Attacking>,
|
||||
Option<&mut states::Awaiting>,
|
||||
), With<Player>>
|
||||
) {
|
||||
for (maybe_attacking, maybe_awaiting) in player_query {
|
||||
if let Some(mut attacking) = maybe_attacking {
|
||||
info!("attack tick");
|
||||
attacking.beats_remaining -= 1;
|
||||
if attacking.timer.just_finished() {
|
||||
info!("{}", attacking.accuracy);
|
||||
commands.entity(player_id).insert(Done::Success);
|
||||
let Some(weapon) = maybe_weapon else {
|
||||
error!("No weapon provided for player");
|
||||
return;
|
||||
};
|
||||
|
||||
if let Some(attack_area) = weapon.attack_area(attacking.phys, attacking.accuracy) {
|
||||
let offset = weapon.attack_offset();
|
||||
commands.entity(player_id)
|
||||
.with_child(attack_area.into_bundle(offset, sprite.flip_x, GROUP_ENEMY));
|
||||
}
|
||||
}
|
||||
} else if let Some(mut awaiting) = maybe_awaiting {
|
||||
info!("await tick");
|
||||
awaiting.beats_remaining -= 1;
|
||||
awaiting.timer.tick(time.delta());
|
||||
if awaiting.timer.just_finished() {
|
||||
commands.entity(player_id).insert(Done::Success);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue