Working on battle animation
This commit is contained in:
1 parent
422ff1fbe3
commit
493eb5a5d7
13 files changed
+946723
-25
No files matched your search
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+65
-7
@@ -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
-4
@@ -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;
|
||||||
|
|||||||
+41
-13
@@ -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) {
|
||||||
|
|||||||
Reference in new issue
Block a user