MIF_E31230535/stage0.gd

182 lines
6.2 KiB
GDScript

extends Node2D
# --- 🛠️ PRELOAD CETAKAN TUTORIAL UTAMA ---
const TUTORIAL_SCENE = preload("res://tutorial.tscn")
# ==============================================================================
# 🎛️ SETELAN AUDIO MANUAL STAGE 0 (UBAH DI SINI)
# ==============================================================================
var VOLUME_DASAR_BGM: float = 10.0
var VOLUME_DASAR_BGM_2: float = -5.0
var DURASI_FADE_IN: float = 3.0
var DURASI_FADE_OUT: float = 1.5
# ==============================================================================
@onready var bgm_player = $AudioStreamPlayer
@onready var bgm_player_2 = $AudioStreamPlayer2
var game_selesai = false
@onready var player = $Player
@onready var folder_npc = $NPC
var template_npc: Dictionary = {}
var kecepatan_npc: float = 120.0
var jarak_jalan_npc: float = 2100.0
func _ready() -> void:
# 🎬 Memutar animasi fadein saat stage pertama kali dibuka
$TransitionLayer/fade_to_black.play("fadein")
player.SPEED = 300
# 🎵 SISTEM FADE IN AUDIO OTOMATIS (AUDIO 1)
if bgm_player:
if bgm_player.stream and bgm_player.stream is AudioStreamOggVorbis:
bgm_player.stream.loop = true
bgm_player.volume_db = -80.0
bgm_player.play()
var tween_fadein = create_tween()
tween_fadein.tween_property(bgm_player, "volume_db", VOLUME_DASAR_BGM, DURASI_FADE_IN)\
.set_trans(Tween.TRANS_QUAD)\
.set_ease(Tween.EASE_OUT)
print("🎵 Musik 1 di Inspector berhasil diputar dengan efek Fade-In!")
# 🎵 SISTEM FADE IN AUDIO OTOMATIS (AUDIO 2)
if bgm_player_2:
if bgm_player_2.stream and bgm_player_2.stream is AudioStreamOggVorbis:
bgm_player_2.stream.loop = true
bgm_player_2.volume_db = -80.0
bgm_player_2.play()
var tween_fadein2 = create_tween()
tween_fadein2.tween_property(bgm_player_2, "volume_db", VOLUME_DASAR_BGM_2, DURASI_FADE_IN)\
.set_trans(Tween.TRANS_QUAD)\
.set_ease(Tween.EASE_OUT)
print("🎵 Musik 2 di Inspector berhasil diputar dengan efek Fade-In bersamaan!")
# 🛠️ AMBIL DAN SEMBUNYIKAN TEMPLATE NPC ASLI
for i in range(1, 7):
var nama_node = "npc" + str(i)
var node_npc = folder_npc.get_node_or_null(nama_node)
if node_npc:
template_npc[i] = node_npc
node_npc.visible = false
else:
print("⚠️ Peringatan: Node ", nama_node, " tidak ditemukan di dalam folder NPC!")
# 🚀 MEMULAI DUA LOOP PARALEL (GANJIL & GENAP)
loop_spawner_ganjil()
loop_spawner_genap()
# 🛠️ BARU: PICU TUTORIAL GERAKAN SAAT AWAL MULAI STAGE
pemicu_tutorial_awal()
# --- 🛠️ FUNGSI UNTUK MEMUNCULKAN TUTORIAL GERAKAN DI AWAL ---
func pemicu_tutorial_awal() -> void:
var tutorial_instance = TUTORIAL_SCENE.instantiate()
# Memasukkan teks panduan gerakan dasar ke dalam cetakan tutorial
tutorial_instance.teks_panduan = "Tutorial:\nGunakan tombol Kiri dan Kanan untuk menggerakkan Karakter.\nGunakan juga tombol 'Jump' untuk membuat Karakter melompat."
# Munculkan ke layar utama stage (Otomatis mem-pause game lewat Engine.time_scale)
get_tree().current_scene.add_child(tutorial_instance)
print("💡 Tutorial Gerakan Awal berhasil dimunculkan.")
# --- 🏃‍♂️ LOOP 1: SPAWN GANJIL (TIAP 6 DETIK) ---
func loop_spawner_ganjil():
while not game_selesai:
spawn_grup_npc([1, 3, 5])
await get_tree().create_timer(6.0).timeout
# --- 🏃‍♂️ LOOP 2: SPAWN GENAP WITH OFFSET (TIAP 6 DETIK, DELAY 3 DETIK DI AWAL) ---
func loop_spawner_genap():
await get_tree().create_timer(3.0).timeout
while not game_selesai:
spawn_grup_npc([2, 4, 6])
await get_tree().create_timer(6.0).timeout
# --- 🛠️ FUNGSI UNTUK MENDUPLIKAT & MENGGERAKKAN NPC ---
func spawn_grup_npc(daftar_angka: Array):
for angka in daftar_angka:
if not template_npc.has(angka) or game_selesai: continue
var npc_clone = template_npc[angka].duplicate()
folder_npc.add_child(npc_clone)
npc_clone.visible = true
npc_clone.modulate.a = 0.0
eksekusi_animasi_dan_gerak_npc(npc_clone, angka)
func eksekusi_animasi_dan_gerak_npc(npc: Node2D, angka: int):
var anim_player = npc.get_node_or_null("animasi")
if anim_player and anim_player.has_animation("idle"):
anim_player.play("idle")
var arah = 1.0
if angka == 3 or angka == 4:
arah = -1.0
npc.scale.x = -abs(npc.scale.x)
else:
arah = 1.0
npc.scale.x = abs(npc.scale.x)
var durasi = jarak_jalan_npc / kecepatan_npc
var posisi_tujuan = npc.global_position + Vector2(jarak_jalan_npc * arah, 0)
var tween_gerak = create_tween()
tween_gerak.tween_property(npc, "global_position:x", posisi_tujuan.x, durasi).set_trans(Tween.TRANS_LINEAR)
var tween_fade = create_tween()
tween_fade.tween_property(npc, "modulate:a", 1.0, 0.5)
var waktu_tunggu_fadeout = max(0.1, durasi - 1.0)
tween_fade.tween_interval(waktu_tunggu_fadeout)
tween_fade.tween_property(npc, "modulate:a", 0.0, 0.5)
tween_gerak.finished.connect(func(): npc.queue_free())
# --- 🏁 GARIS FINISH STAGE 0 ---
func _on_finish_line_body_entered(body: Node2D) -> void:
print("Seseorang menabrak garis finish!")
if body is CharacterBody2D and not game_selesai:
print("Robot terdeteksi! Jalankan animasi...")
game_selesai = true
if Global.stage_terbuka == 0:
Global.stage_terbuka = 1
print("💾 Progress Diupdate: Stage 0 Selesai -> Stage 1 Terbuka!")
# 🎵 EFEK FADE OUT AUDIO 1 SAAT MENABRAK FINISH LINE
if bgm_player and bgm_player.is_playing():
print("🎵 Menurunkan volume musik Stage 0 (Audio 1) perlahan (Fade-Out)...")
var tween_fadeout = create_tween()
tween_fadeout.tween_property(bgm_player, "volume_db", -80.0, DURASI_FADE_OUT)\
.set_trans(Tween.TRANS_QUAD)\
.set_ease(Tween.EASE_IN)
# 🎵 EFEK FADE OUT AUDIO 2 SAAT MENABRAK FINISH LINE
if bgm_player_2 and bgm_player_2.is_playing():
print("🎵 Menurunkan volume musik Stage 0 (Audio 2) perlahan (Fade-Out)...")
var tween_fadeout2 = create_tween()
tween_fadeout2.tween_property(bgm_player_2, "volume_db", -80.0, DURASI_FADE_OUT)\
.set_trans(Tween.TRANS_QUAD)\
.set_ease(Tween.EASE_IN)
$TransitionLayer/fade_to_black.play("fadeout")
await get_tree().create_timer(1.5).timeout
# 🎵 Matikan kedua audio sepenuhnya setelah layar hitam total demi memori
if bgm_player:
bgm_player.stop()
if bgm_player_2:
bgm_player_2.stop()
get_tree().change_scene_to_file("res://cutstage0_2.tscn")