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:

  1. Dessert Production: Setiap click menghasilkan satu unit dessert
  2. Revenue Generation: Setiap dessert yang diproduksi menghasilkan sejumlah virtual currency
  3. Progress Tracking: Aplikasi melacak total dessert yang telah dibuat dan total pendapatan
  4. 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

  1. onCreate(): Dipanggil saat activity dibuat pertama kali
  2. onStart(): Dipanggil saat activity menjadi visible kepada user
  3. onResume(): Dipanggil saat activity siap menerima user interaction
  4. onPause(): Dipanggil saat activity kehilangan focus
  5. onStop(): Dipanggil saat activity tidak lagi visible
  6. 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:

  1. Memantau lifecycle transitions: Melihat kapan setiap lifecycle method dipanggil
  2. Debug application behavior: Mengidentifikasi potential issues dalam state management
  3. Understand app flow: Memahami sequence of events dalam aplikasi Android

State Management

Aplikasi mengimplementasikan state management untuk melacak:

  1. Dessert Count: Jumlah total dessert yang telah diproduksi
  2. Revenue Amount: Total pendapatan yang telah dikumpulkan
  3. Current Dessert Type: Jenis dessert yang sedang diproduksi
  4. 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:

  1. Declarative UI: Interface dideklarasikan berdasarkan state
  2. Automatic Recomposition: UI secara otomatis update ketika state berubah
  3. 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:

  1. onCreate(): Dipanggil pertama kali saat activity dibuat, setup initial UI
  2. onStart(): Activity menjadi visible, persiapan untuk user interaction
  3. onResume(): Activity siap menerima input, game logic aktif
  4. onPause(): Activity kehilangan focus, pause game logic jika diperlukan
  5. onStop(): Activity tidak visible, save state jika diperlukan
  6. onDestroy(): Cleanup resources sebelum activity dihancurkan


Comments

Popular posts from this blog

EAS PPB

Tugas Pertemuan 13: Membuat Aplikasi Unscramble