support multiple different attack animations
authorStan_Lewry <stanley.jml@gmail.com>
Sat, 31 Aug 2024 16:53:01 +0000 (17:53 +0100)
committerStan_Lewry <stanley.jml@gmail.com>
Sat, 31 Aug 2024 16:53:01 +0000 (17:53 +0100)
combat.cpp

index 59b2cd9..3b372c0 100644 (file)
@@ -8,6 +8,22 @@
 #include <cmath>
 #include <algorithm>
 
+enum SpellType {
+       BASIC_ATTACK,
+       SLASH
+};
+
+SpellType selectedSpell = BASIC_ATTACK;
+
+struct AttackAnim {
+       SDL_Texture* texture;
+       int numFrames;
+       int spriteWidth;
+       int spriteHeight;
+};
+
+std::map<SpellType, AttackAnim> animLookup;
+
 
 struct Character {
        bool allied;
@@ -33,6 +49,8 @@ struct Character {
        bool canAttack = true;
 
        bool alive = true;
+
+       SpellType basicAttackType = BASIC_ATTACK;
 };
 
 std::vector<Character> 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();