Skip to content

Commit

Permalink
missing files
Browse files Browse the repository at this point in the history
  • Loading branch information
stillonearth committed Oct 12, 2023
1 parent 048dfa9 commit 205c5e2
Show file tree
Hide file tree
Showing 8 changed files with 1,174 additions and 0 deletions.
58 changes: 58 additions & 0 deletions src/ai.rs
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();
}
}
}
89 changes: 89 additions & 0 deletions src/controls.rs
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;
}
}
}
}
}
211 changes: 211 additions & 0 deletions src/events.rs
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;
}
}
}
Loading

0 comments on commit 205c5e2

Please sign in to comment.