initial add
This commit is contained in:
215
gobbos_delivery/scripts/Player.cs
Normal file
215
gobbos_delivery/scripts/Player.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
using Godot;
|
||||
using gobbos_logic;
|
||||
|
||||
public partial class Player : CharacterBody2D, IPlayer
|
||||
{
|
||||
[Signal]
|
||||
public delegate void BlinkTimerTimeoutEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void WallCastDelayTimeoutEventHandler();
|
||||
|
||||
// Constants
|
||||
const double COYOTE_JUMP_WINDOW = 0.15;
|
||||
|
||||
// private readonly Vector2 TILE_SIZE = new(8, 8);
|
||||
|
||||
[Export]
|
||||
public AnimationPlayer Blinkplayer { get; set; }
|
||||
|
||||
private double timeSinceLeavingGround = 0.0;
|
||||
|
||||
public bool CanCoyoteJump => timeSinceLeavingGround < COYOTE_JUMP_WINDOW;
|
||||
|
||||
public void ResetCoyoteTimer()
|
||||
{
|
||||
timeSinceLeavingGround = 0.0;
|
||||
}
|
||||
|
||||
public float Acceleration { get; set; } = 4.0f;
|
||||
public float Friction { get; set; } = 4.0f;
|
||||
public float AirFriction { get; set; } = 0.1f;
|
||||
public float WallFriction { get; set; } = 1200.0f;
|
||||
public int Speed { get; set; } = 40;
|
||||
public int WallSpeed { get; set; } = 15;
|
||||
public float SlowMod { get; set; } = 0.5f;
|
||||
public int Gravity { get; set; } = 250;
|
||||
public int Jump { get; set; } = -95;
|
||||
public int WallJump { get; set; } = 55;
|
||||
public int LedgeJump { get; set; } = -70;
|
||||
public float FallMod { get; set; } = 1.5f;
|
||||
public float ParachuteMod { get; set; } = 0.2f;
|
||||
public bool OnLedge { get; set; } = false;
|
||||
public bool InParachute { get; set; } = false;
|
||||
public bool CanParachute { get; set; } = false;
|
||||
|
||||
public Vector2 AnimDir { get; set; } = Vector2.Zero;
|
||||
public Vector2 LastDir { get; set; } = Vector2.Zero;
|
||||
public Vector2 MoveDir { get; set; } = Vector2.Zero;
|
||||
public Label StateLabel { get; set; }
|
||||
public RayCast2D WallCastTop { get; set; }
|
||||
public RayCast2D WallCastMid { get; set; }
|
||||
public RayCast2D WallCastLow { get; set; }
|
||||
public AnimationNodeStateMachinePlayback AnimStateMachine { get; set; }
|
||||
public AnimationNodeStateMachinePlayback GroundedStateMachine { get; set; }
|
||||
public AnimationNodeStateMachinePlayback AirborneStateMachine { get; set; }
|
||||
public AnimationNodeStateMachinePlayback SprintStateMachine { get; set; }
|
||||
public float LastVelocityY { get; set; } = 0.0f;
|
||||
public float WallCastLength { get; set; } = 3.8f;
|
||||
public Timer WallCastDelayTimer { get; set; }
|
||||
|
||||
private RayCast2D cameraOffsetCast;
|
||||
private RayCast2D cameraDownCast;
|
||||
private Node2D modelContainer;
|
||||
private Timer blinkTimer;
|
||||
public AnimationTree animTree;
|
||||
private StateMachine stateMachine;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
modelContainer = GetNode<Node2D>("ModelContainer");
|
||||
blinkTimer = GetNode<Timer>("BlinkTimer");
|
||||
animTree = GetNode<AnimationTree>("AnimationTree");
|
||||
cameraOffsetCast = GetNode<RayCast2D>("CameraOffsetCast");
|
||||
cameraDownCast = GetNode<RayCast2D>("CameraOffsetCast/CameraDownCast");
|
||||
stateMachine = GetNode<StateMachine>("StateMachine");
|
||||
animTree.Set("parameters/Airborne/Standard/blend_position", 1.0f);
|
||||
animTree.Set("parameters/Airborne/Parachute/blend_position", 1.0f);
|
||||
|
||||
WallCastTop = GetNode<RayCast2D>("WallCastTop");
|
||||
WallCastMid = GetNode<RayCast2D>("WallCastMid");
|
||||
WallCastLow = GetNode<RayCast2D>("WallCastLow");
|
||||
WallCastDelayTimer = GetNode<Timer>("WallCastDelay");
|
||||
WallCastDelayTimer.Timeout += OnWallCastDelayTimeout;
|
||||
AnimStateMachine = (AnimationNodeStateMachinePlayback)animTree.Get("parameters/playback");
|
||||
GroundedStateMachine = (AnimationNodeStateMachinePlayback)animTree.Get("parameters/Grounded/playback");
|
||||
AirborneStateMachine = (AnimationNodeStateMachinePlayback)animTree.Get("parameters/Airborne/playback");
|
||||
SprintStateMachine = (AnimationNodeStateMachinePlayback)animTree.Get("parameters/Grounded/Sprint/playback");
|
||||
StateLabel = GetNode<Label>("StateLabel");
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
var floatDelta = (float)delta;
|
||||
Vector2 inputDir = new(Input.GetAxis("move_left", "move_right"), Input.GetAxis("move_up", "move_down"));
|
||||
|
||||
if (inputDir.X != 0.0f)
|
||||
{
|
||||
MoveDir = new(Mathf.MoveToward(MoveDir.X, inputDir.X, 20 * floatDelta), MoveDir.Y);
|
||||
LastDir = new(inputDir.X, LastDir.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveDir = new Vector2(
|
||||
Mathf.MoveToward(MoveDir.X, 0.0f, 20 * floatDelta),
|
||||
MoveDir.Y);
|
||||
}
|
||||
|
||||
if (inputDir.Y != 0.0f)
|
||||
{
|
||||
MoveDir = new(MoveDir.X, Mathf.MoveToward(MoveDir.Y, inputDir.Y, 20 * floatDelta));
|
||||
LastDir = new(LastDir.X, inputDir.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveDir = new(MoveDir.X, Mathf.MoveToward(MoveDir.Y, 0.0f, 20 * floatDelta));
|
||||
}
|
||||
|
||||
AnimDir = new(Mathf.MoveToward(AnimDir.X, LastDir.X, 20 * floatDelta), AnimDir.Y);
|
||||
|
||||
// Set wall cast positions based on input direction
|
||||
if (inputDir.X > 0)
|
||||
{
|
||||
WallCastTop.TargetPosition = new(WallCastLength, WallCastTop.TargetPosition.Y);
|
||||
WallCastMid.TargetPosition = new(WallCastLength, WallCastMid.TargetPosition.Y);
|
||||
WallCastLow.TargetPosition = new(WallCastLength, WallCastLow.TargetPosition.Y);
|
||||
}
|
||||
else if (inputDir.X < 0)
|
||||
{
|
||||
WallCastTop.TargetPosition = new(0.0f - WallCastLength, WallCastTop.TargetPosition.Y);
|
||||
WallCastMid.TargetPosition = new(0.0f - WallCastLength, WallCastMid.TargetPosition.Y);
|
||||
WallCastLow.TargetPosition = new(0.0f - WallCastLength, WallCastLow.TargetPosition.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
WallCastTop.TargetPosition = new(0.0f, WallCastTop.TargetPosition.Y);
|
||||
WallCastMid.TargetPosition = new(0.0f, WallCastMid.TargetPosition.Y);
|
||||
WallCastLow.TargetPosition = new(0.0f, WallCastLow.TargetPosition.Y);
|
||||
}
|
||||
|
||||
// Update animation parameters
|
||||
animTree.Set("parameters/Airborne/Standard/0/blend_position", Velocity.Y);
|
||||
animTree.Set("parameters/Airborne/Standard/1/blend_position", Velocity.Y);
|
||||
animTree.Set("parameters/Airborne/Parachute/0/blend_position", Velocity.Y);
|
||||
animTree.Set("parameters/Airborne/Parachute/1/blend_position", Velocity.Y);
|
||||
|
||||
// Create tweens for animation blending
|
||||
var idleBlend = GetTree().CreateTween();
|
||||
var walkBlend = GetTree().CreateTween();
|
||||
var airBlend = GetTree().CreateTween();
|
||||
var parachuteBlend = GetTree().CreateTween();
|
||||
|
||||
idleBlend.TweenProperty(animTree, "parameters/Grounded/Idle/blend_position", AnimDir.X, 0.2f);
|
||||
walkBlend.TweenProperty(animTree, "parameters/Grounded/Walk/blend_position", AnimDir.X, 0.2f);
|
||||
airBlend.TweenProperty(animTree, "parameters/Airborne/Standard/blend_position", AnimDir.X, 0.2f);
|
||||
parachuteBlend.TweenProperty(animTree, "parameters/Airborne/Parachute/blend_position", AnimDir.X, 0.5f);
|
||||
|
||||
TiltModel(floatDelta);
|
||||
CameraOffset();
|
||||
|
||||
// Increment time since leaving ground if not on floor
|
||||
if (!IsOnFloor())
|
||||
{
|
||||
timeSinceLeavingGround += delta;
|
||||
}
|
||||
|
||||
// Call StateMachine PhysicsUpdate to handle state-specific movement
|
||||
stateMachine?.PhysicsUpdate(floatDelta);
|
||||
|
||||
MoveAndSlide();
|
||||
}
|
||||
|
||||
private void CameraOffset()
|
||||
{
|
||||
var targetX = Mathf.Lerp(cameraOffsetCast.TargetPosition.X, AnimDir.X * 50.0f, 0.6f);
|
||||
cameraOffsetCast.TargetPosition = new(targetX, cameraOffsetCast.TargetPosition.Y);
|
||||
|
||||
if (cameraOffsetCast.IsColliding())
|
||||
{
|
||||
cameraDownCast.Position = cameraOffsetCast.GetCollisionPoint();
|
||||
cameraDownCast.Position = new(cameraDownCast.Position.X, cameraDownCast.Position.Y + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
cameraDownCast.Position = cameraOffsetCast.GlobalPosition + cameraOffsetCast.TargetPosition;
|
||||
}
|
||||
}
|
||||
|
||||
private void TiltModel(float delta)
|
||||
{
|
||||
var floorNormal = GetFloorNormal();
|
||||
var tilt = 0.0f;
|
||||
|
||||
if (floorNormal != new Vector2(0.0f, -1.0f))
|
||||
{
|
||||
tilt = Mathf.Atan2(floorNormal.X, floorNormal.Y);
|
||||
tilt /= 10;
|
||||
}
|
||||
|
||||
modelContainer.Rotation = Mathf.Lerp(modelContainer.Rotation, tilt, 5 * delta);
|
||||
}
|
||||
|
||||
private void OnBlinkTimerTimeout()
|
||||
{
|
||||
Blinkplayer?.Play("blink");
|
||||
var randomWaitTime = GD.RandRange(1.0f, 7.0f);
|
||||
blinkTimer?.WaitTime = randomWaitTime;
|
||||
}
|
||||
|
||||
private void OnWallCastDelayTimeout()
|
||||
{
|
||||
WallCastTop.Enabled = true;
|
||||
WallCastMid.Enabled = true;
|
||||
WallCastLow.Enabled = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user