Boxing Game Update 15 (02/02/24)


Today I wanted to add a knocked down state for the player, where they must copy a random sequence of arrows to successfully recover.

Character CPP File

void ACompetitionCharacter::Dodge(const FInputActionValue& Value)
...
//only activated on when knocked and sequence isn't over limit
if (PlayerState == "KnockedDown" && SequencePosition <= 3)
{
//setup local variable thats defined according to which key
FString Key;
if (DirectionValue < 0)
{
Key = "Left";
}
else
{
Key = "Right";
}
//add to array and advance position
SequenceArray.Add(Key);
SequencePosition += 1;
...
void ACompetitionCharacter::VerticalButtons(const FInputActionValue& Value)
{
if (PlayerState == "KnockedDown" && SequencePosition <= 3)
{
const float WhichDirection = Value.Get<float>();
FString Key;
if (WhichDirection < 0)
{
Key = "Down";
}
else
{
Key = "Up";
}
SequenceArray.Add(Key);
SequencePosition += 1;

These two functions have been created/modified similarly to check if the player is knocked down and assign directional key presses that must correspond to the random pattern provided. To check this pattern later, the keys are added to an array.

void ACompetitionCharacter::KnockedDown()
{
PlayerState = "KnockedDown";
//Push player back so they can't get hit again
SetActorLocation(GetActorLocation() - FVector(100, 0, 0));
//Generates a random number from 1-4 that is assigned a direction //and added to the array
for (int i = 0; i <= 3; i++)
{
int RandomDirection = FMath::RandRange(0, 3);
if (RandomDirection == 0)
{
RandomisedArray.Add("Left");
}
//this continues for the other values generated
...
}
//timer to check sequence
GetWorldTimerManager().SetTimer(KnockOutHandle, this, &ACompetitionCharacter::CheckSequence, 5.0f, false);
}

In this function, the player is moved and random directions are generated and added to an array that will be compared against the player’s input. Also, a timer is set up with a long wait time so the player has time to try and mimic the pattern.

void ACompetitionCharacter::CheckSequence()
{
//If both arrays are of the same size
if ((RandomisedArray.Num() == 4) && (SequenceArray.Num() == 4))
{
//check each array value against the other in the same spot
for (int i = 0; i <= 3; i++)
{
if (RandomisedArray[i] != SequenceArray[i])
{
//quit if one is incorrect
UKismetSystemLibrary::QuitGame(this->GetWorld(), this->GetWorld()->GetFirstPlayerController(), EQuitPreference::Quit, true);
}
//otherwise do nothing as it quits anyway
else
{
}
}
//reset values
PlayerState = "Inactive";
health = 100;
SetActorLocation(GetActorLocation() + FVector(100, 0, 0));
RandomisedArray.Empty();
SequenceArray.Empty();
SequencePosition = 0;
}
else
{
//quit anyway if arrays aren't of same size
UKismetSystemLibrary::QuitGame(this->GetWorld(), this->GetWorld()->GetFirstPlayerController(), EQuitPreference::Quit, true);;

This code will check if the arrays are of the correct size. If so it will compare the corresponding values and quit if one is correct, or reset the health and player position etc if not. Otherwise, it will quit anyway as the array isn’t correctly sized.

Player Header File

UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
TArray<FString> SequenceArray;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
TArray<FString> RandomisedArray;

I have made both arrays “BlueprintReadOnly” so that they can be used within the UI.

UI Blueprint

This code is used on each arrow image space with a different array value to get

This results in a random sequence of arrows that pop up on screen, that the user must copy to recover their character:


Leave a Reply

Your email address will not be published.