Podemos implementar funciones que dibujen con la función composable 'Canvas' y llamarlas en forma sucesiva.
Confeccionar una aplicación que muestre tres dados, un botón y un texto. Cuando se presione un botón proceder a generar tres valores aleatorios, a partir de dichos valores llamar a una función componsable que reciba el valor aleatorio y pase a dibujar el dado.
La función que llama a la función que dibuja el dado debe almacenar el estado (en nuestro caso los tres valores aleatorios)
Si los tres valores son iguales mostrar un mensaje que "ganó", sino que "perdió".
Crearemos el proyecto 'Compose28'
La interfaz visual debe ser similar a:
El código a implementar en Kotlin para obtener dicha funcionalidad es:
package com.tutorialesprogramacionya.compose28 import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.* import androidx.compose.material.Button import androidx.compose.material.Text import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import kotlin.random.Random class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { JuegoDeDados() } } } @Composable fun JuegoDeDados() { var dado1 by remember { mutableStateOf(1) } var dado2 by remember { mutableStateOf(1) } var dado3 by remember { mutableStateOf(1) } var resultado by remember { mutableStateOf("")} Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = "Si los 3 son iguales GANA", fontSize = 30.sp, fontFamily = FontFamily.Cursive ) Dado(dado1) Dado(dado2) Dado(dado3) Button(onClick = { dado1 = Random.nextInt(1, 6) dado2 = Random.nextInt(1, 6) dado3 = Random.nextInt(1, 6) resultado=if (dado1==dado2 && dado1==dado3) "ganó" else "perdió" }) { Text("Tirar") } Text(text = "Resultado: $resultado") } } @Composable fun Dado(valor: Int) { Canvas( modifier = Modifier .width(150.dp) .height(150.dp) .padding(10.dp) ) { val todo = size val radio = size.width / 12 drawRoundRect(size = todo, color = Color.Black, cornerRadius = CornerRadius(10f, 10f)) if (valor == 1 || valor == 3 || valor == 5) drawCircle( center = Offset(x = size.width * 0.5f, y = size.height * 0.5f), color = Color.White, radius = radio ) if (valor == 2 || valor == 3 || valor == 4 || valor == 5 || valor == 6) { drawCircle( center = Offset(x = size.width * 0.3f, y = size.height * 0.3f), color = Color.White, radius = radio ) drawCircle( center = Offset(x = size.width * 0.7f, y = size.height * 0.7f), color = Color.White, radius = radio ) } if (valor == 4 || valor == 5 || valor == 6) { drawCircle( center = Offset(x = size.width * 0.7f, y = size.height * 0.3f), color = Color.White, radius = radio ) drawCircle( center = Offset(x = size.width * 0.3f, y = size.height * 0.7f), color = Color.White, radius = radio ) } if (valor == 6) { drawCircle( center = Offset(x = size.width * 0.3f, y = size.height * 0.5f), color = Color.White, radius = radio ) drawCircle( center = Offset(x = size.width * 0.7f, y = size.height * 0.5f), color = Color.White, radius = radio ) } } }
La función composable 'JuegoDeDados' almacena el estado de los tres valores generados con el objeto de poder verificar si ganó o perdió:
@Composable fun JuegoDeDados() { var dado1 by remember { mutableStateOf(1) } var dado2 by remember { mutableStateOf(1) } var dado3 by remember { mutableStateOf(1) } var resultado by remember { mutableStateOf("")}
Aquí seencuentra lo interesante donde llamamos a la otra función composable Dado, y le pasamos el número que debe mostrar el mismo, además llamamos a la función 3 veces (3 dados):
Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Text( text = "Si los 3 son iguales GANA", fontSize = 30.sp, fontFamily = FontFamily.Cursive ) Dado(dado1) Dado(dado2) Dado(dado3) Button(onClick = { dado1 = Random.nextInt(1, 6) dado2 = Random.nextInt(1, 6) dado3 = Random.nextInt(1, 6) resultado=if (dado1==dado2 && dado1==dado3) "ganó" else "perdió" }) { Text("Tirar") } Text(text = "Resultado: $resultado") }
Es importante notar que cuando se presiona el botón, generamos tres valores aleatorios y procedemos a actualizar las tres variables de estado, esto hace que se actualicen los gráficos de cada dado.
Finalmente la función composable "Dado" recibe como parámetro el número que debe mostrar.
Definimos el ancho del Canvas de 150*150 píxeles dp.
Con una serie de if graficamos los círculos que corresponden según la cara del dado a mostrar:
@Composable fun Dado(valor: Int) { Canvas( modifier = Modifier .width(150.dp) .height(150.dp) .padding(10.dp) ) { val todo = size val radio = size.width / 12 drawRoundRect(size = todo, color = Color.Black, cornerRadius = CornerRadius(10f, 10f)) if (valor == 1 || valor == 3 || valor == 5) drawCircle( center = Offset(x = size.width * 0.5f, y = size.height * 0.5f), color = Color.White, radius = radio ) if (valor == 2 || valor == 3 || valor == 4 || valor == 5 || valor == 6) { drawCircle( center = Offset(x = size.width * 0.3f, y = size.height * 0.3f), color = Color.White, radius = radio ) drawCircle( center = Offset(x = size.width * 0.7f, y = size.height * 0.7f), color = Color.White, radius = radio ) } if (valor == 4 || valor == 5 || valor == 6) { drawCircle( center = Offset(x = size.width * 0.7f, y = size.height * 0.3f), color = Color.White, radius = radio ) drawCircle( center = Offset(x = size.width * 0.3f, y = size.height * 0.7f), color = Color.White, radius = radio ) } if (valor == 6) { drawCircle( center = Offset(x = size.width * 0.3f, y = size.height * 0.5f), color = Color.White, radius = radio ) drawCircle( center = Offset(x = size.width * 0.7f, y = size.height * 0.5f), color = Color.White, radius = radio ) } } }
Es importante notar que la función 'Dado' no tiene estado, solo tiene el objetivo de dibujar el dado cuando Compose lo requiera, que será cuando la variable de estado de la otra función cambie.
Este proyecto lo puede descargar en un zip desde este enlace: Compose28.zip