Jumping and gravity

Jumping and gravity
This commit is contained in:
Kevin Poretti 2022-01-29 17:01:29 -05:00
parent 2b4c138b13
commit 7751b63b98
27 changed files with 378 additions and 517 deletions

View File

@ -36,7 +36,8 @@ r.Editor.SkipSourceControlCheckForEditablePackages = 1
[/Script/Engine.RendererSettings]
r.DefaultFeature.AntiAliasing=0
r.DefaultFeature.AutoExposure=False
r.DefaultFeature.MotionBlur=False
[CoreRedirects]
+ClassRedirects=(OldName="/Script/KOFForever.KOFRenderableCharacter",NewName="/Script/KOFForever.KOFBaseCharacter")

View File

@ -9,7 +9,6 @@ SupportContact=kevinporetti@gmail.com
CopyrightNotice=A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
ProjectDisplayedTitle=NSLOCTEXT("[/Script/EngineSettings]", "F64B16CA410C5695462A51B3C0F03C9C", "{GameName}-{PlatformArchitecture}")
ProjectDebugTitleInfo=NSLOCTEXT("[/Script/EngineSettings]", "C2DB330840BAEB6B6D05629B908D8ADD", "{GameName}-{PlatformArchitecture}")
LicensingTerms=
[StartupActions]
bAddPacks=True

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,7 +8,6 @@ public class KOFForever : ModuleRules
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Paper2D", "UnrealEd" });
PrivateDependencyModuleNames.AddRange( new string [] {"FixedPointMath"});
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "Paper2D", "UnrealEd", "FixedPointMath" });
}
}

View File

