Question: Modify the behavior of the template to implement a 2 player tic-tac-toe game. When player1 clicks a block, it turns yellow. When player2 clicks a

Modify the behavior of the template to implement a 2 player tic-tac-toe game. When player1 clicks a block, it turns yellow. When player2 clicks a block, it turns red. If a line of 3 blocks of either team is detected, the blocks of the line turn white and an appropriate message is displayed to the debug console. (either Player 2 wins or Player 1 wins);

TicTacToe2PlayerPlayerController.cpp

#include \"TicTacToe2PlayerPlayerController.h\"

ATicTacToe2PlayerPlayerController::ATicTacToe2PlayerPlayerController() { bShowMouseCursor = true; bEnableClickEvents = true; bEnableTouchEvents = true; DefaultMouseCursor = EMouseCursor::Crosshairs; }

TicTacToe2PlayerGameMode.cpp

#include \"TicTacToe2PlayerGameMode.h\" #include \"TicTacToe2PlayerPlayerController.h\" #include \"TicTacToe2PlayerPawn.h\"

ATicTacToe2PlayerGameMode::ATicTacToe2PlayerGameMode() { // no pawn by default DefaultPawnClass = ATicTacToe2PlayerPawn::StaticClass(); // use our own player controller class PlayerControllerClass = ATicTacToe2PlayerPlayerController::StaticClass(); }

TicTacToe2PlayerBlock.cpp

#include \"TicTacToe2PlayerBlock.h\" #include \"TicTacToe2PlayerBlockGrid.h\" #include \"UObject/ConstructorHelpers.h\" #include \"Components/StaticMeshComponent.h\" #include \"Engine/StaticMesh.h\" #include \"Materials/MaterialInstance.h\"

ATicTacToe2PlayerBlock::ATicTacToe2PlayerBlock() { // Structure to hold one-time initialization struct FConstructorStatics { ConstructorHelpers::FObjectFinderOptional PlaneMesh; ConstructorHelpers::FObjectFinderOptional BaseMaterial; ConstructorHelpers::FObjectFinderOptional BlueMaterial; ConstructorHelpers::FObjectFinderOptional OrangeMaterial; FConstructorStatics() : PlaneMesh(TEXT(\"/Game/Puzzle/Meshes/PuzzleCube.PuzzleCube\")) , BaseMaterial(TEXT(\"/Game/Puzzle/Meshes/BaseMaterial.BaseMaterial\")) , BlueMaterial(TEXT(\"/Game/Puzzle/Meshes/BlueMaterial.BlueMaterial\")) , OrangeMaterial(TEXT(\"/Game/Puzzle/Meshes/OrangeMaterial.OrangeMaterial\")) { } }; static FConstructorStatics ConstructorStatics;

// Create dummy root scene component DummyRoot = CreateDefaultSubobject(TEXT(\"Dummy0\")); RootComponent = DummyRoot;

// Create static mesh component BlockMesh = CreateDefaultSubobject(TEXT(\"BlockMesh0\")); BlockMesh->SetStaticMesh(ConstructorStatics.PlaneMesh.Get()); BlockMesh->SetRelativeScale3D(FVector(1.f,1.f,0.25f)); BlockMesh->SetRelativeLocation(FVector(0.f,0.f,25.f)); BlockMesh->SetMaterial(0, ConstructorStatics.BlueMaterial.Get()); BlockMesh->SetupAttachment(DummyRoot); BlockMesh->OnClicked.AddDynamic(this, &ATicTacToe2PlayerBlock::BlockClicked); BlockMesh->OnInputTouchBegin.AddDynamic(this, &ATicTacToe2PlayerBlock::OnFingerPressedBlock);

// Save a pointer to the orange material BaseMaterial = ConstructorStatics.BaseMaterial.Get(); BlueMaterial = ConstructorStatics.BlueMaterial.Get(); OrangeMaterial = ConstructorStatics.OrangeMaterial.Get(); }

void ATicTacToe2PlayerBlock::BlockClicked(UPrimitiveComponent* ClickedComp, FKey ButtonClicked) { HandleClicked(); }

void ATicTacToe2PlayerBlock::OnFingerPressedBlock(ETouchIndex::Type FingerIndex, UPrimitiveComponent* TouchedComponent) { HandleClicked(); }

void ATicTacToe2PlayerBlock::HandleClicked() { // Check we are not already active if (!bIsActive) { bIsActive = true;

// Change material BlockMesh->SetMaterial(0, OrangeMaterial);

// Tell the Grid if (OwningGrid != nullptr) { OwningGrid->AddScore(); } } }

void ATicTacToe2PlayerBlock::Highlight(bool bOn) { // Do not highlight if the block has already been activated. if (bIsActive) { return; }

if (bOn) { BlockMesh->SetMaterial(0, BaseMaterial); } else { BlockMesh->SetMaterial(0, BlueMaterial); } }

TicTacToe2PlayerBlockGrid.cpp

#include \"TicTacToe2PlayerBlockGrid.h\" #include \"TicTacToe2PlayerBlock.h\" #include \"Components/TextRenderComponent.h\" #include \"Engine/World.h\"

#define LOCTEXT_NAMESPACE \"PuzzleBlockGrid\"

ATicTacToe2PlayerBlockGrid::ATicTacToe2PlayerBlockGrid() { // Create dummy root scene component DummyRoot = CreateDefaultSubobject(TEXT(\"Dummy0\")); RootComponent = DummyRoot;

// Create static mesh component ScoreText = CreateDefaultSubobject(TEXT(\"ScoreText0\")); ScoreText->SetRelativeLocation(FVector(200.f,0.f,0.f)); ScoreText->SetRelativeRotation(FRotator(90.f,0.f,0.f)); ScoreText->SetText(FText::Format(LOCTEXT(\"ScoreFmt\", \"Score: {0}\"), FText::AsNumber(0))); ScoreText->SetupAttachment(DummyRoot);

// Set defaults Size = 3; BlockSpacing = 300.f; }

void ATicTacToe2PlayerBlockGrid::BeginPlay() { Super::BeginPlay();

// Number of blocks const int32 NumBlocks = Size * Size;

// Loop to spawn each block for(int32 BlockIndex=0; BlockIndex;> { const float XOffset = (BlockIndex/Size) * BlockSpacing; // Divide by dimension const float YOffset = (BlockIndex%Size) * BlockSpacing; // Modulo gives remainder

// Make position vector, offset from Grid location const FVector BlockLocation = FVector(XOffset, YOffset, 0.f) + GetActorLocation();

// Spawn a block ATicTacToe2PlayerBlock* NewBlock = GetWorld()->SpawnActor(BlockLocation, FRotator(0,0,0));

// Tell the block about its owner if (NewBlock != nullptr) { NewBlock->OwningGrid = this; } } }

void ATicTacToe2PlayerBlockGrid::AddScore() { // Increment score Score++;

// Update text ScoreText->SetText(FText::Format(LOCTEXT(\"ScoreFmt\", \"Score: {0}\"), FText::AsNumber(Score))); }

#undef LOCTEXT_NAMESPACE

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Programming Questions!