从QuickDraw项目入门,制作一个简单的2D小游戏2
一.类继承
继续上一次的工作,在内容浏览器中右键Samurai类,创建派生自Samurai类的C++类,并将其命名为Samurai_Player。
然后进行同样的操作,创建一个名为Samurai_NPC的派生类。
创建一个名为BP_Samurai_Player的蓝图类,并替换原先的BP_Samurai实例,最后删除蓝图类BP_Samurai。
替换完后需要重新设置一下变量参数,再把这个实例名字改成Samurai_Player
再创建一个基于Samurai_NPC的蓝图类,命名为BP_Samurai_NPC,相同的,在场景中创建一个它的实例,命名为Samurai_NPC。
设定这个实例的滑动参数
设定这个实例用到的精灵
二.感叹号精灵
新建一个C++类,父类选择Actor
命名为Exclamation,然后在Exclamation.h里这样写
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
//Paper2D的部分头文件
#include "PaperFlipbookComponent.h"
#include "PaperSpriteComponent.h"
#include "Exclamation.generated.h"
UCLASS()
class QUICKDRAW_API AExclamation : public AActor
{
GENERATED_BODY()
public:
AExclamation();
//精灵组件,赋予Samurai类有形实体
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TObjectPtr<UPaperSpriteComponent> SpriteComponent;
protected:
virtual void BeginPlay() override;
public:
virtual void Tick(float DeltaTime) override;
//控制组件是否可见
UFUNCTION()
void SetVisibility(bool IsVisible);
};
在Exclamation.cpp中这样写
#include "Exclamation.h"
AExclamation::AExclamation()
{
PrimaryActorTick.bCanEverTick = true;
//创建精灵组件,并将其作为根组件
this->SpriteComponent = CreateDefaultSubobject<UPaperSpriteComponent>(TEXT("T_Exclamation_Sprite"));
this->SpriteComponent->SetupAttachment(this->RootComponent);
}
void AExclamation::BeginPlay()
{
Super::BeginPlay();
//游戏开始时不可见
this->SetVisibility(false);
}
void AExclamation::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AExclamation::SetVisibility(bool IsVisible)
{
this->SpriteComponent->SetVisibility(IsVisible);
}
然后基于这个C++类新建一个蓝图类,命名为BP_Exclamation
在关卡中创建一个该蓝图类的实例,再进行编辑,选择精灵和材质,不要忘记将透明排序设置为1
最后把这个实例放到地图中间位置
三.游戏模式实现
创建一个基于GameMode的C++类,命名为GM_Duel
GM_Duel.h中这样实现
#pragma once
#include "CoreMinimal.h"
#include "Exclamation.h"
#include "GameFramework/GameMode.h"
#include "GM_Duel.generated.h"
//枚举类
UENUM(BlueprintType)
enum class E_Phase : uint8
{
Intro UMETA(DisplayName = "Intro"),
Wait UMETA(DisplayName = "Wait"),
Draw UMETA(DisplayName = "Draw"),
Finished UMETA(DisplayName = "Finished")
};
UCLASS()
class QUICKDRAW_API AGM_Duel : public AGameMode
{
GENERATED_BODY()
public:
//统计游戏开始时长
UPROPERTY(EditAnywhere, BlueprintReadWrite)
double ElapsedTime;
//Draw阶段最小开始时间
UPROPERTY(EditAnywhere, BlueprintReadWrite)
double MinDrawStartTime = 2.0;
//Draw阶段最大开始时间
UPROPERTY(EditAnywhere, BlueprintReadWrite)
double MaxDrawStartTime = 5.0;
//标识目前游戏阶段
E_Phase Phase = E_Phase::Intro;
//感叹号组件的指针
TObjectPtr<AActor> Exclamation;
//游戏开始的时间,用于游戏阶段变更
double StartTime = 1.0;
//游戏开始时执行
virtual void BeginPlay() override;
//每帧处理
virtual void Tick(float DeltaTime) override;
//从wait阶段转化到draw阶段
UFUNCTION(BlueprintCallable)
void TransWaitToDraw();
};
GM_Duel.cpp中这样实现
#include "GM_Duel.h"
#include "Kismet/GameplayStatics.h"
#include <Kismet/KismetSystemLibrary.h>
void AGM_Duel::BeginPlay()
{
//游戏开始时取得第一个Exclamation类的实例的指针
this->Exclamation = UGameplayStatics::GetActorOfClass(this->GetWorld(), AExclamation::StaticClass());
}
void AGM_Duel::Tick(float DeltaTime)
{
this->ElapsedTime += DeltaTime;
//GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Green, FString::Printf(TEXT("%f"), this->ElapsedTime));
switch (this->Phase)
{
case E_Phase::Intro:
{
//在intro阶段,等两个精灵滑动结束后,切换到wait阶段,然后延迟一段时间转进draw阶段
if (this->ElapsedTime >= this->StartTime)
{
this->Phase = E_Phase::Wait;
FLatentActionInfo LatentAction(0, FMath::Rand(), TEXT("TransWaitToDraw"), this);
UKismetSystemLibrary::Delay(this, FMath::FRandRange(MinDrawStartTime, MaxDrawStartTime), LatentAction);
}
break;
}
case E_Phase::Wait:
{
break;
}
case E_Phase::Draw:
{
//GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Green, FString::Printf(TEXT("draw %i"), this->Phase));
if (this->Exclamation != NULL)
{
//假如指针有效,将一个指向Exclamation类的指针指向他,然后设置可见性为true
AExclamation* tem = Cast<AExclamation>(this->Exclamation);
tem->SetVisibility(true);
}
break;
}
case E_Phase::Finished:
{
//GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Green, FString::Printf(TEXT("Finished %i"), this->Phase));
break;
}
default:
{
break;
}
}
}
void AGM_Duel::TransWaitToDraw()
{
this->Phase = E_Phase::Draw;
//GEngine->AddOnScreenDebugMessage(-1, 1.0f, FColor::Green, FString::Printf(TEXT("TransWaitToDraw %i"), this->Phase));
}
编译保存一下之后来到项目设置
在地图模式中,设置游戏模式和地图
之后再次运行游戏能看到感叹号精灵在Draw阶段被绘制,而在其他阶段不可见