CrossyRoad minigame
This commit is contained in:
parent
7c1610534c
commit
33ea9807d6
BIN
Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoadManager.uasset
(Stored with Git LFS)
BIN
Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoadManager.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoad_Obstacle.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoad_Obstacle.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Left.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Left.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Right.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Right.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Up.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Up.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Input/Minigame/IMC_Minigame_CrossyRoad.uasset
(Stored with Git LFS)
Normal file
BIN
Content/Input/Minigame/IMC_Minigame_CrossyRoad.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/Levels/Test/L_Test.umap
(Stored with Git LFS)
BIN
Content/Levels/Test/L_Test.umap
(Stored with Git LFS)
Binary file not shown.
BIN
Content/MaterialsLibrary/Colors/M_Color_Black.uasset
(Stored with Git LFS)
Normal file
BIN
Content/MaterialsLibrary/Colors/M_Color_Black.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/MaterialsLibrary/Colors/M_Color_White.uasset
(Stored with Git LFS)
Normal file
BIN
Content/MaterialsLibrary/Colors/M_Color_White.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Content/MaterialsLibrary/Colors/M_Color_Yellow.uasset
(Stored with Git LFS)
Normal file
BIN
Content/MaterialsLibrary/Colors/M_Color_Yellow.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
Plugins/FMODStudio/Binaries/Win64/UnrealEditor.modules
(Stored with Git LFS)
BIN
Plugins/FMODStudio/Binaries/Win64/UnrealEditor.modules
(Stored with Git LFS)
Binary file not shown.
BIN
Plugins/FMODStudioNiagara/Binaries/Win64/UnrealEditor.modules
(Stored with Git LFS)
BIN
Plugins/FMODStudioNiagara/Binaries/Win64/UnrealEditor.modules
(Stored with Git LFS)
Binary file not shown.
@ -3,11 +3,35 @@
|
|||||||
|
|
||||||
#include "CrossyRoadManager.h"
|
#include "CrossyRoadManager.h"
|
||||||
|
|
||||||
|
#include "Camera/CameraComponent.h"
|
||||||
|
#include "Components/SkeletalMeshComponent.h"
|
||||||
|
#include "Components/SplineComponent.h"
|
||||||
|
#include "EnhancedInputComponent.h"
|
||||||
|
#include "InputMappingContext.h"
|
||||||
|
|
||||||
|
#include "CrossyRoadObstacle.h"
|
||||||
|
#include "CustomGameInstanceBase.h"
|
||||||
#include "MainGameModeBase.h"
|
#include "MainGameModeBase.h"
|
||||||
#include "PlayerBase.h"
|
#include "PlayerBase.h"
|
||||||
|
#include "Widgets/WidgetsManager.h"
|
||||||
|
|
||||||
ACrossyRoadManager::ACrossyRoadManager()
|
ACrossyRoadManager::ACrossyRoadManager()
|
||||||
{}
|
: AMinigame()
|
||||||
|
{
|
||||||
|
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_CrossyRoad.IMC_Minigame_CrossyRoad'") };
|
||||||
|
input = asset.Object;
|
||||||
|
|
||||||
|
auto root = CreateDefaultSubobject<USceneComponent>(TEXT("Scene"));
|
||||||
|
|
||||||
|
playerPos = CreateDefaultSubobject<USceneComponent>(TEXT("PlayerPos"));
|
||||||
|
playerPos->AttachToComponent(root, FAttachmentTransformRules::KeepRelativeTransform);
|
||||||
|
|
||||||
|
camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
|
||||||
|
camera->AttachToComponent(root, FAttachmentTransformRules::KeepRelativeTransform);
|
||||||
|
|
||||||
|
mannequin = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mannequin"));
|
||||||
|
mannequin->AttachToComponent(root, FAttachmentTransformRules::KeepRelativeTransform);
|
||||||
|
}
|
||||||
|
|
||||||
void ACrossyRoadManager::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate)
|
void ACrossyRoadManager::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate)
|
||||||
{
|
{
|
||||||
@ -17,11 +41,211 @@ void ACrossyRoadManager::Start(APlayerBase* playerPawn, FMinigameEndCallback del
|
|||||||
AMinigame::Start(playerPawn, delegate);
|
AMinigame::Start(playerPawn, delegate);
|
||||||
|
|
||||||
player->LockPlayer(FPlayerLock::All());
|
player->LockPlayer(FPlayerLock::All());
|
||||||
|
player->SwitchToView(this);
|
||||||
|
|
||||||
|
for(auto& mapping : input.LoadSynchronous()->GetMappings())
|
||||||
|
{
|
||||||
|
if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Up"))))
|
||||||
|
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Up).GetHandle());
|
||||||
|
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Down"))))
|
||||||
|
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Down).GetHandle());
|
||||||
|
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Left"))))
|
||||||
|
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Left).GetHandle());
|
||||||
|
else if(mapping.Action->ActionDescription.EqualTo(FText::AsCultureInvariant(TEXT("Right"))))
|
||||||
|
inputHandlers.Add(player->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &ACrossyRoadManager::Right).GetHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
playerPos->SetWorldLocation(lines[0]->GetLocationAtTime(lines[0]->Duration * playerLineTime, ESplineCoordinateSpace::World));
|
||||||
|
mannequin->SetWorldLocation(playerPos->GetComponentLocation());
|
||||||
|
|
||||||
|
for(auto line : lines)
|
||||||
|
if(FMath::RandRange(0, 1))
|
||||||
|
RotateLine(line);
|
||||||
|
|
||||||
|
PrimaryActorTick.SetTickFunctionEnable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ACrossyRoadManager::End()
|
void ACrossyRoadManager::End()
|
||||||
{
|
{
|
||||||
|
PrimaryActorTick.SetTickFunctionEnable(false);
|
||||||
|
|
||||||
|
for(int32 handler : inputHandlers)
|
||||||
|
player->inputComponent->RemoveActionBindingForHandle(handler);
|
||||||
|
|
||||||
player->UnlockPlayer(FPlayerLock::All());
|
player->UnlockPlayer(FPlayerLock::All());
|
||||||
|
player->ReturnPlayerView();
|
||||||
|
|
||||||
AMinigame::End();
|
AMinigame::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::Hit()
|
||||||
|
{
|
||||||
|
if(ended)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ended = true;
|
||||||
|
|
||||||
|
if(score > 1000)
|
||||||
|
{
|
||||||
|
Finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = EMinigameResult::Loss;
|
||||||
|
End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::Finish()
|
||||||
|
{
|
||||||
|
result = EMinigameResult::Win;
|
||||||
|
End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::PostInitializeComponents()
|
||||||
|
{
|
||||||
|
AMinigame::PostInitializeComponents();
|
||||||
|
|
||||||
|
GetComponents<USplineComponent>(lines);
|
||||||
|
for(int32 i = 0; i < lines.Num(); ++i)
|
||||||
|
{
|
||||||
|
int32 id = FCString::Atoi(*lines[i]->GetName().Mid(6));
|
||||||
|
if(i != id - 1)
|
||||||
|
{
|
||||||
|
auto l = lines[i];
|
||||||
|
lines[i] = lines[id - 1];
|
||||||
|
lines[id - 1] = l;
|
||||||
|
}
|
||||||
|
|
||||||
|
linesRotated.Add(lines[i], false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::Tick(float deltaTime)
|
||||||
|
{
|
||||||
|
AMinigame::Tick(deltaTime);
|
||||||
|
|
||||||
|
time += deltaTime;
|
||||||
|
|
||||||
|
if(time >= spawnDelay / speed)
|
||||||
|
{
|
||||||
|
time = 0; //FMath::RandRange(0.0f, spawnDelay / 4 * speed); // (time -= spawnDelay) is not good on lags
|
||||||
|
CreateObstacle();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int32 i = 0; i < obstacles.Num(); ++i)
|
||||||
|
{
|
||||||
|
if(obstacles[i].time > obstacles[i].line->Duration)
|
||||||
|
{
|
||||||
|
obstacles[i].actor->Destroy();
|
||||||
|
obstacles.RemoveAt(i);
|
||||||
|
//CreateObstacle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obstacles[i].time += deltaTime * speed * obstacles[i].speed;
|
||||||
|
obstacles[i].actor->SetActorLocation(obstacles[i].line->GetWorldLocationAtTime(obstacles[i].time));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::CreateObstacle(int32 index)
|
||||||
|
{
|
||||||
|
auto obstacleClass = obstacleClasses.CreateIterator();
|
||||||
|
for(int32 i = 0; i < FMath::RandRange(0, obstacleClasses.Num() - 1); ++i) // std::advance not works :(
|
||||||
|
++obstacleClass;
|
||||||
|
|
||||||
|
auto spline = lines[FMath::RandRange(0, lines.Num() - 1)];
|
||||||
|
|
||||||
|
FActorSpawnParameters spawnParams{};
|
||||||
|
spawnParams.Owner = this;
|
||||||
|
auto obstacle = GetWorld()->SpawnActor<ACrossyRoadObstacle>(*obstacleClass, spline->GetComponentLocation(), GetActorRotation(), spawnParams);
|
||||||
|
obstacle->manager = this;
|
||||||
|
|
||||||
|
if(index < 0)
|
||||||
|
{
|
||||||
|
obstacles.Add({ .actor = obstacle, .line = spline, .time = 0, .speed = FMath::RandRange(0.2f, 1.0f) * speed });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obstacles[index].actor->Destroy();
|
||||||
|
obstacles[index].actor = obstacle;
|
||||||
|
obstacles[index].line = spline;
|
||||||
|
obstacles[index].time = 0;
|
||||||
|
obstacles[index].speed = FMath::RandRange(1.0f, 2.0f) * speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::RotateLine(USplineComponent* line)
|
||||||
|
{
|
||||||
|
auto pos = line->GetComponentLocation();
|
||||||
|
auto rot = line->GetComponentRotation();
|
||||||
|
auto dist = line->GetWorldLocationAtSplinePoint(1) - line->GetWorldLocationAtSplinePoint(0);
|
||||||
|
|
||||||
|
if(linesRotated[line])
|
||||||
|
{
|
||||||
|
line->SetWorldLocationAndRotation(pos - dist, FRotator{ rot.Pitch, rot.Yaw - 180, rot.Roll });
|
||||||
|
linesRotated[line] = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line->SetWorldLocationAndRotation(pos + dist, FRotator{ rot.Pitch, rot.Yaw + 180, rot.Roll });
|
||||||
|
linesRotated[line] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::Up()
|
||||||
|
{
|
||||||
|
if(ended)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto line = lines[0];
|
||||||
|
auto diffY = lines[0]->GetComponentLocation().Y - lines[1]->GetComponentLocation().Y;
|
||||||
|
for(int32 i = 1; i < lines.Num(); ++i)
|
||||||
|
{
|
||||||
|
lines[i]->AddRelativeLocation(FVector{ 0, diffY, 0 });
|
||||||
|
lines[i - 1] = lines[i];
|
||||||
|
}
|
||||||
|
line->AddRelativeLocation(FVector{ 0, (lines.Num() - 1) * diffY * -1, 0 });
|
||||||
|
lines[lines.Num() - 1] = line;
|
||||||
|
//if(FMath::RandRange(0, 1))
|
||||||
|
// RotateLine(line);
|
||||||
|
|
||||||
|
speed += 0.15;
|
||||||
|
score += 100 * speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::Down()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::Left()
|
||||||
|
{
|
||||||
|
if(ended || playerLineTime >= 1.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
playerLineTime += 0.1f;
|
||||||
|
|
||||||
|
float lineTime = playerLineTime;
|
||||||
|
if(linesRotated[lines[0]])
|
||||||
|
lineTime = 1 - lineTime;
|
||||||
|
|
||||||
|
playerPos->SetWorldLocation(lines[0]->GetLocationAtTime(lines[0]->Duration * lineTime, ESplineCoordinateSpace::World));
|
||||||
|
mannequin->SetWorldLocation(playerPos->GetComponentLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ACrossyRoadManager::Right()
|
||||||
|
{
|
||||||
|
if(ended || playerLineTime <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
playerLineTime -= 0.1f;
|
||||||
|
|
||||||
|
float lineTime = playerLineTime;
|
||||||
|
if(linesRotated[lines[0]])
|
||||||
|
lineTime = 1 - lineTime;
|
||||||
|
|
||||||
|
playerPos->SetWorldLocation(lines[0]->GetLocationAtTime(lines[0]->Duration * lineTime, ESplineCoordinateSpace::World));
|
||||||
|
mannequin->SetWorldLocation(playerPos->GetComponentLocation());
|
||||||
|
}
|
||||||
|
@ -16,4 +16,51 @@ public:
|
|||||||
|
|
||||||
virtual void Start(class APlayerBase* playerPawn, FMinigameEndCallback delegate) override;
|
virtual void Start(class APlayerBase* playerPawn, FMinigameEndCallback delegate) override;
|
||||||
virtual void End() override;
|
virtual void End() override;
|
||||||
|
|
||||||
|
void Hit();
|
||||||
|
void Finish();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct ObstacleData
|
||||||
|
{
|
||||||
|
class ACrossyRoadObstacle* actor;
|
||||||
|
class USplineComponent* line;
|
||||||
|
float time;
|
||||||
|
float speed;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual void PostInitializeComponents() override;
|
||||||
|
virtual void Tick(float deltaTime) override;
|
||||||
|
|
||||||
|
void CreateObstacle(int32 index = -1);
|
||||||
|
void RotateLine(class USplineComponent* line);
|
||||||
|
|
||||||
|
void Up();
|
||||||
|
void Down();
|
||||||
|
void Left();
|
||||||
|
void Right();
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly)
|
||||||
|
TSet<TSubclassOf<class ACrossyRoadObstacle>> obstacleClasses;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
class UCameraComponent* camera;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere)
|
||||||
|
class USkeletalMeshComponent* mannequin;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly)
|
||||||
|
float speed = 2;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly)
|
||||||
|
float spawnDelay = 3;
|
||||||
|
float time = spawnDelay;
|
||||||
|
|
||||||
|
TArray<class USplineComponent*> lines;
|
||||||
|
TMap<class USplineComponent*, bool> linesRotated;
|
||||||
|
|
||||||
|
TArray<ObstacleData> obstacles;
|
||||||
|
TArray<int32> inputHandlers;
|
||||||
|
class USceneComponent* playerPos;
|
||||||
|
float playerLineTime = 0.5f;
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
// Oleg Petruny proprietary.
|
||||||
|
|
||||||
|
|
||||||
|
#include "CrossyRoadObstacle.h"
|
||||||
|
|
||||||
|
#include "CrossyRoadManager.h"
|
||||||
|
|
||||||
|
void ACrossyRoadObstacle::Hit()
|
||||||
|
{
|
||||||
|
if(!manager)
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager->Hit();
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
// Oleg Petruny proprietary.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GameFramework/Actor.h"
|
||||||
|
|
||||||
|
#include "CrossyRoadObstacle.generated.h"
|
||||||
|
|
||||||
|
UCLASS(Blueprintable, BlueprintType, MinimalAPI, Abstract)
|
||||||
|
class ACrossyRoadObstacle : public AActor
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void Hit();
|
||||||
|
|
||||||
|
class ACrossyRoadManager* manager = nullptr;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue
Block a user