Tutorial Pembuatan Aplikasi Dice Roller Interaktif dengan Jetpack Compose
Nama : Iftala Zahri Sukmana
NRP : 5025221002
Kelas : G
Link GitHub : https://github.com/ifzahri/ppb/tree/main/DiceRoller
Pada kesempatan kali ini, kita akan mempelajari cara membuat aplikasi Dice Roller (Pelempar Dadu) yang interaktif menggunakan Jetpack Compose dan Kotlin. Aplikasi ini tidak hanya menampilkan animasi pelemparan dadu, tetapi juga menyimpan riwayat lemparan terakhir untuk pengalaman pengguna yang lebih menarik.
Persiapan Awal
Sebelum memulai, pastikan Anda telah menginstal Android Studio versi terbaru. Untuk tutorial ini, kita akan menggunakan Jetpack Compose - UI toolkit modern untuk Android yang ditulis dalam bahasa Kotlin.
Langkah 1: Membuat Proyek Baru
- Buka Android Studio
- Pilih "New Project"
- Pilih "Empty Compose Activity"
- Beri nama proyek "Dice Roller"
- Atur package name menjadi "com.example.diceroller"
- Pilih Kotlin sebagai bahasa pemrograman
- Klik "Finish"
Membuat Aset Gambar Dadu
Untuk aplikasi ini, kita membutuhkan gambar dadu dengan angka 1 sampai 6. Kita akan membuat gambar vektor (Vector Drawable) untuk setiap sisi dadu.
Langkah 2: Menambahkan Sumber Daya Gambar Dadu
- Klik kanan pada folder
res/drawable - Pilih "New" → "Vector Asset" atau "New" → "File"
- Buat file XML untuk setiap dadu (dice_1.xml hingga dice_6.xml)
Contoh kode untuk dice_1.xml:
<?xml version="1.0" encoding="utf-8"?><vector xmlns:android="http://schemas.android.com/apk/res/android"android:width="200dp"android:height="200dp"android:viewportWidth="200"android:viewportHeight="200"><pathandroid:fillColor="#FFFFFF"android:pathData="M20,20L180,20L180,180L20,180z"android:strokeWidth="8"android:strokeColor="#000000"android:strokeLineCap="round"android:strokeLineJoin="round" /><pathandroid:fillColor="#000000"android:pathData="M100,100m-15,0a15,15 0,1 1,30 0a15,15 0,1 1,-30 0" /></vector>
Catatan: Ulangi langkah yang sama untuk dadu lainnya (dice_2.xml hingga dice_6.xml) dengan memodifikasi posisi titik sesuai dengan pola dadu.
Menambahkan String Resources
Langkah 3: Modifikasi File Strings.xml
Buka file res/values/strings.xml dan tambahkan string yang diperlukan:
<resources><string name="app_name">Dice Roller</string><string name="roll">Roll</string><string name="roll_history">Roll History</string></resources>
Kode MainActivity
Langkah 4: Menerapkan Kode MainActivity.kt
Ganti konten file MainActivity.kt dengan kode berikut:
package com.example.dicerollerimport android.os.Bundleimport androidx.activity.ComponentActivityimport androidx.activity.compose.setContentimport androidx.compose.animation.core.animateFloatAsStateimport androidx.compose.animation.core.tweenimport androidx.compose.foundation.Imageimport androidx.compose.foundation.backgroundimport androidx.compose.foundation.clickableimport androidx.compose.foundation.layout.Arrangementimport androidx.compose.foundation.layout.Boximport androidx.compose.foundation.layout.Columnimport androidx.compose.foundation.layout.Rowimport androidx.compose.foundation.layout.Spacerimport androidx.compose.foundation.layout.fillMaxSizeimport androidx.compose.foundation.layout.fillMaxWidthimport androidx.compose.foundation.layout.heightimport androidx.compose.foundation.layout.paddingimport androidx.compose.foundation.layout.sizeimport androidx.compose.foundation.shape.RoundedCornerShapeimport androidx.compose.material3.Buttonimport androidx.compose.material3.MaterialThemeimport androidx.compose.material3.Surfaceimport androidx.compose.material3.Textimport androidx.compose.runtime.Composableimport androidx.compose.runtime.getValueimport androidx.compose.runtime.mutableStateOfimport androidx.compose.runtime.rememberimport androidx.compose.runtime.setValueimport androidx.compose.ui.Alignmentimport androidx.compose.ui.Modifierimport androidx.compose.ui.draw.clipimport androidx.compose.ui.draw.rotateimport androidx.compose.ui.graphics.Colorimport androidx.compose.ui.res.painterResourceimport androidx.compose.ui.res.stringResourceimport androidx.compose.ui.text.font.FontWeightimport androidx.compose.ui.tooling.preview.Previewimport androidx.compose.ui.unit.dpimport androidx.compose.ui.unit.spimport com.example.diceroller.ui.theme.DiceRollerThemeclass MainActivity : ComponentActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContent {DiceRollerTheme {Surface(modifier = Modifier.fillMaxSize(),color = MaterialTheme.colorScheme.background) {DiceRollerApp()}}}}}@Composablefun DiceRollerApp() {var diceValue by remember { mutableStateOf(1) }var isRolling by remember { mutableStateOf(false) }var diceHistory by remember { mutableStateOf(listOf<Int>()) }val rotation by animateFloatAsState(targetValue = if (isRolling) 360f else 0f,animationSpec = tween(500),finishedListener = {isRolling = false})Column(modifier = Modifier.fillMaxSize().padding(16.dp),horizontalAlignment = Alignment.CenterHorizontally,verticalArrangement = Arrangement.Center) {Text(text = stringResource(R.string.app_name),fontSize = 28.sp,fontWeight = FontWeight.Bold,modifier = Modifier.padding(bottom = 24.dp))Box(contentAlignment = Alignment.Center,modifier = Modifier.size(200.dp).padding(16.dp).clip(RoundedCornerShape(8.dp)).background(Color(0xFFE0E0E0)).clickable {rollDice(onRollStart = { isRolling = true },onNewValue = { newValue ->diceValue = newValuediceHistory = diceHistory + newValueif (diceHistory.size > 10) {diceHistory = diceHistory.drop(1)}})}) {Image(painter = painterResource(getDiceImageResource(diceValue)),contentDescription = diceValue.toString(),modifier = Modifier.size(140.dp).rotate(rotation))}Spacer(modifier = Modifier.height(24.dp))Button(onClick = {rollDice(onRollStart = { isRolling = true },onNewValue = { newValue ->diceValue = newValuediceHistory = diceHistory + newValueif (diceHistory.size > 10) {diceHistory = diceHistory.drop(1)}})},modifier = Modifier.padding(16.dp)) {Text(text = stringResource(R.string.roll),fontSize = 18.sp)}Spacer(modifier = Modifier.height(32.dp))if (diceHistory.isNotEmpty()) {Text(text = stringResource(R.string.roll_history),fontSize = 18.sp,fontWeight = FontWeight.Bold,modifier = Modifier.padding(8.dp))Row(modifier = Modifier.fillMaxWidth().padding(8.dp),horizontalArrangement = Arrangement.Center) {diceHistory.forEach { value ->Image(painter = painterResource(getDiceImageResource(value)),contentDescription = value.toString(),modifier = Modifier.size(40.dp).padding(horizontal = 4.dp))}}}}}private fun rollDice(onRollStart: () -> Unit, onNewValue: (Int) -> Unit) {onRollStart()val newValue = (1..6).random()onNewValue(newValue)}private fun getDiceImageResource(diceValue: Int): Int {return when (diceValue) {1 -> R.drawable.dice_12 -> R.drawable.dice_23 -> R.drawable.dice_34 -> R.drawable.dice_45 -> R.drawable.dice_5else -> R.drawable.dice_6}}@Preview(showBackground = true)@Composablefun DiceRollerPreview() {DiceRollerTheme {DiceRollerApp()}}
Penjelasan Kode
Mari kita bahas komponen utama dari aplikasi kita:
1. State Management
var diceValue by remember { mutableStateOf(1) }var isRolling by remember { mutableStateOf(false) }var diceHistory by remember { mutableStateOf(listOf<Int>()) }
Kode ini membuat tiga variabel state:
diceValue: menyimpan nilai dadu saat ini (1-6)isRolling: status apakah dadu sedang berputar atau tidakdiceHistory: menyimpan riwayat hasil lemparan dadu sebelumnya
2. Animasi Rotasi
val rotation by animateFloatAsState(targetValue = if (isRolling) 360f else 0f,animationSpec = tween(500),finishedListener = {isRolling = false})
Kode ini membuat animasi rotasi 360 derajat ketika dadu dilempar. Animasi berlangsung selama 500 milidetik, dan ketika selesai, status isRolling diubah menjadi false.
3. Fungsi Pelemparan Dadu
private fun rollDice(onRollStart: () -> Unit, onNewValue: (Int) -> Unit) {onRollStart()val newValue = (1..6).random()onNewValue(newValue)}
Fungsi ini menghasilkan angka acak antara 1 dan 6, dan memanggil callback-callback yang diberikan untuk menangani permulaan dan hasil lemparan.
4. Fitur Riwayat Lemparan
diceHistory = diceHistory + newValueif (diceHistory.size > 10) {diceHistory = diceHistory.drop(1)}
Kode ini menambahkan hasil lemparan baru ke riwayat dan membatasi ukuran riwayat hingga maksimal 10 lemparan terakhir.
Fitur Utama Aplikasi
Aplikasi Dice Roller kita memiliki beberapa fitur menarik:
-
Interaksi yang Intuitif: Pengguna dapat melempar dadu dengan menekan tombol "Roll" atau dengan mengklik langsung pada gambar dadu.
-
Animasi Rotasi: Setiap kali dadu dilempar, gambar dadu akan berputar 360 derajat, memberikan efek visual yang lebih menarik.
-
Riwayat Lemparan: Aplikasi menyimpan dan menampilkan hingga 10 hasil lemparan terakhir, sehingga pengguna dapat melihat pola atau tren dari lemparan sebelumnya.
-
Antarmuka Modern: Dengan Jetpack Compose, aplikasi memiliki tampilan yang bersih dan modern dengan penempatan elemen yang tepat.
Kesimpulan
Dalam tutorial ini, kita telah berhasil membuat aplikasi Dice Roller interaktif menggunakan Jetpack Compose. Aplikasi ini menunjukkan bagaimana menggunakan fitur-fitur Compose seperti state management, animasi, dan layout yang responsif untuk menciptakan pengalaman pengguna yang menarik.
Aplikasi ini juga mendemonstrasikan pola desain yang baik seperti:
- Komponen yang dapat digunakan kembali
- Pemisahan antara UI dan logika
- Penanganan state yang efektif
- Penggunaan animasi untuk meningkatkan pengalaman pengguna

Komentar
Posting Komentar