Files
Frostbite2D/Game/include/character/CharacterAnimation.h
Lenheart e570fec599 feat(角色): 添加角色阴影渲染功能
新增 CharacterShadowActor 类用于处理角色阴影的渲染
在 CharacterObject 中实现阴影的同步和渲染逻辑
移除 GameDebugActor 中不再使用的合成纹理预览代码
添加 EnsureCompositeTextureReady 方法确保纹理准备就绪
2026-04-07 07:08:53 +08:00

100 lines
3.7 KiB
C++

#pragma once
#include "character/CharacterDataLoader.h"
#include "character/CharacterEquipmentManager.h"
#include <frostbite2D/2d/actor.h>
#include <frostbite2D/2d/canvas_actor.h>
#include <frostbite2D/animation/animation.h>
#include <frostbite2D/base/RefPtr.h>
#include <functional>
#include <map>
#include <string>
#include <unordered_set>
#include <vector>
namespace frostbite2D {
class CharacterObject;
class CharacterAnimation : public Actor {
public:
using ActionAnimationList = std::map<std::string, std::vector<RefPtr<Animation>>>;
using ActionFrameFlagCallback = std::function<void(int)>;
using ActionEndCallback = std::function<void()>;
struct CompositeFrameInfo {
bool valid = false;
Rect localBounds;
Vec2 originInTexture = Vec2::Zero();
Vec2 groundAnchorInTexture = Vec2::Zero();
int width = 1;
int height = 1;
};
bool Init(CharacterObject* parent,
const character::CharacterConfig& config,
const CharacterEquipmentManager& equipmentManager);
void Update(float deltaTime) override;
void Render() override;
bool SetAction(const std::string& actionName);
void SetDirection(int direction);
const std::string& GetCurrentAction() const { return currentActionTag_; }
bool HasAction(const std::string& actionName) const {
return actionAnimations_.count(actionName) > 0;
}
std::string DescribeAvailableActions() const;
bool IsCurrentActionFinished() const;
int GetCurrentFrameIndex() const;
int GetCurrentFrameCount() const;
float GetCurrentNormalizedProgress() const;
animation::AniFrame GetCurrentFrameInfo() const;
void SetActionFrameFlagCallback(ActionFrameFlagCallback callback);
void SetActionEndCallback(ActionEndCallback callback);
bool EnsureCompositeTextureReady();
bool HasCompositeTexture() const;
Ptr<Texture> GetCompositeTexture() const;
Vec2 GetCompositeTextureSize() const;
Vec2 GetCompositeOriginInTexture() const;
Vec2 GetCompositeGroundAnchorInTexture() const;
uint64 GetCompositeVersion() const { return compositeVersion_; }
private:
static std::string FormatImgPath(std::string path, Animation::ReplaceData data);
Animation* GetPrimaryAnimation(const std::string& actionName) const;
Animation* GetCurrentPrimaryAnimation() const;
void RefreshRuntimeCallbacks();
bool shouldSkipMissingAnimation(const std::string& aniPath);
void BuildCompositeActionFrames();
CompositeFrameInfo ComputeCompositeFrameInfo(const std::vector<RefPtr<Animation>>& animations,
int direction) const;
CompositeFrameInfo GetCurrentCompositeFrameInfo() const;
uint64 CaptureCurrentRenderSignature() const;
void MarkCompositeDirty();
void UpdateCompositeCamera();
void RefreshCompositeTextureIfNeeded();
void RenderCurrentActionToCompositeCanvas();
void CreateAnimationBySlot(const std::string& actionName,
const std::string& slotName,
const std::string& actionPath,
const character::CharacterConfig& config,
const CharacterEquipmentManager& equipmentManager);
CharacterObject* parent_ = nullptr;
ActionAnimationList actionAnimations_;
std::string currentActionTag_;
int direction_ = 1;
ActionFrameFlagCallback actionFrameFlagCallback_;
ActionEndCallback actionEndCallback_;
std::unordered_set<std::string> missingAnimationPaths_;
size_t skippedMissingAnimationCount_ = 0;
RefPtr<CanvasActor> compositeCanvas_ = nullptr;
std::map<std::string, CompositeFrameInfo> compositeFrameInfoByAction_;
bool compositeDirty_ = true;
uint64 compositeVersion_ = 0;
uint64 lastCompositeSignature_ = 0;
};
} // namespace frostbite2D