Compare commits
14 Commits
06f9a6ac5a
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| fc97901cdc | |||
| 600897b905 | |||
| 17c60a72e3 | |||
| a85c596e23 | |||
| 7e3424d0f6 | |||
| 987856ca09 | |||
|
|
df25b61b8f | ||
|
|
c844a8a896 | ||
| d20171032f | |||
|
|
f65171d5c2 | ||
| dc2002fbb1 | |||
| 134883273e | |||
| d8497da0bd | |||
| 272f0bf877 |
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
UnrealToolbox.exe filter=lfs diff=lfs merge=lfs -text
|
||||
@@ -10,9 +10,9 @@ r.AllowStaticLighting=False
|
||||
|
||||
r.GenerateMeshDistanceFields=True
|
||||
|
||||
r.DynamicGlobalIlluminationMethod=1
|
||||
r.DynamicGlobalIlluminationMethod=0
|
||||
|
||||
r.ReflectionMethod=1
|
||||
r.ReflectionMethod=0
|
||||
|
||||
r.SkinCache.CompileShaders=True
|
||||
|
||||
@@ -27,6 +27,12 @@ r.DefaultFeature.AutoExposure.ExtendDefaultLuminanceRange=True
|
||||
r.DefaultFeature.LocalExposure.HighlightContrastScale=0.8
|
||||
|
||||
r.DefaultFeature.LocalExposure.ShadowContrastScale=0.8
|
||||
r.Lumen.HardwareRayTracing=False
|
||||
r.Lumen.Reflections.HardwareRayTracing.Translucent.Refraction.EnableForProject=False
|
||||
r.Mobile.SupportsGen4TAA=False
|
||||
r.CustomDepthTemporalAAJitter=False
|
||||
r.AntiAliasingMethod=1
|
||||
r.DefaultFeature.MotionBlur=False
|
||||
|
||||
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
|
||||
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
|
||||
@@ -94,3 +100,7 @@ ConnectionType=USBOnly
|
||||
bUseManualIPAddress=False
|
||||
ManualIPAddress=
|
||||
|
||||
|
||||
[CoreRedirects]
|
||||
+ClassRedirects=(OldName="/Script/M4_CPP.M4_CentipedeController",NewName="/Script/M4_CPP.M4_CentipedeController")
|
||||
|
||||
|
||||
Binary file not shown.
BIN
Content/CTP/05_Material/MI_Body.uasset
Normal file
BIN
Content/CTP/05_Material/MI_Body.uasset
Normal file
Binary file not shown.
BIN
Content/CTP/05_Material/MI_Head.uasset
Normal file
BIN
Content/CTP/05_Material/MI_Head.uasset
Normal file
Binary file not shown.
51
Source/M4_CPP/private/M4_CentipedeBody.cpp
Normal file
51
Source/M4_CPP/private/M4_CentipedeBody.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include "M4_CentipedeBody.h"
|
||||
|
||||
AM4_CentipedeBody::AM4_CentipedeBody()
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UStaticMesh> MeshRef(TEXT("/Game/CTP/04_Mesh/SM_Cube.SM_Cube"));
|
||||
if (MeshRef.Succeeded())
|
||||
{
|
||||
GetStaticMeshComponent()->SetStaticMesh(MeshRef.Object);
|
||||
}
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> HeadMatRef(TEXT("/Game/CTP/05_Material/MI_Head.MI_Head"));
|
||||
if (HeadMatRef.Succeeded())
|
||||
{
|
||||
HeadMaterial = HeadMatRef.Object;
|
||||
}
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UMaterialInterface> BodyMatRef(TEXT("/Game/CTP/05_Material/MI_Body.MI_Body"));
|
||||
if (BodyMatRef.Succeeded())
|
||||
{
|
||||
BodyMaterial = BodyMatRef.Object;
|
||||
}
|
||||
|
||||
GetStaticMeshComponent()->SetRelativeScale3D(FVector(1.f, 0.4f, 0.4f));
|
||||
GetStaticMeshComponent()->SetMobility(EComponentMobility::Movable);
|
||||
GetStaticMeshComponent()->SetCollisionObjectType(ECollisionChannel::ECC_WorldDynamic);
|
||||
GetStaticMeshComponent()->SetGenerateOverlapEvents(true);
|
||||
GetStaticMeshComponent()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
|
||||
GetStaticMeshComponent()->SetCollisionProfileName(TEXT("OverlapAll"));
|
||||
}
|
||||
|
||||
void AM4_CentipedeBody::SetAsHead(bool bHead)
|
||||
{
|
||||
bIsHead = bHead;
|
||||
|
||||
if (bIsHead)
|
||||
{
|
||||
if (HeadMaterial)
|
||||
{
|
||||
GetStaticMeshComponent()->SetMaterial(0, HeadMaterial);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BodyMaterial)
|
||||
{
|
||||
GetStaticMeshComponent()->SetMaterial(0, BodyMaterial);
|
||||
}
|
||||
}
|
||||
}
|
||||
318
Source/M4_CPP/private/M4_CentipedeController.cpp
Normal file
318
Source/M4_CPP/private/M4_CentipedeController.cpp
Normal file
@@ -0,0 +1,318 @@
|
||||
#include "M4_CentipedeController.h"
|
||||
#include "M4_LOG.h"
|
||||
#include "M4_Gamemode.h"
|
||||
#include "M4_Mushroom.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
UM4_CentipedeController::UM4_CentipedeController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::Initialize(FSubsystemCollectionBase& Collection)
|
||||
{
|
||||
Super::Initialize(Collection);
|
||||
|
||||
UE_LOG(M4_CPP, Warning, TEXT("Centipede Controller Initialized"));
|
||||
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::Deinitialize()
|
||||
{
|
||||
UE_LOG(M4_CPP, Warning, TEXT("Centipede Controller Deinitialized"));
|
||||
|
||||
BodySegments.Empty();
|
||||
PreviousPositions.Empty();
|
||||
SegmentDirections.Empty();
|
||||
|
||||
Super::Deinitialize();
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::StartCentipede(FVector SpawnLocation)
|
||||
{
|
||||
if (BodySegments.Num() > 0)
|
||||
{
|
||||
UE_LOG(M4_CPP, Warning, TEXT("Centipede already spawned"));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < BodyCount; ++i)
|
||||
{
|
||||
FVector SegmentLocation = SpawnLocation - FVector(0.f, i * CellSize, 0.f);
|
||||
|
||||
AM4_CentipedeBody* Body = GetWorld()->SpawnActor<AM4_CentipedeBody>(
|
||||
AM4_CentipedeBody::StaticClass(),
|
||||
SegmentLocation,
|
||||
FRotator::ZeroRotator
|
||||
);
|
||||
|
||||
if (Body)
|
||||
{
|
||||
BodySegments.Add(Body);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
Body->PreviousBody = BodySegments[i - 1];
|
||||
BodySegments[i - 1]->NextBody = Body;
|
||||
}
|
||||
|
||||
Body->SetAsHead(i == 0);
|
||||
}
|
||||
}
|
||||
|
||||
SegmentHistory.SetNum(BodyCount);
|
||||
for (int32 i = 0; i < BodyCount; ++i)
|
||||
{
|
||||
if (BodySegments.IsValidIndex(i) && BodySegments[i])
|
||||
{
|
||||
FVector InitialPos = BodySegments[i]->GetActorLocation();
|
||||
|
||||
int32 InitialHistorySize = SegmentSpacing * (i + 1) + MaxHistorySize;
|
||||
for (int32 j = 0; j < InitialHistorySize; ++j)
|
||||
{
|
||||
SegmentHistory[i].Add(InitialPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (AM4_CentipedeBody* Segment : BodySegments)
|
||||
{
|
||||
SegmentDirections.Add(Segment, FVector2D(0.f, 1.f));
|
||||
}
|
||||
|
||||
UE_LOG(M4_CPP, Warning, TEXT("Centipede spawned with %d segments"), BodySegments.Num());
|
||||
}
|
||||
|
||||
TStatId UM4_CentipedeController::GetStatId() const
|
||||
{
|
||||
RETURN_QUICK_DECLARE_CYCLE_STAT(UM4_CentipedeController, STATGROUP_Tickables);
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::SpawnCentipede()
|
||||
{
|
||||
AM4_Gamemode* GM = Cast<AM4_Gamemode>(GetWorld()->GetAuthGameMode());
|
||||
if (!GM) return;
|
||||
|
||||
FVector SpawnLocation = FVector(
|
||||
GM->MushroomSpawnBounds.Max.X,
|
||||
0.f,
|
||||
0.f
|
||||
);
|
||||
|
||||
UE_LOG(M4_CPP, Warning, TEXT("Controller spawn location: X=%.2f, Y=%.2f, Z=%.2f"),
|
||||
SpawnLocation.X, SpawnLocation.Y, SpawnLocation.Z);
|
||||
|
||||
if (SpawnLocation.IsZero())
|
||||
{
|
||||
UE_LOG(M4_CPP, Error, TEXT("Controller position is zero! Check spawn parameters."));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32 i = 0; i < BodyCount; ++i)
|
||||
{
|
||||
FVector SegmentLocation = SpawnLocation - FVector(0.f, i * CellSize, 0.f);
|
||||
|
||||
AM4_CentipedeBody* Body = GetWorld()->SpawnActor<AM4_CentipedeBody>(
|
||||
AM4_CentipedeBody::StaticClass(),
|
||||
SegmentLocation,
|
||||
FRotator::ZeroRotator
|
||||
);
|
||||
|
||||
if (Body)
|
||||
{
|
||||
BodySegments.Add(Body);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
Body->PreviousBody = BodySegments[i - 1];
|
||||
BodySegments[i - 1]->NextBody = Body;
|
||||
}
|
||||
|
||||
Body->SetAsHead(i == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
|
||||
if (BodySegments.Num() == 0) return;
|
||||
|
||||
AM4_CentipedeBody* Head = BodySegments[0];
|
||||
if (Head && Head->bIsHead)
|
||||
{
|
||||
FVector CurrentPos = Head->GetActorLocation();
|
||||
FVector2D SegmentDirection = GetSegmentDirection(Head);
|
||||
|
||||
bool bRowChanged = CheckCollision(Head, SegmentDirection);
|
||||
|
||||
if (bRowChanged)
|
||||
{
|
||||
FVector NewPos = CurrentPos - FVector(0.f, 0.f, CellSize);
|
||||
Head->SetActorLocation(NewPos);
|
||||
|
||||
SegmentDirection.Y *= -1.f;
|
||||
SetSegmentDirection(Head, SegmentDirection);
|
||||
}
|
||||
else
|
||||
{
|
||||
FVector NewPos = CurrentPos + FVector(0.f, SegmentDirection.Y * CentipedeSpeed * DeltaTime, 0.f);
|
||||
Head->SetActorLocation(NewPos);
|
||||
}
|
||||
|
||||
SegmentHistory[0].Add(Head->GetActorLocation());
|
||||
if (SegmentHistory[0].Num() > MaxHistorySize)
|
||||
{
|
||||
SegmentHistory[0].RemoveAt(0);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32 i = 1; i < BodySegments.Num(); ++i)
|
||||
{
|
||||
AM4_CentipedeBody* Segment = BodySegments[i];
|
||||
if (!Segment) continue;
|
||||
|
||||
int32 PrevIndex = i - 1;
|
||||
int32 HistoryLookback = SegmentSpacing;
|
||||
|
||||
if (SegmentHistory[PrevIndex].Num() > HistoryLookback)
|
||||
{
|
||||
int32 HistoryIndex = SegmentHistory[PrevIndex].Num() - HistoryLookback - 1;
|
||||
FVector TargetPos = SegmentHistory[PrevIndex][HistoryIndex];
|
||||
|
||||
Segment->SetActorLocation(TargetPos);
|
||||
|
||||
SegmentHistory[i].Add(Segment->GetActorLocation());
|
||||
if (SegmentHistory[i].Num() > MaxHistorySize)
|
||||
{
|
||||
SegmentHistory[i].RemoveAt(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UpdateHeadStatus();
|
||||
}
|
||||
|
||||
bool UM4_CentipedeController::CheckCollision(AM4_CentipedeBody* Segment, FVector2D Direction)
|
||||
{
|
||||
if (!Segment) return false;
|
||||
|
||||
FVector CurrentPos = Segment->GetActorLocation();
|
||||
FVector NextPos = CurrentPos + FVector(0.f, Direction.Y * CellSize, 0.f);
|
||||
|
||||
AM4_Gamemode* GM = Cast<AM4_Gamemode>(GetWorld()->GetAuthGameMode());
|
||||
if (!GM) return false;
|
||||
|
||||
const float LeftBound = GM->MushroomSpawnBounds.Min.Y;
|
||||
const float RightBound = GM->MushroomSpawnBounds.Max.Y;
|
||||
const float MinRows = GM->MushroomSpawnBounds.Min.X;
|
||||
const float MaxRows = GM->MushroomSpawnBounds.Max.X;
|
||||
|
||||
if (NextPos.Y <= LeftBound || NextPos.Y >= RightBound)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CurrentPos.Z > MinRows && NextPos.Z <= MinRows)
|
||||
{
|
||||
// On inverse la direction de descente pour remonter
|
||||
FVector2D CurrentDirection = GetSegmentDirection(Segment);
|
||||
CurrentDirection.Y *= -1.f;
|
||||
SetSegmentDirection(Segment, CurrentDirection);
|
||||
return true; // Collision détectée, le centipede descendra à la prochaine itération
|
||||
}
|
||||
|
||||
// Vérification si on atteint la limite haute
|
||||
if (CurrentPos.Z < MaxRows && NextPos.Z >= MaxRows)
|
||||
{
|
||||
// On inverse la direction de montée pour descendre
|
||||
FVector2D CurrentDirection = GetSegmentDirection(Segment);
|
||||
CurrentDirection.Y *= -1.f;
|
||||
SetSegmentDirection(Segment, CurrentDirection);
|
||||
return true; // Collision détectée, le centipede remontera à la prochaine itération
|
||||
}
|
||||
|
||||
int32 NextGridZ = FMath::RoundToInt(NextPos.Z / CellSize);
|
||||
int32 NextGridY = FMath::RoundToInt(NextPos.Y / CellSize);
|
||||
|
||||
TArray<AActor*> FoundMushrooms;
|
||||
UGameplayStatics::GetAllActorsOfClass(GetWorld(), AM4_Mushroom::StaticClass(), FoundMushrooms);
|
||||
|
||||
for (AActor* Actor : FoundMushrooms)
|
||||
{
|
||||
FVector MushroomPos = Actor->GetActorLocation();
|
||||
|
||||
// Conversion de la position du mushroom en coordonnées de grille (Z, Y)
|
||||
int32 MushroomGridZ = FMath::RoundToInt(MushroomPos.Z / CellSize);
|
||||
int32 MushroomGridY = FMath::RoundToInt(MushroomPos.Y / CellSize);
|
||||
|
||||
// Vérification si c'est la même cellule de grille
|
||||
if (NextGridZ == MushroomGridZ && NextGridY == MushroomGridY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FVector2D UM4_CentipedeController::GetSegmentDirection(AM4_CentipedeBody* Segment)
|
||||
{
|
||||
if (SegmentDirections.Contains(Segment))
|
||||
{
|
||||
return SegmentDirections[Segment];
|
||||
}
|
||||
return FVector2D(0.f, 1.f);
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::SetSegmentDirection(AM4_CentipedeBody* Segment, FVector2D Direction)
|
||||
{
|
||||
if (Segment)
|
||||
{
|
||||
SegmentDirections.Add(Segment, Direction);
|
||||
}
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::UpdateHeadStatus()
|
||||
{
|
||||
for (int32 i = 0; i < BodySegments.Num(); ++i)
|
||||
{
|
||||
AM4_CentipedeBody* Body = BodySegments[i];
|
||||
if (!Body) continue;
|
||||
|
||||
bool bShouldBeHead = (i == 0) || (Body->PreviousBody == nullptr);
|
||||
|
||||
if (Body->bIsHead != bShouldBeHead)
|
||||
{
|
||||
Body->SetAsHead(bShouldBeHead);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UM4_CentipedeController::OnSegmentDestroyed(AM4_CentipedeBody* DestroyedSegment)
|
||||
{
|
||||
if (!DestroyedSegment) return;
|
||||
|
||||
int32 SegmentIndex = BodySegments.Find(DestroyedSegment);
|
||||
if (SegmentIndex == INDEX_NONE) return;
|
||||
|
||||
if (SegmentIndex + 1 < BodySegments.Num())
|
||||
{
|
||||
AM4_CentipedeBody* NewHead = BodySegments[SegmentIndex + 1];
|
||||
if (NewHead)
|
||||
{
|
||||
NewHead->SetAsHead(true);
|
||||
NewHead->PreviousBody = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (SegmentIndex > 0 && BodySegments[SegmentIndex - 1])
|
||||
{
|
||||
BodySegments[SegmentIndex - 1]->NextBody = nullptr;
|
||||
}
|
||||
|
||||
BodySegments.RemoveAt(SegmentIndex);
|
||||
SegmentHistory.RemoveAt(SegmentIndex);
|
||||
SegmentDirections.Remove(DestroyedSegment);
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
#include "M4_Gamemode.h"
|
||||
|
||||
#include "M4_CTP_Macros.h"
|
||||
#include "M4_Mushroom.h"
|
||||
#include "M4_PlayerController.h"
|
||||
#include "M4_PlayerPawn.h"
|
||||
|
||||
@@ -11,10 +13,97 @@ AM4_Gamemode::AM4_Gamemode()
|
||||
|
||||
PlayerControllerClass = AM4_PlayerController::StaticClass();
|
||||
DefaultPawnClass = AM4_PlayerPawn::StaticClass();
|
||||
|
||||
MushroomCount = FMath::RandRange(20, 25);
|
||||
|
||||
}
|
||||
|
||||
void AM4_Gamemode::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
Score = 0;
|
||||
Lives = 3;
|
||||
|
||||
// Get mushroom size from the class
|
||||
AM4_Mushroom* TempMushroom = GetWorld()->SpawnActor<AM4_Mushroom>(AM4_Mushroom::StaticClass());
|
||||
if (TempMushroom)
|
||||
{
|
||||
FVector MushroomSize = TempMushroom->GetStaticMeshComponent()->Bounds.BoxExtent * 2.0f;
|
||||
CellSize = FMath::Max(MushroomSize.Y, MushroomSize.Z); // Use largest dimension
|
||||
TempMushroom->Destroy();
|
||||
}
|
||||
|
||||
// Calculate grid dimensions based on cell size
|
||||
const int32 GridRows = FMath::FloorToInt(MushroomSpawnBounds.GetSize().X / CellSize);
|
||||
const int32 GridCols = FMath::FloorToInt(MushroomSpawnBounds.GetSize().Y / CellSize);
|
||||
|
||||
// spawn mushrooms in a grid inside the spawn bounds and in random cell
|
||||
if (MushroomCount > 0)
|
||||
{
|
||||
TSet<FIntPoint> OccupiedCells;
|
||||
|
||||
for (int32 i = 0; i < MushroomCount; ++i)
|
||||
{
|
||||
FIntPoint Cell;
|
||||
bool bValidCell;
|
||||
int32 MaxAttempts = 100;
|
||||
int32 Attempts = 0;
|
||||
|
||||
do
|
||||
{
|
||||
Cell.X = FMath::RandRange(0, GridRows - 1);
|
||||
Cell.Y = FMath::RandRange(0, GridCols - 1);
|
||||
|
||||
// Check if cell and adjacent cells are free
|
||||
bValidCell = !OccupiedCells.Contains(Cell) &&
|
||||
!OccupiedCells.Contains(FIntPoint(Cell.X - 1, Cell.Y)) &&
|
||||
!OccupiedCells.Contains(FIntPoint(Cell.X + 1, Cell.Y)) &&
|
||||
!OccupiedCells.Contains(FIntPoint(Cell.X, Cell.Y - 1)) &&
|
||||
!OccupiedCells.Contains(FIntPoint(Cell.X, Cell.Y + 1));
|
||||
|
||||
Attempts++;
|
||||
} while (!bValidCell && Attempts < MaxAttempts);
|
||||
|
||||
if (!bValidCell)
|
||||
{
|
||||
PRINT_SCREEN(TEXT("Could not find valid cell for mushroom"), FColor::Yellow);
|
||||
continue;
|
||||
}
|
||||
|
||||
OccupiedCells.Add(Cell);
|
||||
|
||||
FVector SpawnLocation;
|
||||
SpawnLocation.Z = MushroomSpawnBounds.Min.X + Cell.X * CellSize + CellSize / 2.0f;
|
||||
SpawnLocation.Y = MushroomSpawnBounds.Min.Y + Cell.Y * CellSize + CellSize / 2.0f;
|
||||
SpawnLocation.X = -400.0f;
|
||||
|
||||
GetWorld()->SpawnActor<AM4_Mushroom>(
|
||||
AM4_Mushroom::StaticClass(),
|
||||
SpawnLocation,
|
||||
FRotator::ZeroRotator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
PRINT_SCREEN(TEXT("Spawning Centipede Controller"), FColor::Green);
|
||||
|
||||
FVector CentipedeSpawnLocation = FVector(
|
||||
-400.0f,
|
||||
0.0f,
|
||||
MushroomSpawnBounds.Max.X + CellSize
|
||||
);
|
||||
|
||||
// PRINT SCREEN Max.X value
|
||||
PRINT_SCREEN(*FString::Printf(TEXT("Mushroom Spawn Bounds Max.X: %.2f"), MushroomSpawnBounds.Max.X), FColor::Green);
|
||||
|
||||
UM4_CentipedeController* Controller = GetWorld()->GetSubsystem<UM4_CentipedeController>();
|
||||
if (Controller)
|
||||
{
|
||||
Controller->BodyCount = CentipedeBodyCount;
|
||||
Controller->CellSize = CellSize;
|
||||
|
||||
Controller->StartCentipede(CentipedeSpawnLocation);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
42
Source/M4_CPP/private/M4_Mushroom.cpp
Normal file
42
Source/M4_CPP/private/M4_Mushroom.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "M4_Mushroom.h"
|
||||
|
||||
#include "M4_CTP_Macros.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "M4_Gamemode.h"
|
||||
|
||||
|
||||
// Sets default values
|
||||
AM4_Mushroom::AM4_Mushroom()
|
||||
{
|
||||
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
|
||||
static ConstructorHelpers::FObjectFinder<UStaticMesh> StaticMeshRef(TEXT("/Game/CTP/04_Mesh/SM_Cube.SM_Cube"));
|
||||
if (StaticMeshRef.Succeeded())
|
||||
{
|
||||
GetStaticMeshComponent()->SetStaticMesh(StaticMeshRef.Object);
|
||||
}
|
||||
|
||||
GetStaticMeshComponent()->SetDefaultCustomPrimitiveDataVector4(0, FVector4(0.0, 0.2, 0.2, 1.0));
|
||||
|
||||
GetStaticMeshComponent()->SetCollisionEnabled(ECollisionEnabled::QueryOnly);
|
||||
GetStaticMeshComponent()->SetGenerateOverlapEvents(true);
|
||||
// Set as static object
|
||||
GetStaticMeshComponent()->SetMobility(EComponentMobility::Static);
|
||||
|
||||
// Set scale
|
||||
const FVector2D MushroomScale = FVector2D(0.3f, 0.25f);
|
||||
GetStaticMeshComponent()->SetRelativeScale3D(FVector(1.f, 0.45f, 0.20f));
|
||||
|
||||
// Set collision profile to overlap all
|
||||
GetStaticMeshComponent()->SetCollisionProfileName(TEXT("OverlapAll"));
|
||||
|
||||
}
|
||||
|
||||
void AM4_Mushroom::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
}
|
||||
35
Source/M4_CPP/private/M4_Projectile.cpp
Normal file
35
Source/M4_CPP/private/M4_Projectile.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
|
||||
#include "M4_Projectile.h"
|
||||
#include "GameFramework/ProjectileMovementComponent.h"
|
||||
#include "Components/MeshComponent.h"
|
||||
|
||||
// Sets default values
|
||||
AM4_Projectile::AM4_Projectile()
|
||||
{
|
||||
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComp"));
|
||||
MeshComp-> SetRelativeScale3D(FVector(1.f, .1f,.1f));
|
||||
MeshComp->BodyInstance.SetCollisionProfileName(TEXT("Projectile"));
|
||||
MeshComp->OnComponentHit.AddDynamic(this, &AM4_Projectile::OnHit);
|
||||
}
|
||||
|
||||
void AM4_Projectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector Impulse, const FHitResult& Hit)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Called when the game starts or when spawned
|
||||
void AM4_Projectile::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
}
|
||||
|
||||
Called every frame
|
||||
void AM4_Projectile::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
}*/
|
||||
|
||||
31
Source/M4_CPP/public/M4_CentipedeBody.h
Normal file
31
Source/M4_CPP/public/M4_CentipedeBody.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/StaticMeshActor.h"
|
||||
#include "M4_CentipedeBody.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class M4_CPP_API AM4_CentipedeBody : public AStaticMeshActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
AM4_CentipedeBody();
|
||||
|
||||
UPROPERTY()
|
||||
AM4_CentipedeBody* NextBody;
|
||||
|
||||
UPROPERTY()
|
||||
AM4_CentipedeBody* PreviousBody;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
bool bIsHead = false;
|
||||
|
||||
void SetAsHead(bool bHead);
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Materials")
|
||||
UMaterialInterface* HeadMaterial;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Materials")
|
||||
UMaterialInterface* BodyMaterial;
|
||||
};
|
||||
60
Source/M4_CPP/public/M4_CentipedeController.h
Normal file
60
Source/M4_CPP/public/M4_CentipedeController.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "M4_CentipedeBody.h"
|
||||
#include "Subsystems/WorldSubsystem.h"
|
||||
#include "M4_CentipedeController.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class M4_CPP_API UM4_CentipedeController : public UTickableWorldSubsystem
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UM4_CentipedeController();
|
||||
|
||||
virtual void Initialize(FSubsystemCollectionBase& Collection) override;
|
||||
virtual void Deinitialize() override;
|
||||
void StartCentipede(FVector SpawnLocation);
|
||||
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
virtual TStatId GetStatId() const override;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Centipede")
|
||||
int32 BodyCount = 10;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Centipede")
|
||||
float CellSize = 50.f;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Centipede")
|
||||
float MoveInterval = 0.1f;
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "Centipede")
|
||||
void OnSegmentDestroyed(AM4_CentipedeBody* DestroyedSegment);
|
||||
|
||||
private:
|
||||
UPROPERTY()
|
||||
TArray<AM4_CentipedeBody*> BodySegments;
|
||||
TArray<TArray<FVector>> SegmentHistory; // Historique pour chaque segment
|
||||
int32 MaxHistorySize = 200;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "Centipede")
|
||||
int32 SegmentSpacing = 15; // Distance en nombre de frames entre segments
|
||||
|
||||
float TimeSinceLastMove = 0.f;
|
||||
float CentipedeSpeed = 400.f;
|
||||
bool bFirstTick = true;
|
||||
|
||||
TArray<FVector> PreviousPositions;
|
||||
|
||||
TMap<AM4_CentipedeBody*, FVector2D> SegmentDirections;
|
||||
|
||||
void SpawnCentipede();
|
||||
void UpdateHeadStatus();
|
||||
|
||||
bool CheckCollision(AM4_CentipedeBody* Segment, FVector2D Direction);
|
||||
|
||||
FVector2D GetSegmentDirection(AM4_CentipedeBody* Segment);
|
||||
void SetSegmentDirection(AM4_CentipedeBody* Segment, FVector2D Direction);
|
||||
};
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/GameModeBase.h"
|
||||
#include "M4_CentipedeController.h"
|
||||
#include "M4_Gamemode.generated.h"
|
||||
|
||||
/**
|
||||
@@ -20,6 +21,60 @@ public:
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
/**
|
||||
* The movement bounds for the player pawn
|
||||
*/
|
||||
UPROPERTY(EditAnywhere)
|
||||
FBox2D Bounds = FBox2D(FVector2D(-400.0f, -750.0f), FVector2D(-200.0f, 750.0f));
|
||||
|
||||
/**
|
||||
* Bounds for spawning mushrooms
|
||||
*/
|
||||
UPROPERTY(EditAnywhere)
|
||||
FBox2D MushroomSpawnBounds = FBox2D(FVector2D(-300.0f, -750.0f), FVector2D(550.0f, 750.0f));
|
||||
|
||||
/**
|
||||
* Add to the player's score
|
||||
* @param Amount
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void AddScore(int Amount) { Score += Amount; }
|
||||
|
||||
/**
|
||||
* Get the player's current score
|
||||
* @return Current score
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
int GetScore() const { return Score; }
|
||||
|
||||
/**
|
||||
* Decrease the player's lives by 1, but not below 0
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void LoseLife() { Lives = FMath::Max(0, Lives - 1); }
|
||||
|
||||
/**
|
||||
* Get the player's current lives
|
||||
* @return Current lives
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
int GetLives() const { return Lives; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(EditAnywhere, Category="Centipede")
|
||||
int32 CentipedeBodyCount = 10;
|
||||
|
||||
UPROPERTY()
|
||||
TObjectPtr<UM4_CentipedeController> CentipedeController;
|
||||
|
||||
int Score = 0;
|
||||
int Lives = 3;
|
||||
|
||||
// default mushroom count
|
||||
int MushroomCount;
|
||||
float CellSize = 50.f;
|
||||
|
||||
|
||||
};
|
||||
|
||||
21
Source/M4_CPP/public/M4_Mushroom.h
Normal file
21
Source/M4_CPP/public/M4_Mushroom.h
Normal file
@@ -0,0 +1,21 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/StaticMeshActor.h"
|
||||
#include "GameFramework/Pawn.h"
|
||||
#include "M4_Mushroom.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class M4_CPP_API AM4_Mushroom : public AStaticMeshActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
// Sets default values for this pawn's properties
|
||||
AM4_Mushroom();
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
};
|
||||
36
Source/M4_CPP/public/M4_Projectile.h
Normal file
36
Source/M4_CPP/public/M4_Projectile.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "M4_Projectile.generated.h"
|
||||
|
||||
class UProjectileMovementComponent;
|
||||
class UMeshComponent;
|
||||
|
||||
UCLASS()
|
||||
class M4_CPP_API AM4_Projectile : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
UPROPERTY(VisibleDefaultsOnly, Category = Projectile)
|
||||
UMeshComponent* MeshComp;
|
||||
|
||||
UPROPERTY(VisibleAnywhere,BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = "true"))
|
||||
UProjectileMovementComponent* ProjectileMovem;
|
||||
|
||||
public:
|
||||
|
||||
AM4_Projectile();
|
||||
|
||||
protected:
|
||||
float bullSpeed = 50.f;
|
||||
float lifeTime = 3.f;
|
||||
|
||||
public:
|
||||
|
||||
UFUNCTION()
|
||||
void OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp,FVector Impulse, const FHitResult& Hit);
|
||||
UMeshComponent* GetCollisionComp() const { return MeshComp; }
|
||||
UProjectileMovementComponent* GetMovementComp() const { return ProjectileMovem; }
|
||||
};
|
||||
Reference in New Issue
Block a user