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.BorderStroke
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
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.TextUnitType
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ch.dissem.yaep.domain.Clue
|
import ch.dissem.yaep.domain.Clue
|
||||||
import ch.dissem.yaep.domain.Game
|
|
||||||
import ch.dissem.yaep.domain.Grid
|
import ch.dissem.yaep.domain.Grid
|
||||||
import ch.dissem.yaep.domain.HorizontalClue
|
import ch.dissem.yaep.domain.HorizontalClue
|
||||||
import ch.dissem.yaep.domain.ItemClass
|
import ch.dissem.yaep.domain.ItemClass
|
||||||
@@ -58,11 +58,13 @@ class DisplayClue<C : Clue>(val clue: C) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@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 horizontalClues = remember(game) { game.horizontalClues.map { DisplayClue(it) } }
|
||||||
val verticalClues = remember(game) { game.verticalClues.map { DisplayClue(it) } }
|
val verticalClues = remember(game) { game.verticalClues.map { DisplayClue(it) } }
|
||||||
val timer = remember(game) { GameTimer() }
|
val timer = remember(game) { GameTimer() }
|
||||||
val time by timer.elapsedTime.collectAsState("00:00")
|
val time by timer.elapsedTime.collectAsState("00:00")
|
||||||
|
var isSolved by remember(game) { mutableStateOf(false) }
|
||||||
LaunchedEffect(game) {
|
LaunchedEffect(game) {
|
||||||
game.onStart {
|
game.onStart {
|
||||||
timer.start()
|
timer.start()
|
||||||
@@ -70,10 +72,12 @@ fun App(modifier: Modifier = Modifier, game: Game = remember { generateGame() })
|
|||||||
|
|
||||||
game.onSolved {
|
game.onSolved {
|
||||||
timer.stop()
|
timer.stop()
|
||||||
|
isSolved = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row(modifier = modifier) {
|
Box(modifier = modifier) {
|
||||||
|
Row(modifier = Modifier.blurOnFinished(isSolved)) {
|
||||||
PuzzleGrid(
|
PuzzleGrid(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.aspectRatio(1f)
|
.aspectRatio(1f)
|
||||||
@@ -97,6 +101,10 @@ fun App(modifier: Modifier = Modifier, game: Game = remember { generateGame() })
|
|||||||
Text(time, fontSize = TextUnit(4f, TextUnitType.Em))
|
Text(time, fontSize = TextUnit(4f, TextUnitType.Em))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
EndOfGame(isSolved = isSolved) {
|
||||||
|
game = generateGame()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -114,9 +122,10 @@ fun PuzzleGrid(
|
|||||||
) {
|
) {
|
||||||
val allOptions = row.options
|
val allOptions = row.options
|
||||||
for (item in row) {
|
for (item in row) {
|
||||||
var selection by remember { mutableStateOf(item.selection) }
|
var selection by remember(item) { mutableStateOf(item.selection) }
|
||||||
val options =
|
val options = remember(item) {
|
||||||
remember { allOptions.map { Toggleable(it, item.options.contains(it)) } }
|
allOptions.map { Toggleable(it, item.options.contains(it)) }
|
||||||
|
}
|
||||||
LaunchedEffect(item) {
|
LaunchedEffect(item) {
|
||||||
item.optionsRemovedListeners.add { removed ->
|
item.optionsRemovedListeners.add { removed ->
|
||||||
options
|
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]
|
[versions]
|
||||||
agp = "8.8.2"
|
agp = "8.9.0"
|
||||||
jdk = "21"
|
jdk = "21"
|
||||||
android-compileSdk = "35"
|
android-compileSdk = "35"
|
||||||
android-minSdk = "24"
|
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
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
Reference in New Issue
Block a user