generated from 2ndbeam/bevy-template
feat: Collision groups and states
This commit is contained in:
parent
f6022d84b2
commit
88a73275ff
8 changed files with 108 additions and 3 deletions
|
|
@ -5,6 +5,8 @@ use std::time::Duration;
|
|||
use bevy::prelude::*;
|
||||
use bevy_rapier2d::prelude::*;
|
||||
|
||||
use crate::{GROUP_ATTACK, GROUP_INTERACTIVE, GROUP_STATIC};
|
||||
|
||||
/// Contains logic for attack-related calculations
|
||||
#[derive(Component, Clone, Debug, Reflect)]
|
||||
#[reflect(Component, Clone, Debug)]
|
||||
|
|
@ -33,6 +35,7 @@ impl AttackArea {
|
|||
max_distance,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns attack area bundle with everything needed
|
||||
pub fn bundle(
|
||||
damage: f32,
|
||||
|
|
@ -41,6 +44,7 @@ impl AttackArea {
|
|||
position: Vec2,
|
||||
half_area: Vec2,
|
||||
facing_left: bool,
|
||||
affinity: Group,
|
||||
) -> impl Bundle {
|
||||
let origin_x = if facing_left { position.x - half_area.x } else { position.x + half_area.x };
|
||||
(
|
||||
|
|
@ -49,6 +53,10 @@ impl AttackArea {
|
|||
|
||||
// Collision
|
||||
Transform::from_xyz(position.x, position.y, 0.),
|
||||
CollisionGroups::new(
|
||||
GROUP_ATTACK,
|
||||
GROUP_STATIC | GROUP_INTERACTIVE | affinity,
|
||||
),
|
||||
Collider::cuboid(half_area.x, half_area.y),
|
||||
|
||||
// AttackAreaOrigin
|
||||
|
|
@ -73,3 +81,12 @@ impl AttackArea {
|
|||
self.damage * EaseFunction::QuinticOut.sample_unchecked(total_multiplier)
|
||||
}
|
||||
}
|
||||
|
||||
/// System that updates AttackArea timers and despawns those who timed out
|
||||
pub fn update_attack_areas(mut commands: Commands, time: Res<Time>, areas: Query<(Entity, &mut AttackArea)>) {
|
||||
for (area_id, mut area) in areas {
|
||||
if area.tick(time.delta()) {
|
||||
commands.entity(area_id).despawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,25 @@
|
|||
//! This module contains core concepts of the combat system
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
pub mod attack;
|
||||
|
||||
/// Combat health component
|
||||
#[derive(Component, Clone, Copy, PartialEq, Debug, Default, Reflect)]
|
||||
#[reflect(Component, Clone, PartialEq, Debug, Default)]
|
||||
pub struct Health {
|
||||
/// Current health value
|
||||
pub current: f32,
|
||||
/// Maximum health value
|
||||
pub max: f32,
|
||||
}
|
||||
|
||||
impl Health {
|
||||
/// Constructs new health component
|
||||
pub fn new(max: f32) -> Self {
|
||||
Self {
|
||||
current: max,
|
||||
max,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
src/lib.rs
13
src/lib.rs
|
|
@ -10,14 +10,27 @@ pub mod graph;
|
|||
pub mod input;
|
||||
pub mod player;
|
||||
pub mod plugin;
|
||||
pub mod states;
|
||||
pub mod timer;
|
||||
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier2d::prelude::*;
|
||||
|
||||
use crate::{player::Player, timer::BpmTimer};
|
||||
|
||||
const PIXELS_PER_METER: f32 = 16.;
|
||||
|
||||
/// Collision group for static entities (walls, floors, etc)
|
||||
pub const GROUP_STATIC: Group = Group::GROUP_1;
|
||||
/// Collision group for interactive entities (doors, buttons, etc)
|
||||
pub const GROUP_INTERACTIVE: Group = Group::GROUP_2;
|
||||
/// Collision group for player and player-related entities
|
||||
pub const GROUP_FRIENDLY: Group = Group::GROUP_3;
|
||||
/// Collision group for enemy-related entities
|
||||
pub const GROUP_ENEMY: Group = Group::GROUP_4;
|
||||
/// Collision group for attack-related entities
|
||||
pub const GROUP_ATTACK: Group = Group::GROUP_5;
|
||||
|
||||
/// Returns pixel measurement for given length in meters
|
||||
#[inline(always)] pub const fn meters(length: f32) -> f32 { PIXELS_PER_METER * length }
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,10 @@ use bevy_rapier2d::prelude::*;
|
|||
use leafwing_input_manager::prelude::*;
|
||||
|
||||
use crate::{
|
||||
meters,
|
||||
input::{
|
||||
GROUP_ATTACK, GROUP_ENEMY, GROUP_FRIENDLY, GROUP_INTERACTIVE, GROUP_STATIC, input::{
|
||||
DefaultInputMap,
|
||||
PlayerInput,
|
||||
}
|
||||
}, meters
|
||||
};
|
||||
|
||||
pub mod systems;
|
||||
|
|
@ -51,11 +50,19 @@ impl Player {
|
|||
RigidBody::KinematicPositionBased,
|
||||
KinematicCharacterController::default(),
|
||||
ActiveCollisionTypes::default() | ActiveCollisionTypes::KINEMATIC_STATIC,
|
||||
CollisionGroups::new(
|
||||
GROUP_FRIENDLY,
|
||||
GROUP_STATIC | GROUP_INTERACTIVE | GROUP_ENEMY | GROUP_ATTACK,
|
||||
),
|
||||
Collider::cuboid(meters(0.3), meters(0.9)),
|
||||
ActiveEvents::COLLISION_EVENTS,
|
||||
Sleeping::disabled(),
|
||||
|
||||
// State
|
||||
crate::states::Free,
|
||||
|
||||
Children::spawn((
|
||||
// Camera
|
||||
Spawn((
|
||||
Name::new("Player camera"),
|
||||
Camera2d,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
use bevy::prelude::*;
|
||||
use bevy_rapier2d::prelude::*;
|
||||
use leafwing_input_manager::prelude::*;
|
||||
use seldom_state::prelude::*;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -18,6 +19,8 @@ impl Plugin for GamePlugin {
|
|||
|
||||
InputManagerPlugin::<input::PlayerInput>::default(),
|
||||
InputManagerPlugin::<input::DebugInput>::default(),
|
||||
|
||||
StateMachinePlugin::default(),
|
||||
))
|
||||
.add_systems(Startup, setup)
|
||||
.add_systems(Update, (
|
||||
|
|
|
|||
24
src/states.rs
Normal file
24
src/states.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//! Commonly used entity states
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
/// Entity is not doing anything special
|
||||
#[derive(Component, Clone, Copy, PartialEq, Eq, Debug, Default, Reflect)]
|
||||
#[reflect(Component, Clone, PartialEq, Debug, Default)]
|
||||
pub struct Free;
|
||||
|
||||
/// Entity is acting and cannot do something else
|
||||
#[derive(Component, Clone, Copy, PartialEq, Eq, Debug, Default, Reflect)]
|
||||
#[reflect(Component, Clone, PartialEq, Debug, Default)]
|
||||
pub struct Acting {
|
||||
/// How much time left before action ends
|
||||
pub beats_remaining: u32,
|
||||
}
|
||||
|
||||
/// Entity is awaiting a specific set of actions
|
||||
#[derive(Component, Clone, Copy, PartialEq, Eq, Debug, Default, Reflect)]
|
||||
#[reflect(Component, Clone, PartialEq, Debug, Default)]
|
||||
pub struct ActionWindow {
|
||||
/// How much time left before window ends
|
||||
pub beats_remaining: u32,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue