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")
            }
        }
    )
}

7. Selesai

Setelah mengikuti semua langkah-langkah tersebut, maka jadilah sebuah aplikasi Unscramble menggunakan ViewModel dan State pada Compose


Screenshot Hasil :



8. Kode Lengkap (Github Code):



9. Video Demo Compile/Run Application Unscramble:




Referensi : 
https://kuliahppb.blogspot.com/2024/05/viewmodel-and-state-in-compose.html
https://developer.android.com/codelabs/basic-android-kotlin-compose-viewmodel-and-state#0

Comments

Popular posts from this blog

Tugas 2: Membuat Aplikasi Hello World menggunakan Jetpack Compose (PPB - A)

Tugas 1: Review Perkembangan Teknologi Perangkat Bergerak (PPB - A)

ETS - Evaluasi Tengah Semester: Proyek - Mobile Front End