feat(npc): 添加NPC交互高亮效果及复合纹理支持
实现NPC交互时的绿色高亮效果,通过InteractionHighlightSprite类实现 重构NpcAnimation支持复合纹理渲染,优化高亮效果的性能 添加ShaderManager获取所有加载Shader的方法,优化渲染器uniform更新逻辑
This commit is contained in:
@@ -42,10 +42,13 @@ bool NpcObject::Construction(int npcId) {
|
||||
worldPosition_ = CharacterWorldPosition();
|
||||
config_.reset();
|
||||
animation_ = nullptr;
|
||||
interactionHighlight_ = nullptr;
|
||||
nameOutlineLabels_.fill(nullptr);
|
||||
nameLabel_ = nullptr;
|
||||
interactable_ = true;
|
||||
interacting_ = false;
|
||||
interactionHighlighted_ = false;
|
||||
syncedHighlightCompositeVersion_ = 0;
|
||||
|
||||
auto config = npc::loadNpcConfig(npcId);
|
||||
if (!config) {
|
||||
@@ -68,11 +71,13 @@ bool NpcObject::Construction(int npcId) {
|
||||
config_ = *config;
|
||||
npcId_ = npcId;
|
||||
animation_ = animation;
|
||||
EnsureInteractionHighlight();
|
||||
AddChild(animation_);
|
||||
EnsureNameLabel();
|
||||
|
||||
SetWorldPosition({});
|
||||
SetDirection(1);
|
||||
SetInteractionHighlighted(false);
|
||||
RefreshNameLabel();
|
||||
SDL_Log("NpcObject: npc %d construction complete", npcId_);
|
||||
return true;
|
||||
@@ -84,6 +89,7 @@ void NpcObject::SetDirection(int direction) {
|
||||
animation_->SetDirection(direction_);
|
||||
}
|
||||
RefreshNameLabel();
|
||||
SyncInteractionHighlight();
|
||||
}
|
||||
|
||||
void NpcObject::SetNpcPosition(const Vec2& pos) {
|
||||
@@ -108,6 +114,19 @@ void NpcObject::SetInteractable(bool interactable) {
|
||||
}
|
||||
}
|
||||
|
||||
void NpcObject::SetInteractionHighlighted(bool highlighted) {
|
||||
if (interactionHighlighted_ == highlighted) {
|
||||
SyncInteractionHighlight();
|
||||
return;
|
||||
}
|
||||
|
||||
interactionHighlighted_ = highlighted;
|
||||
if (!interactionHighlighted_) {
|
||||
syncedHighlightCompositeVersion_ = 0;
|
||||
}
|
||||
SyncInteractionHighlight();
|
||||
}
|
||||
|
||||
void NpcObject::BeginInteract() {
|
||||
if (CanInteract()) {
|
||||
interacting_ = true;
|
||||
@@ -144,6 +163,19 @@ bool NpcObject::IsAnimationFinished() const {
|
||||
|
||||
void NpcObject::Update(float deltaTime) {
|
||||
Actor::Update(deltaTime);
|
||||
SyncInteractionHighlight();
|
||||
}
|
||||
|
||||
void NpcObject::EnsureInteractionHighlight() {
|
||||
if (interactionHighlight_) {
|
||||
return;
|
||||
}
|
||||
|
||||
interactionHighlight_ = MakePtr<InteractionHighlightSprite>();
|
||||
interactionHighlight_->SetZOrder(-1);
|
||||
interactionHighlight_->SetPosition(0.0f, 0.0f);
|
||||
interactionHighlight_->SetVisible(false);
|
||||
AddChild(interactionHighlight_);
|
||||
}
|
||||
|
||||
void NpcObject::EnsureNameLabel() {
|
||||
@@ -206,6 +238,38 @@ void NpcObject::RefreshNameLabel() {
|
||||
}
|
||||
}
|
||||
|
||||
void NpcObject::SyncInteractionHighlight() {
|
||||
if (!interactionHighlight_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!interactionHighlighted_ || !animation_ ||
|
||||
!animation_->EnsureCompositeTextureReady() ||
|
||||
!animation_->HasCompositeTexture()) {
|
||||
interactionHighlight_->SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
uint64 compositeVersion = animation_->GetCompositeVersion();
|
||||
if (syncedHighlightCompositeVersion_ != compositeVersion) {
|
||||
Ptr<Texture> compositeTexture = animation_->GetCompositeTexture();
|
||||
Vec2 compositeSize = animation_->GetCompositeTextureSize();
|
||||
if (!compositeTexture || compositeSize.x <= 0.0f || compositeSize.y <= 0.0f) {
|
||||
interactionHighlight_->SetVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
interactionHighlight_->SetTexture(compositeTexture);
|
||||
interactionHighlight_->SetSize(compositeSize);
|
||||
interactionHighlight_->SetGroundAnchorInTexture(
|
||||
animation_->GetCompositeGroundAnchorInTexture());
|
||||
interactionHighlight_->SetPosition(0.0f, 0.0f);
|
||||
syncedHighlightCompositeVersion_ = compositeVersion;
|
||||
}
|
||||
|
||||
interactionHighlight_->SetVisible(true);
|
||||
}
|
||||
|
||||
void NpcObject::SyncActorPositionFromWorld() {
|
||||
SetPosition(worldPosition_.ToScreenPosition());
|
||||
SetZOrder(worldPosition_.y);
|
||||
|
||||
Reference in New Issue
Block a user