@ -4,8 +4,8 @@
#include "DrawDebugHelpers.h"
#include "Camera/CameraComponent.h"
#include "Character/KOFBaseCharacter_DEPRECATED.h"
#include "GameModes/KOFDefaultGameMode.h"
#include "Character/KOFBaseCharacter.h"
#include "Game/KOFDefaultGameMode.h"
#include "Kismet/GameplayStatics.h"
AKOFDefaultCamera::AKOFDefaultCamera()
@ -16,7 +16,7 @@ AKOFDefaultCamera::AKOFDefaultCamera()
MaxFOV = 85.0f;
GetCameraComponent()->SetFieldOfView(MinFOV);
HeightOffset = 60.0f;
HeightOffset = 160.0f;
ZAveragingFactor = 2.0f;
MovementYDistanceThreshold = 500.0f;
@ -32,8 +32,8 @@ void AKOFDefaultCamera::Tick(float DeltaSeconds)
if(GameMode)
{
AKOFBaseCharacter_DEPRECATED* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P2 = GameMode->GetP2CurrentCharacter();
AKOFBaseCharacter* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter* P2 = GameMode->GetP2CurrentCharacter();
check(P1);
check(P2);
@ -42,7 +42,7 @@ void AKOFDefaultCamera::Tick(float DeltaSeconds)
FVector P2Loc = P2->GetActorLocation();
FVector CameraLoc = GetActorLocation();
float HalfStageLength = GameMode->GetStageLength() / 2.0f;
float HalfStageLength = float(GameMode->GetStageLength()) / 2.0f;
FVector MidPoint = FVector(CameraLoc.X, FMath::Clamp((P1Loc.Y + P2Loc.Y) / 2.0f, -HalfStageLength, HalfStageLength), ((P1Loc.Z + P2Loc.Z) / ZAveragingFactor) + HeightOffset);
SetActorLocation(MidPoint);
@ -58,8 +58,8 @@ void AKOFDefaultCamera::UpdateCamera()
if(GameMode)
{
AKOFBaseCharacter_DEPRECATED* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter_DEPRECATED* P2 = GameMode->GetP2CurrentCharacter();
AKOFBaseCharacter* P1 = GameMode->GetP1CurrentCharacter();
AKOFBaseCharacter* P2 = GameMode->GetP2CurrentCharacter();
FVector P1Loc = P1->GetActorLocation();
FVector P2Loc = P2->GetActorLocation();

View File

@ -1,11 +1,11 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "Character/KOFBaseCharacter.h"
#include "Character/KOFBaseCharacter.h"
#include "PaperFlipbookComponent.h"
#include "Components/InputComponent.h"
#include "KOFForever/KOFTypes.h"
#include "Game/KOFDefaultGameMode.h"
// Sets default values
AKOFBaseCharacter::AKOFBaseCharacter()
@ -33,17 +33,78 @@ AKOFBaseCharacter::AKOFBaseCharacter()
Shadow->bOwnerNoSee = false;
Shadow->bAffectDynamicIndirectLighting = true;
Shadow->SetupAttachment(Sprite);
//Shadow->SetRelativeLocation(FVector(0.0f, 0.0f, -96.0f));
Shadow->SetRelativeScale3D(FVector(1.0f, 1.0f, -0.3f));
Shadow->SetSpriteColor(FLinearColor::Black);
Shadow->SetRelativeLocation(FVector(0.0f, 0.0f, 5.0f));
Shadow->SetRelativeRotation(FRotator(90.0f, 0.0f, 0.0f));
Shadow->SetRelativeScale3D(FVector(1.0f, 1.0f, 1.0f));
Shadow->SetSpriteColor(FColor(0.0f, 0.0f, 0.0f, 128));
}
MaxWalkSpeed = 400;
MaxWalkSpeed = 300;
GravityScale = 2;
VerticalNormalJumpVelocity = 1000;
HorizontalNormalJumpVelocity = MaxWalkSpeed;
/*
VerticalSuperJumpVelocity = 2000;
VerticalNormalHopVelocity = 1000;
VerticalSuperHopVelocity;
HorizontalSuperJumpVelocity;
HorizontalNormalHopVelocity;
HorizontalSuperHopVelocity;
*/
bIsInAir = false;
bIsPossessedByPlayer1;
}
void AKOFBaseCharacter::SetPosition(FFixedVector Param)
void AKOFBaseCharacter::Init()
{
Position = Param;
Position = FFixedVector(0, bIsPossessedByPlayer1 ? -GameMode->GetStartY() : GameMode->GetStartY(), 0);
SetActorLocation(FVector(Position));
// eventually character will have a forward and actor rotation will be derived from that
SetActorRotation(FRotator(0.0f, bIsPossessedByPlayer1 ? 90.0f : -90.0f, 0.0f));
//Shadow->SetRelativeRotation(FRotator(bIsPossessedByPlayer1 ? 90.0f : -90.0f, 0.0f, 0.0f));
}
UPaperFlipbook* AKOFBaseCharacter::GetAnimation(FName Key)
{
return Animations.Contains(Key) ? Animations[Key] : nullptr;
}
void AKOFBaseCharacter::UpdateAnimation()
{
// rendering
if(!bIsInAir)
{
if(Direction > 0)
{
SetAnimationFlipbook("WALK_FWD");
}
else if (Direction < 0)
{
SetAnimationFlipbook("WALK_BACK");
}
else
{
SetAnimationFlipbook("IDLE");
}
}
else
{
SetAnimationFlipbook("JUMP_NEUTRAL");
}
}
void AKOFBaseCharacter::SetAnimationFlipbook(FName AnimName)
{
UPaperFlipbook* Anim = GetAnimation(AnimName);
if(Anim)
{
Sprite->SetFlipbook(Anim);
Shadow->SetFlipbook(Anim);
}
else
{
UE_LOG(LogTemp, Error, TEXT("AKOFBaseCharacter::SetAnimationFlipbook - tried to set character animation to %s but the flipbook has not been set for this state."), *AnimName.ToString());
}
}
void AKOFBaseCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
@ -60,17 +121,12 @@ void AKOFBaseCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputCo
void AKOFBaseCharacter::ProcessInputs(EVirtualGamePadButton Button)
{
/*
switch(Button)
{
case EVirtualGamePadButton::VGP_Left:
Position = FFixedVector(0, -250, 0);
break;
case EVirtualGamePadButton::VGP_Right:
Position = FFixedVector(0, 250, 0);
case EVirtualGamePadButton::VGP_Up:
Jump();
break;
}
*/
}
void AKOFBaseCharacter::RegisterInput(FName ActionName, EVirtualGamePadButton Button)
@ -92,8 +148,42 @@ void AKOFBaseCharacter::MoveRight(float Axis)
void AKOFBaseCharacter::UpdateMovement(FFixed DeltaTime)
{
FFixedVector Velocity = FFixedVector(0, Direction * MaxWalkSpeed, 0);
// should have game mode
check(GameMode);
if(!bIsInAir) // apply walking movement
{
Velocity.Y = Direction * MaxWalkSpeed;
}
else // apply gravity
{
// I keep getting confused with Z being vertical and Y being horizontal
Velocity.Z -= (GameMode->GetGravity() * GravityScale) * DeltaTime;
}
Position += Velocity * DeltaTime;
// clamp
FFixed AdjustedZ = FFixedMath::Clamp(Position.Z, 0, 10000);
FFixed HalfStageLength = GameMode->GetStageLength()/2;
FFixed AdjustedY = FFixedMath::Clamp(Position.Y, -HalfStageLength, HalfStageLength);
Position = FFixedVector(Position.X, AdjustedY, AdjustedZ);
if(Position.Z <= 0) // hmmmmmmmmmmmmmmm
{
bIsInAir = false;
}
}
void AKOFBaseCharacter::Jump()
{
// can't jump if already airborne
if(bIsInAir)
{
return;
}
Velocity = FFixedVector(0, HorizontalNormalJumpVelocity * Direction, VerticalNormalJumpVelocity);
bIsInAir = true;
}
// Called when the game starts or when spawned
@ -101,8 +191,10 @@ void AKOFBaseCharacter::BeginPlay()
{
Super::BeginPlay();
SetActorLocation(FVector(Position));
SetActorRotation(FRotator(0.0f, 90.0f, 0.0f));
// NOTE(kevin): This will only return the game mode if we are the server. Since this game is local only we should always
// be both server and client
GameMode = Cast<AKOFDefaultGameMode>(GetWorld()->GetAuthGameMode());
check(GameMode);
}
// Called every frame
@ -110,9 +202,11 @@ void AKOFBaseCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// character logic
UpdateMovement(FFixed(DeltaTime));
// might need some helpers to convert a FFixedVector to a FVector
SetActorRelativeLocation(FVector(Position));
SetActorLocation(FVector(Position));
Shadow->SetWorldLocation(FVector(float(Position.Z), float(Position.Y), 5.0f));
UpdateAnimation();
}

