import 'package:flutter/material.dart'; import 'dart:async'; import 'dart:math'; import 'package:flame/game.dart'; import '../landing_page.dart'; import 'level3_hindubuddha.dart'; import '../utils/level_manager.dart'; import '../utils/audio_manager.dart'; import 'package:permainan_kata_anak_sd/services/database_service.dart'; import 'package:firebase_auth/firebase_auth.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 Level2HinduBuddha extends StatefulWidget { const Level2HinduBuddha({Key? key}) : super(key: key); @override _Level2HinduBuddhaState createState() => _Level2HinduBuddhaState(); } class _Level2HinduBuddhaState extends State { // Definisikan gridSize sebagai konstanta kelas static const int GRID_SIZE = 15; 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': 'JAGO', 'question': 'Salah satu candi peninggalan kerajaan Singasari', 'image': 'assets/images_hindubuddha/peninggalan_singosari.png', 'isFound': false, 'isUnlocked': true, // Pertanyaan pertama sudah unlocked 'isVisible': true, // Pertanyaan pertama sudah visible }, { 'word': 'KALINGGA', 'question': 'Kerajaan Hindu tertua di Jawa Tengah yang dipimpin oleh Ratu Shima', 'image': 'assets/images_raja/raja_kalingga.png', 'isFound': false, 'isUnlocked': false, 'isVisible': false, }, { 'word': 'SINGASARI', 'question': 'Rajanya yang terkenal adalah Ken Arok', 'image': 'assets/images_raja/raja_singasari.png', 'isFound': false, 'isUnlocked': false, 'isVisible': false, }, { 'word': 'MALANG', 'question': 'Letak pusat kekuasaan kerajaan Singasari', 'image': 'assets/images_wilayah/wilayah_singasari.png', 'isFound': false, 'isUnlocked': false, 'isVisible': false, }, { 'word': 'KUTAI', 'question': 'Mulawarman merupakan salah satu raja dari Kerajaan apa', 'image': 'assets/images_raja/raja_kutai.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(); // Tampilkan notifikasi jumlah pertanyaan setelah build pertama 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 = [ 'JAGO', 'KALINGGA', 'SINGASARI', 'MALANG', 'KUTAI' ]; // Bersihkan grid grid = List.generate(GRID_SIZE, (_) => List.filled(GRID_SIZE, '')); // Posisi yang tersedia untuk penempatan kata List horizontalPositions = [2, 4, 6, 8, 10, 12]; // Tambah posisi baris List verticalPositions = [2, 4, 6, 8, 10, 12]; // Tambah posisi kolom // Acak urutan kata-kata final random = Random(); words.shuffle(random); // Tempatkan kata-kata dengan arah acak for (String word in words) { bool placed = false; List directions = [ WordDirection.horizontal, WordDirection.vertical ]; directions.shuffle(random); // Acak urutan arah untuk mencoba for (WordDirection direction in directions) { if (placed) break; if (direction == WordDirection.horizontal) { // Coba setiap posisi horizontal yang tersedia horizontalPositions.shuffle(random); for (int row in horizontalPositions) { if (placed) break; // Hitung kolom awal yang memungkinkan int maxStartCol = GRID_SIZE - word.length; if (maxStartCol < 0) continue; // Kata terlalu panjang untuk grid int startCol = random.nextInt(maxStartCol); // Cek apakah kata bisa ditempatkan di posisi ini if (canPlaceWord(word, row, startCol, WordDirection.horizontal)) { placeWordInGrid(PlacedWord( word: word, startRow: row, startCol: startCol, direction: WordDirection.horizontal, )); placed = true; // Hapus posisi yang sudah digunakan horizontalPositions.remove(row); break; } } } else { // Coba setiap posisi vertikal yang tersedia verticalPositions.shuffle(random); for (int col in verticalPositions) { if (placed) break; // Hitung baris awal yang memungkinkan int maxStartRow = GRID_SIZE - word.length; if (maxStartRow < 0) continue; // Kata terlalu panjang untuk grid int startRow = random.nextInt(maxStartRow); // Cek apakah kata bisa ditempatkan di posisi ini if (canPlaceWord(word, startRow, col, WordDirection.vertical)) { placeWordInGrid(PlacedWord( word: word, startRow: startRow, startCol: col, direction: WordDirection.vertical, )); placed = true; // Hapus posisi yang sudah digunakan verticalPositions.remove(col); break; } } } } // Jika kata tidak bisa ditempatkan dengan arah yang diinginkan, coba arah lain if (!placed) { // Coba tempatkan secara horizontal di posisi default int row = horizontalPositions.isNotEmpty ? horizontalPositions.first : 2; placeWordInGrid(PlacedWord( word: word, startRow: row, startCol: 1, direction: WordDirection.horizontal, )); if (horizontalPositions.isNotEmpty) { horizontalPositions.remove(row); } } } fillEmptySpaces(); } 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 if (direction == WordDirection.horizontal && col + word.length > GRID_SIZE) return false; if (direction == WordDirection.vertical && row + word.length > GRID_SIZE) return false; // Cek apakah ada tumpang tindih dengan kata lain for (int i = 0; i < word.length; i++) { // Cek batas grid if (row >= GRID_SIZE || col >= GRID_SIZE) return false; // Cek apakah sel sudah terisi dengan huruf berbeda if (grid[row][col].isNotEmpty && grid[row][col] != word[i]) { return false; } // Cek sel di sekitar untuk menghindari kata yang terlalu dekat if (row > 0 && grid[row - 1][col].isNotEmpty) return false; if (row < GRID_SIZE - 1 && grid[row + 1][col].isNotEmpty) return false; if (col > 0 && grid[row][col - 1].isNotEmpty) return false; if (col < GRID_SIZE - 1 && grid[row][col + 1].isNotEmpty) return false; // Pindah ke sel berikutnya sesuai arah if (direction == WordDirection.horizontal) { col++; } else { row++; } } 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: row++; col++; break; } } } 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(); // Simpan status level 2 selesai (bukan level 1) LevelManager.setLevelCompleted(2, true, LevelManager.TYPE_HINDU_BUDDHA); final user = FirebaseAuth.instance.currentUser; if (user != null) { await DatabaseService().saveScore( userId: user.uid, score: score, formattedTime: formatTime(elapsedSeconds), levelName: "Level 2", category: "Hindu Buddha", ); } 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 Level2HinduBuddha(), ), ); }, 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/menu.png'), fit: BoxFit.contain, ), ), ), ), const SizedBox(width: 20), GestureDetector( onTap: () { AudioManager.playClickSound(); Navigator.push( context, MaterialPageRoute( builder: (context) => const Level3HinduBuddha(), ), ); }, child: Container( width: 40, height: 40, decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/next.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: 15, 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 2", category: "Hindu Buddha", ); } 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 Level2HinduBuddha(), ), ); }, 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/menu.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 Level2HinduBuddha(), ), ); }, 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 2 class GameLevel2 extends FlameGame { @override Color backgroundColor() => Colors.white; @override Future onLoad() async { // Bisa ditambahkan komponen lain jika diperlukan } }