Tugas Pertemuan 12 - Dessert Clicker
github: https://github.com/ilomimo/dessert-clicker
demo:
Tugas Pertemuan 12: Aplikasi Dessert Clicker
Pada tugas kali ini, Pak Fajar memberikan instruks untuk menganalisis dan memahami cara kerja aplikasi Dessert Clicker. Aplikasi ini merupakan bagian dari pembelajaran Android Basics with Compose Codelab yang bertujuan untuk mengeksplorasi Android lifecycle dan melakukan logging ke Android console (Logcat). Melalui analisis dan percobaan ini, materi yang dipelajari antara lain: mekanisme kerja aplikasi, struktur kode utama, dan implementasi lifecycle management dalam Android development.
Konsep Dasar Aplikasi
Dessert Clicker adalah aplikasi game sederhana yang mengimplementasikan konsep incremental clicker game. Pemain berinteraksi dengan aplikasi melalui mekanisme tap atau click untuk menghasilkan progress dalam bentuk pembuatan dessert dan akumulasi pendapatan virtual.
Mekanisme Permainan
Aplikasi beroperasi dengan sistem yang sangat straightforward dimana setiap interaksi pengguna (button press) akan mentrigger serangkaian action yang menghasilkan outcome berupa:
- Dessert Production: Setiap click menghasilkan satu unit dessert
- Revenue Generation: Setiap dessert yang diproduksi menghasilkan sejumlah virtual currency
- Progress Tracking: Aplikasi melacak total dessert yang telah dibuat dan total pendapatan
- Visual Feedback: Interface memberikan feedback visual terhadap action pengguna
Struktur Kode Utama
Berdasarkan analisis file yang tersedia, aplikasi menggunakan arsitektur Android modern dengan Jetpack Compose. Berikut adalah komponen-komponen utama:
1. Configuration Files
build.gradle.kts (Module Level):
android {
namespace = "com.example.dessertclicker"
compileSdk = 35
defaultConfig {
applicationId = "com.example.dessertclicker"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"
}
buildFeatures {
compose = true
}
}
dependencies {
implementation(platform("androidx.compose:compose-bom:2024.12.01"))
implementation("androidx.activity:activity-compose:1.9.3")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7")
}
Konfigurasi build menunjukkan bahwa aplikasi menggunakan Android API level 24-35 dan mengimplementasikan Jetpack Compose sebagai UI framework. Dependencies yang digunakan fokus pada Compose ecosystem dan lifecycle management.
2. Project Structure
settings.gradle.kts:
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "Dessert Clicker"
include(":app")
Project menggunakan standard Android project structure dengan dependency resolution melalui Google dan Maven Central repositories. Konfigurasi ini memastikan semua dependencies dapat diakses dengan proper version management.
Implementasi Android Lifecycle
Aplikasi Dessert Clicker dirancang khusus untuk mengajarkan pemahaman tentang Android Activity Lifecycle. Lifecycle events yang dimonitor meliputi:
Lifecycle States dan Methods
- onCreate(): Dipanggil saat activity dibuat pertama kali
- onStart(): Dipanggil saat activity menjadi visible kepada user
- onResume(): Dipanggil saat activity siap menerima user interaction
- onPause(): Dipanggil saat activity kehilangan focus
- onStop(): Dipanggil saat activity tidak lagi visible
- onDestroy(): Dipanggil saat activity akan dihancurkan
Logging dan Debugging
Salah satu tujuan utama aplikasi ini adalah untuk mengajarkan implementasi logging dalam Android development. Setiap lifecycle event akan menghasilkan log message yang dapat diamati melalui Logcat. Implementasi logging memungkinkan developer untuk:
- Memantau lifecycle transitions: Melihat kapan setiap lifecycle method dipanggil
- Debug application behavior: Mengidentifikasi potential issues dalam state management
- Understand app flow: Memahami sequence of events dalam aplikasi Android
State Management
Aplikasi mengimplementasikan state management untuk melacak:
- Dessert Count: Jumlah total dessert yang telah diproduksi
- Revenue Amount: Total pendapatan yang telah dikumpulkan
- Current Dessert Type: Jenis dessert yang sedang diproduksi
- Game Progress: Overall progress dalam permainan
User Interface dengan Jetpack Compose
Aplikasi menggunakan Jetpack Compose untuk membangun user interface yang reactive dan modern. Compose memungkinkan:
- Declarative UI: Interface dideklarasikan berdasarkan state
- Automatic Recomposition: UI secara otomatis update ketika state berubah
- Material Design 3: Implementasi design system terbaru dari Google
Implementasi MainActivity
Berdasarkan struktur project yang ada, MainActivity.kt merupakan entry point utama aplikasi Dessert Clicker. Berikut adalah analisis implementasi yang seharusnya ada dalam file tersebut:
Struktur Dasar MainActivity
package com.example.dessertclicker
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.dessertclicker.ui.theme.DessertClickerTheme
class MainActivity : ComponentActivity() {
private val TAG = "MainActivity"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate Called")
enableEdgeToEdge()
setContent {
DessertClickerTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
DessertClickerApp()
}
}
}
}
override fun onStart() {
super.onStart()
Log.d(TAG, "onStart Called")
}
override fun onResume() {
super.onResume()
Log.d(TAG, "onResume Called")
}
override fun onPause() {
super.onPause()
Log.d(TAG, "onPause Called")
}
override fun onStop() {
super.onStop()
Log.d(TAG, "onStop Called")
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy Called")
}
override fun onRestart() {
super.onRestart()
Log.d(TAG, "onRestart Called")
}
}
MainActivity mewarisi ComponentActivity yang merupakan base class untuk activities yang menggunakan Jetpack Compose. Setiap lifecycle method di-override dengan implementasi logging untuk educational purposes.
Implementasi Game Logic dan UI
@Composable
fun DessertClickerApp() {
var dessertsSold by remember { mutableStateOf(0) }
var revenue by remember { mutableStateOf(0) }
var currentDessertIndex by remember { mutableStateOf(0) }
val desserts = listOf(
Dessert(R.drawable.cupcake, 5, 0),
Dessert(R.drawable.donut, 10, 5),
Dessert(R.drawable.eclair, 15, 20),
Dessert(R.drawable.froyo, 30, 50),
Dessert(R.drawable.gingerbread, 50, 100),
Dessert(R.drawable.honeycomb, 100, 200),
Dessert(R.drawable.icecream, 500, 500),
Dessert(R.drawable.jellybean, 1000, 1000),
Dessert(R.drawable.kitkat, 2000, 2000),
Dessert(R.drawable.lollipop, 3000, 4000),
Dessert(R.drawable.marshmallow, 4000, 8000),
Dessert(R.drawable.nougat, 5000, 16000),
Dessert(R.drawable.oreo, 6000, 20000)
)
val currentDessert = desserts[currentDessertIndex]
Column(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFFFF3E0)),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Header dengan informasi revenue dan desserts sold
DessertClickerHeader(
revenue = revenue,
dessertsSold = dessertsSold,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(32.dp))
// Main dessert image yang bisa diklik
Image(
painter = painterResource(currentDessert.imageId),
contentDescription = "Dessert to click",
modifier = Modifier
.size(300.dp)
.clickable {
// Logic ketika dessert diklik
dessertsSold++
revenue += currentDessert.price
// Check untuk upgrade dessert
for (dessertIndex in desserts.indices.reversed()) {
if (dessertsSold >= desserts[dessertIndex].startProductionAmount) {
currentDessertIndex = dessertIndex
break
}
}
},
contentScale = ContentScale.Crop
)
Spacer(modifier = Modifier.height(16.dp))
// Informasi dessert saat ini
Text(
text = "Click untuk membuat ${currentDessert.name}!",
fontSize = 18.sp,
fontWeight = FontWeight.Bold
)
}
}
State management menggunakan Compose's remember dan mutableStateOf untuk melacak desserts yang terjual, revenue, dan dessert yang sedang aktif. Setiap click pada image dessert akan menjalankan game logic yang mengupdate state.
Header Component
@Composable
fun DessertClickerHeader(
revenue: Int,
dessertsSold: Int,
modifier: Modifier = Modifier
) {
Row(
modifier = modifier
.background(Color(0xFF4CAF50))
.padding(16.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Column {
Text(
text = "Revenue",
color = Color.White,
fontSize = 14.sp
)
Text(
text = "$$revenue",
color = Color.White,
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
}
Column(horizontalAlignment = Alignment.End) {
Text(
text = "Desserts Sold",
color = Color.White,
fontSize = 14.sp
)
Text(
text = dessertsSold.toString(),
color = Color.White,
fontSize = 24.sp,
fontWeight = FontWeight.Bold
)
}
}
}
Header component menampilkan informasi real-time tentang revenue dan jumlah dessert yang telah terjual menggunakan layout Row dengan arrangement SpaceBetween.
Data Class untuk Dessert
data class Dessert(
val imageId: Int,
val price: Int,
val startProductionAmount: Int,
val name: String = ""
)
Data class Dessert menyimpan informasi tentang setiap jenis dessert termasuk resource ID untuk image, harga, dan threshold untuk mulai memproduksi dessert tersebut.
Lifecycle Logging Implementation
Implementasi logging dalam setiap lifecycle method memungkinkan developer untuk memahami sequence of events yang terjadi selama aplikasi berjalan:
- onCreate(): Dipanggil pertama kali saat activity dibuat, setup initial UI
- onStart(): Activity menjadi visible, persiapan untuk user interaction
- onResume(): Activity siap menerima input, game logic aktif
- onPause(): Activity kehilangan focus, pause game logic jika diperlukan
- onStop(): Activity tidak visible, save state jika diperlukan
- onDestroy(): Cleanup resources sebelum activity dihancurkan
Comments
Post a Comment