View File

@ -1,165 +0,0 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "Character/KOFBaseCharacter_DEPRECATED.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "PaperFlipbookComponent.h"
#include "Componenets/KOFCharacterMovementComponent.h"
#include "GameModes/KOFDefaultGameMode.h"
DEFINE_LOG_CATEGORY_STATIC(SideScrollerCharacter, Log, All);
//////////////////////////////////////////////////////////////////////////
// ASideScroller2DCharacter
AKOFBaseCharacter_DEPRECATED::AKOFBaseCharacter_DEPRECATED(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<UKOFCharacterMovementComponent>(ACharacter::CharacterMovementComponentName))
{
// Use only Yaw from the controller and ignore the rest of the rotation.
bUseControllerRotationPitch = false;
bUseControllerRotationYaw = false;
bUseControllerRotationRoll = false;
// Set the size of our collision capsule.
GetCapsuleComponent()->SetCapsuleHalfHeight(96.0f);
GetCapsuleComponent()->SetCapsuleRadius(40.0f);
GetCharacterMovement()->bOrientRotationToMovement = false;
// Configure character movement
GetCharacterMovement()->GravityScale = 2.0f;
GetCharacterMovement()->AirControl = 0.0f;
GetCharacterMovement()->JumpZVelocity = 1000.f;
GetCharacterMovement()->GroundFriction = 3.0f;
GetCharacterMovement()->MaxWalkSpeed = 600.0f;
GetCharacterMovement()->MaxFlySpeed = 600.0f;
// Lock character motion onto the XZ plane, so the character can't move in or out of the screen
GetCharacterMovement()->bConstrainToPlane = true;
GetCharacterMovement()->SetPlaneConstraintNormal(FVector(1.0, 0.0f, 0.0f));
// Behave like a traditional 2D platformer character, with a flat bottom instead of a curved capsule bottom
// Note: This can cause a little floating when going up inclines; you can choose the tradeoff between better
// behavior on the edge of a ledge versus inclines by setting this to true or false
GetCharacterMovement()->bUseFlatBaseForFloorChecks = true;
// TextComponent = CreateDefaultSubobject<UTextRenderComponent>(TEXT("IncarGear"));
// TextComponent->SetRelativeScale3D(FVector(3.0f, 3.0f, 3.0f));
// TextComponent->SetRelativeLocation(FVector(35.0f, 5.0f, 20.0f));
// TextComponent->SetRelativeRotation(FRotator(0.0f, 90.0f, 0.0f));
// TextComponent->SetupAttachment(RootComponent);
// Enable replication on the Sprite component so animations show up when networked
GetSprite()->SetIsReplicated(true);
GetSprite()->SetRelativeLocation(FVector(0.0f, 0.0f, -96.0f));
bReplicates = true;
// Try to create the sprite component
Shadow = CreateOptionalDefaultSubobject<UPaperFlipbookComponent>(TEXT("Shadow"));
if (Shadow)
{
Shadow->AlwaysLoadOnClient = true;
Shadow->AlwaysLoadOnServer = true;
Shadow->bOwnerNoSee = false;
Shadow->bAffectDynamicIndirectLighting = true;
Shadow->PrimaryComponentTick.TickGroup = TG_PrePhysics;
Shadow->SetupAttachment(GetCapsuleComponent());
Shadow->SetRelativeLocation(FVector(0.0f, 0.0f, -96.0f));
Shadow->SetRelativeScale3D(FVector(1.0f, 1.0f, -0.3f));
Shadow->SetSpriteColor(FLinearColor::Black);
Shadow->SetTranslucentSortPriority(1000);
}
}
//////////////////////////////////////////////////////////////////////////
// Animation
void AKOFBaseCharacter_DEPRECATED::UpdateAnimation()
{
const FVector PlayerVelocity = GetVelocity();
const float PlayerSpeedSqr = PlayerVelocity.SizeSquared();
const float TravelDirection = PlayerVelocity.Y;
// Are we moving or standing still?
UPaperFlipbook* DesiredAnimation = IdleAnimation;
if(PlayerSpeedSqr > 0.0f)
{
if (TravelDirection > 0.0f)
{
DesiredAnimation = WalkFwdAnimation;
}
else if (TravelDirection < 0.0f)
{
DesiredAnimation = WalkBackAnimation;
}
}
if( GetSprite()->GetFlipbook() != DesiredAnimation )
{
GetSprite()->SetFlipbook(DesiredAnimation);
Shadow->SetFlipbook(DesiredAnimation);
}
}
void AKOFBaseCharacter_DEPRECATED::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
UpdateCharacter();
}
void AKOFBaseCharacter_DEPRECATED::BeginPlay()
{
Super::BeginPlay();
if(Controller)
{
Controller->SetControlRotation(FRotator(0.0f, -90.0f, 0.0));
}
}
void AKOFBaseCharacter_DEPRECATED::PostInitializeComponents()
{
Super::PostInitializeComponents();
if (!IsPendingKill())
{
if (Shadow)
{
// force animation tick after movement component updates
if (Shadow->PrimaryComponentTick.bCanEverTick && GetCharacterMovement())
{
Shadow->PrimaryComponentTick.AddPrerequisite(GetCharacterMovement(), GetCharacterMovement()->PrimaryComponentTick);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// Input
void AKOFBaseCharacter_DEPRECATED::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)
{
// Note: the 'Jump' action and the 'MoveRight' axis are bound to actual keys/buttons/sticks in DefaultInput.ini (editable from Project Settings..Input)
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
PlayerInputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
PlayerInputComponent->BindAxis("MoveRight", this, &AKOFBaseCharacter_DEPRECATED::MoveRight);
}
void AKOFBaseCharacter_DEPRECATED::MoveRight(float Value)
{
/*UpdateChar();*/
// Apply the input to the character motion
AddMovementInput(FVector(0.0f, 1.0f, 0.0f), Value);
}
void AKOFBaseCharacter_DEPRECATED::UpdateCharacter()
{
// Update animation to match the motion
UpdateAnimation();
}

View File

@ -1,49 +0,0 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "Componenets/KOFCharacterMovementComponent.h"
#include "GameModes/KOFDefaultGameMode.h"
UKOFCharacterMovementComponent::UKOFCharacterMovementComponent()
{
PrimaryComponentTick.bCanEverTick = true;
}
void UKOFCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
AKOFBaseCharacter_DEPRECATED* Owner = Cast<AKOFBaseCharacter_DEPRECATED>(GetOwner());
if(!Owner)
{
UE_LOG(LogTemp, Error, TEXT("AKOFCharacterMovementComponent::PostPhysicsTickComponent - could not get the owner"));
return;
}
AKOFDefaultGameMode* GameMode = Cast<AKOFDefaultGameMode>(GetWorld()->GetAuthGameMode());
if(!GameMode)
{
UE_LOG(LogTemp, Error, TEXT("AKOFCharacterMovementComponent::PostPhysicsTickComponent - could not get the game mode"));
return;
}
AKOFBaseCharacter_DEPRECATED* Opponent = GameMode->GetCurrentOpponent(Owner->IsPossessedByPlayer1());
if(Opponent)
{
float HalfYDistance = GameMode->GetMaxAllowedDistanceFromOpponent() / 2.0f;
float YMidpoint = (Owner->GetActorLocation().Y + Opponent->GetActorLocation().Y) / 2.0f;
float AdjustedY = FMath::Clamp(Owner->GetActorLocation().Y, YMidpoint - HalfYDistance, YMidpoint + HalfYDistance);
FVector CurrentLoc = Owner->GetActorLocation();
Owner->SetActorLocation(FVector(CurrentLoc.X, AdjustedY, CurrentLoc.Z));
}
// clamp to stage bounds
FVector CurrentLoc = Owner->GetActorLocation();
float HalfStageLength = GameMode->GetStageLength() / 2.0f;
Owner->SetActorLocation(FVector(CurrentLoc.X,
FMath::Clamp(CurrentLoc.Y, -HalfStageLength, HalfStageLength),
CurrentLoc.Z));
}

View File

@ -0,0 +1,68 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "Game/KOFDefaultGameMode.h"
#include "Kismet/GameplayStatics.h"
AKOFDefaultGameMode::AKOFDefaultGameMode()
{
NumCharactersPerTeam = 3;
Gravity = 1000;
MaxAllowedDistanceFromOpponent = 700;
StageLength = 2400;
StartY = 150;
}
void AKOFDefaultGameMode::InitTeams()
{
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P1TeamTemplate)
{
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate);
Temp->SetIsPossessedByPlayer1(true);
Temp->Init();
if(Temp)
{
P1Team.Add(Temp);
}
}
for (TSubclassOf<AKOFBaseCharacter> CharacterTemplate : P2TeamTemplate)
{
AKOFBaseCharacter* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter>(CharacterTemplate);
Temp->SetIsPossessedByPlayer1(false);
Temp->Init();
if(Temp)
{
P2Team.Add(Temp);
}
}
}
void AKOFDefaultGameMode::StartPlay()
{
Super::StartPlay();
InitTeams();
// is this the right place to do this?
APlayerController* PC1 = UGameplayStatics::GetPlayerController(GetWorld(), 0);
if(PC1)
{
AKOFBaseCharacter* P1 = GetP1CurrentCharacter();
if(P1)
{
PC1->Possess(P1);
}
}
APlayerController* PC2 = UGameplayStatics::GetPlayerController(GetWorld(), 1);
if(PC2)
{
AKOFBaseCharacter* P2 = GetP1CurrentCharacter();
if(P2)
{
PC2->Possess(P2);
}
}
}

