Add restart
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
[versions]
|
||||
agp = "8.8.2"
|
||||
agp = "8.9.0"
|
||||
jdk = "21"
|
||||
android-compileSdk = "35"
|
||||
android-minSdk = "24"
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user