Proyek Robotik #10: Game Tebak Warna
Proyek ini adalah game edukatif interaktif berbasis ESP32 yang memungkinkan pengguna untuk bermain Tebak Warna melalui halaman web yang diakses lewat WiFi Access Point (tanpa internet). ESP32 menampilkan kotak berwarna secara acak, dan pemain diminta memilih nama warna yang sesuai dari tiga pilihan. Jika tebakan benar, skor bertambah. Jika salah, skor direset ke nol. Halaman akan otomatis memuat warna baru setelah jawaban diberikan.
Cara Kerja:
- ESP32 membuat hotspot WiFi sendiri (Access Point) dengan SSID dan password yang ditentukan (“Game-Warna”, “12345678”).
- Pengguna menghubungkan HP atau laptop ke WiFi tersebut.
- Akses ke halaman game cukup dengan membuka alamat IP yang dicetak di Serial Monitor (biasanya 192.168.4.1).
- Di halaman web:
- Sebuah kotak warna ditampilkan.
- Pemain memilih salah satu dari tiga nama warna.
- Jika benar → muncul pesan “Benar!”, skor bertambah, dan otomatis lanjut ke warna baru.
- Jika salah → muncul pesan “Salah! Coba lagi.”, dan skor kembali ke nol.
- Semuanya dijalankan di dalam ESP32 tanpa perlu koneksi internet atau server eksternal.

Komponen yang Digunakan:
- 1 × ESP32
- 1 x Kabel USB (untuk upload dan power)
- 1 x Smartphone atau Laptop (untuk bermain game)
Fitur Game:
- Menampilkan warna acak dari daftar: Merah, Hijau, Biru, Kuning, Ungu, Coklat.
- Mengacak posisi jawaban (pilihan ganda).
- Menampilkan skor secara real-time.
- Interaksi penuh berbasis JavaScript & Fetch API.
- Responsif & ringan, cocok untuk pembelajaran IoT interaktif.
Kode:
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "Game-Warna";
const char* password = "12345678";
WebServer server(80);
String warna[] = {"Merah", "Hijau", "Biru", "Kuning", "Ungu", "Coklat"};
String warnaKode[] = {"#FF0000", "#00FF00", "#0000FF", "#FFFF00", "#800080", "#8B4513"};
int warnaAcakIndex;
int skor = 0;
void pilihWarnaBaru() {
warnaAcakIndex = random(0, 6);
}
void handleRoot() {
pilihWarnaBaru();
String html = "<html><head><title>Tebak Warna</title></head><body>";
html += "<h2>Tebak Warna!</h2>";
html += "<div style='width:100px; height:100px; background-color:" + warnaKode[warnaAcakIndex] + ";'></div>";
html += "<p>Pilih nama warna yang sesuai:</p>";
int pilihanBenar = warnaAcakIndex;
int pilihanSalah1 = (pilihanBenar + random(1, 5)) % 6;
int pilihanSalah2 = (pilihanBenar + random(2, 6)) % 6;
String opsi[3] = {warna[pilihanBenar], warna[pilihanSalah1], warna[pilihanSalah2]};
for (int i = 0; i < 3; i++) {
int j = random(i, 3);
String temp = opsi[i];
opsi[i] = opsi[j];
opsi[j] = temp;
}
for (int i = 0; i < 3; i++) {
html += "<button onclick='pilih(\"" + opsi[i] + "\")'>" + opsi[i] + "</button> ";
}
html += "<h3 id='hasil'></h3><h3>Skor: <span id='skor'>" + String(skor) + "</span></h3>";
html += "<script>";
html += "function pilih(namaWarna) { fetch('/cek?jawaban=' + namaWarna).then(res => res.text()).then(data => {";
html += "document.getElementById('hasil').innerHTML = data;";
html += "if (data.includes('Benar')) { document.getElementById('skor').innerText = parseInt(document.getElementById('skor').innerText) + 1; setTimeout(() => location.reload(), 1000); }";
html += "else { setTimeout(() => location.reload(), 1500); }";
html += "}); }";
html += "</script>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void handleCek() {
if (!server.hasArg("jawaban")) {
server.send(400, "text/plain", "Jawaban tidak valid.");
return;
}
String jawaban = server.arg("jawaban");
if (jawaban == warna[warnaAcakIndex]) {
skor++;
server.send(200, "text/html", "<h3 style='color:green;'>Benar!</h3>");
} else {
skor = 0;
server.send(200, "text/html", "<h3 style='color:red;'>Salah! Coba lagi.</h3>");
}
}
void setup() {
Serial.begin(115200);
// Mode Access Point (Hotspot)
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("Hotspot aktif! Akses game di: ");
Serial.println(IP);
pilihWarnaBaru();
server.on("/", handleRoot);
server.on("/cek", handleCek);
server.begin();
Serial.println("Server dimulai!");
}
void loop() {
server.handleClient();
}
