refactor: movement system - MovementPreset, decouple abilities, fix timing
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Godot;
|
using Godot;
|
||||||
using Mr.BrickAdventures.scripts.components;
|
using Mr.BrickAdventures.scripts.components;
|
||||||
|
using Mr.BrickAdventures.scripts.Resources;
|
||||||
|
|
||||||
namespace Mr.BrickAdventures.scripts;
|
namespace Mr.BrickAdventures.scripts;
|
||||||
|
|
||||||
@@ -8,17 +9,17 @@ namespace Mr.BrickAdventures.scripts;
|
|||||||
public partial class PacXonLevel : Node
|
public partial class PacXonLevel : Node
|
||||||
{
|
{
|
||||||
[Export] public PlayerController Player { get; set; }
|
[Export] public PlayerController Player { get; set; }
|
||||||
|
[Export] public MovementPreset GridPreset { get; set; }
|
||||||
[Export] public PacXonGridManager GridManager { get; set; }
|
[Export] public PacXonGridManager GridManager { get; set; }
|
||||||
[Export] public Node GhostContainer { get; set; }
|
[Export] public Node GhostContainer { get; set; }
|
||||||
[Export] public Label PercentageLabel { get; set; }
|
[Export] public Label PercentageLabel { get; set; }
|
||||||
|
|
||||||
private const float WinPercentage = 0.90f;
|
private const float WinPercentage = 0.90f;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
var ghosts = GhostContainer.GetChildren().OfType<Node2D>().ToList();
|
var ghosts = GhostContainer.GetChildren().OfType<Node2D>().ToList();
|
||||||
Player.ClearMovementAbilities();
|
Player.ApplyPreset(GridPreset);
|
||||||
Player.SetGridMovement();
|
|
||||||
|
|
||||||
foreach (var ghost in ghosts)
|
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]
|
[GlobalClass]
|
||||||
public partial class DoubleJumpAbility : MovementAbility
|
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 bool _hasDoubleJumped = false;
|
||||||
private float _jumpVelocity;
|
private float _jumpVelocity;
|
||||||
|
|
||||||
public override void Initialize(PlayerController controller)
|
public override void Initialize(PlayerController controller)
|
||||||
{
|
{
|
||||||
base.Initialize(controller);
|
base.Initialize(controller);
|
||||||
|
_jumpVelocity = (2.0f * JumpHeight) / JumpTimeToPeak * -1.0f;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Vector2 ProcessMovement(Vector2 velocity, double delta)
|
public override Vector2 ProcessMovement(Vector2 velocity, double delta)
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ namespace Mr.BrickAdventures.scripts.components;
|
|||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class GravityAbility : MovementAbility
|
public partial class GravityAbility : MovementAbility
|
||||||
{
|
{
|
||||||
public float AscendGravity { get; set; }
|
[Export] public float AscendGravity { get; set; } = 980f;
|
||||||
public float DescendGravity { get; set; }
|
[Export] public float DescendGravity { get; set; } = 1960f;
|
||||||
|
|
||||||
private float _gravity;
|
private float _gravity;
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ public partial class GridMovementAbility : MovementAbility
|
|||||||
|
|
||||||
public override Vector2 ProcessMovement(Vector2 currentVelocity, double delta)
|
public override Vector2 ProcessMovement(Vector2 currentVelocity, double delta)
|
||||||
{
|
{
|
||||||
GD.Print($"Player position: {_body.Position}, {_body.GlobalPosition}");
|
|
||||||
|
|
||||||
var inputDirection = _input.MoveDirection;
|
var inputDirection = _input.MoveDirection;
|
||||||
var newDirection = Vector2.Zero;
|
var newDirection = Vector2.Zero;
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,6 @@ public abstract partial class MovementAbility : Node
|
|||||||
SetProcess(false);
|
SetProcess(false);
|
||||||
SetPhysicsProcess(false);
|
SetPhysicsProcess(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_body.Velocity = Vector2.Zero;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Vector2 ProcessMovement(Vector2 currentVelocity, double delta);
|
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 DownReleased { get; private set; }
|
||||||
public bool DownHeld { 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");
|
MoveDirection = Input.GetVector("left", "right", "up", "down");
|
||||||
|
|
||||||
|
|||||||
@@ -7,19 +7,26 @@ public partial class WallJumpAbility : MovementAbility
|
|||||||
{
|
{
|
||||||
[ExportGroup("Wall Jump Design")]
|
[ExportGroup("Wall Jump Design")]
|
||||||
[Export] public Vector2 WallJumpVelocity { get; set; } = new(500.0f, -350.0f);
|
[Export] public Vector2 WallJumpVelocity { get; set; } = new(500.0f, -350.0f);
|
||||||
|
|
||||||
[ExportGroup("Wall Slide Feel")]
|
[ExportGroup("Wall Slide Feel")]
|
||||||
[Export(PropertyHint.Range, "0.0, 1.0, 0.05")] public float WallSlideGravityMultiplier { get; set; } = 0.7f;
|
[Export(PropertyHint.Range, "0.0, 1.0, 0.05")] public float WallSlideGravityMultiplier { get; set; } = 0.7f;
|
||||||
[Export] public float MaxWallSlideSpeed { get; set; } = 150.0f;
|
[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)
|
public override Vector2 ProcessMovement(Vector2 velocity, double delta)
|
||||||
{
|
{
|
||||||
var isOnWall = _body.IsOnWall();
|
var isOnWall = _body.IsOnWall();
|
||||||
|
|
||||||
if (isOnWall && !_body.IsOnFloor() && velocity.Y > 0f)
|
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);
|
velocity.Y = Mathf.Min(newYVelocity, MaxWallSlideSpeed);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
using Mr.BrickAdventures.Autoloads;
|
using Mr.BrickAdventures.Autoloads;
|
||||||
|
using Mr.BrickAdventures.scripts.Resources;
|
||||||
|
|
||||||
namespace Mr.BrickAdventures.scripts.components;
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
@@ -10,15 +9,7 @@ namespace Mr.BrickAdventures.scripts.components;
|
|||||||
public partial class PlayerController : CharacterBody2D
|
public partial class PlayerController : CharacterBody2D
|
||||||
{
|
{
|
||||||
[Export] private Node MovementAbilitiesContainer { get; set; }
|
[Export] private Node MovementAbilitiesContainer { get; set; }
|
||||||
|
[Export] public MovementPreset DefaultPreset { 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; }
|
|
||||||
|
|
||||||
[Signal] public delegate void JumpInitiatedEventHandler();
|
[Signal] public delegate void JumpInitiatedEventHandler();
|
||||||
[Signal] public delegate void MovementAbilitiesChangedEventHandler();
|
[Signal] public delegate void MovementAbilitiesChangedEventHandler();
|
||||||
@@ -48,16 +39,10 @@ public partial class PlayerController : CharacterBody2D
|
|||||||
}
|
}
|
||||||
|
|
||||||
_inputHandler = GetNode<PlayerInputHandler>("PlayerInputHandler");
|
_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();
|
EmitSignalMovementAbilitiesChanged();
|
||||||
EventBus.EmitPlayerSpawned(this);
|
EventBus.EmitPlayerSpawned(this);
|
||||||
}
|
}
|
||||||
@@ -81,6 +66,19 @@ public partial class PlayerController : CharacterBody2D
|
|||||||
MoveAndSlide();
|
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)
|
public void AddAbility(MovementAbility ability)
|
||||||
{
|
{
|
||||||
MovementAbilitiesContainer.AddChild(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 Godot;
|
||||||
|
using Mr.BrickAdventures.scripts.Resources;
|
||||||
|
|
||||||
namespace Mr.BrickAdventures.scripts.components;
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class SpaceshipEnterComponent : Area2D
|
public partial class SpaceshipEnterComponent : Area2D
|
||||||
{
|
{
|
||||||
|
[Export] public MovementPreset Preset { get; set; }
|
||||||
[Signal] public delegate void SpaceshipEnteredEventHandler();
|
[Signal] public delegate void SpaceshipEnteredEventHandler();
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
@@ -15,7 +17,7 @@ public partial class SpaceshipEnterComponent : Area2D
|
|||||||
private void OnBodyEntered(Node2D body)
|
private void OnBodyEntered(Node2D body)
|
||||||
{
|
{
|
||||||
if (body is not PlayerController player) return;
|
if (body is not PlayerController player) return;
|
||||||
player.SetSpaceshipMovement();
|
player.ApplyPreset(Preset);
|
||||||
EmitSignalSpaceshipEntered();
|
EmitSignalSpaceshipEntered();
|
||||||
QueueFree();
|
QueueFree();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
|
using Mr.BrickAdventures.scripts.Resources;
|
||||||
|
|
||||||
namespace Mr.BrickAdventures.scripts.components;
|
namespace Mr.BrickAdventures.scripts.components;
|
||||||
|
|
||||||
[GlobalClass]
|
[GlobalClass]
|
||||||
public partial class SpaceshipExitComponent : Area2D
|
public partial class SpaceshipExitComponent : Area2D
|
||||||
{
|
{
|
||||||
|
[Export] public MovementPreset Preset { get; set; }
|
||||||
[Signal] public delegate void SpaceshipExitEventHandler();
|
[Signal] public delegate void SpaceshipExitEventHandler();
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
BodyEntered += OnBodyEntered;
|
BodyEntered += OnBodyEntered;
|
||||||
@@ -16,6 +18,6 @@ public partial class SpaceshipExitComponent : Area2D
|
|||||||
{
|
{
|
||||||
if (body is not PlayerController player) return;
|
if (body is not PlayerController player) return;
|
||||||
EmitSignalSpaceshipExit();
|
EmitSignalSpaceshipExit();
|
||||||
player.SetPlatformMovement();
|
player.ApplyPreset(Preset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user