Skip to content

Commit

Permalink
machete
Browse files Browse the repository at this point in the history
  • Loading branch information
stillonearth committed Jun 10, 2024
1 parent f7ffdc5 commit d84a8b7
Show file tree
Hide file tree
Showing 10 changed files with 522 additions and 206 deletions.
265 changes: 186 additions & 79 deletions assets/levels/example.ldtk

Large diffs are not rendered by default.

Binary file added assets/raw-pixelart/machete.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
154 changes: 91 additions & 63 deletions src/controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@ use crate::{
sprites::*,
};

pub fn controls(
#[derive(Event, Copy, Clone, Reflect, Debug, PartialEq, Eq, Default)]
pub struct ControlEvent {
pub up: bool,
pub down: bool,
pub left: bool,
pub right: bool,
pub attack: bool,
}

pub fn control_character(
mut commands: Commands,
input: Res<Input<KeyCode>>,
mut ev_control: EventReader<ControlEvent>,
mut query: Query<
(
Entity,
Expand All @@ -24,73 +33,92 @@ pub fn controls(
>,
spritesheets: Res<CharacterSpritesheets>,
) {
for (entity, mut texture_atlas, mut velocity, mut char_animation, mut sprite, _player) 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;
}
for control in ev_control.read() {
for (entity, mut texture_atlas, mut velocity, mut char_animation, mut sprite, _player) in
&mut query
{
// no control during attack phase
if char_animation.animation_type == AnimationType::Attack {
return;
}

// 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 control.attack {
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 control.right { 1. } else { 0. };
let left = if control.left { 1. } else { 0. };
let up = if control.up { 1. } else { 0. };
let down = if control.down { 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;
}
}

if linvel_norm == 0.0 {
char_animation.animation_type = AnimationType::Stand;
} else {
char_animation.animation_type = AnimationType::Walk;
// 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;
}
}
}
}
}
}

pub fn keyboard_controls(input: Res<Input<KeyCode>>, mut ev_control: EventWriter<ControlEvent>) {
let mut control = ControlEvent { ..default() };

control.right = input.pressed(KeyCode::D);
control.left = input.pressed(KeyCode::A);
control.up = input.pressed(KeyCode::W);
control.down = input.pressed(KeyCode::S);

// if input.pressed(KeyCode::Space) {
// // control.attack = true;
// } else {

// }

ev_control.send(control);
}
55 changes: 32 additions & 23 deletions src/entities/characters/enemy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ pub enum EnemyType {
#[default]
Mierda,
Pendejo,
Psychiatrist,
Psychiatrist1,
Psychiatrist2,
}

#[derive(Clone, PartialEq, Debug, Default, Component, Reflect)]
Expand Down Expand Up @@ -113,25 +114,30 @@ pub fn create_enemy_bundle(
*spritesheet_type,
)
}
EnemyType::Psychiatrist => {
let psychiatrist_sprite_sheet = if rand::random::<u8>() % 2 == 0 {
PSYCHIATRIST_1_ASSET_SHEET
} else {
PSYCHIATRIST_2_ASSET_SHEET
};
(
load_texture_atlas(
psychiatrist_sprite_sheet.to_string(),
asset_server,
1,
1,
None,
128. * Vec2::ONE,
texture_atlasses,
),
AnimatedCharacterType::NotAnimated,
)
}
EnemyType::Psychiatrist1 => (
load_texture_atlas(
PSYCHIATRIST_1_ASSET_SHEET.to_string(),
asset_server,
1,
1,
None,
128. * Vec2::ONE,
texture_atlasses,
),
AnimatedCharacterType::NotAnimated,
),
EnemyType::Psychiatrist2 => (
load_texture_atlas(
PSYCHIATRIST_2_ASSET_SHEET.to_string(),
asset_server,
1,
1,
None,
128. * Vec2::ONE,
texture_atlasses,
),
AnimatedCharacterType::NotAnimated,
),
};

