generated from bevyengine/bevy_github_ci_template
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
048dfa9
commit 205c5e2
Showing
8 changed files
with
1,174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use bevy::prelude::*; | ||
|
||
use bevy_rapier2d::prelude::*; | ||
|
||
use crate::components::*; | ||
|
||
pub(crate) fn mierda_activity( | ||
time: Res<Time>, | ||
mut los_mierdas: Query<(&mut Velocity, &mut Mierda)>, | ||
) { | ||
for (mut v, mut mierda) in los_mierdas.iter_mut().filter(|(_, m)| !m.is_dummy) { | ||
let rotation_angle = time.elapsed_seconds().cos() * std::f32::consts::FRAC_PI_4; | ||
|
||
if mierda.hit_at.is_some() { | ||
let timer = mierda.hit_at.as_mut().unwrap(); | ||
timer.tick(time.delta()); | ||
if !timer.finished() { | ||
continue; | ||
} else { | ||
mierda.hit_at = None; | ||
} | ||
} | ||
|
||
v.linvel = Vec2::new( | ||
mierda.move_direction.x * rotation_angle.cos() | ||
- mierda.move_direction.y * rotation_angle.sin(), | ||
mierda.move_direction.x * rotation_angle.sin() | ||
+ mierda.move_direction.y * rotation_angle.cos(), | ||
) * 30.0; | ||
} | ||
} | ||
|
||
pub(crate) fn update_mierdas_move_direction( | ||
time: Res<Time>, | ||
player: Query<(&Transform, &Player)>, | ||
mut los_mierdas: Query<(&Transform, &mut DirectionUpdateTime, &mut Mierda)>, | ||
) { | ||
if player.iter().count() == 0 { | ||
return; | ||
} | ||
|
||
let player_position = player.single().0.translation; | ||
|
||
for (mierda_position, mut direction_update_timer, mut mierda) in | ||
los_mierdas.iter_mut().filter(|(_, _, m)| !m.is_dummy) | ||
{ | ||
direction_update_timer.timer.tick(time.delta()); | ||
|
||
if direction_update_timer.timer.finished() { | ||
let mierda_position = mierda_position.translation; | ||
mierda.move_direction = Vec2::new( | ||
player_position.x - mierda_position.x, | ||
player_position.y - mierda_position.y, | ||
) | ||
.normalize_or_zero(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
use bevy::prelude::*; | ||
use bevy_rapier2d::prelude::*; | ||
use pecs::prelude::*; | ||
|
||
use crate::{components::*, events::*, sprites::*}; | ||
|
||
pub fn controls( | ||
mut commands: Commands, | ||
input: Res<Input<KeyCode>>, | ||
mut query: Query< | ||
( | ||
Entity, | ||
&mut Handle<TextureAtlas>, | ||
&mut Velocity, | ||
&mut CharacterAnimation, | ||
&mut TextureAtlasSprite, | ||
), | ||
With<Player>, | ||
>, | ||
spritesheets: Res<PlayerSpritesheets>, | ||
) { | ||
for (entity, mut texture_atlas, mut velocity, mut char_animation, mut sprite) in &mut query { | ||
// no control during attack phase | ||
if char_animation.animation_type == AnimationType::Attack { | ||
return; | ||
} | ||
|
||
if input.pressed(KeyCode::Space) { | ||
char_animation.animation_type = AnimationType::Attack; | ||
texture_atlas.clone_from(&spritesheets.player_atlas_2); | ||
|
||
let indices = | ||
get_animation_indices(char_animation.animation_type, char_animation.direction); | ||
sprite.index = indices.first; | ||
velocity.linvel = Vec2::ZERO; | ||
|
||
commands | ||
.promise(|| (entity)) | ||
.then(asyn!(state => { | ||
state.asyn().timeout(0.3) | ||
})) | ||
.then( | ||
asyn!(state, mut ev_attack: EventWriter<PlayerAttackEvent> => { | ||
let event = PlayerAttackEvent { entity: state.value }; | ||
ev_attack.send(event); | ||
}), | ||
); | ||
} else { | ||
let right = if input.pressed(KeyCode::D) { 1. } else { 0. }; | ||
let left = if input.pressed(KeyCode::A) { 1. } else { 0. }; | ||
let up = if input.pressed(KeyCode::W) { 1. } else { 0. }; | ||
let down = if input.pressed(KeyCode::S) { 1. } else { 0. }; | ||
|
||
velocity.linvel.x = right - left; | ||
velocity.linvel.y = up - down; | ||
|
||
velocity.linvel = velocity.linvel.normalize_or_zero() * 100.; | ||
|
||
let linvel_norm = velocity.linvel.distance(Vec2::ZERO); | ||
|
||
// Change animation type if player moved | ||
if char_animation.animation_type == AnimationType::Walk { | ||
if velocity.linvel.x > 0. { | ||
char_animation.direction = AnimationDirection::Right; | ||
} else if velocity.linvel.x < 0. { | ||
char_animation.direction = AnimationDirection::Left; | ||
} else if velocity.linvel.y > 0. { | ||
char_animation.direction = AnimationDirection::Up; | ||
} else if velocity.linvel.y < 0. { | ||
char_animation.direction = AnimationDirection::Down; | ||
} | ||
} | ||
|
||
// Don't interrupt attack animation | ||
if char_animation.animation_type != AnimationType::Attack { | ||
// Change spritesheet | ||
if char_animation.animation_type != AnimationType::Walk { | ||
texture_atlas.clone_from(&spritesheets.player_atlas_1); | ||
} | ||
|
||
if linvel_norm == 0.0 { | ||
char_animation.animation_type = AnimationType::Stand; | ||
} else { | ||
char_animation.animation_type = AnimationType::Walk; | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,211 @@ | ||
use bevy::prelude::*; | ||
use bevy_ecs_ldtk::{LdtkLevel, LevelSelection}; | ||
use bevy_rapier2d::prelude::Velocity; | ||
use pecs::prelude::*; | ||
|
||
use crate::{ | ||
components::{Mierda, Player}, | ||
sprites::{AnimationDirection, CharacterAnimation, FlashingTimer}, | ||
ui::{self, UiGameOver}, | ||
utils::CloneEntity, | ||
}; | ||
|
||
#[derive(Event, Clone)] | ||
pub struct PlayerAttackEvent { | ||
pub entity: Entity, | ||
} | ||
|
||
#[derive(Event, Clone)] | ||
pub struct PlayerHitEvent { | ||
pub entity: Entity, | ||
} | ||
|
||
#[derive(Event, Clone)] | ||
pub struct GameOverEvent; | ||
|
||
#[derive(Event, Clone)] | ||
pub struct MierdaHitEvent(pub Entity); | ||
|
||
#[derive(Event, Clone)] | ||
pub struct SpawnMierdaEvent { | ||
pub(crate) count: u32, | ||
} | ||
|
||
pub fn event_spawn_mierda( | ||
mut commands: Commands, | ||
mut ev_spawn_mierda: EventReader<SpawnMierdaEvent>, | ||
level_selection: Res<LevelSelection>, | ||
level_handles: Query<(Entity, &Handle<LdtkLevel>)>, | ||
level_assets: Res<Assets<LdtkLevel>>, | ||
_texture_atlasses: ResMut<Assets<TextureAtlas>>, | ||
los_mierdas: Query<(Entity, &Parent, &mut Visibility, &Mierda)>, | ||
levels: Query<(Entity, &Handle<LdtkLevel>)>, | ||
) { | ||
for ev_spawn in ev_spawn_mierda.iter() { | ||
for (_, level_handle) in level_handles.iter() { | ||
let level = &level_assets.get(level_handle).unwrap().level; | ||
|
||
if level_selection.is_match(&0, level) { | ||
let (parent_entity, _) = levels | ||
.iter() | ||
.find(|(_, handle)| *handle == level_handle) | ||
.unwrap(); | ||
|
||
for _i in 0..ev_spawn.count { | ||
for (mierda_entity, mierda_parent, _mierda_visibility, mierda) in | ||
los_mierdas.iter() | ||
{ | ||
if !mierda.is_dummy { | ||
continue; | ||
} | ||
|
||
let mierda_parent = mierda_parent.get(); | ||
|
||
if parent_entity != mierda_parent { | ||
continue; | ||
} | ||
|
||
let mut parent = commands.entity(mierda_parent); | ||
|
||
let mut new_entity: Option<Entity> = None; | ||
parent.with_children(|cm| { | ||
let ne = cm.spawn_empty().id(); | ||
new_entity = Some(ne); | ||
}); | ||
|
||
let new_entity = new_entity.unwrap(); | ||
commands.entity(new_entity).insert(Mierda { | ||
is_dummy: false, | ||
health: 100, | ||
move_direction: Vec2::ZERO, | ||
hit_at: None, | ||
}); | ||
|
||
commands.add(CloneEntity { | ||
source: mierda_entity, | ||
destination: new_entity, | ||
}); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn event_player_attack( | ||
mut ev_player_attack: EventReader<PlayerAttackEvent>, | ||
mut ev_mierda_hit: EventWriter<MierdaHitEvent>, | ||
mut q_player: Query<(Entity, &Transform, &CharacterAnimation), With<Player>>, | ||
mut los_mierdas: Query<(Entity, &Transform, &mut Mierda)>, | ||
) { | ||
for ev in ev_player_attack.iter() { | ||
let (_, transform, char_animation) = q_player.get_mut(ev.entity).unwrap(); | ||
|
||
let player_position = transform.translation; | ||
let player_orientation = char_animation.direction; | ||
|
||
// find all mierdas in range | ||
for (entity, mierda_transform, _) in los_mierdas.iter_mut().filter(|(_, _, m)| !m.is_dummy) | ||
{ | ||
let mierda_position = mierda_transform.translation; | ||
|
||
let distance = player_position.distance(mierda_position); | ||
|
||
if distance >= 75. { | ||
continue; | ||
} | ||
|
||
// cause damage accrodign to player_orientation | ||
let is_merda_attacked = match player_orientation { | ||
AnimationDirection::Up => player_position.y < mierda_position.y, | ||
AnimationDirection::Down => player_position.y > mierda_position.y, | ||
AnimationDirection::Left => player_position.x > mierda_position.x, | ||
AnimationDirection::Right => player_position.x < mierda_position.x, | ||
}; | ||
|
||
if !is_merda_attacked { | ||
continue; | ||
} | ||
|
||
ev_mierda_hit.send(MierdaHitEvent(entity)); | ||
} | ||
} | ||
} | ||
|
||
pub fn event_mierda_hit( | ||
mut commands: Commands, | ||
q_player: Query<(&Transform, &Player)>, | ||
mut los_mierdas: Query<(Entity, &Transform, &mut Velocity, &mut Mierda)>, | ||
mut ev_mierda_hit: EventReader<MierdaHitEvent>, | ||
mut ev_mierda_spawn: EventWriter<SpawnMierdaEvent>, | ||
) { | ||
for event in ev_mierda_hit.iter() { | ||
let los_mierdas_count = los_mierdas.iter().len(); | ||
|
||
for (player_transform, _) in q_player.iter() { | ||
let player_position = player_transform.translation; | ||
|
||
let (mierda_entity, mierda_transform, mut mierda_velocity, mut mierda) = | ||
los_mierdas.get_mut(event.0).unwrap(); | ||
let mierda_position = mierda_transform.translation; | ||
let vector_attack = (mierda_position - player_position).normalize(); | ||
mierda_velocity.linvel.x += vector_attack.x * 200.; | ||
mierda_velocity.linvel.y += vector_attack.y * 200.; | ||
|
||
let timer = Timer::new(std::time::Duration::from_millis(200), TimerMode::Once); | ||
mierda.hit_at = Some(timer.clone()); | ||
|
||
commands.entity(mierda_entity).insert(FlashingTimer { | ||
timer: timer.clone(), | ||
}); | ||
|
||
// despawn mierda async | ||
commands | ||
.promise(|| (mierda_entity)) | ||
.then(asyn!(state => { | ||
state.asyn().timeout(0.3) | ||
})) | ||
.then(asyn!(state, mut commands: Commands => { | ||
commands.entity(state.value).despawn_recursive(); | ||
|
||
})); | ||
|
||
if los_mierdas_count < 256 { | ||
ev_mierda_spawn.send(SpawnMierdaEvent { count: 2 }); | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn event_player_hit( | ||
mut ev_player_hit_reader: EventReader<PlayerHitEvent>, | ||
mut ev_game_over: EventWriter<GameOverEvent>, | ||
mut q_player: Query<(Entity, &mut Player)>, | ||
mut q_ui_healthbar: Query<(Entity, &mut Style, &ui::UiPlayerHealth)>, | ||
) { | ||
for ev in ev_player_hit_reader.iter() { | ||
let (_, mut player) = q_player.get_mut(ev.entity).unwrap(); | ||
|
||
if player.health < 10 { | ||
ev_game_over.send(GameOverEvent); | ||
continue; | ||
} else { | ||
player.health -= 10; | ||
|
||
for (_, mut style, _) in q_ui_healthbar.iter_mut() { | ||
style.width = Val::Percent(player.health as f32); | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub fn event_game_over( | ||
mut ev_game_over: EventReader<GameOverEvent>, | ||
mut q_ui_game_over: Query<(&mut Visibility, &UiGameOver)>, | ||
) { | ||
for _ in ev_game_over.iter() { | ||
for (mut visibility, _) in q_ui_game_over.iter_mut() { | ||
*visibility = Visibility::Visible; | ||
} | ||
} | ||
} |
Oops, something went wrong.