summaryrefslogtreecommitdiff
path: root/player.gd
diff options
context:
space:
mode:
Diffstat (limited to 'player.gd')
-rw-r--r--player.gd389
1 files changed, 389 insertions, 0 deletions
diff --git a/player.gd b/player.gd
new file mode 100644
index 0000000..8ac0da7
--- /dev/null
+++ b/player.gd
@@ -0,0 +1,389 @@
+class_name Player
+extends CharacterBody2D
+
+
+const SPEED = 100.0
+const JUMP_VELOCITY = -225.0
+const AIR_SPEED = SPEED * 0.75
+const FLY_VELOCITY = -100
+
+var previous_velocity: Vector2 = Vector2.ZERO
+
+var current_state: Dictionary = state_idle():
+ set(new_state):
+ if current_state.id != new_state.id:
+ current_state.exit.call()
+ new_state.enter.call()
+ current_state = new_state
+
+
+func _ready():
+ current_state = state_idle()
+
+func _physics_process(delta: float) -> void:
+ # Add the gravity.
+ if not is_on_floor():
+ velocity += get_gravity() * delta
+
+ previous_velocity = velocity
+ current_state.process.call(delta)
+
+func apply_directional_movement(speed = SPEED):
+ var direction = Input.get_axis("ui_left", "ui_right")
+ if direction:
+ if direction < 0:
+ $AnimatedSprite2D.flip_h = true
+ else:
+ $AnimatedSprite2D.flip_h = false
+ velocity.x = direction * speed
+
+ return direction
+
+
+func state_idle():
+ return {
+ "id": "idle",
+ "enter": func():
+ $AnimatedSprite2D.play("idle")
+ ,
+ "process": func(_delta):
+ velocity.x = move_toward(velocity.x, 0, SPEED)
+ move_and_slide()
+
+ var direction = Input.get_axis("ui_left", "ui_right")
+ if direction:
+ current_state = state_walk()
+
+ if Input.is_action_just_pressed("jump"):
+ current_state = state_jump()
+
+ if not is_on_floor():
+ current_state = state_fall()
+
+ if Input.is_action_pressed("duck"):
+ current_state = state_duck()
+
+ if Input.is_action_just_pressed("inhale_exhale"):
+ current_state = state_inhale()
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_walk():
+ return {
+ "id": "walk",
+ "enter": func():
+ $AnimatedSprite2D.play("walk")
+ ,
+ "process": func(_delta):
+ var direction = apply_directional_movement()
+ if direction:
+ move_and_slide()
+ else:
+ current_state = state_idle()
+
+ if Input.is_action_just_pressed("jump"):
+ current_state = state_jump()
+
+ if not is_on_floor():
+ $CoyoteTimer.start()
+ current_state = state_fall()
+
+ if Input.is_action_pressed("duck"):
+ current_state = state_duck()
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_jump():
+ return {
+ "id": "jump",
+ "enter": func():
+ $SoundJump.play()
+ $AnimatedSprite2D.play("jump")
+ velocity.y = JUMP_VELOCITY
+ ,
+ "process": func(_delta):
+ apply_directional_movement(AIR_SPEED)
+ move_and_slide()
+
+ if Input.is_action_just_pressed("jump"):
+ velocity.y = FLY_VELOCITY
+ current_state = state_fly_idle()
+
+ if velocity.y >= 0:
+ current_state = state_fall()
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_fall():
+ return {
+ "id": "fall",
+ "enter": func():
+ $AnimatedSprite2D.play("jump")
+ ,
+ "process": func(_delta):
+ if not $CoyoteTimer.is_stopped() and Input.is_action_just_pressed("jump"):
+ current_state = state_jump()
+
+ elif Input.is_action_just_pressed("jump"):
+ velocity.y = FLY_VELOCITY
+ current_state = state_fly_idle()
+
+ if velocity.y > abs(JUMP_VELOCITY) * 2:
+ get_node("AnimatedSprite2D").play("fall")
+
+ apply_directional_movement(AIR_SPEED)
+ move_and_slide()
+
+ if is_on_floor():
+ if previous_velocity.y > abs(JUMP_VELOCITY):
+ #$SoundFall.volume_db = linear_to_db(
+ #clamp(abs(previous_velocity.y) / abs(JUMP_VELOCITY*2), 0.5, 1.0)
+ #)
+ $SoundFall.play()
+ current_state = state_idle()
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_duck():
+ return {
+ "id": "duck",
+ "enter": func():
+ $AnimatedSprite2D.play("duck")
+ ,
+ "process": func(_delta):
+ if Input.is_action_just_released("duck"):
+ current_state = state_idle()
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_fly_idle():
+ return {
+ "id": "fly_idle",
+ "enter": func():
+ $AnimatedSprite2D.play("fly")
+ ,
+ "process": func(delta):
+ velocity -= (get_gravity() * delta) / 1.5
+
+ if Input.is_action_just_pressed("jump"):
+ velocity.y = FLY_VELOCITY
+ $AnimatedSprite2D.play("fly")
+
+ velocity.x = move_toward(velocity.x, 0, SPEED)
+ move_and_slide()
+
+ var direction = Input.get_axis("ui_left", "ui_right")
+ if direction:
+ current_state = state_fly_walk()
+
+ if Input.is_action_just_pressed("inhale_exhale"):
+ $SoundExhale.play()
+ current_state = state_idle()
+
+ if is_on_floor():
+ current_state = state_idle()
+ # current_state = state_inflated_idle()
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_fly_walk():
+ return {
+ "id": "fly_walk",
+ "enter": func():
+ $AnimatedSprite2D.play("fly")
+ ,
+ "process": func(delta):
+ velocity -= (get_gravity() * delta) / 1.5
+
+ if Input.is_action_just_pressed("jump"):
+ velocity.y = FLY_VELOCITY
+
+ var direction = apply_directional_movement()
+ if direction:
+ $AnimatedSprite2D.play("fly")
+ move_and_slide()
+ else:
+ current_state = state_fly_idle()
+
+ if Input.is_action_just_pressed("inhale_exhale"):
+ $SoundExhale.play()
+ current_state = state_walk()
+
+ if is_on_floor():
+ current_state = state_walk()
+ # current_state = state_inflated_walk()
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_fly_exhale():
+ # todo: play animation, can't move during that, fly gravity applies?
+ # goto idle state? fall state?
+ return {}
+
+
+func state_inhale():
+ return {
+ "id": "inhale",
+ "enter": func():
+ #$AnimationPlayer.play("inhale")
+ $AnimatedSprite2D.play("inhale")
+ $SoundInhale.play()
+ $SoundInhale.finished.connect(func():
+ #$SoundInhaleContinue.play()
+ $SoundInhale.play()
+ )
+ ,
+ "process": func(_delta):
+ if Input.is_action_just_released("inhale_exhale"):
+ current_state = state_idle()
+ ,
+ "exit": func():
+ $SoundInhale.stop()
+ ,
+ }
+
+
+func state_inflated_idle():
+ return {}
+
+
+func state_inflated_walk():
+ return {}
+
+
+#class StateIdle:
+ #var player: Player
+ #
+ #func _init(_player):
+ #player = _player
+ #func _get_class():
+ #return "StateIdle"
+ #
+ #func enter():
+ #player.get_node("AnimatedSprite2D").play("idle")
+ #
+ #func process():
+ #player.velocity.x = move_toward(player.velocity.x, 0, SPEED)
+ #player.move_and_slide()
+ #
+ #var direction = Input.get_axis("ui_left", "ui_right")
+ #if direction:
+ #player.current_state = StateWalk.new(player)
+ #
+ #if Input.is_action_just_pressed("ui_accept"):
+ #player.current_state = StateJump.new(player)
+ #
+ #if not player.is_on_floor():
+ #player.current_state = StateFall.new(player)
+ #
+ #func exit():
+ #pass
+#
+#class StateWalk:
+ #var player: Player
+ #
+ #func _init(_player):
+ #player = _player
+ #func _get_class():
+ #return "StateWalk"
+ #
+ #func enter():
+ #player.get_node("AnimatedSprite2D").play("walk")
+ #
+ #func process():
+ #var direction = player.apply_directional_movement()
+ #if direction:
+ #player.move_and_slide()
+ #else:
+ #player.current_state = StateIdle.new(player)
+ #
+ #if Input.is_action_just_pressed("ui_accept"):
+ #player.current_state = StateJump.new(player)
+ #
+ #if not player.is_on_floor():
+ #player.get_node("CoyoteTimer").start()
+ #player.current_state = StateFall.new(player)
+ #
+ #func exit():
+ #pass
+#
+#class StateJump:
+ #var player: Player
+ #
+ #func _init(_player):
+ #player = _player
+ #func _get_class():
+ #return "StateJump"
+ #
+ #func enter():
+ #player.get_node("SoundJump").play()
+ #player.get_node("AnimatedSprite2D").play("jump")
+ #player.velocity.y = JUMP_VELOCITY
+ #
+ #func process():
+ #player.apply_directional_movement(AIR_SPEED)
+ #player.move_and_slide()
+ #
+ #if player.velocity.y >= 0:
+ #player.current_state = StateFall.new(player)
+ #
+ #func exit():
+ #pass
+#
+#class StateFall:
+ #var player: Player
+ #var is_falling = false
+ #
+ #func _init(_player):
+ #player = _player
+ #func _get_class():
+ #return "StateFall"
+ #
+ #func enter():
+ #player.get_node("AnimatedSprite2D").play("jump")
+ #
+ #func process():
+ #if not player.get_node("CoyoteTimer").is_stopped() and Input.is_action_just_pressed("ui_accept"):
+ #player.current_state = StateJump.new(player)
+ #
+ #if player.velocity.y > abs(JUMP_VELOCITY) * 2:
+ #is_falling = true
+ #player.get_node("AnimatedSprite2D").play("fall")
+ #
+ #player.apply_directional_movement(AIR_SPEED)
+ #player.move_and_slide()
+ #
+ #if player.is_on_floor():
+ #player.get_node("SoundFall").play()
+ #player.current_state = StateIdle.new(player)
+ #
+ #func exit():
+ #pass