class_name Player extends Character var is_invincible := false @onready var camera := $Camera2D func _ready() -> void: super._ready() $AnimatedSprite2D.modulate = Color(max(0.1, randf()), max(0.1, randf()), max(0.1, randf())) func _process(_delta: float) -> void: if current_state == State.Idle: if Input.is_action_pressed("ui_left"): walk(Direction.Left) elif Input.is_action_pressed("ui_right"): walk(Direction.Right) else: idle() if Input.is_action_pressed("ui_up"): jump() if Input.is_action_pressed("ui_down"): if not is_on_bottom_floor(): fall() if not is_on_floor(): fall() elif current_state == State.Walk: if Input.is_action_pressed("ui_left"): walk(Direction.Left) elif Input.is_action_pressed("ui_right"): walk(Direction.Right) else: idle() if Input.is_action_pressed("ui_up"): jump() if Input.is_action_pressed("ui_down"): if not is_on_bottom_floor(): fall() if not is_on_floor(): fall() if Input.is_action_just_pressed("ui_accept"): change_type_random() func invincible(duration: float): is_invincible = true var tween := get_tree().create_tween().set_loops(int(duration / 0.5)) tween.tween_property($AnimatedSprite2D, "self_modulate", Color(1.0, 1.0, 1.0, 0.25), 0.25) tween.tween_property($AnimatedSprite2D, "self_modulate", Color(1.0, 1.0, 1.0, 1.0), 0.25) await tween.finished is_invincible = false enum Result { Draw, Win, Lose, } static func is_rock_paper_scissors_win(player: Character, opponent: Character) -> Result: if player.current_type == Type.Rock and opponent.current_type == Type.Scissors: return Result.Win elif player.current_type == Type.Paper and opponent.current_type == Type.Rock: return Result.Win elif player.current_type == Type.Scissors and opponent.current_type == Type.Paper: return Result.Win elif player.current_type == Type.Rock and opponent.current_type == Type.Paper: return Result.Lose elif player.current_type == Type.Paper and opponent.current_type == Type.Scissors: return Result.Lose elif player.current_type == Type.Rock and opponent.current_type == Type.Paper: return Result.Lose elif player.current_type == Type.Scissors and opponent.current_type == Type.Rock: return Result.Lose else: return Result.Draw func _on_collision_area_entered(area: Area2D) -> void: if area.is_in_group("item"): var item: Item = area.get_parent() item.apply(self) elif area.is_in_group("opponent"): if is_invincible or current_state == State.Transform: return var opponent: Character = area.get_parent() var result := Player.is_rock_paper_scissors_win(self, opponent) if result == Result.Draw: type_change_finished.connect(func(): change_type_random() ) animate_type_change() elif result == Result.Win: (get_tree().get_first_node_in_group("hud") as HUD).score += 1 SoundManager.get_node("OpponentHit").play() type_change_finished.connect(func(): change_type_random() invincible(1.0) ) animate_type_change() opponent.process_mode = Node.PROCESS_MODE_DISABLED var tween = get_tree().create_tween() tween.tween_property( opponent, "position", position + (opponent.position - position) * 10, 0.5 ) await tween.finished opponent.queue_free() await get_tree().process_frame if (get_tree().current_scene as Stage).has_win_condition(): await get_tree().create_timer(2.0).timeout get_tree().change_scene_to_file("res://stage/stage_01.tscn") elif result == Result.Lose: (func(): $Collision.process_mode = Node.PROCESS_MODE_DISABLED).call_deferred() set_process(false) if vertical_tween: vertical_tween.stop() SoundManager.get_node("PlayerKO").play() $AnimatedSprite2D.play("ko") await $AnimatedSprite2D.animation_finished SoundManager.get_node("PlayerKO").stop() visible = false get_tree().change_scene_to_file("res://stage/stage_01.tscn")