Working on battle animation

This commit is contained in:
Vladislav Khorev committed 2026-04-13 23:19:03 +03:00
1 parent 422ff1fbe3
commit 493eb5a5d7
13 files changed
+946723 -25

No files matched your search

+65 -7
View File
@@ -25,8 +25,9 @@ void Character::setTarget(const Eigen::Vector3f& target,
}
AnimationState Character::resolveActiveState() const {
if (animations.count(currentState)) return currentState;
return AnimationState::IDLE;
return AnimationState::STAND;
}
void Character::update(int64_t deltaMs) {
@@ -46,9 +47,17 @@ void Character::update(int64_t deltaMs) {
position += dir * moveAmount;
}
targetFacingAngle = atan2(dir.x(), -dir.z());
currentState = AnimationState::WALK;
if (battle_state == 0 && currentState == AnimationState::STAND)
{
currentState = AnimationState::WALK;
}
} else {
currentState = AnimationState::IDLE;
if (battle_state == 0 &&
currentState == AnimationState::WALK
)
{
currentState = AnimationState::STAND;
}
if (onArrivedCallback) {
auto cb = std::move(onArrivedCallback);
onArrivedCallback = nullptr;
@@ -67,17 +76,66 @@ void Character::update(int64_t deltaMs) {
facingAngle += (angleDiff > 0.f ? rotStep : -rotStep);
}
// Advance active animation frame
AnimationState animState = resolveActiveState();
auto it = animations.find(animState);
if (battle_state == 1)
{
if (currentState == AnimationState::STAND || currentState == AnimationState::WALK) {
currentState = AnimationState::STAND_TO_ACTION;
resetAnim = true;
}
if (attack == 1 && currentState == AnimationState::ACTION_IDLE)
{
currentState = AnimationState::ACTION_ATTACK;
resetAnim = true;
}
}
else
{
if (currentState == AnimationState::STAND_TO_ACTION
|| currentState == AnimationState::ACTION_IDLE
|| currentState == AnimationState::ACTION_ATTACK
) {
currentState = AnimationState::ACTION_TO_STAND;
resetAnim = true;
}
}
auto it = animations.find(currentState);
if (it == animations.end()) return;
auto& anim = it->second;
if (resetAnim)
{
resetAnim = false;
anim.currentFrame = 0;
}
anim.currentFrame += static_cast<float>(deltaMs) / 24.f;
//std::cout << "Current animation frame: " << anim.currentFrame << " / " << anim.totalFrames << " -- " << anim.lastFrame << std::endl;
if (static_cast<int>(anim.currentFrame) >= anim.totalFrames-1) {
int frms = anim.model.animations[0].keyFrames[anim.model.animations[0].keyFrames.size() - 1].frame;
if (static_cast<int>(anim.currentFrame) >= frms) {
anim.currentFrame = anim.model.startingFrame;
if (currentState == AnimationState::STAND_TO_ACTION)
{
currentState = AnimationState::ACTION_IDLE;
resetAnim = true;
}
if (currentState == AnimationState::ACTION_TO_STAND)
{
currentState = AnimationState::STAND;
resetAnim = true;
}
if (currentState == AnimationState::ACTION_ATTACK)
{
currentState = AnimationState::ACTION_IDLE;
resetAnim = true;
attack = 0;
}
}
if (static_cast<int>(anim.currentFrame) != anim.lastFrame) {
anim.model.Interpolate(static_cast<int>(anim.currentFrame));
anim.lastFrame = static_cast<int>(anim.currentFrame);
+12 -4
View File
@@ -12,8 +12,12 @@
namespace ZL {
enum class AnimationState {
IDLE = 0,
WALK = 1
STAND = 0,
WALK = 1,
STAND_TO_ACTION = 2,
ACTION_ATTACK = 3,
ACTION_IDLE = 4,
ACTION_TO_STAND = 5
};
class Character {
@@ -47,6 +51,11 @@ public:
std::string npcName;
bool giftReceived = false;
int battle_state = 0;
bool resetAnim = false;
int attack = 0;
AnimationState currentState = AnimationState::STAND;
private:
struct AnimationData {
BoneSystem model;
@@ -57,8 +66,7 @@ private:
};
std::map<AnimationState, AnimationData> animations;
AnimationState currentState = AnimationState::IDLE;
std::shared_ptr<Texture> texture;
std::shared_ptr<Texture> texture;
Eigen::Vector3f walkTarget = Eigen::Vector3f(0.f, 0.f, 0.f);
float targetFacingAngle = 0.0f;
+41 -13
View File
@@ -154,19 +154,26 @@ namespace ZL
// Load interactive objects
interactiveObjects = GameObjectLoader::loadAndCreateInteractiveObjects("resources/config2/gameobjects.json", renderer, CONST_ZIP_FILE);
auto violaTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/viola.png", CONST_ZIP_FILE));
auto violaTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/gg/IMG_20260413_182354_992.png", CONST_ZIP_FILE));
// Player (Viola)
player = std::make_unique<Character>();
player->loadAnimation(AnimationState::IDLE, "resources/idleviola_uv010.txt", CONST_ZIP_FILE);
player->loadAnimation(AnimationState::WALK, "resources/walkviola_uv010.txt", CONST_ZIP_FILE);
player->loadAnimation(AnimationState::STAND, "resources/w/gg/gg_stand_idle001.txt", CONST_ZIP_FILE);
player->loadAnimation(AnimationState::WALK, "resources/w/gg/gg_walking001.txt", CONST_ZIP_FILE);
player->loadAnimation(AnimationState::STAND_TO_ACTION, "resources/w/gg/gg_stand_to_action002.txt", CONST_ZIP_FILE);
player->loadAnimation(AnimationState::ACTION_ATTACK, "resources/w/gg/gg_action_attack001.txt", CONST_ZIP_FILE);
player->loadAnimation(AnimationState::ACTION_IDLE, "resources/w/gg/gg_action_idle001.txt", CONST_ZIP_FILE);
player->loadAnimation(AnimationState::ACTION_TO_STAND, "resources/w/gg/gg_action_to_stand001.txt", CONST_ZIP_FILE);
player->setTexture(violaTexture);
player->walkSpeed = 3.0f;
player->rotationSpeed = 8.0f;
player->modelScale = 0.12f;
player->modelCorrectionRotation =
Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5f, Eigen::Vector3f::UnitX())) *
Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitZ()));
player->modelScale = 1.f;
player->modelCorrectionRotation = Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitY()));
//Eigen::Quaternionf::Identity();
/*Eigen::Quaternionf(Eigen::AngleAxisf(-M_PI * 0.5f, Eigen::Vector3f::UnitX())) * */
/*Eigen::Quaternionf(Eigen::AngleAxisf(M_PI, Eigen::Vector3f::UnitZ()));*/
std::cout << "Load resurces step 9" << std::endl;
@@ -178,9 +185,9 @@ namespace ZL
auto defaultTexture = std::make_shared<Texture>(CreateTextureDataFromPng("resources/w/default_skin001.png", CONST_ZIP_FILE));
auto npc01 = std::make_unique<Character>();
npc01->loadAnimation(AnimationState::IDLE, "resources/w/default_idle002.txt", CONST_ZIP_FILE);
npc01->loadAnimation(AnimationState::STAND, "resources/w/default_idle002.txt", CONST_ZIP_FILE);
npc01->loadAnimation(AnimationState::WALK, "resources/w/default_walk001.txt", CONST_ZIP_FILE);
//npc01->loadAnimation(AnimationState::IDLE, "resources/idleviola_uv010.txt", CONST_ZIP_FILE);
//npc01->loadAnimation(AnimationState::STAND, "resources/idleviola_uv010.txt", CONST_ZIP_FILE);
//npc01->loadAnimation(AnimationState::WALK, "resources/walkviola_uv010.txt", CONST_ZIP_FILE);
npc01->setTexture(defaultTexture);
npc01->walkSpeed = 1.5f;
@@ -198,9 +205,9 @@ namespace ZL
std::cout << "Load resurces step 11" << std::endl;
auto npc02 = std::make_unique<Character>();
npc02->loadAnimation(AnimationState::IDLE, "resources/w/default_float001.txt", CONST_ZIP_FILE);
//npc02->loadAnimation(AnimationState::IDLE, "resources/w/float_attack003.txt", CONST_ZIP_FILE);
//npc02->loadAnimation(AnimationState::IDLE, "resources/idleviola_uv010.txt", CONST_ZIP_FILE);
npc02->loadAnimation(AnimationState::STAND, "resources/w/default_float001.txt", CONST_ZIP_FILE);
//npc02->loadAnimation(AnimationState::STAND, "resources/w/float_attack003.txt", CONST_ZIP_FILE);
//npc02->loadAnimation(AnimationState::STAND, "resources/idleviola_uv010.txt", CONST_ZIP_FILE);
npc02->setTexture(ghostTexture);
npc02->walkSpeed = 1.5f;
npc02->rotationSpeed = 8.0f;
@@ -669,7 +676,11 @@ namespace ZL
float t = -camPos.y() / rayDir.y();
Eigen::Vector3f hit = camPos + rayDir * t;
std::cout << "[CLICK] Clicked on ground at: (" << hit.x() << ", " << hit.z() << ")" << std::endl;
player->setTarget(Eigen::Vector3f(hit.x(), 0.f, hit.z()));
if (player->currentState == AnimationState::STAND || player->currentState == AnimationState::WALK)
{
player->setTarget(Eigen::Vector3f(hit.x(), 0.f, hit.z()));
}
}
else {
std::cout << "[CLICK] No valid target found" << std::endl;
@@ -739,6 +750,23 @@ namespace ZL
dialogueSystem.startDialogue("test_cutscene_dialogue");
break;
case SDLK_p:
if (player->battle_state == 0)
{
player->battle_state = 1;
}
else
{
player->battle_state = 0;
}
break;
case SDLK_l:
if (player->attack == 0)
{
player->attack = 1;
}
break;
case SDLK_RETURN:
default:
+1 -1
View File
@@ -331,7 +331,7 @@ namespace ZL {
// Load animations
try {
npc->loadAnimation(AnimationState::IDLE, npcData.animationIdlePath, zipPath);
npc->loadAnimation(AnimationState::STAND, npcData.animationIdlePath, zipPath);
std::cout << " Loaded IDLE animation: " << npcData.animationIdlePath << std::endl;
}
catch (const std::exception& e) {