From f30de54a34142030ad66426fea1dabd44edbefd1 Mon Sep 17 00:00:00 2001 From: Stan_Lewry Date: Sat, 31 Aug 2024 17:53:01 +0100 Subject: [PATCH] support multiple different attack animations --- combat.cpp | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/combat.cpp b/combat.cpp index 59b2cd9..3b372c0 100644 --- a/combat.cpp +++ b/combat.cpp @@ -8,6 +8,22 @@ #include #include +enum SpellType { + BASIC_ATTACK, + SLASH +}; + +SpellType selectedSpell = BASIC_ATTACK; + +struct AttackAnim { + SDL_Texture* texture; + int numFrames; + int spriteWidth; + int spriteHeight; +}; + +std::map animLookup; + struct Character { bool allied; @@ -33,6 +49,8 @@ struct Character { bool canAttack = true; bool alive = true; + + SpellType basicAttackType = BASIC_ATTACK; }; std::vector combatants; @@ -54,11 +72,7 @@ enum CombatState { CombatState currentCombatState = TURN_ORDER; -enum Spell { - BASIC_ATTACK -}; -Spell currentSpell = BASIC_ATTACK; static double frameTimer = 0; static const double frameTime = 1.0f / 60.0f; @@ -69,6 +83,7 @@ SDL_Texture* arrowSprite = nullptr; SDL_Texture* indicatorSprite = nullptr; SDL_Texture* indicatorRedSprite = nullptr; SDL_Texture* hitAnim = nullptr; +SDL_Texture* slashAnim = nullptr; static constexpr int arenaWidth = 100; static constexpr int arenaHeight = 100; @@ -312,7 +327,10 @@ void initCombatScene() indicatorSprite = S2DE::loadTexture("assets/little_indicator.png", &renderer); indicatorRedSprite = S2DE::loadTexture("assets/little_indicator_red.png", &renderer); hitAnim = S2DE::loadTexture("assets/hit_anim_1.png", &renderer); + slashAnim = S2DE::loadTexture("assets/slash_anim_1.png", &renderer); + animLookup[BASIC_ATTACK] = { hitAnim, 4, 48, 48 }; + animLookup[SLASH] = { slashAnim, 5, 48, 48 }; //Character player = { true, "Player", 100, 100, 50, 50, 10.0f, 3.0f, player_sheet, { 23.0f, 13.0f } }; Character player; @@ -341,6 +359,7 @@ void initCombatScene() monica.texture = monica_texture; monica.position = { player.position.x - 2, player.position.y }; monica.attack = 6; + monica.basicAttackType = SLASH; Character enemy; enemy.allied = false; @@ -441,8 +460,9 @@ void actionSelectState(double delta) { moveCursorPos = activeCombatant->position; } break; - case 1: // attack selected + case 1: // basic mellee attack selected if (activeCombatant->canAttack) { + selectedSpell = activeCombatant->basicAttackType; // filter the targets - Have to do it here too in case the player attacks without moving? targets.clear(); for (auto& c : combatants) { @@ -599,7 +619,6 @@ void selectAttackTarget(double delta) { if (inputState.rtrn) { inputState.rtrn = false; if (targets.size() > 0) { - currentSpell = BASIC_ATTACK; currentCombatState = DO_ATTACK; } else { @@ -674,6 +693,8 @@ void doAttack(double delta) { Character* target = targets.at(currentTargetIdx); + AttackAnim anim = animLookup[selectedSpell]; + if (currentTargetIdx == -1) { // AOE, apply to all targets in range ? } @@ -683,7 +704,7 @@ void doAttack(double delta) { animTimer = 0; animFrame += 1; - if (animFrame > 4) { + if (animFrame > anim.numFrames) { // anim is complete, apply damage and move on. // reset timers etc. target->currentHP -= activeCombatant->attack; @@ -708,9 +729,11 @@ void doAttack(double delta) { SDL_RenderClear(renderer); renderCombat(); + + // this renders the anim at a bit of a weird size S2DE::Rect animDRect = S2DE::worldToScreenRect(&combatCam, &target->position, 2, WINDOW_WIDTH, WINDOW_HEIGHT, 32, 32); - S2DE::Rect animSRect = { 48 * animFrame, 0, 48, 48 }; - S2DE::renderTexture(&renderer, &hitAnim, &animSRect, &animDRect); + S2DE::Rect animSRect = { anim.spriteWidth * animFrame, 0, anim.spriteWidth, anim.spriteHeight}; + S2DE::renderTexture(&renderer, &anim.texture, &animSRect, &animDRect); renderUIFull(); -- 2.20.1