当玩家吃掉超级豆子,就会让所有的敌人变虚弱。
我们打开游戏模式类。添加函数
- //将所有敌人变虚弱
- void SetEnermiesVolunerable();
定义这个函数
- void APacmanGameModeBase::SetEnermiesVolunerable()
- {
- for (auto Iter(Enermis.CreateIterator()); Iter; ++Iter)
- {
- (*Iter)->SetVulnerable();
-
- }
- }
然后打开玩家类
完善吃豆子逻辑
- //发生重叠,就会调用这个函数
- void APacdotPlayer::OnPacmanBeginOverlay(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
- {
- if (OtherActor->IsA(APacdot::StaticClass()))
- {
- //当前的豆子
- APacdot* CurrentPacdot = Cast
(OtherActor); - //判断是否是超级豆子
- if (CurrentPacdot->bIsSuperPacdot)
- {
- //让所有的敌人变虚弱
- ModeBaseRef->SetEnermiesVolunerable();
- }
- OtherActor->Destroy();
- //更新一下豆子的数量
- ModeBaseRef->SetPacdotNum(ModeBaseRef->GetPacdotNum()-1);
- }
-
- }
===========================
完善一下游戏状态逻辑
只有当游戏在游玩状态,我们才可以控制角色
- void APacdotPlayer::MoveX(float value)
- {
- //用if包裹起来
- if (ModeBaseRef->GetCurrentState() == EGameState::EPlay)
- {
- Vlocity.X = value;
- Vlocity.Y = 0;
-
- //character自带的函数,我们把向量喂给他就可以了
- AddMovementInput(Vlocity);
-
- if (value > 0)
- {
- SetActorRotation(FRotator(0, 0, 0));
- }
- else if (value < 0)
- {
- SetActorRotation(FRotator(0, -180, 0));
- }
- }
-
- }
- void APacdotPlayer::MoveY(float value)
- {
- 用if包裹起来
- if (ModeBaseRef->GetCurrentState() == EGameState::EPlay)
- {
- Vlocity.X = 0;
- Vlocity.Y = value;
- AddMovementInput(Vlocity);
- if (value > 0)
- {
- SetActorRotation(FRotator(0, 90, 0));
- }
- else if (value < 0)
- {
- SetActorRotation(FRotator(0, -90, 0));
- }
- }
-
- }
- //发生重叠,就会调用这个函数
- void APacdotPlayer::OnPacmanBeginOverlay(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
- {
- 用if包裹起来
- if (ModeBaseRef->GetCurrentState() == EGameState::EPlay)
- {
- if (OtherActor->IsA(APacdot::StaticClass()))
- {
- //当前的豆子
- APacdot* CurrentPacdot = Cast
(OtherActor); - //判断是否是超级豆子
- if (CurrentPacdot->bIsSuperPacdot)
- {
- //让所有的敌人变虚弱
- ModeBaseRef->SetEnermiesVolunerable();
- }
- OtherActor->Destroy();
- //更新一下豆子的数量
- ModeBaseRef->SetPacdotNum(ModeBaseRef->GetPacdotNum());
- }
- }
-
-
- }
=============================
实现重新游戏
打开游戏模式类,定义重启游戏函数
- void APacmanGameModeBase::ReStartGame()
- {
- GetWorld()->GetFirstLocalPlayerFromController()->ConsoleCommand(TEXT("RestartLevel"));
- }
定义暂停游戏函数
- void APacmanGameModeBase::PauseGame()
- {
- if (GetCurrentState() == EGameState::EPlay)
- {
- SetCurrentState(EGameState::EPause);
- }
- else if (GetCurrentState() == EGameState::EPause)
- {
- SetCurrentState(EGameState::EPlay);
- }
- }
现在定义一下改变状态函数
- void APacmanGameModeBase::SetCurrentState(EGameState value)
- {
- CurrentState = value;
- switch (CurrentState)
- {
- case EGameState::EMenu:
-
- break;
- case EGameState::EPlay:
- //改变敌人的移动
- for (auto Iter(Enermis.CreateIterator()); Iter; ++Iter)
- {
- (*Iter)->SetMovement(true);
- }
- //改变玩家的移动
- Cast< APacdotPlayer>(GetWorld()->GetFirstPlayerController()->GetPawn())->SetMovement(true);
- break;
- case EGameState::EPause:
- //改变敌人的移动,并清除计时器
- for (auto Iter(Enermis.CreateIterator()); Iter; ++Iter)
- {
- (*Iter)->SetMovement(false);
- GetWorldTimerManager().ClearAllTimersForObject(*Iter);
- }
- //改变玩家的移动
- Cast< APacdotPlayer>(GetWorld()->GetFirstPlayerController()->GetPawn())->SetMovement(false);
- break;
- case EGameState::EWin:
- //销毁所有敌人
- for (auto Iter(Enermis.CreateIterator()); Iter; ++Iter)
- {
- (*Iter)->Destroy();
- }
- break;
- case EGameState::EGameOver:
- //改变敌人的移动并清除计时器
- for (auto Iter(Enermis.CreateIterator()); Iter; ++Iter)
- {
- (*Iter)->SetMovement(false);
- GetWorldTimerManager().ClearAllTimersForObject(*Iter);
- }
- //改变玩家的移动
- Cast< APacdotPlayer>(GetWorld()->GetFirstPlayerController()->GetPawn())->SetMovement(false);
- break;
- default:
- break;
- }
- }
=======================
打开游戏模式类,声明保存和还原计时器函数
- //记录所有敌人计时器
- void RecordEnermiesTimer();
-
- //还原所有敌人计时器
- void RestoreEnermiesTimer();
再声明一个私有容器属性,存放每个敌人计时器剩余时间
- //每个敌人计时器剩余时间
- TArray<float> EnermisRemainingTime;
定义RecordEnermiesTimer()函数
- //用来记录计时器剩余时间
- void APacmanGameModeBase::RecordEnermiesTimer()
- {
- //清空容器
- EnermisRemainingTime.Empty();
- //遍历场景中的敌人
- for (auto Iter(Enermis.CreateIterator()); Iter; ++Iter)
- {
- //正常状态
- if ((*Iter)->bIsVulnerable == false && (*Iter)->bIsDeath == false)
- {
- EnermisRemainingTime.Add(-1);
- }
- //虚弱状态
- if ((*Iter)->bIsVulnerable == true && (*Iter)->bIsDeath == false)
- {
- //存储计时器
- float VulnerableRemainingTime = GetWorldTimerManager().GetTimerRemaining((*Iter)->VulnerableTimerHandle);
- EnermisRemainingTime.Add(VulnerableRemainingTime);
- }
- //死亡状态
- if ((*Iter)->bIsDeath == true)
- {
- //存储计时器
- float DeathRemainingTime = GetWorldTimerManager().GetTimerRemaining((*Iter)->DeathTimerHandle);
- EnermisRemainingTime.Add(DeathRemainingTime);
- }
-
- }
-
- }
定义恢复计时器函数
- //回复计时器
- void APacmanGameModeBase::RestoreEnermiesTimer()
- {
- for (auto Iter(Enermis.CreateIterator()); Iter; ++Iter)
- {
- //虚弱状态
- if ((*Iter)->bIsVulnerable == true && (*Iter)->bIsDeath == false)
- {
- (*Iter)->SetVulnerable(true, EnermisRemainingTime[Iter.GetIndex()]);
- }
- //死亡状态
- if ((*Iter)->bIsDeath == true)
- {
- (*Iter)->SetDeath(true, EnermisRemainingTime[Iter.GetIndex()]);
- }
- }
- }
此时我们完善一下pause()暂停函数
- void APacmanGameModeBase::PauseGame()
- {
- if (GetCurrentState() == EGameState::EPlay)
- {
- //暂停之后,记录剩余时间
- RecordEnermiesTimer();
- SetCurrentState(EGameState::EPause);
-
- }
- else if (GetCurrentState() == EGameState::EPause)
- {
- //暂停之后,恢复剩余时间
- RestoreEnermiesTimer();
- SetCurrentState(EGameState::EPlay);
-
- }
- }