MIF_E31230535/cutstage3_1.gd

170 lines
6.6 KiB
GDScript

extends Node2D
# ==============================================================================
# 🎛️ SETELAN AUDIO MANUAL CUTSCENE (UBAH DI SINI)
# ==============================================================================
@export var VOLUME_BGM: float = -10.0 # Volume musik latar (dB)
@export var VOLUME_KETIKAN: float = -15.0 # Volume suara ketikan teks (dB)
@export var VOLUME_AUDIO_3: float = -12.0 # Volume untuk audio ketiga (dB)
@export var DURASI_FADE_IN: float = 2.5 # Durasi musik memudar masuk (detik)
@export var DURASI_FADE_OUT: float = 1.5 # Durasi musik memudar keluar (detik)
@export var JEDA_AUDIO_3: float = 1.5 # ⏱️ BARU: Jeda waktu sebelum audio ketiga mulai (detik)
# ==============================================================================
@onready var label = $CanvasLayer/RichTextLabel
@onready var anim_player = $AnimationPlayer
@onready var timer_jeda = $TimerJeda
# 🎵 AMBIL REFERENSI KETIGA NODE AUDIO STREAM
@onready var audio_bgm = $AudioStreamPlayer
@onready var audio_ketikan = $AudioStreamPlayer2
@onready var audio_tambahan = $AudioStreamPlayer3
@export_file("*.tscn") var target_scene
@export_multiline var dialog_teks = """(1 September 1939) Langit di atas Polandia masih meremang kelabu, menyisakan sisa-sisa dingin malam yang perlahan memudar. Di sudut kota, detak kehidupan justru mulai menggeliat lebih awal. Sayup-sayup terdengar suara riuh rendah dari para pedagang yang mulai menggelar dagangannya di pasar, kepulan asap hangat dari kedai roti beraliran arsitektur klasik, serta langkah kaki beberapa warga yang menyapa fajar dengan senyuman.
Berjalan di antara ramahnya trotoar kota ini, semuanya terasa begitu damai. Sebuah simfoni pagi yang tenang, hangat, dan hidup."""
var kecepatan_teks = 0.03
var sudah_mulai = false
# 🛠️ VARIABEL BARU UNTUK KONTROL FITUR KLIK
var teks_selesai_diketik = false # Penanda teks sudah muncul semua (lewat loop atau skip)
var boleh_klik_instan = false # Kunci pengaman 2 detik pertama
var paksa_tampilkan_semua = false # Trigger untuk memotong loop ketikan
func _ready():
label.text = ""
label.visible_characters = 0
sudah_mulai = false
teks_selesai_diketik = false
boleh_klik_instan = false
paksa_tampilkan_semua = false
# Kita matikan autostart pada TimerJeda karena transisi level dikontrol oleh klik pemain
timer_jeda.one_shot = true
if timer_jeda.timeout.is_connected(_on_timer_jeda_timeout):
timer_jeda.timeout.disconnect(_on_timer_jeda_timeout)
# Play BGM dengan efek Fade In
if audio_bgm:
audio_bgm.volume_db = -80.0
audio_bgm.play()
var tween_in = create_tween()
tween_in.tween_property(audio_bgm, "volume_db", VOLUME_BGM, DURASI_FADE_IN)\
.set_trans(Tween.TRANS_QUAD)\
.set_ease(Tween.EASE_OUT)
# 🔊 BARU: Beri jeda waktu sebelum Audio Ketiga otomatis berputar
if audio_tambahan:
audio_tambahan.volume_db = VOLUME_AUDIO_3
# Menggunakan timer asinkron bawaan scene tree agar tidak membekukan game
get_tree().create_timer(JEDA_AUDIO_3).timeout.connect(func():
# Pastikan musuh atau scene belum berganti/mati saat timer selesai
if is_inside_tree() and audio_tambahan:
audio_tambahan.play()
print("🔊 Audio ketiga mulai berputar setelah jeda ", JEDA_AUDIO_3, " detik.")
)
anim_player.play("fadein")
func mulai_tulis_teks():
print("Fungsi mulai_tulis_teks terpanggil!")
if sudah_mulai:
return
sudah_mulai = true
label.text = dialog_teks
label.visible_characters = 0
label.autowrap_mode = TextServer.AUTOWRAP_WORD
# ⏱️ Jalankan timer internal 2 detik untuk mengaktifkan fitur klik instan
get_tree().create_timer(2.0).timeout.connect(func():
boleh_klik_instan = true
print("⚡ Fitur klik instan/skip sekarang aktif!")
)
for i in range(dialog_teks.length() + 1):
# Jika pemain melakukan klik setelah 2 detik, batalkan loop ketikan
if paksa_tampilkan_semua:
break
label.visible_characters = i
if i > 0 and i - 1 < dialog_teks.length():
var karakter_saat_ini = dialog_teks[i - 1]
if karakter_saat_ini != " " and karakter_saat_ini != "\n" and karakter_saat_ini != "\t":
bunyikan_sfx_ketikan_bebas()
await get_tree().create_timer(kecepatan_teks).timeout
# Blok eksekusi setelah teks tampil penuh (baik lewat ketikan normal maupun di-skip)
label.visible_characters = dialog_teks.length()
teks_selesai_diketik = true
print("📖 Semua teks telah ditampilkan. Menunggu klik pemain untuk lanjut...")
# 🖱️ / 📱 INPUT DETECTION: Mendeteksi klik mouse atau TAP layar di mana saja
func _input(event):
var is_click = event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT
var is_touch = event is InputEventScreenTouch and event.pressed
if is_click or is_touch:
# Kondisi 1: Teks masih mengetik, sudah lewat 2 detik, dan pemain klik untuk SKIP
if sudah_mulai and not teks_selesai_diketik and boleh_klik_instan:
paksa_tampilkan_semua = true
print("⏭️ Teks dipaksa muncul semua!")
get_viewport().set_input_as_handled()
return
# Kondisi 2: Semua teks sudah muncul di layar, klik sekali lagi untuk PINDAH SCENE
if teks_selesai_diketik:
teks_selesai_diketik = false # Kunci anti-spam klik saat fadeout
get_viewport().set_input_as_handled()
mulai_transisi_fadeout()
# 🎬 SEKUENS FADE OUT DAN PERPINDAHAN LEVEL MANUAL
func mulai_transisi_fadeout():
print("🎬 Memulai proses fadeout cutscene...")
# Fade out untuk BGM
if audio_bgm and audio_bgm.is_playing():
var tween_out = create_tween()
tween_out.tween_property(audio_bgm, "volume_db", -80.0, DURASI_FADE_OUT)\
.set_trans(Tween.TRANS_QUAD)\
.set_ease(Tween.EASE_IN)
# Lakukan juga Fade Out untuk Audio Ketiga agar tidak mati mendadak
if audio_tambahan and audio_tambahan.is_playing():
var tween_out_3 = create_tween()
tween_out_3.tween_property(audio_tambahan, "volume_db", -80.0, DURASI_FADE_OUT)\
.set_trans(Tween.TRANS_QUAD)\
.set_ease(Tween.EASE_IN)
if anim_player and anim_player.has_animation("fadeout"):
anim_player.play("fadeout")
await anim_player.animation_finished
# 🔒 MATIKAN TOTAL KEDUA AUDIO SAAT PINDAH SCENE
if audio_bgm:
audio_bgm.stop()
if audio_tambahan:
audio_tambahan.stop()
if target_scene != "":
get_tree().change_scene_to_file(target_scene)
# 🛠️ FUNGSI UNTUK DUPLIKASI AUDIO SECARA REAL-TIME
func bunyikan_sfx_ketikan_bebas():
if audio_ketikan and audio_ketikan.stream:
var audio_baru = AudioStreamPlayer.new()
audio_baru.stream = audio_ketikan.stream
audio_baru.volume_db = VOLUME_KETIKAN
add_child(audio_baru)
audio_baru.play()
audio_baru.finished.connect(func(): audio_baru.queue_free())
func _on_timer_jeda_timeout():
pass