446 lines
15 KiB
C#
446 lines
15 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class MemoryManager : MonoBehaviour
|
|
{
|
|
[Header("--- PANEL NAVIGASI & POP UP ---")]
|
|
public GameObject panelPilihLevel;
|
|
public GameObject panelGameMemory;
|
|
public GameObject panelPopUpBenar;
|
|
|
|
// SINKRONISASI LOGIKA DARI GAME SEBELUMNYA
|
|
public static bool mauUlangGame = false;
|
|
public static bool mauKembaliKePeta = false;
|
|
public static bool sudahPernahSapaMemory = false;
|
|
|
|
[Header("--- KOLEKSI SUARA MEMORY ---")]
|
|
public AudioSource speakerGame;
|
|
public AudioClip kasetNarator;
|
|
public AudioClip kasetBukaKartu;
|
|
public AudioClip kasetCocok;
|
|
public AudioClip kasetSalah;
|
|
public AudioClip kasetPopUpHebat;
|
|
public AudioClip kasetPanelHasil;
|
|
public AudioClip kasetKlikTombol;
|
|
public AudioClip kasetKalahWaktu;
|
|
|
|
[Header("--- DAFTAR STAGE (EMPTY OBJECT) ---")]
|
|
public GameObject[] listStage;
|
|
[Tooltip("Isi manual: Stage 1 ada berapa PASANG? (Misal 4 kartu = 2 pasang)")]
|
|
public int[] targetPasanganPerStage;
|
|
|
|
private int stageSekarang = 0;
|
|
private int benarDiStageIni = 0;
|
|
private int totalBenarGlobal = 0;
|
|
private int totalTargetSemuaStage = 0;
|
|
private bool gameSelesai = false;
|
|
|
|
[Header("--- SISTEM SKOR KIRI ---")]
|
|
public Image barSkor;
|
|
public TextMeshProUGUI teksSkorKiri;
|
|
public Image[] bintangSkorProgress;
|
|
|
|
[Header("--- PENGATURAN WAKTU & HAFALAN ---")]
|
|
public float waktuNgafal = 3f;
|
|
public float durasiWaktuMain = 60f;
|
|
private float waktuSisa;
|
|
public Image barWaktu;
|
|
|
|
// --- BARU: KONTROL WAKTU ---
|
|
private bool waktuBolehJalan = false;
|
|
|
|
[Header("--- PANEL HASIL AKHIR & ANIMASI ---")]
|
|
public GameObject panelHasil;
|
|
public RectTransform kontenPanelHasil;
|
|
public Image[] slotBintangPanel;
|
|
public TextMeshProUGUI teksSkorAkhir;
|
|
|
|
// --- BARU: FITUR ANTI-KLIK ---
|
|
[Header("--- FITUR ANTI-KLIK ---")]
|
|
public CanvasGroup groupKlikGame; // TARIK PANEL_GAMEMEMORY KE SINI
|
|
|
|
void Start()
|
|
{
|
|
// Bersihkan total semua suara & coroutine masa lalu
|
|
StopAllCoroutines();
|
|
if (speakerGame != null) speakerGame.Stop();
|
|
|
|
waktuSisa = durasiWaktuMain;
|
|
gameSelesai = false;
|
|
totalBenarGlobal = 0;
|
|
stageSekarang = 0;
|
|
benarDiStageIni = 0;
|
|
kartuTerbuka.Clear();
|
|
|
|
// Pastikan awal game gemboknya terbuka
|
|
if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true;
|
|
|
|
// Hitung total target
|
|
totalTargetSemuaStage = 0;
|
|
foreach (int t in targetPasanganPerStage) totalTargetSemuaStage += t;
|
|
|
|
// Reset UI
|
|
if (panelHasil != null) panelHasil.SetActive(false);
|
|
if (panelPopUpBenar != null) panelPopUpBenar.SetActive(false);
|
|
if (barSkor != null) barSkor.fillAmount = 0;
|
|
if (teksSkorKiri != null) teksSkorKiri.text = "0";
|
|
|
|
foreach (Image b in bintangSkorProgress) if(b != null) b.color = Color.gray;
|
|
foreach (Image b in slotBintangPanel) if(b != null) b.color = Color.gray;
|
|
if (barWaktu != null) { barWaktu.fillAmount = 1; barWaktu.color = Color.white; }
|
|
|
|
UpdateTampilanStage();
|
|
|
|
// CEK MODE ULANGI (SINKRON SEMUA GAME)
|
|
if (mauUlangGame)
|
|
{
|
|
if (panelPilihLevel != null) panelPilihLevel.SetActive(false);
|
|
if (panelGameMemory != null) panelGameMemory.SetActive(true);
|
|
mauUlangGame = false;
|
|
|
|
MulaiSuaraNaratorSatuPintu();
|
|
}
|
|
else if (mauKembaliKePeta)
|
|
{
|
|
if (panelPilihLevel != null) panelPilihLevel.SetActive(true);
|
|
if (panelGameMemory != null) panelGameMemory.SetActive(false);
|
|
mauKembaliKePeta = false;
|
|
}
|
|
}
|
|
|
|
// FUNGSI SATU PINTU (Mencegah suara nabrak & Anti Klik)
|
|
public void MulaiSuaraNaratorSatuPintu()
|
|
{
|
|
StopAllCoroutines();
|
|
if (speakerGame != null)
|
|
{
|
|
speakerGame.Stop();
|
|
StartCoroutine(LogikaTungguNarator());
|
|
}
|
|
}
|
|
|
|
IEnumerator LogikaTungguNarator()
|
|
{
|
|
// Kunci tombol pas narator ngomong
|
|
if (groupKlikGame != null) groupKlikGame.blocksRaycasts = false;
|
|
waktuBolehJalan = false;
|
|
|
|
yield return new WaitForSeconds(0.2f);
|
|
|
|
if (!sudahPernahSapaMemory)
|
|
{
|
|
if (kasetNarator != null)
|
|
{
|
|
speakerGame.PlayOneShot(kasetNarator);
|
|
yield return new WaitForSeconds(kasetNarator.length);
|
|
sudahPernahSapaMemory = true;
|
|
}
|
|
}
|
|
|
|
// Buka gembok setelah narator beres
|
|
if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true;
|
|
waktuBolehJalan = true;
|
|
|
|
StartCoroutine(FaseMenghafalStage());
|
|
}
|
|
|
|
public void MasukGameDanNgomongMemory()
|
|
{
|
|
// =========================================================
|
|
// JURUS MUTLAK ANTI-NABRAK: TEMBAK LANGSUNG DARI KODE!
|
|
// =========================================================
|
|
ManagerSuaraBermain satpamMenu = FindObjectOfType<ManagerSuaraBermain>();
|
|
if (satpamMenu != null)
|
|
{
|
|
satpamMenu.HentikanPaksaSuara(); // Paksa diam detik ini juga!
|
|
}
|
|
|
|
if (panelPilihLevel != null) panelPilihLevel.SetActive(false);
|
|
if (panelGameMemory != null) panelGameMemory.SetActive(true);
|
|
|
|
MulaiSuaraNaratorSatuPintu();
|
|
}
|
|
|
|
// --- LOGIKA MEMORY (SISA KODE ASLI) ---
|
|
private List<Card> kartuTerbuka = new List<Card>();
|
|
public bool lagiNgecek = false;
|
|
|
|
void Update()
|
|
{
|
|
if (gameSelesai) return;
|
|
|
|
// --- BARU: JIKA NARATOR BICARA / DIKUNCI, JANGAN JALAN WAKTUNYA ---
|
|
if (!waktuBolehJalan) return;
|
|
|
|
if (waktuSisa > 0) {
|
|
waktuSisa -= Time.deltaTime;
|
|
if (barWaktu != null) {
|
|
barWaktu.fillAmount = waktuSisa / durasiWaktuMain;
|
|
if (waktuSisa <= 10f) barWaktu.color = Color.red;
|
|
}
|
|
} else if (waktuBolehJalan && waktuSisa <= 0) {
|
|
waktuSisa = 0;
|
|
if (barWaktu != null) barWaktu.fillAmount = 0;
|
|
GagalMain();
|
|
}
|
|
}
|
|
|
|
IEnumerator FaseMenghafalStage()
|
|
{
|
|
lagiNgecek = true;
|
|
waktuBolehJalan = false;
|
|
|
|
// Kunci layar saat anak lagi menghafal biar kartu gak bisa diklik dulu
|
|
if (groupKlikGame != null) groupKlikGame.blocksRaycasts = false;
|
|
|
|
yield return new WaitForSeconds(1f);
|
|
|
|
Card[] kartuDiStageIni = listStage[stageSekarang].GetComponentsInChildren<Card>();
|
|
|
|
// ACAK POSISI FISIK
|
|
for (int i = 0; i < kartuDiStageIni.Length; i++) {
|
|
int r = Random.Range(i, kartuDiStageIni.Length);
|
|
int tempIndex = kartuDiStageIni[i].transform.GetSiblingIndex();
|
|
kartuDiStageIni[i].transform.SetSiblingIndex(kartuDiStageIni[r].transform.GetSiblingIndex());
|
|
kartuDiStageIni[r].transform.SetSiblingIndex(tempIndex);
|
|
|
|
Vector3 tempPos = kartuDiStageIni[i].transform.position;
|
|
kartuDiStageIni[i].transform.position = kartuDiStageIni[r].transform.position;
|
|
kartuDiStageIni[r].transform.position = tempPos;
|
|
}
|
|
|
|
foreach (Card k in kartuDiStageIni) {
|
|
if (k != null) StartCoroutine(AnimasiFlip(k.GetComponent<RectTransform>(), true, k));
|
|
}
|
|
|
|
yield return new WaitForSeconds(waktuNgafal);
|
|
|
|
foreach (Card k in kartuDiStageIni) {
|
|
if (k != null) StartCoroutine(AnimasiFlip(k.GetComponent<RectTransform>(), false, k));
|
|
}
|
|
|
|
lagiNgecek = false;
|
|
waktuBolehJalan = true;
|
|
|
|
// Buka gembok layar biar bisa mulai main
|
|
if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true;
|
|
}
|
|
|
|
public void KartuDipilih(Card kartu)
|
|
{
|
|
if (lagiNgecek || !waktuBolehJalan) return;
|
|
|
|
if (speakerGame != null && kasetBukaKartu != null) speakerGame.PlayOneShot(kasetBukaKartu);
|
|
|
|
StartCoroutine(AnimasiFlip(kartu.GetComponent<RectTransform>(), true, kartu));
|
|
kartuTerbuka.Add(kartu);
|
|
|
|
if (kartuTerbuka.Count == 2) {
|
|
StartCoroutine(CekKembar());
|
|
}
|
|
}
|
|
|
|
IEnumerator CekKembar()
|
|
{
|
|
lagiNgecek = true;
|
|
yield return new WaitForSeconds(0.8f);
|
|
|
|
if (kartuTerbuka[0].idPasangan == kartuTerbuka[1].idPasangan)
|
|
{
|
|
if (speakerGame != null && kasetCocok != null) speakerGame.PlayOneShot(kasetCocok);
|
|
|
|
benarDiStageIni++;
|
|
totalBenarGlobal++;
|
|
UpdateUISkorKiri();
|
|
|
|
if (benarDiStageIni >= targetPasanganPerStage[stageSekarang]) {
|
|
StartCoroutine(PindahStageNext());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (speakerGame != null && kasetSalah != null) speakerGame.PlayOneShot(kasetSalah);
|
|
|
|
StartCoroutine(AnimasiFlip(kartuTerbuka[0].GetComponent<RectTransform>(), false, kartuTerbuka[0]));
|
|
StartCoroutine(AnimasiFlip(kartuTerbuka[1].GetComponent<RectTransform>(), false, kartuTerbuka[1]));
|
|
}
|
|
|
|
kartuTerbuka.Clear();
|
|
lagiNgecek = false;
|
|
}
|
|
|
|
IEnumerator AnimasiFlip(RectTransform kartu, bool buka, Card scriptKartu)
|
|
{
|
|
float t = 0;
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime * 10f;
|
|
kartu.localScale = new Vector3(Mathf.Lerp(1, 0, t), 1, 1);
|
|
yield return null;
|
|
}
|
|
|
|
if (buka) scriptKartu.BukaKartu(); else scriptKartu.TutupKartu();
|
|
|
|
t = 0;
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime * 10f;
|
|
kartu.localScale = new Vector3(Mathf.Lerp(0, 1, t), 1, 1);
|
|
yield return null;
|
|
}
|
|
kartu.localScale = Vector3.one;
|
|
}
|
|
|
|
IEnumerator PindahStageNext()
|
|
{
|
|
waktuBolehJalan = false;
|
|
// Kunci layar saat pindah stage biar ga dispam
|
|
if (groupKlikGame != null) groupKlikGame.blocksRaycasts = false;
|
|
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
if (panelPopUpBenar != null) {
|
|
panelPopUpBenar.SetActive(true);
|
|
if (speakerGame != null && kasetPopUpHebat != null) speakerGame.PlayOneShot(kasetPopUpHebat);
|
|
}
|
|
|
|
yield return new WaitForSeconds(1.5f);
|
|
if (panelPopUpBenar != null) panelPopUpBenar.SetActive(false);
|
|
|
|
TutupSemuaKartuDiLayar();
|
|
yield return new WaitForSeconds(0.5f);
|
|
|
|
if (stageSekarang < listStage.Length - 1) {
|
|
if (listStage[stageSekarang] != null) listStage[stageSekarang].SetActive(false);
|
|
stageSekarang++;
|
|
benarDiStageIni = 0;
|
|
UpdateTampilanStage();
|
|
StartCoroutine(FaseMenghafalStage()); // FaseMenghafalStage akan mengunci dan membuka layar otomatis
|
|
} else {
|
|
MenangMain();
|
|
}
|
|
}
|
|
|
|
void UpdateTampilanStage()
|
|
{
|
|
for (int i = 0; i < listStage.Length; i++) {
|
|
if (listStage[i] != null) listStage[i].SetActive(i == stageSekarang);
|
|
}
|
|
}
|
|
|
|
void UpdateUISkorKiri()
|
|
{
|
|
if (totalTargetSemuaStage == 0) return;
|
|
float persentase = (float)totalBenarGlobal / totalTargetSemuaStage;
|
|
if (barSkor != null) barSkor.fillAmount = persentase;
|
|
if (teksSkorKiri != null) teksSkorKiri.text = Mathf.RoundToInt(persentase * 100f).ToString();
|
|
|
|
if (bintangSkorProgress.Length >= 3) {
|
|
if (persentase >= 0.33f && bintangSkorProgress[0] != null) bintangSkorProgress[0].color = Color.white;
|
|
if (persentase >= 0.66f && bintangSkorProgress[1] != null) bintangSkorProgress[1].color = Color.white;
|
|
if (persentase >= 1.00f && bintangSkorProgress[2] != null) bintangSkorProgress[2].color = Color.white;
|
|
}
|
|
}
|
|
|
|
void MenangMain()
|
|
{
|
|
if (gameSelesai) return;
|
|
gameSelesai = true;
|
|
waktuBolehJalan = false;
|
|
TutupSemuaKartuDiLayar();
|
|
StartCoroutine(AnimasiPanelDanBintang(3, false));
|
|
}
|
|
|
|
void GagalMain()
|
|
{
|
|
if (gameSelesai) return;
|
|
gameSelesai = true;
|
|
waktuBolehJalan = false;
|
|
TutupSemuaKartuDiLayar();
|
|
|
|
float persentase = (float)totalBenarGlobal / totalTargetSemuaStage;
|
|
int bintangDapat = (persentase >= 1.00f) ? 3 : (persentase >= 0.66f) ? 2 : (persentase >= 0.33f) ? 1 : 0;
|
|
|
|
StartCoroutine(AnimasiPanelDanBintang(bintangDapat, true));
|
|
}
|
|
|
|
IEnumerator AnimasiPanelDanBintang(int jumlahBintang, bool waktuHabis)
|
|
{
|
|
// --- BUKA KUNCI KLIK DISINI BIAR AMAN SAAT MUNCUL HASIL ---
|
|
if (groupKlikGame != null) groupKlikGame.blocksRaycasts = true;
|
|
|
|
if (kontenPanelHasil != null)
|
|
{
|
|
kontenPanelHasil.localScale = Vector3.zero;
|
|
panelHasil.SetActive(true);
|
|
panelHasil.transform.SetAsLastSibling();
|
|
|
|
float t = 0;
|
|
while (t < 1f)
|
|
{
|
|
t += Time.deltaTime * 4f;
|
|
float curve = Mathf.Sin(t * Mathf.PI * 0.7f) * 1.15f;
|
|
kontenPanelHasil.localScale = new Vector3(curve, curve, curve);
|
|
yield return null;
|
|
}
|
|
kontenPanelHasil.localScale = Vector3.one;
|
|
}
|
|
else { panelHasil.SetActive(true); }
|
|
|
|
if (teksSkorAkhir != null) teksSkorAkhir.text = teksSkorKiri.text;
|
|
|
|
if (waktuHabis) {
|
|
if (speakerGame != null && kasetKalahWaktu != null) speakerGame.PlayOneShot(kasetKalahWaktu);
|
|
} else {
|
|
if (speakerGame != null && kasetPanelHasil != null) speakerGame.PlayOneShot(kasetPanelHasil);
|
|
}
|
|
|
|
yield return new WaitForSeconds(0.3f);
|
|
for (int i = 0; i < jumlahBintang; i++)
|
|
{
|
|
if (i < slotBintangPanel.Length && slotBintangPanel[i] != null)
|
|
{
|
|
if (speakerGame != null && kasetCocok != null) speakerGame.PlayOneShot(kasetCocok);
|
|
slotBintangPanel[i].color = Color.white;
|
|
|
|
float bT = 0; Vector3 startScale = Vector3.one * 2f;
|
|
while(bT < 1f){
|
|
bT += Time.deltaTime * 5f;
|
|
slotBintangPanel[i].rectTransform.localScale = Vector3.Lerp(startScale, Vector3.one, bT);
|
|
yield return null;
|
|
}
|
|
yield return new WaitForSeconds(0.4f);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void TombolUlangi() {
|
|
if (speakerGame != null && kasetKlikTombol != null) speakerGame.PlayOneShot(kasetKlikTombol);
|
|
sudahPernahSapaMemory = false;
|
|
mauUlangGame = true;
|
|
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
|
|
}
|
|
|
|
public void TombolKeluar() {
|
|
if (speakerGame != null && kasetKlikTombol != null) speakerGame.PlayOneShot(kasetKlikTombol);
|
|
sudahPernahSapaMemory = false;
|
|
mauKembaliKePeta = true;
|
|
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
|
|
}
|
|
|
|
void TutupSemuaKartuDiLayar()
|
|
{
|
|
if (stageSekarang < listStage.Length && listStage[stageSekarang] != null)
|
|
{
|
|
Card[] kartuDiStageIni = listStage[stageSekarang].GetComponentsInChildren<Card>();
|
|
foreach (Card k in kartuDiStageIni)
|
|
{
|
|
if (k != null) StartCoroutine(AnimasiFlip(k.GetComponent<RectTransform>(), false, k));
|
|
}
|
|
}
|
|
}
|
|
} |