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