diff --git a/Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoadManager.uasset b/Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoadManager.uasset index 434b396..751b5eb 100644 --- a/Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoadManager.uasset +++ b/Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoadManager.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2984ab03af8fe924be881f88d9e94170a2d13018fc85161423a594118aa99677 -size 23045 +oid sha256:8be25049605dfc1c8641f94f1eceed0132727851e00f6b881d79110f83195ad2 +size 53846 diff --git a/Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoad_Obstacle.uasset b/Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoad_Obstacle.uasset new file mode 100644 index 0000000..23e32d6 --- /dev/null +++ b/Content/Blueprints/Minigames/CrossyRoad/BP_Minigame_CrossyRoad_Obstacle.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86ba41e2caaabd610d845c3b643839f9c1b5257d34936bf0f48c4db7ace51a34 +size 41788 diff --git a/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Left.uasset b/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Left.uasset new file mode 100644 index 0000000..db20ec0 --- /dev/null +++ b/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Left.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f23b5381e0b8c2487004e40f338a61205ba6f27ad438d09c41344a6db8eb3df1 +size 2198 diff --git a/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Right.uasset b/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Right.uasset new file mode 100644 index 0000000..ab8203b --- /dev/null +++ b/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Right.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:956d7c11ddc10223214a9a29175bb81eeb690dfe59e6dabd240d5891f36a4591 +size 2207 diff --git a/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Up.uasset b/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Up.uasset new file mode 100644 index 0000000..04000e4 --- /dev/null +++ b/Content/Input/Minigame/Actions/IA_Minigame_CrossyRoad_Up.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbcff0a1c8cdefe3e642920590a27bcddf8189cd19c18824e42907d04e0788d1 +size 2180 diff --git a/Content/Input/Minigame/IMC_Minigame_CrossyRoad.uasset b/Content/Input/Minigame/IMC_Minigame_CrossyRoad.uasset new file mode 100644 index 0000000..57f4b47 --- /dev/null +++ b/Content/Input/Minigame/IMC_Minigame_CrossyRoad.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c268d8a3c45a04db70e87e0ec3ef1c5afd40f43625adb3ec7e258ae9e833fb3 +size 4326 diff --git a/Content/Levels/Test/L_Test.umap b/Content/Levels/Test/L_Test.umap index 9f672ea..2047a7e 100644 --- a/Content/Levels/Test/L_Test.umap +++ b/Content/Levels/Test/L_Test.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:433090460cc57acfafc50ada4b1124657d6a58cb9fd4414050cd8aebcc236f22 -size 2238202 +oid sha256:2473597e7884c3270ca415b3cf766d35d22e50dc6040f6ba2800ba71af84d973 +size 2253453 diff --git a/Content/MaterialsLibrary/Colors/M_Color_Black.uasset b/Content/MaterialsLibrary/Colors/M_Color_Black.uasset new file mode 100644 index 0000000..99a4cd8 --- /dev/null +++ b/Content/MaterialsLibrary/Colors/M_Color_Black.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa7a5ec6523e19394f0effda03b11c19f3727592f8dd2fe1206846e6b224248e +size 10812 diff --git a/Content/MaterialsLibrary/Colors/M_Color_White.uasset b/Content/MaterialsLibrary/Colors/M_Color_White.uasset new file mode 100644 index 0000000..aab96b0 --- /dev/null +++ b/Content/MaterialsLibrary/Colors/M_Color_White.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72cb7e48f153eb71253123cd89d202a4e108e8261c0835e8acca9f4d99044f87 +size 12260 diff --git a/Content/MaterialsLibrary/Colors/M_Color_Yellow.uasset b/Content/MaterialsLibrary/Colors/M_Color_Yellow.uasset new file mode 100644 index 0000000..930af06 --- /dev/null +++ b/Content/MaterialsLibrary/Colors/M_Color_Yellow.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:604cf28f38ea7e762650f5a1779ad40e959345c6b0fe864dc49ba9c9afa54b1b +size 12751 diff --git a/Plugins/FMODStudio/Binaries/Win64/UnrealEditor.modules b/Plugins/FMODStudio/Binaries/Win64/UnrealEditor.modules index e21c6fa..36d9568 100644 --- a/Plugins/FMODStudio/Binaries/Win64/UnrealEditor.modules +++ b/Plugins/FMODStudio/Binaries/Win64/UnrealEditor.modules @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4c1ef8b0abfa9c027ee2413c6f4ce856664a5674a700e4a60a4038ab85c5dd67 -size 158 +oid sha256:30f8195fc56588656454b97b3781e8953a79ddd97bef5560bd45dfa65058a047 +size 168 diff --git a/Plugins/FMODStudioNiagara/Binaries/Win64/UnrealEditor.modules b/Plugins/FMODStudioNiagara/Binaries/Win64/UnrealEditor.modules index bab1c38..1ba0274 100644 --- a/Plugins/FMODStudioNiagara/Binaries/Win64/UnrealEditor.modules +++ b/Plugins/FMODStudioNiagara/Binaries/Win64/UnrealEditor.modules @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a8b8269f1aae9783c4984fdf4c86ec1046e6f258803e9d5d81a3c1aacc61e955 -size 112 +oid sha256:5acd55d51b24ded019ebe189677b8e00c89c54d0ad9a383122e0228052235427 +size 117 diff --git a/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.cpp b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.cpp index d36902f..050a08e 100644 --- a/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.cpp +++ b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.cpp @@ -3,11 +3,35 @@ #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 "PlayerBase.h" +#include "Widgets/WidgetsManager.h" ACrossyRoadManager::ACrossyRoadManager() -{} + : AMinigame() +{ + static ConstructorHelpers::FObjectFinder asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/Minigame/IMC_Minigame_CrossyRoad.IMC_Minigame_CrossyRoad'") }; + input = asset.Object; + + auto root = CreateDefaultSubobject(TEXT("Scene")); + + playerPos = CreateDefaultSubobject(TEXT("PlayerPos")); + playerPos->AttachToComponent(root, FAttachmentTransformRules::KeepRelativeTransform); + + camera = CreateDefaultSubobject(TEXT("Camera")); + camera->AttachToComponent(root, FAttachmentTransformRules::KeepRelativeTransform); + + mannequin = CreateDefaultSubobject(TEXT("Mannequin")); + mannequin->AttachToComponent(root, FAttachmentTransformRules::KeepRelativeTransform); +} void ACrossyRoadManager::Start(APlayerBase* playerPawn, FMinigameEndCallback delegate) { @@ -17,11 +41,211 @@ void ACrossyRoadManager::Start(APlayerBase* playerPawn, FMinigameEndCallback del AMinigame::Start(playerPawn, delegate); 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() { + PrimaryActorTick.SetTickFunctionEnable(false); + + for(int32 handler : inputHandlers) + player->inputComponent->RemoveActionBindingForHandle(handler); + player->UnlockPlayer(FPlayerLock::All()); + player->ReturnPlayerView(); 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(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(*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()); +} diff --git a/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.h b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.h index 35acae1..8865efc 100644 --- a/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.h +++ b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadManager.h @@ -16,4 +16,51 @@ public: virtual void Start(class APlayerBase* playerPawn, FMinigameEndCallback delegate) 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> 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 lines; + TMap linesRotated; + + TArray obstacles; + TArray inputHandlers; + class USceneComponent* playerPos; + float playerLineTime = 0.5f; }; diff --git a/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadObstacle.cpp b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadObstacle.cpp new file mode 100644 index 0000000..ea3af7e --- /dev/null +++ b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadObstacle.cpp @@ -0,0 +1,17 @@ +// Oleg Petruny proprietary. + + +#include "CrossyRoadObstacle.h" + +#include "CrossyRoadManager.h" + +void ACrossyRoadObstacle::Hit() +{ + if(!manager) + { + Destroy(); + return; + } + + manager->Hit(); +} diff --git a/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadObstacle.h b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadObstacle.h new file mode 100644 index 0000000..947a70b --- /dev/null +++ b/Source/Lost_Edge/Private/Minigame/CrossyRoad/CrossyRoadObstacle.h @@ -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; + +}; +