View File

@ -1,65 +0,0 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#include "GameModes/KOFDefaultGameMode.h"
#include "Kismet/GameplayStatics.h"
AKOFDefaultGameMode::AKOFDefaultGameMode()
{
NumCharactersPerTeam = 3;
MaxAllowedDistanceFromOpponent = 700.0f;
StageLength = 2400.0f;
StartY = 250.0f;
}
void AKOFDefaultGameMode::InitTeams()
{
for (TSubclassOf<AKOFBaseCharacter_DEPRECATED> CharacterTemplate : P1TeamTemplate)
{
AKOFBaseCharacter_DEPRECATED* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter_DEPRECATED>(CharacterTemplate, FVector(0.0f, -StartY, 204.6241f), FRotator(0.0f, 90.0f, 0.0f));
Temp->SetIsPossesedByPlayer1(true);
if(Temp)
{
P1Team.Add(Temp);
}
}
for (TSubclassOf<AKOFBaseCharacter_DEPRECATED> CharacterTemplate : P2TeamTemplate)
{
AKOFBaseCharacter_DEPRECATED* Temp = GetWorld()->SpawnActor<AKOFBaseCharacter_DEPRECATED>(CharacterTemplate, FVector(0.0f, StartY, 204.6241f), FRotator(0.0f, -90.0f, 0.0f));
Temp->SetIsPossesedByPlayer1(false);
if(Temp)
{
P2Team.Add(Temp);
}
}
}
void AKOFDefaultGameMode::StartPlay()
{
Super::StartPlay();
InitTeams();
// is this the right place to do this?
APlayerController* PC1 = UGameplayStatics::GetPlayerController(GetWorld(), 0);
if(PC1)
{
AKOFBaseCharacter_DEPRECATED* P1 = GetP1CurrentCharacter();
if(P1)
{
PC1->Possess(P1);
}
}
APlayerController* PC2 = UGameplayStatics::GetPlayerController(GetWorld(), 1);
if(PC2)
{
AKOFBaseCharacter_DEPRECATED* P2 = GetP1CurrentCharacter();
if(P2)
{
PC2->Possess(P2);
}
}
}

