Tugas 10: Membuat Aplikasi Unscramble menggunakan ViewModel dan State pada Compose
Nama : Fathin Muhashibi Putra
NRP : 5025211229
Kelas : PPB - A
Tugas 10:
Membuat Aplikasi Unscramble menggunakan ViewModel dan State pada Compose
Pada tugas kali ini, saya membuat aplikasi Unscramble menggunakan ViewModel dan State pada Compose. Berikut adalah langkah-langkah yang dilakukan:
1. Persiapan Proyek
Pertama, buat proyek baru di Android Studio menggunakan template Empty Compose Activity. Beri nama proyek Anda misalnya Unscramble dan biarkan pengaturan lainnya dalam kondisi default.
2. Menambahkan ViewModel
Selanjutnya, tambahkan ViewModel untuk mengelola status UI aplikasi, seperti kata acak, skor, dan tebakan pengguna. Berikut adalah contoh implementasi ViewModel:
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
class GameViewModel : ViewModel() {
private val _uiState = MutableStateFlow(GameUiState())
val uiState: StateFlow = _uiState
var userGuess by mutableStateOf("")
private set
private lateinit var currentWord: String
private var usedWords: MutableSet = mutableSetOf()
fun pickRandomWordAndShuffle(): String {
currentWord = allWords.random()
if (usedWords.contains(currentWord)) {
return pickRandomWordAndShuffle()
} else {
usedWords.add(currentWord)
return shuffleCurrentWord(currentWord)
}
}
fun shuffleCurrentWord(word: String): String {
val tempWord = word.toCharArray()
tempWord.shuffle()
while (String(tempWord).equals(word)) {
tempWord.shuffle()
}
return String(tempWord)
}
fun updateUserGuess(guessedWord: String) {
userGuess = guessedWord
}
fun checkUserGuess() {
if (userGuess.equals(currentWord, ignoreCase = true)) {
updateGameState()
} else {
_uiState.value = _uiState.value.copy(isGuessedWordWrong = true)
}
userGuess = ""
}
private fun updateGameState() {
_uiState.update { currentState ->
currentState.copy(
currentScrambledWord = pickRandomWordAndShuffle(),
score = currentState.score + 20 // Example scoring
)
}
}
}
3. Desain UI dengan Jetpack Compose
Setelah ViewModel ditambahkan, selanjutnya membuat UI menggunakan Jetpack Compose. Berikut adalah kode untuk menampilkan kata yang diacak dan menerima tebakan pengguna:
@Composable
fun GameScreen(gameViewModel: GameViewModel = viewModel()) {
val gameUiState by gameViewModel.uiState.collectAsState()
Column(modifier = Modifier.padding(16.dp)) {
Text("Unscramble Game", style = MaterialTheme.typography.h5)
GameLayout(
currentScrambledWord = gameUiState.currentScrambledWord,
userGuess = gameViewModel.userGuess,
onUserGuessChanged = { gameViewModel.updateUserGuess(it) },
onKeyboardDone = { gameViewModel.checkUserGuess() }
)
GameStatus(score = gameUiState.score)
if (gameUiState.isGameOver) {
FinalScoreDialog(
score = gameUiState.score,
onPlayAgain = { gameViewModel.resetGame() }
)
}
}
}
@Composable
fun GameLayout(
currentScrambledWord: String,
userGuess: String,
onUserGuessChanged: (String) -> Unit,
onKeyboardDone: () -> Unit,
modifier: Modifier = Modifier
) {
Column(modifier = modifier) {
Text(text = currentScrambledWord, style = MaterialTheme.typography.h6)
OutlinedTextField(
value = userGuess,
onValueChange = onUserGuessChanged,
label = { Text("Enter your word") },
isError = false,
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = onKeyboardDone)
)
}
}
@Composable
fun GameStatus(score: Int) {
Text("Score: $score", style = MaterialTheme.typography.body1)
}
@Composable
fun FinalScoreDialog(score: Int, onPlayAgain: () -> Unit) {
AlertDialog(
onDismissRequest = { /* Handle dismiss */ },
title = { Text("Congratulations!") },
text = { Text("You scored: $score") },
confirmButton = {
TextButton(onClick = onPlayAgain) {
Text("Play Again")
}
},
dismissButton = {
TextButton(onClick = { /* Handle exit */ }) {
Text("Exit")
}
}
)
}
4. Menangani Perubahan Konfigurasi
Pastikan bahwa status UI tetap terjaga selama perubahan konfigurasi perangkat, seperti rotasi layar. Dengan menggunakan ViewModel, data tetap tersedia tanpa hilang saat aktivitas dihancurkan dan dibuat ulang.
class GameViewModel : ViewModel() {
private val _uiState = MutableStateFlow(GameUiState())
val uiState: StateFlow = _uiState.asStateFlow()
init {
resetGame()
}
private fun resetGame() {
_uiState.value = GameUiState(currentScrambledWord = pickRandomWordAndShuffle())
}
}
5. Verifikasi Tebakan Pengguna dan Pembaruan Skor
Implementasikan metode untuk memverifikasi tebakan pengguna dan memperbarui skor.
fun checkUserGuess() {
if (userGuess.equals(currentWord, ignoreCase = true)) {
val updatedScore = _uiState.value.score + 20
updateGameState(updatedScore)
} else {
_uiState.update { it.copy(isGuessedWordWrong = true) }
}
userGuess = ""
}
6. Dialog Akhir Permainan
Tampilkan dialog saat permainan selesai dengan opsi untuk melanjutkan atau keluar.
@Composable
fun FinalScoreDialog(score: Int, onPlayAgain: () -> Unit) {
AlertDialog(
onDismissRequest = { /* Handle dismiss */ },
title = { Text("Game Over") },
text = { Text("Your score is: $score") },
confirmButton = {
TextButton(onClick = onPlayAgain) {
Text("Play Again")
}
},
dismissButton = {
TextButton(onClick = { /* Exit the game */ }) {
Text("Exit")
}
}
)
}

Comments
Post a Comment