1.Demo介绍
1.游戏:玩家以第三人称俯视角控制战机与随机生成的敌机进行射击战斗,击落战机玩家获得分数,战机触碰敌机触发爆炸且游戏结束。
2.附件:
1.工程源码:GitHub - CNEarly/SpaceShipBattleDemo: 使用虚幻引擎C++开发Roguelike类型2D飞机大战Demo
2.演示视频:SpaceShipBattleDemo演示_单机游戏热门视频
3.内容:
1.移动:使用WSAD键控制战机上下左右移动
2.朝向:使用鼠标控制战机朝向
3.射击:使用鼠标左键控制战机开火
4.阵亡:玩家触碰敌机触发爆炸
5.生成:敌人在地图中随机生成
2.地图实现
1.材料:①大气雾②音效③阻挡体积④生成敌人蓝图⑤静态网格体⑥光源⑦玩家出生⑧天空球⑨天光⑩球体反射捕获
2.搭建:
3.战机实现
1.C++头文件:
//预处理
#pragma once//保证头文件只被编译一次
#include "CoreMinimal.h"//包含一套来自UE4核心编程环境的普遍存在类型
#include "GameFramework/Pawn.h"//在新建类的时候选择了以Pawn作为父类(所以这里保存的就是Pawn源代码的头文件)
#include "SpaceShip.generated.h"//与反射机制有关(必须放在所有头文件的最下方)
//前向声明
class USphereComponent;//球体碰撞
class UCameraComponent;//摄像机
class USpringArmComponent;//弹簧臂
class ABullet;//子弹类
class USoundCue;//音效
//战机类
UCLASS()
class SPACESHIPBATTLE_API ASpaceShip : public APawn
{
GENERATED_BODY()
public:
//构造函数声明
ASpaceShip();
protected:
//球体碰撞组件变量
UPROPERTY(VisibleAnywhere,Category="Component")
USphereComponent* CollisionComp;
//网格体组件变量
UPROPERTY(VisibleAnywhere, Category = "Component")
UStaticMeshComponent* ShipSM;
//摄像机组件变量
UPROPERTY(VisibleAnywhere, Category = "Component")
UCameraComponent* CameraComp;
//弹簧臂组件变量
UPROPERTY(VisibleAnywhere, Category = "Component")
USpringArmComponent* SpringArmComp;
//玩家控制器类变量
APlayerController* PC;
//子弹类型变量
UPROPERTY(EditAnywhere,Category="Fire")
TSubclassOf<ABullet> Bullet;
//子弹发射位置组件变量
UPROPERTY(VisibleAnywhere, Category = "Component")
USceneComponent* SpawnPoint;
//战机速度变量
UPROPERTY(EditAnywhere,Category="Move")
float Speed;
//射击间隔时间管理器变量
FTimerHandle TimerHandle_BetweenShot;
//游戏开始函数声明
virtual void BeginPlay() override;
//射击间隔变量
UPROPERTY(EditAnywhere, Category = "Fire")
float TimeBetweenShot;
//重启游戏时间管理器变量
FTimerHandle TimerHandle_Restart;
//阵亡音效变量
UPROPERTY(EditAnywhere,Category="Sound")
USoundCue* GameOverCue;
//射击音效变量
UPROPERTY(EditAnywhere, Category = "Sound")
USoundCue* ShootCue;
//推进粒子组件变量
UPROPERTY(VisibleAnywhere,Category="Component")
UParticleSystemComponent* ThrusterParticleComp;
//爆炸粒子变量
UPROPERTY(EditAnywhere,Category="Particle")
UParticleSystem* ExplosionParticle;
//阵亡变量(布尔)
bool bDead;
//上下移动变量(布尔)
bool bUpMove;
//左右移动变量(布尔)
bool bRightMove;
//朝向光标函数实现
void LookAtCursor();
//上下移动函数实现
void MoveUp(float Value);
//左右移动函数实现
void MoveRight(float Value);
//移动函数实现
void Move();
//开火函数声明
void Fire();
//开始开火函数声明
void StartFire();
//停止开火函数声明
void EndFire();
//重启关卡函数声明
void RestartLevel();
//阵亡函数声明
void OnDeath();
public:
//游戏每帧函数声明
virtual void Tick(float DeltaTime) override;
//玩家输入函数声明
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
//碰撞函数声明
virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;
//获取阵亡状态函数
FORCEINLINE bool GetBDead()
{
return bDead;//返回阵亡变量
}
};
2.C++源文件:
//预处理
#include "Public/SpaceShip.h"//战机类
#include "Components/StaticMeshComponent.h"//网格体组件
#include "Components/SphereComponent.h"//球体碰撞组件
#include "Camera/CameraComponent.h"//摄像机组件
#include "GameFramework/PlayerController.h"//玩家控制器
#include "Kismet/KismetMathLibrary.h"//数学库
#include "GameFramework/SpringArmComponent.h"//弹簧臂组件
#include "Public/Misc/App.h"//引擎处理
#include "Engine/World.h"//世界
#include "Public/Bullet.h"//子弹类头文件
#include "Public/Enemy.h"//敌人类头文件
#include "Kismet/GameplayStatics.h"//游戏状态
#include "TimerManager.h"//时间管理器
#include "Sound/SoundCue.h"//音效
#include "Particles/ParticleSystemComponent.h"//粒子特效组件
#include "Particles/ParticleSystem.h"//粒子特效
//构造函数实现
ASpaceShip::ASpaceShip()
{
PrimaryActorTick.bCanEverTick = true;//开启tick函数
CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionComp"));//实例化碰撞组件
RootComponent = CollisionComp;//碰撞组件设置为根组件
ShipSM = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ShipSM"));//实例化网格体组件
ShipSM->SetupAttachment(RootComponent);//网格体组件绑定根组件
SpringArmComp = CreateDefaultSubobject<USpringArmComponent>(TEXT("SpringArmComp"));//实例化弹簧臂组件
SpringArmComp->SetupAttachment(RootComponent);//弹簧臂组件绑定根组件
CameraComp = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComp"));//实例化摄像机组件
CameraComp->SetupAttachment(SpringArmComp);//摄像机组件绑定弹簧臂组件
SpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("SpawnPoint"));//实例化发射位置场景组件
SpawnPoint->SetupAttachment(ShipSM);//发射位置场景组件绑定网格体组件
ThrusterParticleComp = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("TrusterParticle"));//实例化推进器粒子组件
ThrusterParticleComp->SetupAttachment(RootComponent);//推进器粒子组件绑定根组件
Speed = 2500.0f;//设置速度
TimeBetweenShot = 0.2f;//设置发射间隔
bDead = false;//设置阵亡
}
//游戏开始函数实现
void ASpaceShip::BeginPlay()
{
Super::BeginPlay();
PC =Cast<APlayerController>(GetController());//用变量接收获取到的玩家控制器
PC->bShowMouseCursor = true;//控制开启显示光标
}
//朝向光标函数实现
void ASpaceShip::LookAtCursor()
{
FVector MouseLocation, MouseDirection;//光标位置和方向变量
PC->DeprojectMousePositionToWorld(MouseLocation,MouseDirection);//将光标位置投影到世界
FVector TargetLocation = FVector(MouseLocation.X, MouseLocation.Y, GetActorLocation().Z);//将光标位置投影到与战机共面
FRotator Rotator= UKismetMathLibrary::FindLookAtRotation(GetActorLocation(),TargetLocation);//计算旋转值
SetActorRotation(Rotator);//设置战机旋转
}
//上下移动函数实现
void ASpaceShip::MoveUp(float Value)
{
if (Value != 0)//上下移动传参非0
{
bUpMove = true;//上下移动为真
}
else//上下移动传参为0
{
bUpMove = false;//上下移动为假
}
AddMovementInput(FVector::ForwardVector,Value);//添加移动输入
}
//左右移动函数实现
void ASpaceShip::MoveRight(float Value)
{
if (Value != 0)//左右移动传参非0
{
bRightMove = true;//左右移动为真
}
else//左右移动传参为0
{
bRightMove = false;//左右移动为假
}
AddMovementInput(FVector::RightVector,Value);//添加移动输入
}
//移动函数实现
void ASpaceShip::Move()
{
AddActorWorldOffset(ConsumeMovementInputVector()*Speed*FApp::GetDeltaTime(), true);//获取一帧内移动的向量,在位置上增加增量
//FApp::GetDeltaTime();//获取一帧的时间
}
//开火函数实现
void ASpaceShip::Fire()
{
if (Bullet&&!bDead)//子弹为真且为阵亡
{
FActorSpawnParameters SpawnParams;//发射范围参数变量
GetWorld()->SpawnActor<ABullet>(Bullet, SpawnPoint->GetComponentLocation(), SpawnPoint->GetComponentRotation(), SpawnParams);//发射子弹类
if (ShootCue)//射击音效为真
{
UGameplayStatics::PlaySoundAtLocation(this, ShootCue, GetActorLocation());//播放射击音效
}
}
}
//开始开火函数实现
void ASpaceShip::StartFire()
{
GetWorldTimerManager().SetTimer(TimerHandle_BetweenShot, this, &ASpaceShip::Fire, TimeBetweenShot, true, 0.0f);//开火间隔定时器开启
}
//停止开火函数实现
void ASpaceShip::EndFire()
{
GetWorldTimerManager().ClearTimer(TimerHandle_BetweenShot);//开火间隔定时器停止
}
//重启关卡函数实现
void ASpaceShip::RestartLevel()
{
UGameplayStatics::OpenLevel(this,"MainMap");//重新打开当前关卡
}
//阵亡函数实现
void ASpaceShip::OnDeath()
{
bDead = true;//阵亡设置为真
CollisionComp->SetVisibility(false,true);
if (GameOverCue)//战败音效为真
{
UGameplayStatics::PlaySoundAtLocation(this, GameOverCue, GetActorLocation());//播放战败音效
}
if (ExplosionParticle)//爆炸特效为真
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ExplosionParticle, GetActorLocation(), FRotator::ZeroRotator, true);//播放爆炸特效
GetWorldTimerManager().SetTimer(TimerHandle_Restart, this, &ASpaceShip::RestartLevel, 2.0f, false);//重启游戏定时器开启
}
}
//游戏每帧函数实现
void ASpaceShip::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!bDead)//未阵亡
{
if (bUpMove || bRightMove)//上下移动或者左右移动
{
ThrusterParticleComp->Activate();//推机器粒子特效开启
}
else//未上下移动或者左右移动
{
ThrusterParticleComp->Deactivate();//推机器粒子特效结束
}
LookAtCursor();//调用朝向光标函数
Move();//调用移动函数
}
else //阵亡
{
ThrusterParticleComp->Deactivate();//推机器粒子特效结束
}
}
//玩家输入函数实现
void ASpaceShip::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveUp",this,&ASpaceShip::MoveUp);//轴映射上下移动
PlayerInputComponent->BindAxis("MoveRight", this, &ASpaceShip::MoveRight);//轴映射左右移动
PlayerInputComponent->BindAction("Fire",IE_Pressed,this,&ASpaceShip::StartFire);//操作映射按键开火
PlayerInputComponent->BindAction("Fire", IE_Released, this, &ASpaceShip::EndFire);//操作映射松键停火
}
//碰撞函数实现
void ASpaceShip::NotifyActorBeginOverlap(AActor * OtherActor)
{
Super::NotifyActorBeginOverlap(OtherActor);
AEnemy* Enemy = Cast<AEnemy>(OtherActor);//碰撞检测敌人类型
if (Enemy)//敌人为真
{
Enemy->Destroy();//敌人销毁
OnDeath();//战机调用阵亡函数
//Destroy();战机销毁
}
}
3.虚幻蓝图类:①创建蓝图类继承战机C++类
②蓝图类组件添加素材
③蓝图类事件图表调用分数UI到窗口
4.类设置:①类子弹细节添加子弹类
②类音效细节添加音效
③类粒子细节添加粒子
5.总结:战机类作为玩家控制的对象需要根据玩家的输入来触发对应的函数,当战机在游戏中触发不同事件时会调用不同的函数
4.子弹实现
1.C++头文件:
//预处理
#pragma once//编译一次
#include "CoreMinimal.h"//核心编程环境
#include "GameFramework/Actor.h"//Actor源代码
#include "Bullet.generated.h"//反射机制
//前向声明
class UProjectileMovementComponent;//发射物移动
//子弹类
UCLASS()
class SPACESHIPBATTLE_API ABullet : public AActor
{
GENERATED_BODY()
public:
//构造函数声明
ABullet();
protected:
//游戏开始函数声明
virtual void BeginPlay() override;
//根组件变量
UPROPERTY(VisibleAnywhere, Category = "Component")
USceneComponent* RootComp;
//网格体组件变量
UPROPERTY(VisibleAnywhere,Category="Component")
UStaticMeshComponent* BulletSM;
//发射物移动组件变量
UPROPERTY(VisibleAnywhere, Category = "Component")
UProjectileMovementComponent* ProjectileMovementComp;
public:
//游戏每帧函数声明
virtual void Tick(float DeltaTime) override;
//碰撞函数声明
virtual void NotifyActorBeginOverlap(AActor* OtherActor) override;
};
2.C++源文件:
//预处理
#include "Public/Bullet.h"//子弹类
#include "Components/StaticMeshComponent.h"//网格体
#include "Components/SceneComponent.h"//场景
#include "GameFramework/ProjectileMovementComponent.h"//发射物移动
#include "Public/Enemy.h"//敌人类
#include "Engine/BlockingVolume.h"//阻挡体积
#include "Kismet/GameplayStatics.h"//游戏状态
//构造函数实现
ABullet::ABullet()
{
PrimaryActorTick.bCanEverTick = true;//开启tick函数
RootComp = CreateDefaultSubobject<USceneComponent>(TEXT("RootComp"));//实例化根组件
RootComponent = RootComp;//设置根组件
BulletSM = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BulletSM"));//实例化网格体组件
BulletSM->SetupAttachment(RootComponent);//绑定根组件
ProjectileMovementComp = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComp"));//实例化发射物移动组件
}
//游戏开始函数实现
void ABullet::BeginPlay()
{
Super::BeginPlay();
}
//游戏每帧函数实现
void ABullet::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
//碰撞函数实现
void ABullet::NotifyActorBeginOverlap(AActor * OtherActor)
{
Super::NotifyActorBeginOverlap(OtherActor);
AEnemy* Enemy= Cast<AEnemy>(OtherActor);//碰撞检测敌人类型
if (Enemy)//敌人为真
{
Enemy->OnDeath();//敌人调用阵亡函数
Destroy();//子弹销毁
}
else if (Cast<ABlockingVolume>(OtherActor))//碰撞检测其他类型
{
Destroy();//子弹销毁
}
}
3.虚幻蓝图类:①创建蓝图类继承子弹C++类
②蓝图类组件添加素材
4.总结:子弹类作为战机拥有移动能力的生成物发射,需要检测碰撞的结果来触发对应的函数
5.敌机实现
1.C++头文件:
//预处理
#pragma once//保证头文件只被编译一次
#include "CoreMinimal.h"//包含一套来自UE4核心编程环境的普遍存在类型
#include "GameFramework/Pawn.h"//在新建类的时候选择了以Pawn作为父类(所以这里保存的就是Pawn源代码的头文件)
#include "Enemy.generated.h"//与反射机制有关(必须放在所有头文件的最下方)
//前向声明
class USphereComponent;//球体碰撞
class ASpaceShip;//战机类
class AShipGameMode;//战机游戏模式类
class AEnemySpawner;//生成类
//敌人类
UCLASS()
class SPACESHIPBATTLE_API AEnemy : public APawn
{
GENERATED_BODY()
public:
//构造函数声明
AEnemy();
protected:
//球体碰撞组件变量
UPROPERTY(VisibleAnywhere,Category="Component")
USphereComponent* CollisionComp;
//网格体组件变量
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = "Component")
UStaticMeshComponent* ShipSM;
//游戏开始函数声明
virtual void BeginPlay() override;
//移动至战机函数声明
void MoveTowardsPlayer(float DeltaTime);
//战机类变量
ASpaceShip* SpaceShip;
//速度变量
float Speed = 300.0f;
//战机游戏模式类变量
AShipGameMode* MyGameMode;
//生成类变量
AEnemySpawner* EnemySpawner;
//爆炸粒子变量
UPROPERTY(EditAnywhere, Category = "Particle")
UParticleSystem* ExplosionParticle;
//设置颜色函数声明
UFUNCTION(BlueprintImplementableEvent)
void SetColor();
//生成爆炸函数声明
UFUNCTION(BlueprintImplementableEvent)
void SpawnExplosion();
public:
//游戏每帧函数声明
virtual void Tick(float DeltaTime) override;
//玩家输入函数声明
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
//阵亡函数声明
void OnDeath();
};
2.C++源文件:
//预处理
#include "Public/Enemy.h"//敌人类
#include "Components/SphereComponent.h"//球体碰撞
#include "Components/StaticMeshComponent.h"//网格体
#include "Kismet/GameplayStatics.h"//游戏状态
#include "Public/SpaceShip.h"//战机类
#include "Kismet/KismetMathLibrary.h"//数学库
#include "Public/ShipGameMode.h"//战机游戏模式类
#include "Public/EnemySpawner.h"//生成类
#include "Particles/ParticleSystem.h"//粒子特效
//构造函数实现
AEnemy::AEnemy()
{
PrimaryActorTick.bCanEverTick = true;//开启tick函数
CollisionComp = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionComp"));//实例化碰撞组件
RootComponent = CollisionComp;//设置根组件
ShipSM = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ShipSM"));//实例化网格体组件
ShipSM->SetupAttachment(RootComponent);//绑定根组件
}
//游戏开始函数实现
void AEnemy::BeginPlay()
{
Super::BeginPlay();
SpaceShip= Cast<ASpaceShip>(UGameplayStatics::GetPlayerPawn(this,0));//战机类型检测
SetColor();//设置敌人颜色
MyGameMode= Cast<AShipGameMode>(UGameplayStatics::GetGameMode(this));//游戏模式类型检测
TArray<AActor*> EnemySpawnerArray;//敌人生成数组
UGameplayStatics::GetAllActorsOfClass(this, AEnemySpawner::StaticClass(), EnemySpawnerArray);//获取敌人类的所有对象
EnemySpawner = Cast<AEnemySpawner>(EnemySpawnerArray[0]);//生成敌人类型检测
}
//移动至战机函数实现
void AEnemy::MoveTowardsPlayer(float DeltaTime)
{
FVector Direction = (SpaceShip->GetActorLocation() - GetActorLocation()).GetSafeNormal();//获取玩家方向
AddActorWorldOffset(Direction*Speed*DeltaTime, true);//设置敌人的位移
SetActorRotation(UKismetMathLibrary::FindLookAtRotation(GetActorLocation(), SpaceShip->GetActorLocation()));//设置敌人的旋转
}
//阵亡函数实现
void AEnemy::OnDeath()
{
MyGameMode->IncreaseScore();//游戏模式类调用分数增加函数
EnemySpawner->DecreaseEnemyCount();//敌人生成类调用减少敌人计数函数
SpawnExplosion();//生成爆炸
Destroy();//销毁敌人
}
//游戏每帧函数实现
void AEnemy::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (SpaceShip->GetBDead() == false)//战机未阵亡
{
MoveTowardsPlayer(DeltaTime);//移动至战机位置
}
}
//玩家输入函数实现
void AEnemy::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
3.虚幻蓝图类:①创建蓝图类继承敌机C++类
②蓝图类组件添加素材
③蓝图类事件图表调用设置颜色和生成爆炸函数
4.总结:与战机类的基本设置相同,只是作为npc需要使用设置好的函数来控制敌人的行为
6.生成实现
1.C++头文件:
//预处理
#pragma once//编译一次
#include "CoreMinimal.h"//核心编程环境
#include "GameFramework/Actor.h"//Actor源代码
#include "EnemySpawner.generated.h"//反射机制
//前向声明
class AEnemy;//敌人类
class UBoxComponent;//盒体碰撞
class ASpaceShip;//战机类
//生成类
UCLASS()
class SPACESHIPBATTLE_API AEnemySpawner : public AActor
{
GENERATED_BODY()
public:
//构造函数声明
AEnemySpawner();
protected:
//游戏开始函数声明
virtual void BeginPlay() override;
//敌人类型变量
UPROPERTY(EditAnywhere,Category="Enemy")
TSubclassOf<AEnemy> Enemy;
//盒体碰撞组件变量
UPROPERTY(VisibleAnywhere,Category="Component")
UBoxComponent* SpawnArea;
//获取生成位置函数声明
FVector GetGenerateLocation();
//与玩家最小距离变量
float MinimumDistanceToPlayer = 1200.0f;
//战机类
ASpaceShip* SpaceShip;
//生成敌人函数声明
void SpawnEnemy();
//生成敌人时间管理器变量
FTimerHandle TimerHandle_Spawn;
//生成敌人间隔变量
float SpawnInterval;
//最大敌人数量变量
UPROPERTY(EditAnywhere,Category="Spawn")
int MaxEnemyNum;
//当前敌人数量变量
int CurrentEnemyCount;
public:
//游戏每帧函数声明
virtual void Tick(float DeltaTime) override;
//减少敌人数量函数声明
void DecreaseEnemyCount();
};
2.C++源文件:
//预处理
#include "Public/EnemySpawner.h"//生成敌人类
#include "Components/BoxComponent.h"//盒体碰撞
#include "Kismet/KismetMathLibrary.h"//数学库
#include "Kismet/GameplayStatics.h"//游戏状态
#include "Public/SpaceShip.h"//战机类
#include "Engine/World.h"//世界
#include "Public/Enemy.h"//敌人类
#include "TimerManager.h"//时间管理器
//构造函数实现
AEnemySpawner::AEnemySpawner()
{
PrimaryActorTick.bCanEverTick = true;//开启tick函数
SpawnArea = CreateDefaultSubobject<UBoxComponent>(TEXT("SpawnArea"));//实例化碰撞组件
RootComponent = SpawnArea;//设置根组件
SpawnInterval = 2.0f;//敌人生成间隔为2s
MaxEnemyNum = 30;//最大敌人数量为30
CurrentEnemyCount = 0;//当前敌人计数为0
}
//游戏开始函数实现
void AEnemySpawner::BeginPlay()
{
Super::BeginPlay();
SpaceShip=Cast<ASpaceShip>( UGameplayStatics::GetPlayerPawn(this,0));//战机类型检测
GetWorldTimerManager().SetTimer(TimerHandle_Spawn,this,&AEnemySpawner::SpawnEnemy,SpawnInterval,true,0.0f);//开启敌人生成定时器
}
//获取生成位置函数实现
FVector AEnemySpawner::GetGenerateLocation()
{
float Distance=0;//敌人生成位置与玩家位置距离变量
FVector Location;//敌人生成位置变量
while (Distance < MinimumDistanceToPlayer)//敌人生成位置与玩家位置距离小于敌人与玩家最小距离
{
Location = UKismetMathLibrary::RandomPointInBoundingBox(SpawnArea->Bounds.Origin, SpawnArea->Bounds.BoxExtent);//盒体内获取随机坐标
Distance = (Location - SpaceShip->GetActorLocation()).Size();//计算距离
}
return Location;//返回生成位置
}
//生成敌人函数实现
void AEnemySpawner::SpawnEnemy()
{
if (SpaceShip->GetBDead() == false&&CurrentEnemyCount<MaxEnemyNum)//战机未阵亡且当前敌人计数小于最大
{
FActorSpawnParameters SpawnParameters;//生成范围变量
GetWorld()->SpawnActor<AEnemy>(Enemy, GetGenerateLocation(), FRotator::ZeroRotator, SpawnParameters);//生成敌人
CurrentEnemyCount++;//当前敌人计数+1
}
}
//游戏每帧函数实现
void AEnemySpawner::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
//减少敌人数量函数实现
void AEnemySpawner::DecreaseEnemyCount()
{
if (CurrentEnemyCount > 0)//当敌人数量大于1时
{
CurrentEnemyCount--;//当前敌人数量-1
UE_LOG(LogTemp,Warning,TEXT("%s"),*FString::SanitizeFloat(CurrentEnemyCount));//打印日志记录敌人数量
}
}
3.虚幻蓝图类:①创建蓝图类继承生成C++类
②蓝图类组件添加素材
4.类设置:①类敌人细节添加敌人类
②类最大敌人数量细节添加数量
5.总结:生成类负责敌人在一个确定范围内的生成以及敌人生成数量,生成间隔,生成位置的管制
7.模式实现
1.C++头文件:
//预处理
#pragma once//编译一次
#include "CoreMinimal.h"//核心编程环境
#include "GameFramework/GameModeBase.h"//GameModeBase源代码
#include "ShipGameMode.generated.h"//反射机制
//战机游戏模式类
UCLASS()
class SPACESHIPBATTLE_API AShipGameMode : public AGameModeBase
{
GENERATED_BODY()
protected:
//构造函数声明
AShipGameMode();
//分数变量
UPROPERTY(BlueprintReadOnly)
int Score;
public:
//增加敌人数量函数声明
void IncreaseScore();
};
2.C++源文件:
#include "Public/ShipGameMode.h"//战机游戏模式类
//构造函数实现
AShipGameMode::AShipGameMode()
{
Score = 0;//分数初始化为0
}
//增加敌人数量函数实现
void AShipGameMode::IncreaseScore()
{
Score++;//击败敌人分数增加
}