View File

@ -3,11 +3,16 @@
#pragma once
#include "CoreMinimal.h"
#include "PaperFlipbookComponent.h"
#include "../../../../Plugins/FixedPointMath/Source/FixedPointMath/Public/FixedVector.h"
#include "GameFramework/Actor.h"
#include "KOFForever/KOFTypes.h"
#include "KOFBaseCharacter.generated.h"
enum class EVirtualGamePadButton : uint8;
class UPaperFlipbook;
class AKOFDefaultGameMode;
UCLASS()
class KOFFOREVER_API AKOFBaseCharacter : public APawn
{
@ -17,29 +22,86 @@ public:
// Sets default values for this actor's properties
AKOFBaseCharacter();
void SetPosition(FFixedVector Param);
FORCEINLINE bool IsPossessedByPlayer1() const { return bIsPossessedByPlayer1; }
FORCEINLINE void SetIsPossessedByPlayer1(bool bIsPlayer1) { bIsPossessedByPlayer1 = bIsPlayer1; }
void Init();
protected:
// sprite
/** The main flipbook representing the character */
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UPaperFlipbookComponent* Sprite;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Character)
UPaperFlipbookComponent* Sprite;
/**
* Secondary sprite that is mirrored across the ground axis and set to black to give the effect of a
* character's shadow
*/
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UPaperFlipbookComponent* Shadow;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Character)
UPaperFlipbookComponent* Shadow;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Animations")
TMap<FName, UPaperFlipbook*> Animations;
/**
* @brief Gets a character animation given a state name (i.e. WALKING, IDLE, etc.)
* @param Key Name of the animation
* @return the PaperFlipbook animation or a nullptr if the key does not exist in the animation map
*/
UPaperFlipbook* GetAnimation(FName Key);
void UpdateAnimation();
void SetAnimationFlipbook(FName AnimName);
// movement
// need a way to expose this to the editor as a float slider/entry
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement")
FFixed MaxWalkSpeed;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement")
FFixed GravityScale;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed VerticalNormalJumpVelocity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed VerticalSuperJumpVelocity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed VerticalNormalHopVelocity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed VerticalSuperHopVelocity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed HorizontalNormalJumpVelocity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed HorizontalSuperJumpVelocity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed HorizontalNormalHopVelocity;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Movement|Jumping")
FFixed HorizontalSuperHopVelocity;
int Direction;
FFixedVector Position;
FFixedVector Velocity;
void MoveRight(float Axis);
void UpdateMovement(FFixed DeltaTime);
bool bIsInAir;
void Jump();
// input and control
/**
*
* @param PlayerInputComponent
@ -51,13 +113,16 @@ protected:
void RegisterInput(FName ActionName, EVirtualGamePadButton Button);
void MoveRight(float Axis);
void UpdateMovement(FFixed DeltaTime);
UPROPERTY(BlueprintReadOnly)
bool bIsPossessedByPlayer1;
// Called when the game starts or when spawned
virtual void BeginPlay() override;
private:
// reference to the game mode to get global game constants
AKOFDefaultGameMode* GameMode;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;

View File

@ -1,87 +0,0 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#pragma once
#include "CoreMinimal.h"
#include "PaperCharacter.h"
#include "KOFBaseCharacter_DEPRECATED.generated.h"
class UTextRenderComponent;
/**
* This class is the default character for SideScroller2D, and it is responsible for all
* physical interaction between the player and the world.
*
* The capsule component (inherited from ACharacter) handles collision with the world
* The CharacterMovementComponent (inherited from ACharacter) handles movement of the collision capsule
* The Sprite component (inherited from APaperCharacter) handles the visuals
*/
UCLASS()
class KOFFOREVER_API AKOFBaseCharacter_DEPRECATED : public APaperCharacter
{
GENERATED_BODY()
UTextRenderComponent* TextComponent;
virtual void Tick(float DeltaSeconds) override;
virtual void BeginPlay() override;
virtual void PostInitializeComponents() override;
protected:
/**
* Secondary sprite that is mirrored across the ground axis and set to black to give the effect of a
* character's shadow
*/
UPROPERTY(Category = Character, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
class UPaperFlipbookComponent* Shadow;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* RunningAnimation;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* WalkFwdAnimation;
// The animation to play while running around
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Animations)
class UPaperFlipbook* WalkBackAnimation;
// The animation to play while idle (standing still)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Animations)
class UPaperFlipbook* IdleAnimation;
UPROPERTY(BlueprintReadOnly)
bool bIsPossesedByPlayer1;
/** Called to choose the correct animation to play based on the character's movement state */
void UpdateAnimation();
/** Called for side to side input */
void MoveRight(float Value);
void UpdateCharacter();
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
// End of APawn interface
public:
AKOFBaseCharacter_DEPRECATED(const FObjectInitializer& ObjectInitializer);
FORCEINLINE class UPaperFlipbookComponent* GetShadow() const { return Shadow; }
/**
* Returns whether or not this player is possessed by player 1
*
* @returns true is possessed by player 1, false if possessed by player 2
*/
FORCEINLINE bool IsPossessedByPlayer1() const { return bIsPossesedByPlayer1; }
/**
* Sets which player this character is possesed by.
*
* @param bIsPlayer1 true is possessed by player 1, false if possessed by player 2
*/
FORCEINLINE void SetIsPossesedByPlayer1(bool bIsPlayer1) { bIsPossesedByPlayer1 = bIsPlayer1; }
};

View File

@ -1,20 +0,0 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "KOFCharacterMovementComponent.generated.h"
/**
*
*/
UCLASS()
class KOFFOREVER_API UKOFCharacterMovementComponent : public UCharacterMovementComponent
{
GENERATED_BODY()
UKOFCharacterMovementComponent();
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
};

View File

@ -1,70 +1,82 @@
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#pragma once
#include "CoreMinimal.h"
#include "Character/KOFBaseCharacter_DEPRECATED.h"
#include "GameFramework/GameModeBase.h"
#include "KOFDefaultGameMode.generated.h"
/**
*
*/
UCLASS()
class KOFFOREVER_API AKOFDefaultGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
AKOFDefaultGameMode();
TArray<AKOFBaseCharacter_DEPRECATED*>& GetP1Team() { return P1Team; }
TArray<AKOFBaseCharacter_DEPRECATED*>& GetP2Team() { return P2Team; }
// this will need to change when we actually have real time character switching
AKOFBaseCharacter_DEPRECATED* GetP1CurrentCharacter() { return P1Team.Num() > 0 ? P1Team[0] : nullptr; }
// this will need to change when we actually have real time character switching
AKOFBaseCharacter_DEPRECATED* GetP2CurrentCharacter() { return P2Team.Num() > 0 ? P2Team[0] : nullptr; }
AKOFBaseCharacter_DEPRECATED* GetCurrentOpponent(bool bIsPlayer1) { return bIsPlayer1 ? GetP2CurrentCharacter() : GetP1CurrentCharacter(); }
FORCEINLINE float GetMaxAllowedDistanceFromOpponent() { return MaxAllowedDistanceFromOpponent; }
FORCEINLINE float GetStageLength() { return StageLength; }
protected:
/** Number of characters on a single player's team */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Settings|Team")
int32 NumCharactersPerTeam;
/** Max distance the currently controlled player characters can be from one another */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
float MaxAllowedDistanceFromOpponent;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
float StageLength;
/** Y offset from origin where character's will be spawned */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
float StartY;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team")
TArray<TSubclassOf<AKOFBaseCharacter_DEPRECATED>> P1TeamTemplate;
/** List of references to the player's team members */
UPROPERTY(BlueprintReadOnly)
TArray<AKOFBaseCharacter_DEPRECATED*> P1Team;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team")
TArray<TSubclassOf<AKOFBaseCharacter_DEPRECATED>> P2TeamTemplate;
/** List of references to the player's team members */
UPROPERTY(BlueprintReadOnly)
TArray<AKOFBaseCharacter_DEPRECATED*> P2Team;
void InitTeams();
virtual void StartPlay() override;
};
// A fan game by poret. This game is not affiliated with SNK. This is a fan game which is not being sold or distributed for profit.
#pragma once
#include "CoreMinimal.h"
#include "Fixed.h"
#include "Character/KOFBaseCharacter.h"
#include "GameFramework/GameModeBase.h"
#include "KOFDefaultGameMode.generated.h"
/**
*
*/
UCLASS()
class KOFFOREVER_API AKOFDefaultGameMode : public AGameModeBase
{
GENERATED_BODY()
public:
AKOFDefaultGameMode();
FORCEINLINE FFixed GetGravity() { return Gravity; }
// team
TArray<AKOFBaseCharacter*>& GetP1Team() { return P1Team; }
TArray<AKOFBaseCharacter*>& GetP2Team() { return P2Team; }
// this will need to change when we actually have real time character switching
AKOFBaseCharacter* GetP1CurrentCharacter() { return P1Team.Num() > 0 ? P1Team[0] : nullptr; }
// this will need to change when we actually have real time character switching
AKOFBaseCharacter* GetP2CurrentCharacter() { return P2Team.Num() > 0 ? P2Team[0] : nullptr; }
AKOFBaseCharacter* GetCurrentOpponent(bool bIsPlayer1) { return bIsPlayer1 ? GetP2CurrentCharacter() : GetP1CurrentCharacter(); }
FORCEINLINE FFixed GetMaxAllowedDistanceFromOpponent() { return MaxAllowedDistanceFromOpponent; }
FORCEINLINE FFixed GetStartY() { return StartY; }
FORCEINLINE FFixed GetStageLength() { return StageLength; }
protected:
// physics
UPROPERTY(EditDefaultsOnly)
FFixed Gravity;
// stage
/** Max distance the currently controlled player characters can be from one another */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
FFixed MaxAllowedDistanceFromOpponent;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
FFixed StageLength;
/** Y offset from origin where character's will be spawned */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage")
FFixed StartY;
// team
/** Number of characters on a single player's team */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Settings|Team")
int32 NumCharactersPerTeam;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team")
TArray<TSubclassOf<AKOFBaseCharacter>> P1TeamTemplate;
/** List of references to the player's team members */
UPROPERTY(BlueprintReadOnly)
TArray<AKOFBaseCharacter*> P1Team;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team")
TArray<TSubclassOf<AKOFBaseCharacter>> P2TeamTemplate;
/** List of references to the player's team members */
UPROPERTY(BlueprintReadOnly)
TArray<AKOFBaseCharacter*> P2Team;
void InitTeams();
virtual void StartPlay() override;
};