Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extends KinematicBody2D
- # Initialize the nodes
- onready var tween_node = $Tween
- onready var animation_player_node = $AnimationPlayer
- onready var sprite_node = $Sprite
- onready var collision_capsule_node = $CollisionCapsule
- # Finite state machine
- enum states {
- Idle,
- Move,
- }
- var state = states.Move
- # TODO tween gravity?, build a parkour and test the player in it, adjust slope angle and slope stop
- # FIXME walking against a wall causes stuttering on certain resolutions
- # States.Idle is never used!!!
- var velocity = Vector2.ZERO;
- var max_slope = deg2rad(45)
- const FLOOR = Vector2(0, -1)
- export var jump_speed = 400
- export var gravity = 12
- export var walking_speed = 10
- export var max_running_speed = 200
- var ground_damping = 0.5
- var ground_turning_damping = 0.3
- var air_damping = 0.55
- var spriting_turning_multiplier = 0.9
- var sprinting_multiplier = 1.2
- var animation_name = "Idle"
- var unskippable_animations = ["RunTurn", "FastLanding", "SlowLanding"];
- var _scale = 1
- var min_speed_for_falling_animation = 100
- var min_walking_speed = 10
- var max_walking_speed = 115
- var jump_pressed_timer = 0
- var jump_pressed_timer_max_time = 0.2
- var was_on_floor_timer = 0
- var was_on_floor_timer_max_time = 0.1
- var variable_jump_decrease = 0.8
- var slowdown_timer = 0
- var slowdown_timer_max_time = 1.0
- var air_speed = 0
- var speed_for_slow_landing = 380
- var has_player_jump_start = false
- # Input
- var left;
- var right;
- var turning;
- func _physics_process(delta):
- # Always running functions
- _animate();
- match state:
- states.Idle:
- _get_input()
- _idle_state()
- states.Move:
- _get_input()
- _movement(delta)
- _jumping(delta)
- func _idle_state() -> void:
- if left || right:
- state = states.Move
- if Input.is_action_just_pressed("jump"):
- state = states.Jump
- func _get_input():
- left = Input.is_action_pressed("move_left")
- right = Input.is_action_pressed("move_right")
- turning = (velocity.x > 0 && left) || (velocity.x < 0 && right);
- func _movement(delta) -> void:
- if animation_name == "FastLanding" || animation_name == "SlowLanding":
- return
- if left && (animation_name != "RunTurn" || sprite_node.scale.x == 1):
- velocity.x -= walking_speed
- if right && (animation_name != "RunTurn" || sprite_node.scale.x == -1):
- velocity.x += walking_speed
- if is_on_floor():
- # Activates when changing direction
- if turning:
- velocity.x *= pow(1.0 - ground_turning_damping, delta * 10.0)
- # Slows down the velocity
- else:
- velocity.x *= pow(1.0 - ground_damping, delta * 10.0)
- # Slows horizontal movement when in the air
- else:
- velocity.x *= pow(1.0 - air_damping, delta * 10.0)
- # Sprinting
- if Input.is_action_pressed("sprint") && abs(velocity.x) < 200 && (left || right):
- # Deaccelerate faster when changing direction while sprinting
- if turning:
- velocity.x *= spriting_turning_multiplier
- # Boost the speed
- else:
- velocity.x *= sprinting_multiplier
- # Adjust the running speed
- velocity.x = clamp(velocity.x, 0, max_running_speed) if right else clamp(velocity.x, -max_running_speed, 0)
- # Move the character
- velocity = move_and_slide(velocity, FLOOR, false, 4, max_slope)
- if velocity.y > air_speed:
- air_speed = velocity.y
- # Jumping
- _jumping(delta)
- func _jumping(delta) -> void:
- velocity.y += gravity;
- if jump_pressed_timer > 0: jump_pressed_timer -= delta
- if was_on_floor_timer > 0: was_on_floor_timer -= delta
- # Jump a bit after exited the collision to make platforming smoother
- if is_on_floor():
- was_on_floor_timer = was_on_floor_timer_max_time
- # Jump even if the jump button was pressed a bit early
- if Input.is_action_just_pressed("jump") && animation_name != "RunTurn":
- jump_pressed_timer = jump_pressed_timer_max_time
- # Decrease y velocity when not holding jump button and the peak height is not reached
- if Input.is_action_just_released("jump") && velocity.y < 0:
- velocity.y *= variable_jump_decrease
- if jump_pressed_timer > 0 && was_on_floor_timer > 0:
- jump_pressed_timer = 0
- was_on_floor_timer = 0
- velocity.y = -jump_speed
- func _animate() -> void:
- if (animation_name == "JumpFall" || animation_name == "RunJumpFall") && is_on_floor():
- if(air_speed > speed_for_slow_landing):
- air_speed = 0
- animation_name = "SlowLanding"
- else:
- animation_name = "FastLanding"
- animation_player_node.play(animation_name);
- return
- # Animations that have to be played completely
- if(unskippable_animations.has(animation_name)):
- return
- # Scaling
- if round(velocity.x) > 0:
- _scale = 1
- elif round(velocity.x) < 0:
- _scale = -1
- if(sprite_node.scale.x != _scale || collision_capsule_node.position.x != _scale):
- sprite_node.scale.x = _scale;
- collision_capsule_node.position.x *= _scale
- # On floor
- var running = abs(velocity.x) > max_walking_speed
- if is_on_floor():
- if abs(velocity.x) < min_walking_speed:
- animation_name = "Idle"
- else:
- if running:
- animation_name = "Run"
- else:
- animation_name = "Walk"
- if turning:
- if(abs(velocity.x) <= max_walking_speed):
- animation_name = "IdleTurn"
- else:
- animation_name = "RunTurn"
- # In the air
- elif get_slide_count() == 0 && abs(velocity.y) > min_speed_for_falling_animation:
- # Going upwards
- if velocity.y < 0:
- if has_player_jump_start:
- if(running):
- animation_name = "RunJump"
- else:
- animation_name = "Jump"
- else:
- if(running):
- animation_name = "RunJumpStart"
- else:
- animation_name = "JumpStart"
- # Falling down
- else:
- if(running):
- animation_name = "RunJumpFall"
- else:
- animation_name = "JumpFall"
- if animation_player_node.current_animation != animation_name:
- animation_player_node.play(animation_name)
- func _on_AnimationPlayer_animation_finished(anim_name):
- animation_name = ""
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement