Skip to content

Commit

Permalink
interaction_sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
aratama committed Nov 14, 2024
1 parent be3f1e8 commit 321380c
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 28 deletions.
5 changes: 0 additions & 5 deletions src/cast.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use crate::{
asset::GameAssets,
command::GameCommand,
constant::MAX_SPELLS_IN_WAND,
entity::{
actor::Actor,
bullet::{spawn_bullets, SpawnBulletProps, BULLET_SPAWNING_MARGIN},
witch::WITCH_COLLIDER_RADIUS,
},
spell::SpellType,
spell_props::{spell_to_props, SpellCast},
wand::Wand,
wand_props::wand_to_props,
};
use bevy::prelude::*;
use bevy_simple_websocket::ClientMessage;
Expand All @@ -29,8 +26,6 @@ pub fn cast_spell(
online: bool,
) -> i32 {
if let Some(ref mut wand) = &mut actor.wands[actor.current_wand] {
let props = wand_to_props(wand.wand_type);

if 0 < actor.spell_delay {
return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ pub const CAMERA_SPEED: f32 = 0.1;

pub const ENTITY_GROUP: Group = Group::GROUP_1;

pub const PLAYER_INTERACTION_SENSOR_GROUP: Group = Group::GROUP_2;

pub const WALL_GROUP: Group = Group::GROUP_3;

/// プレイヤーキャラクターのグループ
Expand Down
1 change: 1 addition & 0 deletions src/controller/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ fn receive_events(
true,
3.0,
&audio,
false,
);
info!("Remote player spawned: {}", uuid);
}
Expand Down
2 changes: 1 addition & 1 deletion src/entity/actor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::cast::cast_spell;
use crate::config::GameConfig;
use crate::constant::{MAX_SPELLS_IN_WAND, MAX_WANDS};
use crate::constant::MAX_WANDS;
use crate::entity::breakable::BreakableSprite;
use crate::spell::SpellType;
use crate::wand::Wand;
Expand Down
46 changes: 41 additions & 5 deletions src/entity/spell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use bevy_aseprite_ultra::prelude::*;
use bevy_rapier2d::prelude::*;
use rand::random;

#[derive(Default, Component)]
pub struct SpellEntity;
#[derive(Component)]
pub struct SpellEntity(pub SpellType);

pub fn spawn_spell_entity(
commands: &mut Commands,
Expand All @@ -24,7 +24,7 @@ pub fn spawn_spell_entity(
.spawn((
Name::new(format!("spell {}", props.name)),
StateScoped(GameState::InGame),
SpellEntity,
SpellEntity(spell),
EntityDepth,
AsepriteSliceBundle {
aseprite: assets.atlas.clone(),
Expand All @@ -39,8 +39,11 @@ pub fn spawn_spell_entity(
LockedAxes::ROTATION_LOCKED,
RigidBody::Fixed,
Sensor,
Collider::cuboid(16.0, 16.0),
CollisionGroups::new(ENTITY_GROUP, ENTITY_GROUP | WALL_GROUP),
Collider::cuboid(8.0, 8.0),
CollisionGroups::new(
ENTITY_GROUP,
ENTITY_GROUP | WALL_GROUP | PLAYER_INTERACTION_SENSOR_GROUP,
),
))
.with_children(|parent| {
parent.spawn((
Expand All @@ -54,6 +57,39 @@ pub fn spawn_spell_entity(
});
}

// fn interaction(
// mut spell_query: Query<(Entity, &mut SpellEntity)>,
// mut player_query: Query<Entity, With<Player>>,
// mut collision_events: EventReader<CollisionEvent>,
// ) {
// for collision_event in collision_events.read() {
// match collision_event {
// CollisionEvent::Started(a, b, _) => {
// process_intersection_event(&spell_query, &player_query, a, b)
// || process_intersection_event(&spell_query, &player_query, b, a);
// }
// CollisionEvent::Stopped(a, b, _) => {}
// }
// }
// }

// fn process_intersection_event(
// mut spell_query: &Query<(Entity, &mut SpellEntity)>,
// mut player_query: &Query<&mut Player>,
// a: &Entity,
// b: &Entity,
// ) -> bool {
// match (spell_query.get(*a), player_query.get(*b)) {
// (Ok((entity, spell)), Ok(player)) => {
// player.interaction_entity = Some(entity);
// return true;
// }
// _ => {
// return false;
// }
// }
// }

pub struct SpellEntityPlugin;

impl Plugin for SpellEntityPlugin {
Expand Down
9 changes: 8 additions & 1 deletion src/entity/witch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::entity::actor::{Actor, ActorFireState};
use crate::entity::breakable::{Breakable, BreakableSprite};
use crate::entity::EntityDepth;
use crate::hud::life_bar::{spawn_life_bar, LifeBarResource};
use crate::interaction_sensor::spawn_interaction_sensor;
use crate::spell::SpellType;
use crate::states::GameState;
use crate::wand::{Wand, WandType};
Expand Down Expand Up @@ -45,6 +46,8 @@ pub fn spawn_witch<T: Component>(

// 足音のオーディオインスタンス
footstep_audio: &Res<Audio>,

interaction: bool,
) {
let audio_instance = footstep_audio
.play(assets.taiikukan.clone())
Expand Down Expand Up @@ -155,7 +158,11 @@ pub fn spawn_witch<T: Component>(
Footsteps(audio_instance),
));

entity.with_children(move |spawn_children| {
entity.with_children(move |mut spawn_children| {
if interaction {
spawn_interaction_sensor(&mut spawn_children);
}

spawn_children.spawn((
BreakableSprite,
AsepriteAnimationBundle {
Expand Down
2 changes: 2 additions & 0 deletions src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::hud::overlay::*;
use crate::hud::pointer::PointerPlugin;
use crate::hud::*;
use crate::input::GamepadPlugin;
use crate::interaction_sensor::EntityPickerPlugin;
use crate::page::config::ConfigPagePlugin;
use crate::page::main_menu::MainMenuPlugin;
use crate::page::name_input::NameInputPagePlugin;
Expand Down Expand Up @@ -160,6 +161,7 @@ pub fn run_game() {
.add_plugins(ChestPlugin)
.add_plugins(EyeballControlPlugin)
.add_plugins(EntityPlugin)
.add_plugins(EntityPickerPlugin)
.add_plugins(EnemyPlugin)
.add_plugins(GameAudioPlugin)
.add_plugins(GameCommandPlugin)
Expand Down
149 changes: 149 additions & 0 deletions src/interaction_sensor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use crate::{
constant::{ENTITY_GROUP, PLAYER_INTERACTION_SENSOR_GROUP},
controller::player::Player,
entity::{actor::Actor, spell::SpellEntity, witch::Witch},
inventory_item::InventoryItem,
set::GameSet,
states::GameState,
};
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
use std::collections::HashSet;

/// プレイヤーキャラクターがアイテムを拾ったりギミックの操作をするためのセンサーです
#[derive(Component)]
struct InteractionSensor {
entities: HashSet<Entity>,
}

pub fn spawn_interaction_sensor(builder: &mut ChildBuilder) {
builder.spawn((
InteractionSensor {
entities: HashSet::new(),
},
VisibilityBundle::default(),
Transform::IDENTITY,
GlobalTransform::default(),
RigidBody::Fixed,
Sensor,
Collider::cuboid(8.0, 8.0),
CollisionGroups::new(PLAYER_INTERACTION_SENSOR_GROUP, ENTITY_GROUP),
ActiveEvents::COLLISION_EVENTS,
ActiveCollisionTypes::STATIC_STATIC,
));
}

fn update_interaction_sensor_transform(
actor_query: Query<&Actor, (With<Witch>, With<Player>)>,
mut sensror_query: Query<(&Parent, &mut Transform), With<InteractionSensor>>,
) {
for (parent, mut sensor) in sensror_query.iter_mut() {
if let Ok(actor) = actor_query.get(**parent) {
let angle = actor.pointer.to_angle();
sensor.translation = Vec3::new(8.0, 0.0, 0.0);
sensor.rotation = Quat::IDENTITY;
sensor.rotate_around(Vec3::ZERO, Quat::from_rotation_z(angle));
}
}
}

fn interaction(
mut sensor_query: Query<&mut InteractionSensor>,
spell_entity_query: Query<(Entity, &SpellEntity)>,
mut collision_events: EventReader<CollisionEvent>,
) {
for collision_event in collision_events.read() {
match collision_event {
CollisionEvent::Started(a, b, _) => {
info!("CollisionEvent::Started");

let _ = process_started_event(&mut sensor_query, &spell_entity_query, a, b)
|| process_started_event(&mut sensor_query, &spell_entity_query, b, a);
}
CollisionEvent::Stopped(a, b, _) => {
info!("CollisionEvent::Stopped");
let _ = process_stopped_event(&mut sensor_query, &spell_entity_query, a, b)
|| process_stopped_event(&mut sensor_query, &spell_entity_query, b, a);
}
}
}
}

fn process_started_event(
sensor_query: &mut Query<&mut InteractionSensor>,
spell_entity_query: &Query<(Entity, &SpellEntity)>,
a: &Entity,
b: &Entity,
) -> bool {
match (sensor_query.get_mut(*a), spell_entity_query.get(*b)) {
(Ok(mut sensor), Ok((spell_entity, _))) => {
println!("spell_entity: {:?}", spell_entity);
sensor.entities.insert(spell_entity);
true
}
_ => false,
}
}

fn process_stopped_event(
sensor_query: &mut Query<&mut InteractionSensor>,
spell_entity_query: &Query<(Entity, &SpellEntity)>,
a: &Entity,
b: &Entity,
) -> bool {
match (sensor_query.get_mut(*a), spell_entity_query.get(*b)) {
(Ok(mut sensor), Ok((spell_entity, _))) => {
sensor.entities.remove(&spell_entity);
true
}
_ => false,
}
}

fn pick_up(
mut sensor_query: Query<&InteractionSensor>,
mut player_query: Query<&mut Player>,
spell_query: Query<&SpellEntity>,
mut commands: Commands,
keys: Res<ButtonInput<KeyCode>>,
) {
if keys.just_pressed(KeyCode::KeyE) {
let sensor = sensor_query.single_mut();
if let Ok(mut player) = player_query.get_single_mut() {
for entity in &sensor.entities {
if let Ok(SpellEntity(spell)) = spell_query.get(*entity) {
if let Some(index) = player.inventory.iter().position(|i| i.is_none()) {
player.inventory[index] = Some(InventoryItem::Spell(*spell));
commands.entity(*entity).despawn_recursive();

// エンティティを削除すれば Stopped イベントが発生してリストから消えるので、
// ここで削除する必要はない
// entities.remove(entity);
} else {
warn!("Inventory is full");
}
} else {
warn!("SpellEntity not found");
}
}
}
}
}

pub struct EntityPickerPlugin;

impl Plugin for EntityPickerPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
(update_interaction_sensor_transform,).run_if(in_state(GameState::InGame)),
);
app.add_systems(
FixedUpdate,
(interaction, pick_up)
.run_if(in_state(GameState::InGame))
.in_set(GameSet)
.before(PhysicsSet::SyncBackend),
);
}
}
2 changes: 1 addition & 1 deletion src/inventory_item.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{constant::MAX_ITEMS_IN_INVENTORY, spell::SpellType, wand::WandType};
use crate::{constant::MAX_ITEMS_IN_INVENTORY, spell::SpellType};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum InventoryItem {
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod entity;
mod game;
mod hud;
mod input;
mod interaction_sensor;
mod inventory_item;
mod page;
mod set;
Expand Down
3 changes: 1 addition & 2 deletions src/ui/inventory.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::ui::floating::{InventoryItemFloating, InventoryItemFloatingContent};
use crate::wand_props::wand_to_props;
use crate::{
asset::GameAssets, constant::MAX_ITEMS_IN_INVENTORY, controller::player::Player,
entity::actor::Actor, inventory_item::InventoryItem, spell_props::spell_to_props,
Expand Down Expand Up @@ -159,7 +158,7 @@ fn interaction(
*floating = InventoryItemFloating(None);
}
},
Some(InventoryItemFloatingContent::Wand(wand_index)) => {}
Some(InventoryItemFloatingContent::Wand(_)) => {}
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/ui/spell_information.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use bevy_aseprite_ultra::prelude::{AsepriteSlice, AsepriteSliceUiBundle};

use crate::{
asset::GameAssets,
inventory_item::InventoryItem,
spell::SpellType,
spell_props::{get_spell_appendix, spell_to_props},
states::GameState,
Expand Down
Loading

0 comments on commit 321380c

Please sign in to comment.