add player mechanics
This commit is contained in:
parent
5e54f1c329
commit
c37b11005f
@ -1,35 +1,83 @@
|
|||||||
using Godot;
|
using Godot;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
public class Player : KinematicBody2D
|
public class Player : KinematicBody2D
|
||||||
{
|
{
|
||||||
[Export]
|
[Export]
|
||||||
private bool _invincible { get; set; }
|
private bool _isInvincible { get; set; } = false;
|
||||||
|
[Export]
|
||||||
|
private bool _canDoubleJump { get; set; } = true;
|
||||||
|
[Export]
|
||||||
|
private bool _cayoteTime { get; set; } = true;
|
||||||
|
[Export]
|
||||||
|
private int _maxWalkSpeed { get; set; } = 50;
|
||||||
|
[Export]
|
||||||
|
private int _maxRunSpeed { get; set; } = 150;
|
||||||
private Event _eventBus;
|
private Event _eventBus;
|
||||||
private Vector2 _velocity;
|
private Vector2 _velocity;
|
||||||
|
private AnimatedSprite _sprite;
|
||||||
|
private Camera2D _camera;
|
||||||
|
private Timer _cayoteTimer;
|
||||||
|
|
||||||
|
private enum State
|
||||||
|
{
|
||||||
|
Idle,
|
||||||
|
Walk,
|
||||||
|
Jump,
|
||||||
|
DoubleJump,
|
||||||
|
Fall,
|
||||||
|
Swim
|
||||||
|
};
|
||||||
|
|
||||||
|
private Dictionary<State, Action<float>> _states;
|
||||||
|
private Stack<State> _stateStack;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
_eventBus = GetNode<Event>("/root/Event");
|
_eventBus = GetNode<Event>("/root/Event");
|
||||||
_eventBus.Connect("PlayerTouched", this, "PlayerTouched");
|
_eventBus.Connect("PlayerTouched", this, "PlayerTouched");
|
||||||
_invincible = false;
|
|
||||||
_velocity = new Vector2();
|
_velocity = new Vector2();
|
||||||
|
_sprite = GetNode<AnimatedSprite>("AnimatedSprite");
|
||||||
|
_camera = GetNode<Camera2D>("Camera2D");
|
||||||
|
|
||||||
|
_cayoteTimer = GetNode<Timer>("CayoteTimer");
|
||||||
|
|
||||||
|
_states = new Dictionary<State, Action<float>>();
|
||||||
|
_states.Add(State.Idle, Idle);
|
||||||
|
_states.Add(State.Walk, Walk);
|
||||||
|
_states.Add(State.Fall, Fall);
|
||||||
|
_states.Add(State.Jump, Jump);
|
||||||
|
_states.Add(State.DoubleJump, Jump);
|
||||||
|
|
||||||
|
_stateStack = new Stack<State>();
|
||||||
|
_stateStack.Push(State.Idle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _PhysicsProcess(float delta)
|
public override void _PhysicsProcess(float delta)
|
||||||
{
|
{
|
||||||
_velocity.x = 0;
|
_states[_stateStack.Peek()].Invoke(delta);
|
||||||
|
|
||||||
if (Input.IsActionPressed("right"))
|
var maxSpeed = (Input.IsActionPressed("run")) ? _maxRunSpeed : _maxWalkSpeed;
|
||||||
|
|
||||||
|
_velocity.x = Mathf.Clamp(_velocity.x, -_maxRunSpeed, _maxRunSpeed);
|
||||||
|
|
||||||
|
if (_velocity.x > maxSpeed)
|
||||||
{
|
{
|
||||||
_velocity.x += 50;
|
_velocity.x = Mathf.Lerp(maxSpeed, _velocity.x, 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input.IsActionPressed("left")) {
|
if (_velocity.x < -maxSpeed)
|
||||||
_velocity.x -= 50;
|
{
|
||||||
|
_velocity.x = Mathf.Lerp(-maxSpeed, _velocity.x, 0.1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
_velocity = MoveAndSlide(_velocity, Vector2.Up);
|
_velocity = MoveAndSlide(_velocity, Vector2.Up);
|
||||||
|
|
||||||
|
// Make sure the player is drawn in pixel perfect spacing
|
||||||
|
Mathf.Round(Position.x);
|
||||||
|
Mathf.Round(Position.y);
|
||||||
|
|
||||||
var count = GetSlideCount();
|
var count = GetSlideCount();
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
@ -39,10 +87,200 @@ public class Player : KinematicBody2D
|
|||||||
{
|
{
|
||||||
_eventBus.EmitSignal("PlayerTouched");
|
_eventBus.EmitSignal("PlayerTouched");
|
||||||
}
|
}
|
||||||
|
collision.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayerTouched() {
|
private void ApplyGravity(float delta)
|
||||||
|
{
|
||||||
|
_velocity.y += (int) ProjectSettings.GetSetting("physics/2d/default_gravity") * delta * 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnterState(State state)
|
||||||
|
{
|
||||||
|
_eventBus.EmitSignal("DebugState", state.ToString());
|
||||||
|
_stateStack.Push(state);
|
||||||
|
ChangeStateMechanics();
|
||||||
|
ChangeStateAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExitState()
|
||||||
|
{
|
||||||
|
_stateStack.Pop();
|
||||||
|
_eventBus.EmitSignal("DebugState", _stateStack.Peek().ToString());
|
||||||
|
ChangeStateAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeStateMechanics()
|
||||||
|
{
|
||||||
|
switch (_stateStack.Peek())
|
||||||
|
{
|
||||||
|
case State.Jump:
|
||||||
|
_velocity.y = -250;
|
||||||
|
break;
|
||||||
|
case State.DoubleJump:
|
||||||
|
_velocity.y = -260;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_cayoteTimer.Stop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeStateAnimation()
|
||||||
|
{
|
||||||
|
switch (_stateStack.Peek())
|
||||||
|
{
|
||||||
|
case State.Idle:
|
||||||
|
_sprite.Play("idle");
|
||||||
|
break;
|
||||||
|
case State.Walk:
|
||||||
|
_sprite.Play("walk");
|
||||||
|
break;
|
||||||
|
case State.Fall:
|
||||||
|
_sprite.Play("jump");
|
||||||
|
break;
|
||||||
|
case State.Jump:
|
||||||
|
_sprite.Play("jump");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Idle(float delta)
|
||||||
|
{
|
||||||
|
ApplyGravity(delta);
|
||||||
|
|
||||||
|
_velocity.x = Mathf.Lerp(_velocity.x, 0, 0.5f);
|
||||||
|
|
||||||
|
if (Input.IsActionPressed("right") || Input.IsActionPressed("left"))
|
||||||
|
{
|
||||||
|
EnterState(State.Walk);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.IsActionJustPressed("jump"))
|
||||||
|
{
|
||||||
|
EnterState(State.Jump);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsOnFloor())
|
||||||
|
{
|
||||||
|
EnterState(State.Fall);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Walk(float delta)
|
||||||
|
{
|
||||||
|
ApplyGravity(delta);
|
||||||
|
|
||||||
|
if (Input.IsActionPressed("right"))
|
||||||
|
{
|
||||||
|
_velocity.x += (_velocity.x < 0) ? 9 : 3;
|
||||||
|
|
||||||
|
// Ice:
|
||||||
|
//_velocity.x += 3;
|
||||||
|
|
||||||
|
_sprite.FlipH = false;
|
||||||
|
}
|
||||||
|
else if (Input.IsActionPressed("left"))
|
||||||
|
{
|
||||||
|
_velocity.x -= (_velocity.x > 0) ? 9 : 3;
|
||||||
|
|
||||||
|
// Ice:
|
||||||
|
//_velocity.x -= 3;
|
||||||
|
|
||||||
|
_sprite.FlipH = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ExitState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.IsActionJustPressed("jump"))
|
||||||
|
{
|
||||||
|
EnterState(State.Jump);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsOnFloor())
|
||||||
|
{
|
||||||
|
if (!_cayoteTime)
|
||||||
|
{
|
||||||
|
EnterState(State.Fall);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_cayoteTimer.TimeLeft == 0)
|
||||||
|
{
|
||||||
|
_cayoteTimer.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Fall(float delta)
|
||||||
|
{
|
||||||
|
JumpMove(delta);
|
||||||
|
|
||||||
|
if (IsOnFloor())
|
||||||
|
{
|
||||||
|
ExitState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Jump(float delta)
|
||||||
|
{
|
||||||
|
JumpMove(delta);
|
||||||
|
|
||||||
|
if (_canDoubleJump && _stateStack.Peek() != State.DoubleJump && Input.IsActionJustPressed("jump"))
|
||||||
|
{
|
||||||
|
EnterState(State.DoubleJump);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsOnFloor())
|
||||||
|
{
|
||||||
|
ExitState();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void JumpMove(float delta)
|
||||||
|
{
|
||||||
|
ApplyGravity(delta);
|
||||||
|
|
||||||
|
if (Input.IsActionJustReleased("jump"))
|
||||||
|
{
|
||||||
|
if (_velocity.y < -100)
|
||||||
|
{
|
||||||
|
_velocity.y = -100;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.IsActionPressed("right"))
|
||||||
|
{
|
||||||
|
_velocity.x += (_velocity.x >= 20) ? 2 : 5;
|
||||||
|
_sprite.FlipH = false;
|
||||||
|
}
|
||||||
|
else if (Input.IsActionPressed("left"))
|
||||||
|
{
|
||||||
|
_velocity.x -= (_velocity.x <= -20) ? 2 : 5;
|
||||||
|
_sprite.FlipH = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnCayoteTimerTimeout()
|
||||||
|
{
|
||||||
|
EnterState(State.Fall);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlayerTouched()
|
||||||
|
{
|
||||||
GD.Print("Touched");
|
GD.Print("Touched");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,8 +131,9 @@ animations = [ {
|
|||||||
extents = Vector2( 6, 6.5 )
|
extents = Vector2( 6, 6.5 )
|
||||||
|
|
||||||
[node name="Player" type="KinematicBody2D"]
|
[node name="Player" type="KinematicBody2D"]
|
||||||
collision_mask = 0
|
collision_mask = 2
|
||||||
script = ExtResource( 10 )
|
script = ExtResource( 10 )
|
||||||
|
_canDoubleJump = false
|
||||||
|
|
||||||
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
|
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
|
||||||
frames = SubResource( 3 )
|
frames = SubResource( 3 )
|
||||||
@ -145,3 +146,8 @@ shape = SubResource( 4 )
|
|||||||
|
|
||||||
[node name="Camera2D" type="Camera2D" parent="."]
|
[node name="Camera2D" type="Camera2D" parent="."]
|
||||||
current = true
|
current = true
|
||||||
|
|
||||||
|
[node name="CayoteTimer" type="Timer" parent="."]
|
||||||
|
wait_time = 0.2
|
||||||
|
|
||||||
|
[connection signal="timeout" from="CayoteTimer" to="." method="OnCayoteTimerTimeout"]
|
||||||
|
Loading…
Reference in New Issue
Block a user