195 lines
4.0 KiB
GDScript
195 lines
4.0 KiB
GDScript
extends CharacterBody2D
|
|
|
|
var gravity = 900
|
|
var gravity_mid = 500
|
|
var gravity_fall = 1300
|
|
const SPEED = 200.0
|
|
const JUMP_VELOCITY = -300.0
|
|
const roll_speed = 300
|
|
var roll_cooldown_time = 0.5
|
|
var colshape_stand = 30
|
|
|
|
@onready var sprite = $Sprites
|
|
|
|
var land_time = 0
|
|
var roll_cooldown = 0
|
|
var roll_time = 0
|
|
var roll_dir = 1
|
|
var side = 1
|
|
var state = State.Idle
|
|
var double_jump = false
|
|
|
|
enum State {
|
|
Idle,
|
|
Run,
|
|
Walk,
|
|
Jump,
|
|
AirSpin,
|
|
Land,
|
|
Attack,
|
|
Roll,
|
|
OnWall,
|
|
}
|
|
|
|
enum RState {
|
|
Grounded,
|
|
Aerial,
|
|
Combat,
|
|
Climbing
|
|
}
|
|
|
|
# A state machine might be needed here because this is getting really messy?
|
|
# There are 4 major states; grounded, combat, aerial, climbing
|
|
var rstate = RState.Aerial
|
|
|
|
func grounded(delta):
|
|
if land_time >= 0:
|
|
land_time -= delta
|
|
if roll_cooldown >= 0:
|
|
roll_cooldown -= delta
|
|
if roll_time >= 0:
|
|
roll_time -= delta
|
|
elif state == State.Roll:
|
|
$CollisionShape2D.shape.size.y = colshape_stand
|
|
$CollisionShape2D.position.y = colshape_stand / -2
|
|
roll_cooldown = roll_cooldown_time
|
|
# state = State.Idle
|
|
|
|
if Input.is_action_just_pressed("attack"):
|
|
rstate = RState.Combat
|
|
return
|
|
|
|
if Input.is_action_just_pressed("roll"):
|
|
if is_on_floor() and roll_time <= 0 and roll_cooldown <= 0:
|
|
# state = State.Roll
|
|
roll_time = 0.55
|
|
roll_dir = -1 if sprite.flip_h else 1
|
|
$CollisionShape2D.shape.size.y = colshape_stand / 2
|
|
$CollisionShape2D.position.y = colshape_stand / -4
|
|
sprite.play("GroundRoll")
|
|
return
|
|
if Input.is_action_just_pressed("ui_accept") and state != State.Roll:
|
|
velocity.y = JUMP_VELOCITY
|
|
sprite.play("Jump")
|
|
rstate = RState.Aerial
|
|
sprite.pause()
|
|
sprite.set_frame_and_progress(0, 0)
|
|
return
|
|
|
|
# We ran off of a ledge
|
|
if not is_on_floor():
|
|
rstate = RState.Aerial
|
|
return
|
|
|
|
if state == State.Roll:
|
|
velocity.x = roll_dir * roll_speed
|
|
else:
|
|
var speed = SPEED
|
|
if Input.is_key_pressed(KEY_SHIFT):
|
|
speed /= 3
|
|
var direction = Input.get_axis("left", "right")
|
|
|
|
if direction:
|
|
velocity.x = direction * speed
|
|
else:
|
|
# Decelerate
|
|
velocity.x = move_toward(velocity.x, 0, 25)
|
|
|
|
if direction != 0:
|
|
sprite.flip_h = direction == -1
|
|
|
|
|
|
if land_time <= 0:
|
|
if velocity.x != 0:
|
|
if Input.is_key_pressed(KEY_SHIFT):
|
|
sprite.play("Walk")
|
|
else:
|
|
sprite.play("Run")
|
|
else:
|
|
sprite.play("Idle")
|
|
|
|
func aerial(delta):
|
|
if is_on_floor():
|
|
# Transition to grounded
|
|
double_jump = false
|
|
rstate = RState.Grounded
|
|
sprite.play("Land")
|
|
land_time = 0.16
|
|
return
|
|
|
|
if is_on_wall():
|
|
rstate = RState.Climbing
|
|
return
|
|
|
|
# if Input.is_action_just_pressed("ui_accept") and state != State.AirSpin:
|
|
if Input.is_action_just_pressed("ui_accept") and not double_jump:
|
|
sprite.play("AirSpin")
|
|
double_jump = true
|
|
# state = State.AirSpin
|
|
var boost = 0 if velocity.y > 0 else velocity.y / 3
|
|
velocity.y = JUMP_VELOCITY / 1.4 + boost
|
|
|
|
if velocity.y > 50:
|
|
velocity.y += gravity_fall * delta
|
|
elif velocity.y < -50:
|
|
velocity.y += gravity * delta
|
|
else:
|
|
velocity.y += gravity_mid * delta
|
|
|
|
var direction = Input.get_axis("left", "right")
|
|
if direction:
|
|
velocity.x = direction * SPEED * 0.9
|
|
elif double_jump:
|
|
# Decelerate
|
|
velocity.x = move_toward(velocity.x, 0, 3)
|
|
else:
|
|
velocity.x = move_toward(velocity.x, 0, 9)
|
|
|
|
if direction != 0:
|
|
sprite.flip_h = direction == -1
|
|
|
|
if not double_jump:
|
|
if velocity.y > 50:
|
|
sprite.set_frame_and_progress(2,0)
|
|
elif velocity.y > -150:
|
|
sprite.set_frame_and_progress(1, 0)
|
|
|
|
|
|
func combat(delta):
|
|
# state = State.Attack
|
|
velocity = Vector2.ZERO
|
|
sprite.play("Attack1")
|
|
await (sprite as AnimatedSprite2D).animation_finished
|
|
# state = State.Idle
|
|
rstate = RState.Grounded
|
|
|
|
func climbing(delta):
|
|
if Input.is_action_just_pressed("ui_accept"):
|
|
rstate = RState.Aerial
|
|
velocity.x = -150
|
|
velocity.y = -350
|
|
return
|
|
velocity.x = 0
|
|
velocity.y = 0
|
|
|
|
func _physics_process(delta):
|
|
match rstate:
|
|
RState.Grounded:
|
|
grounded(delta)
|
|
RState.Aerial:
|
|
aerial(delta)
|
|
RState.Combat:
|
|
combat(delta)
|
|
RState.Climbing:
|
|
climbing(delta)
|
|
|
|
# if (state == State.Jump or state == State.AirSpin) and is_on_wall():
|
|
# state = State.OnWall
|
|
# return
|
|
|
|
move_and_slide()
|
|
|
|
# Maybe later
|
|
enum JumpState {
|
|
}
|