import 'package:flutter/material.dart'; import 'dart:async'; import 'dart:math'; import 'package:flame/game.dart'; import '../landing_page.dart'; import '../utils/level_manager.dart'; import 'package:permainan_kata_anak_sd/services/database_service.dart'; import 'package:firebase_auth/firebase_auth.dart'; import '../utils/audio_manager.dart'; // Pindahkan enum ke level atas enum WordDirection { horizontal, vertical, diagonal } // Pindahkan class ke level atas class PlacedWord { final String word; final int startRow; final int startCol; final WordDirection direction; PlacedWord( {required this.word, required this.startRow, required this.startCol, required this.direction}); } class Level3Islam extends StatefulWidget { const Level3Islam({Key? key}) : super(key: key); @override _Level3IslamState createState() => _Level3IslamState(); } class _Level3IslamState extends State { // Definisikan gridSize sebagai konstanta kelas static const int GRID_SIZE = 18; static const int MAX_TIME = 300; // 5 menit dalam detik late Timer timer; int seconds = MAX_TIME; int elapsedSeconds = 0; // Tambah variabel untuk menghitung waktu yang digunakan int score = 0; // Data kata dan pertanyaan terkait dengan urutan final List> orderedQuestions = [ { 'word': 'GOWATALLO', 'question': '"Ayam Jantan dari Timur" julukan bagi pemimpin dari Kerajaan', 'image': 'assets/images_raja/raja_gowa.png', 'isFound': false, 'isUnlocked': true, 'isVisible': true, }, { 'word': 'DEMAK', 'question': 'Kerajaan Islam pertama di Nusantara', 'image': 'assets/images_wilayah/wilayah_demak.png', 'isFound': false, 'isUnlocked': false, 'isVisible': false, }, { 'word': 'KIAMUK', 'question': 'Nama meriam besar peninggalan Kerajaan Banten', 'image': 'assets/images_islam/peninggalan_banten.png', 'isFound': false, 'isUnlocked': false, 'isVisible': false, }, { 'word': 'BELANDA', 'question': 'Kerajaan Banten, Gowa, dan Mataram berkonflik dengan bangsa', 'image': 'assets/images_islam/musuh.png', 'isFound': false, 'isUnlocked': false, 'isVisible': false, }, { 'word': 'MAKASSAR', 'question': 'Pusat kekuasaan keraja GowaTallo', 'image': 'assets/images_wilayah/wilayah_gowa.png', 'isFound': false, 'isUnlocked': false, 'isVisible': false, }, ]; int currentQuestionIndex = 0; late List> grid; String? lastFoundWord; // Untuk seleksi kata Offset? startDrag; Offset? currentDrag; List selectedCells = []; List correctCells = []; @override void initState() { super.initState(); startTimer(); initializeGame(); WidgetsBinding.instance.addPostFrameCallback((_) { _showQuestionCountDialog(); }); } void initializeGame() { grid = List.generate(GRID_SIZE, (_) => List.filled(GRID_SIZE, '')); placeWords(); fillEmptySpaces(); } void placeWords() { // Definisikan kata-kata yang akan diacak List words = [ 'GOWATALLO', 'DEMAK', 'KIAMUK', 'BELANDA', 'MAKASSAR', ]; // Urutkan kata dari yang terpanjang ke terpendek untuk optimasi penempatan words.sort((a, b) => b.length.compareTo(a.length)); // Bersihkan grid grid = List.generate(GRID_SIZE, (_) => List.filled(GRID_SIZE, '')); // Definisikan zona aman yang lebih tersebar untuk grid yang lebih besar final List> safeZones = [ [2, 2], // pojok kiri atas [2, 17], // pojok kanan atas [10, 10], // tengah [17, 2], // pojok kiri bawah [17, 17], // pojok kanan bawah [6, 14] // tengah kanan ]; final random = Random(); // Tempatkan kata-kata dengan variasi arah dan posisi for (int i = 0; i < words.length; i++) { String word = words[i]; bool placed = false; // Coba semua zona aman secara acak dengan offset yang lebih bervariasi List> availableZones = List.from(safeZones); availableZones.shuffle(random); for (var zone in availableZones) { // Tambahkan variasi offset yang lebih besar List> offsets = [ [-2, -2], [-2, 0], [-2, 2], [0, -2], [0, 0], [0, 2], [2, -2], [2, 0], [2, 2] ]; offsets.shuffle(random); for (var offset in offsets) { // Tentukan arah yang memungkinkan berdasarkan posisi List directions = []; int startRow = zone[0] + offset[0]; int startCol = zone[1] + offset[1]; // Cek arah horizontal if (startCol + word.length <= GRID_SIZE - 2) { directions.add(WordDirection.horizontal); } // Cek arah vertikal if (startRow + word.length <= GRID_SIZE - 2) { directions.add(WordDirection.vertical); } // Acak urutan arah directions.shuffle(random); for (var direction in directions) { if (canPlaceWord(word, startRow, startCol, direction)) { placeWordInGrid(PlacedWord( word: word, startRow: startRow, startCol: startCol, direction: direction, )); placed = true; break; } } if (placed) break; } if (placed) break; } // Jika masih tidak bisa ditempatkan, gunakan strategi fallback dengan jarak yang lebih besar if (!placed) { // Coba posisi dengan interval yang lebih besar for (int row = 0; row < GRID_SIZE; row += 5) { for (int col = 0; col < GRID_SIZE; col += 5) { List directions = [ WordDirection.horizontal, WordDirection.vertical ]; directions.shuffle(random); for (var direction in directions) { if (canPlaceWord(word, row, col, direction)) { placeWordInGrid(PlacedWord( word: word, startRow: row, startCol: col, direction: direction, )); placed = true; break; } } if (placed) break; } if (placed) break; } } // Jika masih tidak bisa ditempatkan, gunakan posisi terakhir dengan perhitungan dinamis if (!placed) { int baseOffset = (GRID_SIZE - word.length) ~/ 2; int fallbackRow = (i * 5 + baseOffset) % (GRID_SIZE - word.length); int fallbackCol = ((i * 7 + baseOffset) % (GRID_SIZE - word.length)); if (random.nextBool() && canPlaceWord( word, fallbackRow, fallbackCol, WordDirection.vertical)) { placeWordInGrid(PlacedWord( word: word, startRow: fallbackRow, startCol: fallbackCol, direction: WordDirection.vertical, )); } else { placeWordInGrid(PlacedWord( word: word, startRow: fallbackRow, startCol: fallbackCol, direction: WordDirection.horizontal, )); } } } } bool canPlaceWord( String word, int startRow, int startCol, WordDirection direction) { if (startRow < 0 || startCol < 0) return false; int row = startRow; int col = startCol; // Cek apakah kata muat dalam grid dengan margin aman yang lebih besar if (direction == WordDirection.horizontal) { if (col + word.length + 2 > GRID_SIZE) return false; } else if (direction == WordDirection.vertical) { if (row + word.length + 2 > GRID_SIZE) return false; } // Cek area sekitar kata dengan margin yang lebih besar for (int i = -2; i <= word.length + 1; i++) { for (int j = -2; j <= 2; j++) { int checkRow = direction == WordDirection.horizontal ? row + j : row + i; int checkCol = direction == WordDirection.horizontal ? col + i : col + j; if (checkRow >= 0 && checkRow < GRID_SIZE && checkCol >= 0 && checkCol < GRID_SIZE) { if (grid[checkRow][checkCol].isNotEmpty) return false; } } } return true; } void placeWordInGrid(PlacedWord word) { int row = word.startRow; int col = word.startCol; for (int i = 0; i < word.word.length; i++) { if (!isValidPosition(row, col)) break; grid[row][col] = word.word[i]; switch (word.direction) { case WordDirection.horizontal: col++; break; case WordDirection.vertical: row++; break; case WordDirection.diagonal: break; // Tidak menggunakan diagonal } } } void updateSelectedCells(Offset currentPosition) { if (startDrag == null) return; final RenderBox box = context.findRenderObject() as RenderBox; final Offset localStart = box.globalToLocal(startDrag!); final Offset localCurrent = box.globalToLocal(currentPosition); // Dapatkan ukuran dan posisi grid final gridStart = Offset(16.0, 120.0); // Sesuaikan dengan padding dan posisi grid final gridSize = box.size.width - 32.0; // Kurangi padding kiri dan kanan final cellSize = gridSize / GRID_SIZE; // Hitung posisi sel dengan mempertimbangkan offset grid int startRow = ((localStart.dy - gridStart.dy) ~/ cellSize).clamp(0, GRID_SIZE - 1); int startCol = ((localStart.dx - gridStart.dx) ~/ cellSize).clamp(0, GRID_SIZE - 1); int currentRow = ((localCurrent.dy - gridStart.dy) ~/ cellSize).clamp(0, GRID_SIZE - 1); int currentCol = ((localCurrent.dx - gridStart.dx) ~/ cellSize).clamp(0, GRID_SIZE - 1); setState(() { selectedCells = calculateSelectedCells(startRow, startCol, currentRow, currentCol); }); } bool isValidPosition(int row, int col) { return row >= 0 && row < GRID_SIZE && col >= 0 && col < GRID_SIZE; } List calculateSelectedCells( int startRow, int startCol, int endRow, int endCol) { List cells = []; // Hitung arah final int rowStep = startRow == endRow ? 0 : (endRow - startRow).sign; final int colStep = startCol == endCol ? 0 : (endCol - startCol).sign; // Hitung jumlah sel final int steps = max((endRow - startRow).abs(), (endCol - startCol).abs()); // Tambahkan sel ke seleksi for (int i = 0; i <= steps; i++) { final int row = startRow + (i * rowStep); final int col = startCol + (i * colStep); if (isValidPosition(row, col)) { cells.add(Offset(col.toDouble(), row.toDouble())); } } return cells; } void fillEmptySpaces() { final random = Random(); const letters = 'AEIMNRSTUW'; for (int i = 0; i < GRID_SIZE; i++) { for (int j = 0; j < GRID_SIZE; j++) { if (grid[i][j].isEmpty) { grid[i][j] = letters[random.nextInt(letters.length)]; } } } } void checkSelection() { if (selectedCells.length < 2) return; String selectedWord = ''; List orderedCells = List.from(selectedCells); // Urutkan sel berdasarkan arah seleksi if (orderedCells.first.dx > orderedCells.last.dx) { // Jika seleksi dari kanan ke kiri, balik urutan sel orderedCells = orderedCells.reversed.toList(); } for (var cell in orderedCells) { int row = cell.dy.toInt(); int col = cell.dx.toInt(); selectedWord += grid[row][col]; } // Cek kata normal dan terbalik if ((selectedWord == orderedQuestions[currentQuestionIndex]['word'] || selectedWord == orderedQuestions[currentQuestionIndex]['word'] .split('') .reversed .join()) && !orderedQuestions[currentQuestionIndex]['isFound']) { setState(() { orderedQuestions[currentQuestionIndex]['isFound'] = true; correctCells.addAll(selectedCells); score += 20; // Unlock pertanyaan berikutnya jika ada if (currentQuestionIndex < orderedQuestions.length - 1) { currentQuestionIndex++; orderedQuestions[currentQuestionIndex]['isUnlocked'] = true; orderedQuestions[currentQuestionIndex]['isVisible'] = true; } showCorrectAnswerDialog(); // Cek apakah semua pertanyaan sudah ditemukan if (orderedQuestions.every((q) => q['isFound'])) { showCompletionDialog(); } }); } } void showCorrectAnswerDialog() { AudioManager.successsound(); showDialog( context: context, barrierDismissible: false, builder: (context) => Dialog( backgroundColor: Colors.transparent, child: Stack( alignment: Alignment.center, children: [ Container( width: double.infinity, height: 400, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/dialog_complete.png'), fit: BoxFit.fill, ), borderRadius: BorderRadius.circular(16), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 40.0), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Anda menemukan kata "${orderedQuestions[currentQuestionIndex - 1]['word']}"', style: const TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), if (currentQuestionIndex < orderedQuestions.length) Padding( padding: const EdgeInsets.only(top: 10), child: Text( 'Pertanyaan selanjutnya telah dibuka', style: const TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), ), const SizedBox(height: 30), GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pop(context); }, child: Container( width: 150, height: 50, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/button.png'), fit: BoxFit.fill, ), ), child: const Center( child: Text( 'OK', style: TextStyle( fontFamily: 'Bestime', fontSize: 16, color: Color.fromARGB(255, 65, 44, 23), ), ), ), ), ), ], ), ), ], ), ), ); } void showCompletionDialog() async { AudioManager.winsound(); timer.cancel(); LevelManager.setLevelCompleted(3, true, LevelManager.TYPE_ISLAM); final user = FirebaseAuth.instance.currentUser; if (user != null) { await DatabaseService().saveScore( userId: user.uid, score: score, formattedTime: formatTime(elapsedSeconds), levelName: "Level 3", category: "Islam", ); } showDialog( context: context, barrierDismissible: false, builder: (context) => Dialog( backgroundColor: Colors.transparent, child: Stack( alignment: Alignment.center, children: [ Container( width: double.infinity, height: 400, // Sesuaikan tinggi background decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/dialog_complete.png'), fit: BoxFit.fill, ), borderRadius: BorderRadius.circular(16), ), ), // Isi konten berada tepat di tengah gambar Padding( padding: const EdgeInsets.symmetric(horizontal: 40.0), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'Anda telah menyelesaikan semua jawaban dengan benar.', style: TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), const SizedBox(height: 16), Text( 'Total Skor: $score', style: const TextStyle( fontFamily: 'Bestime', fontSize: 12, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), const SizedBox(height: 8), Text( 'Total Waktu: ${formatTime(elapsedSeconds)}', style: const TextStyle( fontFamily: 'Bestime', fontSize: 12, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), const SizedBox(height: 25), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const Level3Islam(), ), ); }, child: Container( width: 40, height: 40, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/restart.png'), fit: BoxFit.contain, ), ), ), ), const SizedBox(width: 20), GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pushAndRemoveUntil( context, MaterialPageRoute( builder: (context) => LandingPage( onStart: () {}, onStats: () {}, ), ), (route) => false, ); }, child: Container( width: 40, height: 40, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/stats.png'), fit: BoxFit.contain, ), ), ), ), ], ), ], ), ), ], ), ), ); } @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { AudioManager.playClickSound(); _showMenuDialog(context); return false; }, child: Scaffold( body: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/background_permainan.png'), fit: BoxFit.cover, ), ), child: Column( children: [ const SizedBox(height: 40), // Header (Timer, Menu, Score) Row( children: [ // Kiri (Timer) Flexible( flex: 2, child: Align( alignment: Alignment.centerLeft, child: Padding( padding: const EdgeInsets.only(left: 22.0), child: Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 5), width: 120, height: 45, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/grey_button.png'), fit: BoxFit.fill, ), ), child: Center( child: Text( '${formatTime(seconds)}', style: const TextStyle( fontSize: 20, color: Colors.black, fontFamily: 'Bestime', ), overflow: TextOverflow.ellipsis, ), ), ), ), ), ), // Tengah (Menu Icon) Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: GestureDetector( onTap: () { AudioManager.playClickSound(); _showMenuDialog(context); }, child: Container( width: 40, height: 40, margin: const EdgeInsets.symmetric(horizontal: 8), child: Image.asset( 'assets/icons/menu.png', fit: BoxFit.contain, ), ), ), ), // Kanan (Skor) Flexible( flex: 2, child: Align( alignment: Alignment.centerRight, child: Padding( padding: const EdgeInsets.only(right: 22.0), child: Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 5), width: 120, height: 45, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/grey_button.png'), fit: BoxFit.fill, ), ), child: Center( child: Text( '$score', style: const TextStyle( fontSize: 20, color: Colors.black, fontFamily: 'Bestime', ), overflow: TextOverflow.ellipsis, ), ), ), ), ), ), ], ), const SizedBox(height: 15), // Grid Area Expanded( child: SingleChildScrollView( physics: const NeverScrollableScrollPhysics(), // Prevent scrolling while selecting child: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ // Word Search Grid AspectRatio( aspectRatio: 1, // Make grid square child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), ), child: GestureDetector( onPanStart: (details) { setState(() { startDrag = details.globalPosition; selectedCells.clear(); }); }, onPanUpdate: (details) { updateSelectedCells(details.globalPosition); }, onPanEnd: (details) { checkSelection(); setState(() { startDrag = null; selectedCells.clear(); }); }, child: GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), padding: const EdgeInsets.all(16.0), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: GRID_SIZE, childAspectRatio: 1, crossAxisSpacing: 1, mainAxisSpacing: 1, ), itemCount: GRID_SIZE * GRID_SIZE, itemBuilder: (context, index) { final row = index ~/ GRID_SIZE; final col = index % GRID_SIZE; final isSelected = selectedCells.contains( Offset(col.toDouble(), row.toDouble())); final isCorrect = correctCells.contains( Offset(col.toDouble(), row.toDouble())); return Container( decoration: BoxDecoration( border: Border.all( color: Colors.grey.withOpacity(0.5)), color: isCorrect ? Colors.green.withOpacity(0.3) : isSelected ? Colors.blue.withOpacity(0.3) : Colors.white, ), child: Center( child: Text( grid[row][col], style: const TextStyle( fontSize: 12, fontFamily: 'Bestime', ), ), ), ); }, ), ), ), ), // Gambar peninggalan Container( height: 200, width: double.infinity, margin: const EdgeInsets.symmetric(vertical: 16), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), ), child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.asset( orderedQuestions[currentQuestionIndex]['image'], fit: BoxFit.fill, errorBuilder: (context, error, stackTrace) { return Container( color: Colors.grey[200], child: const Center( child: Icon( Icons.image_not_supported, size: 60, color: Colors.grey, ), ), ); }, ), ), ), // Pertanyaan yang sedang aktif Container( padding: const EdgeInsets.all(16), child: Stack( children: [ // Outline text Text( orderedQuestions[currentQuestionIndex] ['question'], style: TextStyle( fontFamily: 'Bestime', fontSize: 15, foreground: Paint() ..style = PaintingStyle.stroke ..strokeWidth = 2 ..color = const Color.fromARGB(255, 65, 44, 23), ), textAlign: TextAlign.center, ), // Fill text Text( orderedQuestions[currentQuestionIndex] ['question'], style: const TextStyle( fontFamily: 'Bestime', fontSize: 15, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), ], ), ), ], ), ), ), ), ], ), ), ), ); } String formatTime(int seconds) { int minutes = seconds ~/ 60; int remainingSeconds = seconds % 60; return '${minutes.toString().padLeft(2, '0')}:${remainingSeconds.toString().padLeft(2, '0')}'; } void startTimer() { timer = Timer.periodic(Duration(seconds: 1), (timer) { setState(() { if (seconds > 0) { seconds--; elapsedSeconds++; // Increment waktu yang telah berlalu } else { timer.cancel(); showTimeUpDialog(); } }); }); } void showTimeUpDialog() async { AudioManager.losesound(); final user = FirebaseAuth.instance.currentUser; if (user != null) { await DatabaseService().saveScore( userId: user.uid, score: score, formattedTime: formatTime(elapsedSeconds), levelName: "Level 3", category: "Islam", ); } showDialog( context: context, barrierDismissible: false, builder: (context) => Dialog( backgroundColor: Colors.transparent, child: Stack( alignment: Alignment.center, children: [ Container( width: double.infinity, height: 400, // Sesuaikan dengan tinggi gambar background decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/timeout.png'), fit: BoxFit.fill, ), borderRadius: BorderRadius.circular(16), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 40.0), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'Waktu permainan telah habis.', style: TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), const SizedBox(height: 16), Text( 'Total Skor: $score', style: const TextStyle( fontFamily: 'Bestime', fontSize: 12, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), const SizedBox(height: 8), Text( 'Total Waktu: ${formatTime(elapsedSeconds)}', style: const TextStyle( fontFamily: 'Bestime', fontSize: 12, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), const SizedBox(height: 30), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const Level3Islam(), ), ); }, child: Container( width: 40, height: 40, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/restart.png'), fit: BoxFit.contain, ), ), ), ), const SizedBox(width: 20), GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pushAndRemoveUntil( context, MaterialPageRoute( builder: (context) => LandingPage( onStart: () {}, onStats: () {}, ), ), (route) => false, ); }, child: Container( width: 40, height: 40, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/stats.png'), fit: BoxFit.contain, ), ), ), ), ], ), ], ), ), ], ), ), ); } @override void dispose() { timer.cancel(); super.dispose(); } void _showMenuDialog(BuildContext context) { showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return Dialog( backgroundColor: Colors.transparent, child: Stack( alignment: Alignment.center, children: [ Container( width: double.infinity, height: 400, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/cover_menu.png'), fit: BoxFit.fill, ), borderRadius: BorderRadius.circular(16), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 40.0), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ // Button Lanjut GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pop(context); }, child: Container( width: 170, height: 50, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/grey_button.png'), fit: BoxFit.fill, ), ), child: const Center( child: Text( 'Lanjut', style: TextStyle( fontFamily: 'Bestime', fontSize: 16, color: Color.fromARGB(255, 65, 44, 23), ), ), ), ), ), const SizedBox(height: 18), // Button Restart GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const Level3Islam(), ), ); }, child: Container( width: 170, height: 50, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/grey_button.png'), fit: BoxFit.fill, ), ), child: const Center( child: Text( 'Restart', style: TextStyle( fontFamily: 'Bestime', fontSize: 16, color: Color.fromARGB(255, 65, 44, 23), ), ), ), ), ), const SizedBox(height: 18), // Button Keluar GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pushAndRemoveUntil( context, MaterialPageRoute( builder: (context) => LandingPage( onStart: () {}, onStats: () {}, ), ), (route) => false, ); }, child: Container( width: 170, height: 50, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/grey_button.png'), fit: BoxFit.fill, ), ), child: const Center( child: Text( 'Keluar', style: TextStyle( fontFamily: 'Bestime', fontSize: 16, color: Color.fromARGB(255, 65, 44, 23), ), ), ), ), ), ], ), ), ], ), ); }, ); } void _showQuestionCountDialog() { showDialog( context: context, barrierDismissible: false, builder: (context) => Dialog( backgroundColor: Colors.transparent, child: Stack( alignment: Alignment.center, children: [ Container( width: double.infinity, height: 300, decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/covertext.png'), fit: BoxFit.fill, ), borderRadius: BorderRadius.circular(16), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 40.0), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Level ini memiliki total ${orderedQuestions.length} pertanyaan.', style: const TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB(255, 182, 134, 86), ), textAlign: TextAlign.center, ), const SizedBox(height: 30), GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.pop(context); }, child: Container( width: 150, height: 50, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/button.png'), fit: BoxFit.fill, ), ), child: const Center( child: Text( 'Mulai', style: TextStyle( fontFamily: 'Bestime', fontSize: 16, color: Color.fromARGB(255, 65, 44, 23), ), ), ), ), ), ], ), ), ], ), ), ); } } // Game level 3 class GameLevel3 extends FlameGame { @override Color backgroundColor() => Colors.white; @override Future onLoad() async { // Bisa ditambahkan komponen lain jika diperlukan } }