summaryrefslogtreecommitdiff
path: root/player.gd
diff options
context:
space:
mode:
Diffstat (limited to 'player.gd')
-rw-r--r--player.gd196
1 files changed, 159 insertions, 37 deletions
diff --git a/player.gd b/player.gd
index 9a06615..6bbb038 100644
--- a/player.gd
+++ b/player.gd
@@ -6,7 +6,7 @@ signal hp_changed
signal inhale_finished
-const MAX_SPEED = 70.0
+const MAX_SPEED = 75.0
const ACCELERATION = MAX_SPEED * 0.1
const DECELERATION = ACCELERATION
const JUMP_VELOCITY = -200.0
@@ -39,8 +39,10 @@ var hp = max_hp :
set(value):
hp = clamp(value, 0, max_hp)
hp_changed.emit()
+ Game.player_state.hp = value
+var life = 4
+
var sprite_small_star_base: PackedScene
-var air_shot_base: Area2D
var star_shot_base: Area2D
var is_inhaling = false
@@ -75,13 +77,15 @@ var visual_global_position: Vector2 :
func _ready():
+ if Game.player_state.hp:
+ hp = Game.player_state.hp
+ if Game.player_state.life:
+ life = Game.player_state.life
+
current_state = state_idle()
sprite_small_star_base = preload("res://effect_star.tscn")
- air_shot_base = $AirShot.duplicate()
- $AirShot.queue_free()
-
star_shot_base = $StarShot.duplicate()
$StarShot.queue_free()
@@ -146,19 +150,14 @@ func spawn_small_star():
)
func air_shot(direction: float):
- var shot = air_shot_base.duplicate() as Area2D
+ var shot = preload("res://air_shot.tscn").instantiate() as Area2D
shot.global_position = visual_global_position
+ shot.direction = direction
get_tree().current_scene.add_child(shot)
- %SoundAirShot.play()
- shot.get_node("Sprite2D").flip_h = direction < 0
-
- var tween = get_tree().create_tween()
-
- var shot_hit = func(node):
+ shot.hit.connect(func(node):
Game.score += 400
%ShotObstacleHit.play()
- tween.stop()
if node.has_method("hit_by_projectile"):
node.hit_by_projectile(shot.global_position)
@@ -166,16 +165,9 @@ func air_shot(direction: float):
Game.hit_enemy(node, shot.global_position)
shot.queue_free()
- shot.body_entered.connect(shot_hit)
- shot.area_entered.connect(shot_hit)
+ )
- tween.tween_property(
- shot,
- "global_position",
- shot.global_position + Vector2(sign(direction) * 64, 0),
- 0.3
- ).set_ease(Tween.EASE_OUT)
- tween.tween_callback(func():
+ shot.end_of_life.connect(func():
await get_tree().create_timer(0.2).timeout
if is_instance_valid(shot):
shot.queue_free()
@@ -286,17 +278,43 @@ func wall_bounce_check():
#return false
-func _on_hurt_area_body_entered(body: Node2D) -> void:
- if body.is_in_group("enemy"):
+func on_hurt(node: Node2D):
+ if node.is_in_group("enemy"):
if is_invincible:
%ShotObstacleHit.play()
- body.queue_free()
+ node.queue_free()
else:
- current_state.id = "" # to force trigger state change into hurt
- current_state = state_hurt({"collider": body})
- elif body is TileMapLayer:
+ #current_state.id = "" # to force trigger state change into hurt # not needed anymore because of no double-hurt
+ current_state = state_hurt({
+ "collider": node,
+ "is_inflated": is_inflated,
+ "is_flying": is_flying,
+ })
+ elif node is TileMapLayer:
current_state = state_knockout()
+func _on_hurt_area_body_entered(body: Node2D) -> void:
+ on_hurt(body)
+
+func _on_hurt_area_area_entered(area: Area2D) -> void:
+ on_hurt(area)
+
+
+func _on_collision_area_area_entered(area: Area2D) -> void:
+ if area.is_in_group("object_heal"):
+ %SoundPickup.play()
+ area.visible = false
+
+ if hp == max_hp:
+ Game.score += 50
+ else:
+ for n in range(clamp(max_hp - hp, 0, area.heal_power)):
+ hp += 1
+ SoundManager.play_sound("BossHpFill")
+ await get_tree().create_timer(0.1).timeout
+
+ area.queue_free()
+
func _on_invincibility_timer_timeout() -> void:
stop_blink()
@@ -462,7 +480,10 @@ func state_bump():
"id": "bump",
"enter": func():
$AnimatedSprite2D.play("fall")
- velocity = Vector2(sign(last_direction), -1) * clamp(velocity.x * 1.5, MAX_SPEED * 0.75, MAX_SPEED)
+ velocity = (
+ Vector2(sign(last_direction), -1) *
+ clamp(velocity.x * 1.5, MAX_SPEED * 0.75, MAX_SPEED * 2)
+ )
,
"process": func(_delta):
move_and_slide()
@@ -484,11 +505,18 @@ func state_duck():
return {
"id": "duck",
"enter": func():
- $AnimatedSprite2D.play("duck")
+ $AnimationPlayer.play("duck")
,
"process": func(_delta):
if not Input.is_action_pressed("duck"):
current_state = state_idle()
+
+ var collision := get_last_slide_collision()
+ if collision:
+ var collider = collision.get_collider()
+ if collider.is_in_group("droppable_platforms"):
+ global_position.y += 1
+ current_state = state_fall()
,
"exit": func():
pass
@@ -823,10 +851,14 @@ func state_hurt(data):
else:
%SoundHurt.play()
- if is_inflated:
+ if previous_state.id.contains("exhale"):
+ $AnimationPlayer.play("jump")
+ elif previous_state.id.contains("inflated"):
$AnimatedSprite2D.play("inflated_jump")
+ elif previous_state.id.contains("fly"):
+ $AnimatedSprite2D.play("fly")
else:
- $AnimatedSprite2D.play("jump")
+ $AnimationPlayer.play("jump")
var impulse = sign(visual_global_position - data.collider.global_position) * HURT_VELOCITY
velocity.x = impulse.x
@@ -837,8 +869,12 @@ func state_hurt(data):
start_blink()
await get_tree().create_timer(0.4).timeout
- if is_inflated:
+ if previous_state.id.contains("exhale"):
+ current_state = state_idle()
+ elif previous_state.id.contains("inflated"):
current_state = state_inflated_idle()
+ elif previous_state.id.contains("fly"):
+ current_state = state_fly_idle()
else:
current_state = state_idle()
,
@@ -857,6 +893,7 @@ func state_wall_bounce(return_state):
"enter": func():
%SoundFall.play()
spawn_small_star()
+ $AnimatedSprite2D.position.x = 4 * last_direction # nudge into wall
$AnimationPlayer.play("wall_bounce")
await $AnimationPlayer.animation_finished
@@ -864,6 +901,20 @@ func state_wall_bounce(return_state):
,
"process": func(_delta):
move_and_slide()
+
+ if check_door_enter():
+ current_state = state_enter_door()
+ elif 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
@@ -937,7 +988,7 @@ func state_enter_door():
"id": "enter_door",
"enter": func():
SoundManager.play_sound("EnterDoor")
- $AnimatedSprite2D.play("enter_door")
+ $AnimationPlayer.play("enter_door")
var tween = get_tree().create_tween()
tween.tween_property($AnimatedSprite2D, "self_modulate", Color(0,0,0,1), 0.3)
@@ -956,7 +1007,7 @@ func state_exit_door():
return {
"id": "exit_door",
"enter": func():
- $AnimatedSprite2D.play("exit_door")
+ $AnimationPlayer.play("exit_door")
await get_tree().create_timer(0.3).timeout
current_state = state_idle()
,
@@ -973,6 +1024,9 @@ func state_knockout():
return {
"id": "knockout",
"enter": func():
+ process_mode = PROCESS_MODE_ALWAYS
+ get_tree().paused = true
+
SoundManager.current_background.stop()
$AnimatedSprite2D.play("knockout")
@@ -1009,9 +1063,77 @@ func state_knockout():
%SoundKnockout.play()
await %SoundKnockout.finished
- Game.transition_to_scene(
- get_tree().current_scene.scene_file_path.replace(".tscn", "Intro.tscn")
+ var scene_path = get_tree().current_scene.scene_file_path
+ if scene_path.contains("Boss"):
+ scene_path = scene_path.replace("Boss.tscn", "Intro.tscn")
+ else:
+ scene_path = scene_path.replace(".tscn", "Intro.tscn")
+ Game.transition_to_scene(scene_path)
+
+ process_mode = PROCESS_MODE_INHERIT
+ get_tree().paused = false
+ ,
+ "process": func(_delta):
+ pass
+ ,
+ "exit": func():
+ pass
+ ,
+ }
+
+
+func state_win():
+ return {
+ "id": "win",
+ "enter": func():
+ process_mode = PROCESS_MODE_ALWAYS
+ get_tree().paused = true
+
+ SoundManager.current_background.stop()
+
+ $AnimatedSprite2D.play("knockout")
+ $AnimatedSprite2D.stop()
+ $AnimatedSprite2D.set_frame_and_progress(0, 0)
+
+ %SoundNoHp.play()
+ await %SoundNoHp.finished
+
+ $AnimatedSprite2D.play("knockout")
+ $Camera2D.drag_top_margin = 1.0
+ var tween = get_tree().create_tween()
+ var to_up_difference = visual_global_position.y - 16
+ var to_down_difference = visual_global_position.y + get_viewport_rect().size.y
+ tween.tween_property(
+ self,
+ "visual_global_position",
+ Vector2(
+ visual_global_position.x,
+ to_up_difference
+ ),
+ (to_up_difference / to_down_difference) * 1.0
)
+ tween.tween_property(
+ self,
+ "visual_global_position",
+ Vector2(
+ visual_global_position.x,
+ to_down_difference
+ ),
+ 1.0
+ )
+
+ %SoundKnockout.play()
+ await %SoundKnockout.finished
+
+ var scene_path = get_tree().current_scene.scene_file_path
+ if scene_path.contains("Boss"):
+ scene_path = scene_path.replace("Boss.tscn", "Intro.tscn")
+ else:
+ scene_path = scene_path.replace(".tscn", "Intro.tscn")
+ Game.transition_to_scene(scene_path)
+
+ process_mode = PROCESS_MODE_INHERIT
+ get_tree().paused = false
,
"process": func(_delta):
pass