feat(角色): 添加角色阴影渲染功能

新增 CharacterShadowActor 类用于处理角色阴影的渲染
在 CharacterObject 中实现阴影的同步和渲染逻辑
移除 GameDebugActor 中不再使用的合成纹理预览代码
添加 EnsureCompositeTextureReady 方法确保纹理准备就绪
This commit is contained in:
2026-04-07 07:08:53 +08:00
parent 808431f92c
commit e570fec599
12 changed files with 259 additions and 218 deletions

View File

@@ -51,6 +51,7 @@ public:
animation::AniFrame GetCurrentFrameInfo() const;
void SetActionFrameFlagCallback(ActionFrameFlagCallback callback);
void SetActionEndCallback(ActionEndCallback callback);
bool EnsureCompositeTextureReady();
bool HasCompositeTexture() const;
Ptr<Texture> GetCompositeTexture() const;
Vec2 GetCompositeTextureSize() const;

View File

@@ -5,6 +5,7 @@
#include "character/CharacterDataLoader.h"
#include "character/CharacterEquipmentManager.h"
#include "character/CharacterInputRouter.h"
#include "character/CharacterShadowActor.h"
#include "character/CharacterStateMachine.h"
#include <frostbite2D/2d/actor.h>
#include <frostbite2D/event/event.h>
@@ -31,7 +32,7 @@ class GameMap;
class CharacterObject : public Actor {
public:
CharacterObject() = default;
~CharacterObject() override = default;
~CharacterObject() override;
/// @brief 二段初始化角色。
/// @param jobId 职业 id用来加载职业配置、动作定义和动画资源。
@@ -77,7 +78,10 @@ public:
///
/// 顺序固定为:命令缓冲推进 -> 采样实时输入 -> 生成意图 -> 状态机更新
/// -> motor 推进 -> 投影到 Actor 坐标。
void Update(float deltaTime) override;
void OnUpdate(float deltaTime) override;
void OnAdded(Actor* parent) override;
void PrepareRenderFrame();
/// @brief 统一输入入口。
///
@@ -182,6 +186,9 @@ private:
void ApplyMapMovementConstraints(const CharacterWorldPosition& previousPosition);
void QueueMapTransitionIfNeeded();
void SyncActorPositionFromWorld();
void SyncShadowAttachment();
void SyncShadowPresentation();
void DetachShadowActor();
bool SetActionStrict(const std::string& actionName,
const char* phase,
const std::string& requestedActionId);
@@ -238,6 +245,10 @@ private:
/// 真正负责播放角色分层动画的 Actor 子节点。
RefPtr<CharacterAnimation> animationManager_ = nullptr;
/// ???? normal ???????????
RefPtr<CharacterShadowActor> shadowActor_ = nullptr;
GameMap* shadowAttachedMap_ = nullptr;
/// 缓存上一帧 deltaTime方便状态和脚本系统查询。
float lastDeltaTime_ = 0.0f;

View File

@@ -0,0 +1,32 @@
#pragma once
#include <frostbite2D/2d/sprite.h>
namespace frostbite2D {
struct CharacterShadowFrameSnapshot {
bool visible = false;
Ptr<Texture> texture = nullptr;
Vec2 textureSize = Vec2::Zero();
Vec2 groundAnchorInTexture = Vec2::Zero();
Vec2 groundScreenPosition = Vec2::Zero();
int zOrder = 0;
uint64 textureVersion = 0;
};
class CharacterShadowActor : public Sprite {
public:
CharacterShadowActor();
void ApplyFrameSnapshot(const CharacterShadowFrameSnapshot& snapshot);
private:
void ApplyTextureState(const CharacterShadowFrameSnapshot& snapshot);
Ptr<Texture> appliedTexture_ = nullptr;
Vec2 appliedTextureSize_ = Vec2::Zero();
Vec2 appliedGroundAnchorInTexture_ = Vec2::Zero();
uint64 appliedTextureVersion_ = 0;
};
} // namespace frostbite2D

View File

@@ -1,14 +1,11 @@
#pragma once
#include <frostbite2D/2d/actor.h>
#include <frostbite2D/2d/sprite.h>
namespace frostbite2D {
class CharacterObject;
class GameMap;
class NineSliceActor;
class Sprite;
class TextSprite;
/**
@@ -36,10 +33,6 @@ private:
void initOverlay();
void updateOverlay();
void updateMapDebugHighlight();
void updateCompositePreview();
Vec2 computeScreenMatchedPreviewSize(const Vec2& textureSize) const;
void updateCompositePreviewMarker(const Vec2& textureSize, const Vec2& previewSize,
const Vec2& originInTexture);
void setOverlayVisible(bool visible);
GameDebugActor();
@@ -50,12 +43,6 @@ private:
RefPtr<NineSliceActor> background_;
RefPtr<TextSprite> coordText_;
RefPtr<TextSprite> actionText_;
RefPtr<TextSprite> compositeText_;
RefPtr<Sprite> compositePreview_;
RefPtr<Actor> compositeOriginMarker_;
CharacterObject* previewCharacter_ = nullptr;
uint64 previewCompositeVersion_ = 0;
bool previewTextureAvailable_ = false;
};
} // namespace frostbite2D

View File

@@ -30,9 +30,11 @@ public:
/// 地图进入场景后的初始化入口,目前主要负责音乐播放。
void Enter();
void Update(float deltaTime) override;
void Render() override;
/// 将运行时对象挂到 normal 层,并按 y 值设置基础排序。
void AddObject(RefPtr<Actor> object);
void AddObjectToLayer(const std::string& layerName, RefPtr<Actor> object);
/// 返回地图推荐的默认相机关注点。
Vec2 GetDefaultCameraFocus() const;
@@ -75,6 +77,7 @@ private:
void InitMoveArea();
/// 将各层转换到屏幕空间;远景层在这里做视差滚动。
void updateLayerPositions(const Vec2& cameraFocus);
void PrepareRuntimeObjectsForRender();
/// 原始地图配置,作为运行时装配地图内容的输入。
game::MapConfig mapConfig_;