107 lines
3.6 KiB
C
107 lines
3.6 KiB
C
|
|
#pragma once
|
|||
|
|
|
|||
|
|
#include <easy2d/core/types.h>
|
|||
|
|
#include <easy2d/animation/animation_clip.h>
|
|||
|
|
#include <easy2d/animation/interpolation_engine.h>
|
|||
|
|
#include <functional>
|
|||
|
|
#include <string>
|
|||
|
|
|
|||
|
|
namespace easy2d {
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// 动画播放状态
|
|||
|
|
// ============================================================================
|
|||
|
|
enum class AnimPlayState : uint8 {
|
|||
|
|
Stopped,
|
|||
|
|
Playing,
|
|||
|
|
Paused
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// AnimationController - 动画播放控制器
|
|||
|
|
// 借鉴 Cocos Creator 的 AnimationState:纯播放逻辑,不持有渲染资源
|
|||
|
|
// ============================================================================
|
|||
|
|
class AnimationController {
|
|||
|
|
public:
|
|||
|
|
// 回调类型定义
|
|||
|
|
using FrameChangeCallback = std::function<void(size_t oldIdx, size_t newIdx,
|
|||
|
|
const AnimationFrame& frame)>;
|
|||
|
|
using KeyframeCallback = std::function<void(int flagIndex)>;
|
|||
|
|
using SoundTriggerCallback = std::function<void(const std::string& path)>;
|
|||
|
|
using CompletionCallback = std::function<void()>;
|
|||
|
|
|
|||
|
|
AnimationController() = default;
|
|||
|
|
|
|||
|
|
// ------ 绑定动画数据 ------
|
|||
|
|
void setClip(Ptr<AnimationClip> clip);
|
|||
|
|
Ptr<AnimationClip> getClip() const { return clip_; }
|
|||
|
|
|
|||
|
|
// ------ 播放控制 ------
|
|||
|
|
void play();
|
|||
|
|
void pause();
|
|||
|
|
void resume();
|
|||
|
|
void stop();
|
|||
|
|
void reset();
|
|||
|
|
|
|||
|
|
// ------ 帧控制 ------
|
|||
|
|
void setFrameIndex(size_t index);
|
|||
|
|
void nextFrame();
|
|||
|
|
void prevFrame();
|
|||
|
|
|
|||
|
|
// ------ 核心更新(每帧调用)------
|
|||
|
|
void update(float dt);
|
|||
|
|
|
|||
|
|
// ------ 状态查询 ------
|
|||
|
|
AnimPlayState getState() const { return state_; }
|
|||
|
|
bool isPlaying() const { return state_ == AnimPlayState::Playing; }
|
|||
|
|
bool isPaused() const { return state_ == AnimPlayState::Paused; }
|
|||
|
|
bool isStopped() const { return state_ == AnimPlayState::Stopped; }
|
|||
|
|
|
|||
|
|
size_t getCurrentFrameIndex() const { return currentFrameIndex_; }
|
|||
|
|
size_t getTotalFrames() const;
|
|||
|
|
const AnimationFrame& getCurrentFrame() const;
|
|||
|
|
|
|||
|
|
float getPlaybackSpeed() const { return playbackSpeed_; }
|
|||
|
|
void setPlaybackSpeed(float speed) { playbackSpeed_ = speed; }
|
|||
|
|
|
|||
|
|
bool isLooping() const;
|
|||
|
|
void setLooping(bool loop);
|
|||
|
|
|
|||
|
|
// ------ 插值状态 ------
|
|||
|
|
float getInterpolationFactor() const { return interpolationFactor_; }
|
|||
|
|
bool isInterpolating() const { return interpolating_; }
|
|||
|
|
|
|||
|
|
// ------ 回调注册 ------
|
|||
|
|
void setFrameChangeCallback(FrameChangeCallback cb) { onFrameChange_ = std::move(cb); }
|
|||
|
|
void setKeyframeCallback(KeyframeCallback cb) { onKeyframe_ = std::move(cb); }
|
|||
|
|
void setSoundTriggerCallback(SoundTriggerCallback cb) { onSoundTrigger_ = std::move(cb); }
|
|||
|
|
void setCompletionCallback(CompletionCallback cb) { onComplete_ = std::move(cb); }
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
Ptr<AnimationClip> clip_;
|
|||
|
|
AnimPlayState state_ = AnimPlayState::Stopped;
|
|||
|
|
|
|||
|
|
size_t currentFrameIndex_ = 0;
|
|||
|
|
float accumulatedTime_ = 0.0f; // 当前帧已累积时间 (ms)
|
|||
|
|
float playbackSpeed_ = 1.0f;
|
|||
|
|
bool loopOverride_ = false; // 外部循环覆盖值
|
|||
|
|
bool hasLoopOverride_ = false; // 是否使用外部循环覆盖
|
|||
|
|
|
|||
|
|
// 插值状态
|
|||
|
|
bool interpolating_ = false;
|
|||
|
|
float interpolationFactor_ = 0.0f;
|
|||
|
|
|
|||
|
|
// 回调
|
|||
|
|
FrameChangeCallback onFrameChange_;
|
|||
|
|
KeyframeCallback onKeyframe_;
|
|||
|
|
SoundTriggerCallback onSoundTrigger_;
|
|||
|
|
CompletionCallback onComplete_;
|
|||
|
|
|
|||
|
|
// 内部方法
|
|||
|
|
void advanceFrame(size_t newIndex);
|
|||
|
|
void processFrameProperties(const AnimationFrame& frame);
|
|||
|
|
void updateInterpolation();
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
} // namespace easy2d
|