Add restart

This commit is contained in:
Christian Basler
2025-03-12 07:52:02 +01:00
parent 370dc2a2a2
commit 63f6fca83f
4 changed files with 101 additions and 27 deletions

View File

@@ -2,6 +2,7 @@ package ch.dissem.yaep.ui.common
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.aspectRatio
@@ -30,7 +31,6 @@ import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.dp
import ch.dissem.yaep.domain.Clue
import ch.dissem.yaep.domain.Game
import ch.dissem.yaep.domain.Grid
import ch.dissem.yaep.domain.HorizontalClue
import ch.dissem.yaep.domain.ItemClass
@@ -58,11 +58,13 @@ class DisplayClue<C : Clue>(val clue: C) {
}
@Composable
fun App(modifier: Modifier = Modifier, game: Game = remember { generateGame() }) {
fun App(modifier: Modifier = Modifier) {
var game by remember { mutableStateOf(generateGame()) }
val horizontalClues = remember(game) { game.horizontalClues.map { DisplayClue(it) } }
val verticalClues = remember(game) { game.verticalClues.map { DisplayClue(it) } }
val timer = remember(game) { GameTimer() }
val time by timer.elapsedTime.collectAsState("00:00")
var isSolved by remember(game) { mutableStateOf(false) }
LaunchedEffect(game) {
game.onStart {
timer.start()
@@ -70,31 +72,37 @@ fun App(modifier: Modifier = Modifier, game: Game = remember { generateGame() })
game.onSolved {
timer.stop()
isSolved = true
}
}
Row(modifier = modifier) {
PuzzleGrid(
modifier = Modifier
.aspectRatio(1f)
.weight(0.6f)
.fillMaxHeight(),
grid = game.grid,
onUpdate = {
horizontalClues.forEach { it.update(game.grid) }
verticalClues.forEach { it.update(game.grid) }
}
)
Column(
modifier = Modifier.padding(start = 16.dp).weight(0.4f).fillMaxHeight()
) {
PuzzleClues(
modifier = Modifier,
horizontalClues,
verticalClues
Box(modifier = modifier) {
Row(modifier = Modifier.blurOnFinished(isSolved)) {
PuzzleGrid(
modifier = Modifier
.aspectRatio(1f)
.weight(0.6f)
.fillMaxHeight(),
grid = game.grid,
onUpdate = {
horizontalClues.forEach { it.update(game.grid) }
verticalClues.forEach { it.update(game.grid) }
}
)
Column(
modifier = Modifier.padding(start = 16.dp).weight(0.4f).fillMaxHeight()
) {
PuzzleClues(
modifier = Modifier,
horizontalClues,
verticalClues
)
Text(time, fontSize = TextUnit(4f, TextUnitType.Em))
Text(time, fontSize = TextUnit(4f, TextUnitType.Em))
}
}
EndOfGame(isSolved = isSolved) {
game = generateGame()
}
}
}
@@ -114,9 +122,10 @@ fun PuzzleGrid(
) {
val allOptions = row.options
for (item in row) {
var selection by remember { mutableStateOf(item.selection) }
val options =
remember { allOptions.map { Toggleable(it, item.options.contains(it)) } }
var selection by remember(item) { mutableStateOf(item.selection) }
val options = remember(item) {
allOptions.map { Toggleable(it, item.options.contains(it)) }
}
LaunchedEffect(item) {
item.optionsRemovedListeners.add { removed ->
options

View File

@@ -0,0 +1,65 @@
package ch.dissem.yaep.ui.common
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.graphics.BlurEffect
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.sp
@Composable
fun EndOfGame(
modifier: Modifier = Modifier,
isSolved: Boolean,
onRestart: () -> Unit
) {
AnimatedVisibility(
visible = isSolved,
modifier = modifier,
enter = fadeIn(),
exit = fadeOut()
) {
val background = MaterialTheme.colorScheme.background
Box(modifier = Modifier
.fillMaxSize()
.drawBehind {
drawRect(color = background.copy(alpha = 0.8f))
}
) {
Column(
modifier = Modifier
.align(Alignment.Center)
) {
Text(
text = "You won",
fontSize = 128.sp,
textAlign = TextAlign.Center,
)
Button(
modifier = Modifier.align(CenterHorizontally),
onClick = onRestart
) {
Text("Restart")
}
}
}
}
}
fun Modifier.blurOnFinished(isSolved: Boolean): Modifier = graphicsLayer {
if (isSolved) {
this.renderEffect = BlurEffect(8f, 8f)
}
}

View File

@@ -1,5 +1,5 @@
[versions]
agp = "8.8.2"
agp = "8.9.0"
jdk = "21"
android-compileSdk = "35"
android-minSdk = "24"

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME