refactor: movement system - MovementPreset, decouple abilities, fix timing
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts;
|
||||
|
||||
@@ -8,6 +9,7 @@ namespace Mr.BrickAdventures.scripts;
|
||||
public partial class PacXonLevel : Node
|
||||
{
|
||||
[Export] public PlayerController Player { get; set; }
|
||||
[Export] public MovementPreset GridPreset { get; set; }
|
||||
[Export] public PacXonGridManager GridManager { get; set; }
|
||||
[Export] public Node GhostContainer { get; set; }
|
||||
[Export] public Label PercentageLabel { get; set; }
|
||||
@@ -17,8 +19,7 @@ public partial class PacXonLevel : Node
|
||||
public override void _Ready()
|
||||
{
|
||||
var ghosts = GhostContainer.GetChildren().OfType<Node2D>().ToList();
|
||||
Player.ClearMovementAbilities();
|
||||
Player.SetGridMovement();
|
||||
Player.ApplyPreset(GridPreset);
|
||||
|
||||
foreach (var ghost in ghosts)
|
||||
{
|
||||
|
||||
9
scripts/Resources/MovementPreset.cs
Normal file
9
scripts/Resources/MovementPreset.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class MovementPreset : Resource
|
||||
{
|
||||
[Export] public PackedScene[] Abilities { get; set; } = [];
|
||||
}
|
||||
@@ -5,26 +5,16 @@ namespace Mr.BrickAdventures.scripts.components;
|
||||
[GlobalClass]
|
||||
public partial class DoubleJumpAbility : MovementAbility
|
||||
{
|
||||
[Export] public float JumpHeight { get; set; } = 100f;
|
||||
[Export] public float JumpTimeToPeak { get; set; } = 0.5f;
|
||||
|
||||
private bool _hasDoubleJumped = false;
|
||||
private float _jumpVelocity;
|
||||
|
||||
public override void Initialize(PlayerController controller)
|
||||
{
|
||||
base.Initialize(controller);
|
||||
|
||||
foreach (var ability in _controller.GetActiveAbilities())
|
||||
{
|
||||
if (ability is VariableJumpAbility jumpAbility)
|
||||
{
|
||||
_jumpVelocity = (2.0f * jumpAbility.JumpHeight) / jumpAbility.JumpTimeToPeak * -1.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_jumpVelocity == 0)
|
||||
{
|
||||
_jumpVelocity = -400.0f;
|
||||
}
|
||||
_jumpVelocity = (2.0f * JumpHeight) / JumpTimeToPeak * -1.0f;
|
||||
}
|
||||
|
||||
public override Vector2 ProcessMovement(Vector2 velocity, double delta)
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace Mr.BrickAdventures.scripts.components;
|
||||
[GlobalClass]
|
||||
public partial class GravityAbility : MovementAbility
|
||||
{
|
||||
public float AscendGravity { get; set; }
|
||||
public float DescendGravity { get; set; }
|
||||
[Export] public float AscendGravity { get; set; } = 980f;
|
||||
[Export] public float DescendGravity { get; set; } = 1960f;
|
||||
|
||||
private float _gravity;
|
||||
|
||||
|
||||
@@ -26,8 +26,6 @@ public partial class GridMovementAbility : MovementAbility
|
||||
|
||||
public override Vector2 ProcessMovement(Vector2 currentVelocity, double delta)
|
||||
{
|
||||
GD.Print($"Player position: {_body.Position}, {_body.GlobalPosition}");
|
||||
|
||||
var inputDirection = _input.MoveDirection;
|
||||
var newDirection = Vector2.Zero;
|
||||
|
||||
|
||||
@@ -30,8 +30,6 @@ public abstract partial class MovementAbility : Node
|
||||
SetProcess(false);
|
||||
SetPhysicsProcess(false);
|
||||
}
|
||||
|
||||
_body.Velocity = Vector2.Zero;
|
||||
}
|
||||
|
||||
public abstract Vector2 ProcessMovement(Vector2 currentVelocity, double delta);
|
||||
|
||||
@@ -13,7 +13,7 @@ public partial class PlayerInputHandler : Node
|
||||
public bool DownReleased { get; private set; }
|
||||
public bool DownHeld { get; private set; }
|
||||
|
||||
public override void _Process(double delta)
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
MoveDirection = Input.GetVector("left", "right", "up", "down");
|
||||
|
||||
|
||||
@@ -12,14 +12,21 @@ public partial class WallJumpAbility : MovementAbility
|
||||
[Export(PropertyHint.Range, "0.0, 1.0, 0.05")] public float WallSlideGravityMultiplier { get; set; } = 0.7f;
|
||||
[Export] public float MaxWallSlideSpeed { get; set; } = 150.0f;
|
||||
|
||||
private float _gravity;
|
||||
|
||||
public override void Initialize(PlayerController controller)
|
||||
{
|
||||
base.Initialize(controller);
|
||||
_gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity");
|
||||
}
|
||||
|
||||
public override Vector2 ProcessMovement(Vector2 velocity, double delta)
|
||||
{
|
||||
var isOnWall = _body.IsOnWall();
|
||||
|
||||
if (isOnWall && !_body.IsOnFloor() && velocity.Y > 0f)
|
||||
{
|
||||
var gravity = (float)ProjectSettings.GetSetting("physics/2d/default_gravity");
|
||||
var newYVelocity = velocity.Y + gravity * WallSlideGravityMultiplier * (float)delta;
|
||||
var newYVelocity = velocity.Y + _gravity * WallSlideGravityMultiplier * (float)delta;
|
||||
|
||||
velocity.Y = Mathf.Min(newYVelocity, MaxWallSlideSpeed);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
@@ -10,15 +9,7 @@ namespace Mr.BrickAdventures.scripts.components;
|
||||
public partial class PlayerController : CharacterBody2D
|
||||
{
|
||||
[Export] private Node MovementAbilitiesContainer { get; set; }
|
||||
|
||||
[ExportGroup("Movement Ability Scenes")]
|
||||
[Export] public PackedScene GroundMovementScene { get; set; }
|
||||
[Export] public PackedScene JumpMovementScene { get; set; }
|
||||
[Export] public PackedScene GravityScene { get; set; }
|
||||
[Export] public PackedScene OneWayPlatformScene { get; set; }
|
||||
[Export] public PackedScene SpaceshipMovementScene { get; set; }
|
||||
[Export] public PackedScene WallJumpScene { get; set; }
|
||||
[Export] public PackedScene GridMovementScene { get; set; }
|
||||
[Export] public MovementPreset DefaultPreset { get; set; }
|
||||
|
||||
[Signal] public delegate void JumpInitiatedEventHandler();
|
||||
[Signal] public delegate void MovementAbilitiesChangedEventHandler();
|
||||
@@ -48,16 +39,10 @@ public partial class PlayerController : CharacterBody2D
|
||||
}
|
||||
|
||||
_inputHandler = GetNode<PlayerInputHandler>("PlayerInputHandler");
|
||||
foreach (var child in MovementAbilitiesContainer.GetChildren())
|
||||
{
|
||||
if (child is MovementAbility ability)
|
||||
{
|
||||
ability.Initialize(this);
|
||||
_abilities.Add(ability);
|
||||
}
|
||||
}
|
||||
|
||||
_ = ConnectJumpAndGravityAbilities();
|
||||
if (DefaultPreset != null)
|
||||
ApplyPreset(DefaultPreset);
|
||||
|
||||
EmitSignalMovementAbilitiesChanged();
|
||||
EventBus.EmitPlayerSpawned(this);
|
||||
}
|
||||
@@ -81,6 +66,19 @@ public partial class PlayerController : CharacterBody2D
|
||||
MoveAndSlide();
|
||||
}
|
||||
|
||||
public void ApplyPreset(MovementPreset preset)
|
||||
{
|
||||
if (preset == null) return;
|
||||
ClearMovementAbilities();
|
||||
Velocity = Vector2.Zero;
|
||||
foreach (var scene in preset.Abilities)
|
||||
{
|
||||
if (scene != null)
|
||||
AddAbility(scene.Instantiate<MovementAbility>());
|
||||
}
|
||||
EmitSignalMovementAbilitiesChanged();
|
||||
}
|
||||
|
||||
public void AddAbility(MovementAbility ability)
|
||||
{
|
||||
MovementAbilitiesContainer.AddChild(ability);
|
||||
@@ -110,46 +108,4 @@ public partial class PlayerController : CharacterBody2D
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPlatformMovement()
|
||||
{
|
||||
ClearMovementAbilities();
|
||||
|
||||
if (GroundMovementScene != null) AddAbility(GroundMovementScene.Instantiate<MovementAbility>());
|
||||
if (JumpMovementScene != null) AddAbility(JumpMovementScene.Instantiate<MovementAbility>());
|
||||
if (GravityScene != null) AddAbility(GravityScene.Instantiate<MovementAbility>());
|
||||
if (OneWayPlatformScene != null) AddAbility(OneWayPlatformScene.Instantiate<MovementAbility>());
|
||||
|
||||
_ = ConnectJumpAndGravityAbilities();
|
||||
EmitSignalMovementAbilitiesChanged();
|
||||
}
|
||||
|
||||
public void SetSpaceshipMovement()
|
||||
{
|
||||
ClearMovementAbilities();
|
||||
|
||||
if (SpaceshipMovementScene != null) AddAbility(SpaceshipMovementScene.Instantiate<MovementAbility>());
|
||||
EmitSignalMovementAbilitiesChanged();
|
||||
}
|
||||
|
||||
public void SetGridMovement()
|
||||
{
|
||||
ClearMovementAbilities();
|
||||
if (GridMovementScene != null) AddAbility(GridMovementScene.Instantiate<MovementAbility>());
|
||||
EmitSignalMovementAbilitiesChanged();
|
||||
}
|
||||
|
||||
private async Task ConnectJumpAndGravityAbilities()
|
||||
{
|
||||
await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame);
|
||||
|
||||
var jumpAbility = _abilities.OfType<VariableJumpAbility>().FirstOrDefault();
|
||||
var gravityAbility = _abilities.OfType<GravityAbility>().FirstOrDefault();
|
||||
|
||||
if (jumpAbility != null && gravityAbility != null)
|
||||
{
|
||||
gravityAbility.AscendGravity = jumpAbility.AscendGravity;
|
||||
gravityAbility.DescendGravity = jumpAbility.DescendGravity;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SpaceshipEnterComponent : Area2D
|
||||
{
|
||||
[Export] public MovementPreset Preset { get; set; }
|
||||
[Signal] public delegate void SpaceshipEnteredEventHandler();
|
||||
|
||||
public override void _Ready()
|
||||
@@ -15,7 +17,7 @@ public partial class SpaceshipEnterComponent : Area2D
|
||||
private void OnBodyEntered(Node2D body)
|
||||
{
|
||||
if (body is not PlayerController player) return;
|
||||
player.SetSpaceshipMovement();
|
||||
player.ApplyPreset(Preset);
|
||||
EmitSignalSpaceshipEntered();
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SpaceshipExitComponent : Area2D
|
||||
{
|
||||
[Export] public MovementPreset Preset { get; set; }
|
||||
[Signal] public delegate void SpaceshipExitEventHandler();
|
||||
|
||||
public override void _Ready()
|
||||
@@ -16,6 +18,6 @@ public partial class SpaceshipExitComponent : Area2D
|
||||
{
|
||||
if (body is not PlayerController player) return;
|
||||
EmitSignalSpaceshipExit();
|
||||
player.SetPlatformMovement();
|
||||
player.ApplyPreset(Preset);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user