Working on battle animation
This commit is contained in:
parent
422ff1fbe3
commit
493eb5a5d7
BIN
resources/w/Zombie_BaseColor.png
(Stored with Git LFS)
Normal file
BIN
resources/w/Zombie_BaseColor.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
resources/w/gg/IMG_20260413_182354_992.png
(Stored with Git LFS)
Normal file
BIN
resources/w/gg/IMG_20260413_182354_992.png
(Stored with Git LFS)
Normal file
Binary file not shown.
109258
resources/w/gg/gg_action_attack001.txt
Normal file
109258
resources/w/gg/gg_action_attack001.txt
Normal file
File diff suppressed because it is too large
Load Diff
101964
resources/w/gg/gg_action_idle001.txt
Normal file
101964
resources/w/gg/gg_action_idle001.txt
Normal file
File diff suppressed because it is too large
Load Diff
99359
resources/w/gg/gg_action_to_stand001.txt
Normal file
99359
resources/w/gg/gg_action_to_stand001.txt
Normal file
File diff suppressed because it is too large
Load Diff
214500
resources/w/gg/gg_stand_idle001.txt
Normal file
214500
resources/w/gg/gg_stand_idle001.txt
Normal file
File diff suppressed because it is too large
Load Diff
105611
resources/w/gg/gg_stand_to_action002.txt
Normal file
105611
resources/w/gg/gg_stand_to_action002.txt
Normal file
File diff suppressed because it is too large
Load Diff
100401
resources/w/gg/gg_walking001.txt
Normal file
100401
resources/w/gg/gg_walking001.txt
Normal file
File diff suppressed because it is too large
Load Diff
215505
resources/w/zombie_idle001.txt
Normal file
215505
resources/w/zombie_idle001.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -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,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;
|
||||
|
||||
54
src/Game.cpp
54
src/Game.cpp
@ -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:
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user