let sprite_bundle = SpriteSheetBundle {
Expand Down Expand Up @@ -271,7 +277,8 @@ pub fn handle_spawn_enemy(
health: match ev_spawn.enemy_type {
EnemyType::Mierda => 50,
EnemyType::Pendejo => 100,
EnemyType::Psychiatrist => 5000,
EnemyType::Psychiatrist1 => 5000,
EnemyType::Psychiatrist2 => 5000,
},
move_direction: Vec2::ZERO,
hit_at: None,
Expand Down Expand Up @@ -322,7 +329,8 @@ pub fn handle_enemy_hit(
let damage = match enemy.enemy_type {
EnemyType::Mierda => (1.0 * event.damage as f32) as u16,
EnemyType::Pendejo => (0.5 * event.damage as f32) as u16,
EnemyType::Psychiatrist => (1.0 * event.damage as f32) as u16,
EnemyType::Psychiatrist1 => (1.0 * event.damage as f32) as u16,
EnemyType::Psychiatrist2 => (1.0 * event.damage as f32) as u16,
};

let timer = Timer::new(std::time::Duration::from_millis(200), TimerMode::Once);
Expand Down Expand Up @@ -363,7 +371,8 @@ pub fn despawn_dead_enemies(
enemy.marked_for_despawn = true;
score.score += match enemy.enemy_type {
EnemyType::Mierda => 100,
EnemyType::Psychiatrist => 5000,
EnemyType::Psychiatrist1 => 5000,
EnemyType::Psychiatrist2 => 5000,
EnemyType::Pendejo => 50,
};

Expand Down
66 changes: 58 additions & 8 deletions src/entities/characters/psychiatrist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,19 @@ use super::enemy::{create_enemy_bundle, DirectionUpdateTime, Enemy, EnemyType};
// --------

#[derive(Default, Bundle, Clone)]
pub struct PsychiatristBundle {
pub struct Psychiatrist1Bundle {
pub spritesheet_bundle: SpriteSheetBundle,
pub character_animation: CharacterAnimation,
pub animation_timer: AnimationTimer,
pub enemy: Enemy,
pub collider_bundle: ColliderBundle,
pub active_events: ActiveEvents,
pub direction_update_time: DirectionUpdateTime,
pub animated_character_sprite: AnimatedCharacterSprite,
}

#[derive(Default, Bundle, Clone)]
pub struct Psychiatrist2Bundle {
pub spritesheet_bundle: SpriteSheetBundle,
pub character_animation: CharacterAnimation,
pub animation_timer: AnimationTimer,
Expand All @@ -32,15 +44,48 @@ pub struct PsychiatristBundle {
// LDTK
// ----

impl LdtkEntity for PsychiatristBundle {
impl LdtkEntity for Psychiatrist1Bundle {
fn bundle_entity(
entity_instance: &EntityInstance,
_: &LayerInstance,
_: Option<&Handle<Image>>,
_: Option<&TilesetDefinition>,
asset_server: &AssetServer,
texture_atlasses: &mut Assets<TextureAtlas>,
) -> Psychiatrist1Bundle {
let is_dummy = *entity_instance
.get_bool_field("is_dummy")
.expect("expected entity to have non-nullable name string field");

let enemy_bundle = create_enemy_bundle(
asset_server,
texture_atlasses,
is_dummy,
EnemyType::Psychiatrist1,
);

Psychiatrist1Bundle {
spritesheet_bundle: enemy_bundle.spritesheet_bundle,
character_animation: enemy_bundle.character_animation,
animation_timer: enemy_bundle.animation_timer,
enemy: enemy_bundle.enemy,
collider_bundle: enemy_bundle.collider_bundle,
active_events: enemy_bundle.active_events,
direction_update_time: enemy_bundle.direction_update_time,
animated_character_sprite: enemy_bundle.animated_character_sprite,
}
}
}

impl LdtkEntity for Psychiatrist2Bundle {
fn bundle_entity(
entity_instance: &EntityInstance,
_: &LayerInstance,
_: Option<&Handle<Image>>,
_: Option<&TilesetDefinition>,
asset_server: &AssetServer,
texture_atlasses: &mut Assets<TextureAtlas>,
) -> PsychiatristBundle {
) -> Psychiatrist2Bundle {
let is_dummy = *entity_instance
.get_bool_field("is_dummy")
.expect("expected entity to have non-nullable name string field");
Expand All @@ -49,10 +94,10 @@ impl LdtkEntity for PsychiatristBundle {
asset_server,
texture_atlasses,
is_dummy,
EnemyType::Psychiatrist,
EnemyType::Psychiatrist2,
);

PsychiatristBundle {
Psychiatrist2Bundle {
spritesheet_bundle: enemy_bundle.spritesheet_bundle,
character_animation: enemy_bundle.character_animation,
animation_timer: enemy_bundle.animation_timer,
Expand All @@ -76,7 +121,9 @@ pub fn psychiatrist_activity(
for (mut v, mut psychiatrist) in q_psychiatrists
.iter_mut()
.filter(|(_, m)| !m.is_dummy)
.filter(|(_, m)| m.enemy_type == EnemyType::Psychiatrist)
.filter(|(_, m)| {
m.enemy_type == EnemyType::Psychiatrist1 || m.enemy_type == EnemyType::Psychiatrist2
})
{
let rotation_angle = time.elapsed_seconds().cos() * std::f32::consts::FRAC_PI_4;

Expand Down Expand Up @@ -117,7 +164,9 @@ pub fn update_psychiatrists_move_direction(
for (psychiatrist_position, mut direction_update_timer, mut psychiatrist) in los_pendejos
.iter_mut()
.filter(|(_, _, p)| !p.is_dummy)
.filter(|(_, _, p)| p.enemy_type == EnemyType::Psychiatrist)
.filter(|(_, _, p)| {
p.enemy_type == EnemyType::Psychiatrist1 || p.enemy_type == EnemyType::Psychiatrist2
})
{
direction_update_timer.timer.tick(time.delta());

Expand All @@ -140,7 +189,8 @@ pub struct PsychiatristPlugin;

impl Plugin for PsychiatristPlugin {
fn build(&self, app: &mut App) {
app.register_ldtk_entity::<PsychiatristBundle>("Psychiatrist")
app.register_ldtk_entity::<Psychiatrist1Bundle>("Psychiatrist1")
.register_ldtk_entity::<Psychiatrist2Bundle>("Psychiatrist2")
// Event Handlers
.add_systems(
Update,
Expand Down
Loading

0 comments on commit d84a8b7

Please sign in to comment.