349 lines
11 KiB
C#
349 lines
11 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using TMPro;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
public class PuzzleManager : MonoBehaviour
|
|
{
|
|
[Header("Panel Bayangan (Kiri)")]
|
|
public Image imgBayangan;
|
|
public TextMeshProUGUI textNama;
|
|
public RectTransform dropZoneRect;
|
|
|
|
[Header("Panel Jawaban (Kanan)")]
|
|
public Image img1, img2, img3;
|
|
|
|
[Header("Panel Popup")]
|
|
public GameObject panelPopup;
|
|
public Image imgStiker;
|
|
public Sprite stikerBenar;
|
|
public Sprite stikerSalah;
|
|
|
|
[Header("Panel Hasil")]
|
|
public GameObject panelHasil;
|
|
public TextMeshProUGUI textPesan;
|
|
public TextMeshProUGUI textSkor;
|
|
public Button btnUlang, btnMenu;
|
|
public Image imgStikerHasil;
|
|
public Sprite stikerHasilBagus;
|
|
public Sprite stikerHasilKurang;
|
|
|
|
[Header("Navigasi")]
|
|
public Button btnHome;
|
|
|
|
[Header("Skor Live")]
|
|
public TextMeshProUGUI textSkorLive;
|
|
|
|
private struct DataKarakter
|
|
{
|
|
public string namaFile;
|
|
public string namaLabel;
|
|
public string folder;
|
|
|
|
public DataKarakter(string file, string label, string folder)
|
|
{
|
|
this.namaFile = file;
|
|
this.namaLabel = label;
|
|
this.folder = folder;
|
|
}
|
|
}
|
|
|
|
private List<DataKarakter> semuaKarakter = new List<DataKarakter>()
|
|
{
|
|
// Hewan
|
|
new DataKarakter("anjing", "Anjing", "hewan"),
|
|
new DataKarakter("ayam", "Ayam", "hewan"),
|
|
new DataKarakter("babi", "Babi", "hewan"),
|
|
new DataKarakter("bebek", "Bebek", "hewan"),
|
|
new DataKarakter("buaya", "Buaya", "hewan"),
|
|
new DataKarakter("burung", "Burung", "hewan"),
|
|
new DataKarakter("gajah", "Gajah", "hewan"),
|
|
new DataKarakter("harimau", "Harimau", "hewan"),
|
|
new DataKarakter("ikan", "Ikan", "hewan"),
|
|
new DataKarakter("jerapah", "Jerapah", "hewan"),
|
|
new DataKarakter("kambing", "Kambing", "hewan"),
|
|
new DataKarakter("katak", "Katak", "hewan"),
|
|
new DataKarakter("kelinci", "Kelinci", "hewan"),
|
|
new DataKarakter("kepiting", "Kepiting", "hewan"),
|
|
new DataKarakter("kucing", "Kucing", "hewan"),
|
|
new DataKarakter("kupu-kupu", "Kupu-kupu", "hewan"),
|
|
new DataKarakter("kura", "Kura-kura", "hewan"),
|
|
new DataKarakter("landak", "Landak", "hewan"),
|
|
new DataKarakter("lebah", "Lebah", "hewan"),
|
|
new DataKarakter("rubah", "Rubah", "hewan"),
|
|
new DataKarakter("rusa", "Rusa", "hewan"),
|
|
new DataKarakter("sapi", "Sapi", "hewan"),
|
|
new DataKarakter("singa", "Singa", "hewan"),
|
|
new DataKarakter("ular", "Ular", "hewan"),
|
|
new DataKarakter("ulat", "Ulat", "hewan"),
|
|
new DataKarakter("zebra", "Zebra", "hewan"),
|
|
|
|
// Buah
|
|
new DataKarakter("apel", "Apel", "buah"),
|
|
new DataKarakter("alpukat", "Alpukat", "buah"),
|
|
new DataKarakter("anggur", "Anggur", "buah"),
|
|
new DataKarakter("blueberry", "Blueberry", "buah"),
|
|
new DataKarakter("ceri", "Ceri", "buah"),
|
|
new DataKarakter("durian", "Durian", "buah"),
|
|
new DataKarakter("jeruk", "Jeruk", "buah"),
|
|
new DataKarakter("kelapa", "Kelapa", "buah"),
|
|
new DataKarakter("kiwi", "Kiwi", "buah"),
|
|
new DataKarakter("lemon", "Lemon", "buah"),
|
|
new DataKarakter("lychee", "Lychee", "buah"),
|
|
new DataKarakter("mangga", "Mangga", "buah"),
|
|
new DataKarakter("manggis", "Manggis", "buah"),
|
|
new DataKarakter("melon", "Melon", "buah"),
|
|
new DataKarakter("nanas", "Nanas", "buah"),
|
|
new DataKarakter("pepaya", "Pepaya", "buah"),
|
|
new DataKarakter("pir", "Pir", "buah"),
|
|
new DataKarakter("pisang", "Pisang", "buah"),
|
|
new DataKarakter("rambutan", "Rambutan", "buah"),
|
|
new DataKarakter("semangka", "Semangka", "buah"),
|
|
new DataKarakter("strawberry","Strawberry", "buah"),
|
|
};
|
|
|
|
private Vector2[] posisiAsal = new Vector2[3];
|
|
private Transform panelJawaban;
|
|
private List<int> urutanSoal = new List<int>();
|
|
private int indexSoal = 0;
|
|
private int totalSoal = 8;
|
|
private int skorBenar = 0;
|
|
private int jawabanBenarIndex;
|
|
private AudioSource audioSource;
|
|
|
|
void Start()
|
|
{
|
|
audioSource = GetComponent<AudioSource>();
|
|
if (audioSource == null)
|
|
audioSource = gameObject.AddComponent<AudioSource>();
|
|
|
|
panelHasil.SetActive(false);
|
|
panelPopup.SetActive(false);
|
|
|
|
btnHome.onClick.RemoveAllListeners();
|
|
btnHome.onClick.AddListener(() => SceneManager.LoadScene("MainMenu"));
|
|
|
|
btnUlang.onClick.RemoveAllListeners();
|
|
btnMenu.onClick.RemoveAllListeners();
|
|
btnUlang.onClick.AddListener(() => SceneManager.LoadScene("Puzzle"));
|
|
btnMenu.onClick.AddListener(() => SceneManager.LoadScene("MainMenu"));
|
|
|
|
Image[] imgs = { img1, img2, img3 };
|
|
panelJawaban = img1.transform.parent;
|
|
for (int i = 0; i < 3; i++)
|
|
posisiAsal[i] = imgs[i].GetComponent<RectTransform>().anchoredPosition;
|
|
|
|
UpdateSkorLive();
|
|
BuatUrutanSoal();
|
|
TampilkanSoal();
|
|
}
|
|
|
|
void UpdateSkorLive()
|
|
{
|
|
if (textSkorLive != null)
|
|
textSkorLive.text = "Skor : " + skorBenar;
|
|
}
|
|
|
|
void BuatUrutanSoal()
|
|
{
|
|
List<int> semua = new List<int>();
|
|
for (int i = 0; i < semuaKarakter.Count; i++)
|
|
semua.Add(i);
|
|
|
|
for (int i = semua.Count - 1; i > 0; i--)
|
|
{
|
|
int r = Random.Range(0, i + 1);
|
|
int tmp = semua[i];
|
|
semua[i] = semua[r];
|
|
semua[r] = tmp;
|
|
}
|
|
|
|
totalSoal = Mathf.Min(totalSoal, semua.Count);
|
|
for (int i = 0; i < totalSoal; i++)
|
|
urutanSoal.Add(semua[i]);
|
|
}
|
|
|
|
void ResetPosisiGambar()
|
|
{
|
|
Image[] imgs = { img1, img2, img3 };
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
imgs[i].transform.SetParent(panelJawaban, false);
|
|
imgs[i].GetComponent<RectTransform>().anchoredPosition = posisiAsal[i];
|
|
imgs[i].gameObject.SetActive(true);
|
|
|
|
DragItem d = imgs[i].GetComponent<DragItem>();
|
|
if (d != null) Destroy(d);
|
|
}
|
|
}
|
|
|
|
void TampilkanSoal()
|
|
{
|
|
if (indexSoal >= totalSoal)
|
|
{
|
|
TampilkanHasil();
|
|
return;
|
|
}
|
|
|
|
ResetPosisiGambar();
|
|
|
|
jawabanBenarIndex = urutanSoal[indexSoal];
|
|
DataKarakter karakter = semuaKarakter[jawabanBenarIndex];
|
|
|
|
Sprite spBayangan = Resources.Load<Sprite>("Gambar/" + karakter.folder + "/" + karakter.namaFile);
|
|
if (spBayangan != null)
|
|
{
|
|
imgBayangan.sprite = spBayangan;
|
|
imgBayangan.color = Color.black;
|
|
}
|
|
else
|
|
Debug.LogWarning("⚠️ Bayangan tidak ditemukan: Gambar/" + karakter.folder + "/" + karakter.namaFile);
|
|
|
|
textNama.text = karakter.namaLabel;
|
|
|
|
List<int> pilihan = BuatPilihan(jawabanBenarIndex);
|
|
Image[] imgs = { img1, img2, img3 };
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
int idx = pilihan[i];
|
|
DataKarakter k = semuaKarakter[idx];
|
|
|
|
Sprite sp = Resources.Load<Sprite>("Gambar/" + k.folder + "/" + k.namaFile);
|
|
if (sp != null)
|
|
{
|
|
imgs[i].sprite = sp;
|
|
imgs[i].color = Color.white;
|
|
}
|
|
else
|
|
Debug.LogWarning("⚠️ Gambar tidak ditemukan: Gambar/" + k.folder + "/" + k.namaFile);
|
|
|
|
DragItem drag = imgs[i].gameObject.AddComponent<DragItem>();
|
|
drag.indexHewan = idx;
|
|
drag.puzzleManager = this;
|
|
drag.dropZoneRect = dropZoneRect;
|
|
}
|
|
|
|
Debug.Log("📝 Soal " + (indexSoal + 1) + ": " + karakter.namaLabel + " (" + karakter.folder + ")");
|
|
}
|
|
|
|
List<int> BuatPilihan(int idxBenar)
|
|
{
|
|
DataKarakter k = semuaKarakter[idxBenar];
|
|
|
|
List<int> pilihan = new List<int>();
|
|
pilihan.Add(idxBenar);
|
|
|
|
List<int> salah = new List<int>();
|
|
for (int i = 0; i < semuaKarakter.Count; i++)
|
|
if (i != idxBenar && semuaKarakter[i].folder == k.folder)
|
|
salah.Add(i);
|
|
|
|
if (salah.Count < 2)
|
|
{
|
|
for (int i = 0; i < semuaKarakter.Count; i++)
|
|
if (i != idxBenar && !salah.Contains(i))
|
|
salah.Add(i);
|
|
}
|
|
|
|
for (int i = salah.Count - 1; i > 0; i--)
|
|
{
|
|
int r = Random.Range(0, i + 1);
|
|
int tmp = salah[i]; salah[i] = salah[r]; salah[r] = tmp;
|
|
}
|
|
|
|
pilihan.Add(salah[0]);
|
|
pilihan.Add(salah[1]);
|
|
|
|
for (int i = pilihan.Count - 1; i > 0; i--)
|
|
{
|
|
int r = Random.Range(0, i + 1);
|
|
int tmp = pilihan[i]; pilihan[i] = pilihan[r]; pilihan[r] = tmp;
|
|
}
|
|
|
|
return pilihan;
|
|
}
|
|
|
|
public void CekJawaban(DragItem dragItem)
|
|
{
|
|
bool benar = (dragItem.indexHewan == jawabanBenarIndex);
|
|
|
|
if (benar)
|
|
{
|
|
skorBenar += 10;
|
|
UpdateSkorLive();
|
|
dragItem.SetBenar();
|
|
|
|
DataKarakter k = semuaKarakter[jawabanBenarIndex];
|
|
Sprite spBerwarna = Resources.Load<Sprite>("Gambar/" + k.folder + "/" + k.namaFile);
|
|
if (spBerwarna != null)
|
|
{
|
|
imgBayangan.sprite = spBerwarna;
|
|
imgBayangan.color = Color.white;
|
|
}
|
|
|
|
img1.gameObject.SetActive(false);
|
|
img2.gameObject.SetActive(false);
|
|
img3.gameObject.SetActive(false);
|
|
|
|
StartCoroutine(TampilkanPopupDanLanjut(true));
|
|
}
|
|
else
|
|
{
|
|
dragItem.KembaliKePosisiAsal();
|
|
StartCoroutine(TampilkanPopupDanLanjut(false));
|
|
}
|
|
}
|
|
|
|
IEnumerator TampilkanPopupDanLanjut(bool benar)
|
|
{
|
|
panelPopup.SetActive(true);
|
|
imgStiker.sprite = benar ? stikerBenar : stikerSalah;
|
|
|
|
string namaAudio = benar ? "Audio/suara_benar" : "Audio/suara_salah";
|
|
AudioClip clip = Resources.Load<AudioClip>(namaAudio);
|
|
if (clip != null)
|
|
{
|
|
audioSource.PlayOneShot(clip);
|
|
yield return new WaitForSeconds(clip.length);
|
|
}
|
|
else
|
|
yield return new WaitForSeconds(1f);
|
|
|
|
panelPopup.SetActive(false);
|
|
indexSoal++;
|
|
TampilkanSoal();
|
|
}
|
|
|
|
void TampilkanHasil()
|
|
{
|
|
panelHasil.SetActive(true);
|
|
|
|
int skorMax = totalSoal * 10;
|
|
textSkor.text = "Skor Akhir : " + skorBenar + " / " + skorMax;
|
|
|
|
// Batas bagus: >= 50 (lebih dari separuh benar dari 8 soal)
|
|
bool skorBagus = skorBenar >= 50;
|
|
|
|
if (textPesan != null)
|
|
textPesan.text = skorBagus
|
|
? "Hebat! Kamu Luar Biasa!"
|
|
: "Jangan Menyerah! Coba Lagi!";
|
|
|
|
if (imgStikerHasil != null)
|
|
{
|
|
Sprite stikerDipilih = skorBagus ? stikerHasilBagus : stikerHasilKurang;
|
|
if (stikerDipilih != null)
|
|
imgStikerHasil.sprite = stikerDipilih;
|
|
else
|
|
Debug.LogWarning("⚠️ Sprite stiker hasil belum di-assign di Inspector!");
|
|
}
|
|
}
|
|
|
|
public void KembaliKeMenu()
|
|
{
|
|
SceneManager.LoadScene("MainMenu");
|
|
}
|
|
} |