From b8da0a9f2d868169cb5e6cc8085652f862587540 Mon Sep 17 00:00:00 2001 From: Klemen Plestenjak Date: Fri, 9 Feb 2024 18:50:18 +0100 Subject: [PATCH] Add knockback when attacking, fix animation state --- game/systems/s_animation.c | 26 +++++++++++++++----------- game/systems/s_entity.c | 5 +++++ game/systems/s_event.c | 12 +++++++----- game/systems/systems.h | 2 +- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/game/systems/s_animation.c b/game/systems/s_animation.c index b925695..315f305 100644 --- a/game/systems/s_animation.c +++ b/game/systems/s_animation.c @@ -135,18 +135,29 @@ Particle spawnParticle(const ParticleEmitter *emitter) { }; } -void animationSetState(Animation *anim, AnimType type, bool playInFull) { +static void animationSetTextureRec(ecs_entity_t entity, Animation *anim, TextureRegion *texture) { + texture->rec = getTextureRect(anim->frame.frame); + if (ecs_has(ECS, entity, Owner)) { + Owner owner = *ecs_get(ECS, entity, Owner); + BzTileID base = anim->frame.frame; + Vector2 offset = getTileOffset(base, owner.player); + texture->rec.x += offset.x; + texture->rec.y += offset.y; + } +} +void animationSetState(ecs_entity_t entity, Animation *anim, TextureRegion *texture, AnimType type, bool playInFull) { anim->animType = type; anim->sequence = entityGetAnimationSequence(anim->entityType, type); anim->curFrame = 0; anim->elapsed = 0; anim->playInFull = playInFull; + animationSetTextureRec(entity, anim, texture); } void updateAnimationState(ecs_iter_t *it) { Animation *anim = ecs_field(it, Animation, 1); TextureRegion *text = ecs_field(it, TextureRegion, 2); for (i32 i = 0; i < it->count; i++) { - if (anim->playInFull) continue; + if (anim[i].playInFull) continue; ecs_entity_t entity = it->entities[i]; AnimType type = ANIM_IDLE; if (ecs_has(ECS, entity, Velocity)) { @@ -159,7 +170,7 @@ void updateAnimationState(ecs_iter_t *it) { } if (type != anim[i].animType) { - animationSetState(&anim[i], type, false); + animationSetState(entity, &anim[i], &text[i], type, false); } } } @@ -183,14 +194,7 @@ void updateAnimation(ecs_iter_t *it) { anim[i].frame = entityGetAnimationFrame(anim[i].entityType, anim[i].animType, nextFrame); anim[i].elapsed = 0.0f; - texture[i].rec = getTextureRect(anim[i].frame.frame); - if (ecs_has(ECS, entity, Owner)) { - Owner owner = *ecs_get(ECS, entity, Owner); - BzTileID base = anim[i].frame.frame; - Vector2 offset = getTileOffset(base, owner.player); - texture[i].rec.x += offset.x; - texture[i].rec.y += offset.y; - } + animationSetTextureRec(entity, &anim[i], &texture[i]); } } diff --git a/game/systems/s_entity.c b/game/systems/s_entity.c index ac5484d..f188825 100644 --- a/game/systems/s_entity.c +++ b/game/systems/s_entity.c @@ -181,6 +181,8 @@ void entityUpdate(ecs_iter_t *it) { continue; } + f32 knockback = 1.0f; + // Attack update if (canAttack && ecs_has(ECS, other, Health) && ecs_has(ECS, other, Owner)) { Player otherPlayer = ecs_get(ECS, other, Owner)->player; @@ -202,6 +204,8 @@ void entityUpdate(ecs_iter_t *it) { canAttack = false; unit[i].attackElapsed = 0.0f; + + knockback = 3.0f; } } @@ -209,6 +213,7 @@ void entityUpdate(ecs_iter_t *it) { // Physics update slowDown += 0.2f; Position dif = Vector2Subtract(otherPos, position[i]); + dif = Vector2Scale(dif, knockback); dir = Vector2Add(dir, dif); } diff --git a/game/systems/s_event.c b/game/systems/s_event.c index 78e4fba..b512196 100644 --- a/game/systems/s_event.c +++ b/game/systems/s_event.c @@ -33,14 +33,16 @@ void damageEvent(ecs_entity_t entity, DamageEvent event) { bool hasAnimation = ecs_has(ECS, entity, Animation); if (hasAnimation && health->hp > 0) { // Still alive, just play hurt anim - Animation *animation = ecs_get_mut(ECS, entity, Animation); - animationSetState(animation, ANIM_HURT, true); + Animation *anim = ecs_get_mut(ECS, entity, Animation); + TextureRegion *tex = ecs_get_mut(ECS, entity, TextureRegion); + animationSetState(entity, anim, tex, ANIM_HURT, true); } else if (hasAnimation) { // Delay delete - Animation *animation = ecs_get_mut(ECS, entity, Animation); - animationSetState(animation, ANIM_DIE, true); + Animation *anim = ecs_get_mut(ECS, entity, Animation); + TextureRegion *tex = ecs_get_mut(ECS, entity, TextureRegion); + animationSetState(entity, anim, tex, ANIM_DIE, true); ecs_set(ECS, entity, DelayDelete, { - .time = entityGetAnimationLength(animation->entityType, ANIM_DIE) + .time = entityGetAnimationLength(anim->entityType, ANIM_DIE) }); // Remove, so it becomes inactive ecs_remove_id(ECS, entity, Selectable); diff --git a/game/systems/systems.h b/game/systems/systems.h index 648c652..69cd26b 100644 --- a/game/systems/systems.h +++ b/game/systems/systems.h @@ -52,7 +52,7 @@ bool updateParticle(const Texture2D tex, Particle *particle, f32 dt); Particle spawnParticle(const ParticleEmitter *emitter); -void animationSetState(Animation *anim, AnimType type, bool playInFull); +void animationSetState(ecs_entity_t entity, Animation *anim, TextureRegion *texture, AnimType type, bool playInFull); /* * 1: Animation * 2: TextureRegion