Hi I have an Animating Main Character but my Enemy Sprite does Animate but it renders and just freezes in one frame.
#ifndef ENEMY_H
#define ENEMY_H
#include <string>
#include <SDL.h>
// Forward declaration
class Sprite;
class Enemy {
public:
Enemy(int health, const std::string& spritePath);
virtual ~Enemy();
virtual int calculateDamage(int turn) = 0;
int getHealth() const { return health; }
void takeDamage(int damage) { health -= damage; }
void initSprite(SDL_Renderer* renderer);
void updateAnimation(float deltaTime);
void render(int x, int y, int width, int height);
// Animation control methods
void setFrameRate(float rate);
void setupDefaultAnimation();
Sprite* getSprite() { return sprite; }
protected:
int health;
std::string spritePath;
Sprite* sprite;
// Animation parameters
int frameWidth;
int frameHeight;
int numFrames;
float frameRate;
float frameTimer;
int currentFrame;
};
class EnemyA : public Enemy {
public:
EnemyA();
int calculateDamage(int turn) override;
};
class EnemyB : public Enemy {
public:
EnemyB();
int calculateDamage(int turn) override;
};
class EnemyC : public Enemy {
public:
EnemyC();
int calculateDamage(int turn) override;
};
#endif // ENEMY_H
#include "Enemy.h"
#include "Sprite.h"
#include <stdio.h>
#include <cstdlib>
// Animation frame definitions
#define TZ_H (512 / 4) // Width of a single frame (128px)
#define TZ_V (252 / 2) // Height of a single frame (126px)
Enemy::Enemy(int health, const std::string& spritePath)
: health(health), spritePath(spritePath), sprite(nullptr),
frameWidth(0), frameHeight(0), numFrames(0),
frameRate(0.1f), frameTimer(0.0f), currentFrame(0) {
}
Enemy::~Enemy() {
if (sprite) {
delete sprite;
}
}
void Enemy::setupDefaultAnimation() {
frameWidth = TZ_H;
frameHeight = TZ_V;
numFrames = 8; // Assuming 4 columns x 2 rows
frameRate = 0.1f; // Default frame rate (10 FPS)
}
void Enemy::setFrameRate(float rate) {
frameRate = rate;
}
void Enemy::initSprite(SDL_Renderer* renderer) {
sprite = new Sprite(renderer, spritePath.c_str());
if (!sprite->loadTexture()) {
fprintf(stderr, "Failed to load enemy sprite: %s\n", spritePath.c_str());
delete sprite;
sprite = nullptr;
return;
}
setupDefaultAnimation();
if (sprite) {
sprite->setAnimationParameters(frameWidth, frameHeight, numFrames, frameRate);
}
}
void Enemy::updateAnimation(float deltaTime) {
frameTimer += deltaTime;
while (frameTimer >= frameRate) {
currentFrame = (currentFrame + 1) % numFrames;
frameTimer -= frameRate;
}
if (sprite) {
sprite->updateAnimation(deltaTime);
}
}
void Enemy::render(int x, int y, int width, int height) {
if (sprite) {
sprite->render(x, y, width, height);
}
}
// EnemyA implementation
EnemyA::EnemyA() : Enemy(30, "assets/Sprites/Enemies/enemy1.png") {}
int EnemyA::calculateDamage(int turn) {
return rand() % 6 + 1;
}
// EnemyB implementation
EnemyB::EnemyB() : Enemy(25, "assets/Sprites/Enemies/enemy2.png") {}
int EnemyB::calculateDamage(int turn) {
return turn * 2;
}
// EnemyC implementation
EnemyC::EnemyC() : Enemy(25, "assets/Sprites/Enemies/enemy3.png") {}
int EnemyC::calculateDamage(int turn) {
return (rand() % 6 + 1);
}
//In Combat.cpp
// Create appropriate enemy type
switch (level) {
case 1: currentEnemy = new EnemyA(); break;
case 2: currentEnemy = new EnemyB(); break;
case 3: currentEnemy = new EnemyC(); break;
default: currentEnemy = new EnemyA(); break;
}
// Initialize enemy sprite if renderer is available
if (currentEnemy && renderer) {
currentEnemy->initSprite(renderer);
}
}
// Render the combat UI
extern "C" void renderCombat(CombatContext* context) {
if (currentEnemy == nullptr) {
SDL_Log("Error: currentEnemy is nullptr");
return;
}
//DestroyTexture code
// Render enemy sprite aligned with Knight at Y = 400
if (currentEnemy && currentEnemy->getSprite()) {
const int knightYBase = 400; // Knight's Y position
int enemyX, enemyY, enemyWidth, enemyHeight;
switch (currentLevel) {
case 1:
enemyX = 1500;
enemyWidth = 200;
enemyHeight = 300;
enemyY = SCREEN_HEIGHT - 300;
break;
case 2:
enemyX = 1500;
enemyWidth = 250;
enemyHeight = 350;
enemyY = SCREEN_HEIGHT - 300;
break;
case 3:
enemyX = 1500;
enemyWidth = 300;
enemyHeight = 400;
enemyY = SCREEN_HEIGHT - 300;
break;
default:
enemyX = 1500;
enemyWidth = 200;
enemyHeight = 300;
enemyY = SCREEN_HEIGHT - 300;
}
currentEnemy->getSprite()->render(enemyX, enemyY, enemyWidth, enemyHeight);
}
//other code