从QuickDraw项目入门,制作一个简单的2D小游戏5

一.攻击精灵延后切换
在之前的工作中,当感叹号显示时,按下攻击键,精灵会直接切换到攻击状态,现在开始做一些设置,让切换的动作在攻击滑动后的一定时间后发生。打开VS,在Samurai.h中,对Samurai类追加成员变量和成员函数

public:
	//时间轴时间,动态委托,用于切换攻击姿态
	FOnTimelineEvent TimelineSwitchToAttackSpriteEvent;

	//和时间轴委托绑定的执行函数
	UFUNCTION()
	void TimelineSwitchToAttackSprite();

在Samurai.cpp中进行实现,以及对之前的实现进行修改

void ASamurai::Attack()
{
	if (this->isAttackPressed)
		return;
	this->isAttackPressed = true;

	if (GameMode)
	{
		switch (GameMode->Phase)
		{
		case E_Phase::Wait:
			SetCrossVisbility(true);
			break;

		case E_Phase::Draw:
			AttackSlide();
			break;
		
		default:
			break;
		}
	}
}

void ASamurai::TimelineSwitchToAttackSprite()
{
	//直接更换精灵原,因此不需要再向视频中那样再切换材质
	SpriteComponent->SetSprite(AttackSprite);
}

void ASamurai::AttackSlide()
{
	//初始化攻击滑动的起始位置
	AttackSlideStartPos = this->GetActorLocation();
	//与之前滑动的设定函数含义相当
	AttackSlideStartDelegate.BindUFunction(this, TEXT("AttackSlideStart"));
	
	AttackTimeline->SetPlayRate(2);
	AttackTimeline->AddInterpFloat(AttackCurveFloat, AttackSlideStartDelegate);
	AttackTimeline->SetLooping(false);
	AttackTimeline->PlayFromStart();

	//委托绑定
	TimelineSwitchToAttackSpriteEvent.BindUFunction(this, FName("TimelineSwitchToAttackSprite"));
	//在0.4秒的时候执行切换
	AttackTimeline->AddEvent(0.4, TimelineSwitchToAttackSpriteEvent);
}

二.被打倒后的效果
被打倒后,叉字精灵就不该显示了,然后精灵应该被切换到被打倒的那个
先到Samurai.h中,给Samurai类增加成员变量和成员函数

public:
	//战败时的精灵
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TObjectPtr<UPaperSprite> DefeatedSprite;

	//被打败时做的动作
	UFUNCTION()
	void Defeated();

在Samurai.cpp中实现,并对之前的实现做修改

void ASamurai::Attack()
{
	if (this->isAttackPressed)
		return;
	this->isAttackPressed = true;

	if (GameMode)
	{
		switch (GameMode->Phase)
		{
		case E_Phase::Intro:
			SetCrossVisbility(true);
			break;

		case E_Phase::Wait:
			SetCrossVisbility(true);
			break;

		case E_Phase::Draw:
			AttackSlide();
			//攻击完成后进入结束阶段
			GameMode->Phase = E_Phase::Finished;
			break;
		
		default:
			break;
		}
	}
}

void ASamurai::TimelineSwitchToAttackSprite()
{
	//直接更换精灵原,因此不需要再向视频中那样再切换材质
	SpriteComponent->SetSprite(AttackSprite);

	//攻击的角色切换到攻击姿态时,再将对手角色切换到被击败姿态
	GameMode->AttackSuccessfully(this->IsPlayerControlled());
}

void ASamurai::Defeated()
{
	this->SetCrossVisbility(false);
	SpriteComponent->SetSprite(DefeatedSprite);
}

切换到GM_Duel.h中,增加成员变量

public:
	//攻击成功执行的
	UFUNCTION()
	void AttackSuccessfully(bool isPlayer);

避免循环依赖报错,在GM_Duel.cpp中包含需要用到的头文件,并且进行函数的实现

//避免循环依赖,在这里追加头文件
#include "Samurai_NPC.h"
#include "Samurai_Player.h"

void AGM_Duel::AttackSuccessfully(bool isPlayer)
{
	ASamurai_Player* SamuraiPlayer = Cast<ASamurai_Player>(UGameplayStatics::GetActorOfClass(this->GetWorld(), ASamurai_Player::StaticClass()));
	ASamurai_NPC* SamuraiNPC = Cast<ASamurai_NPC>(UGameplayStatics::GetActorOfClass(this->GetWorld(), ASamurai_NPC::StaticClass()));
	if (isPlayer)
	{
		SamuraiNPC->Defeated();
	}
	else
	{
		SamuraiPlayer->Defeated();
	}

	//因为攻击判定成功了,因此将感叹号置为不可见状态
	if (this->Exclamation != NULL)
	{
		AExclamation* tem = Cast<AExclamation>(this->Exclamation);
		tem->SetVisibility(false);
	}
}

然后返回到编辑器,编辑Samurai_NPC类的实例,选择被击败姿态的精灵

posted @ 2025-03-20 16:02  SuzumiyaYui  阅读(19)  评论(0)    收藏  举报