170 lines
6.6 KiB
GDScript
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
|