In this episode, you’ll modify BullsEye to keep track of the current round of the game and display it. This is a review of even more techniques you’ve learned in this learning path.
To do this, you have to do three things:
- Increment the round whenever a new round starts
- Display the current round number in the appropriate label whenever the player dismisses the alert dialog.
- Generate and display a new target value at the start of a new round. This should also be done when the player dismisses the dialog.
This is very much like what you did in the previous episode. Alright, let’s get to it.
First, let’s create a state object to hold the game rounds.
Declare that right below the totalScore variable like so:
var currentRound by rememberSaveable { mutableStateOf(1) }
We added a currentRound variable and set it to a value of 1.
We use 1 here because the first round of every game is always round 1.
Next, we need to set the round text in the GameDetail component to the value of the currentRound state object we just declared.
Just like we did in the last episode, pass in to the GameDetail call:
GameDetail(
totalScore = totalScore,
round = currentRound, // New Code
modifier = Modifier.fillMaxWidth()
)
We have an error as expected so lets head over to the GameDetail composable.
Then make the following updates:
@Composable
fun GameDetail(
modifier: Modifier = Modifier,
totalScore: Int = 0,
round: Int = 1, // New Code
) {
//...
GameInfo(label = stringResource(id = R.string.score_label), value = totalScore)
GameInfo(label = stringResource(id = R.string.current_round_label), value = round) // New Code
//...
}
We add the round parameter and set it to a default value of 1.
Then we pass it in as the value of the current round’s GameInfo widget and this displays the round in the score board below.
If you refresh the preview, you’ll see it show a value of 1 which is gotten from the state object. That’s the setup needed to display the current round.
Alright, we need a way to increment the game round whenever in the result dialog is dismissed.
So head over to the ResultDialog composable.
Looking at the code, we can see that the dialog can be dismissed in two places: the onDismissRequest and the confirmButton lambdas which are parameters of the AlertDialog composable.
We don’t want to manage the round state in here and thats whey we declared it above in the GameScreen composable. So with our knowledge of state hoisting which we learned from the previous course, we can simply just declare a new lambda parameter which will be called where the ResultDialog composable is called. Let’s do that now.
Enter the following code:
@Composable
fun ResultDialog(
hideDialog: () -> Unit,
onRoundIncrement: () -> Unit, // New Code
//...
){
//...
}
We added a new parameter, onRoundIncrement, which is a lambda without any parameter and returns nothing.
Next, call it in onDismissRequest and the TextButton’s onClick listener inside the confirmButton lambda arguments like so:
AlertDialog(
onDismissRequest = {
hideDialog()
onRoundIncrement() // New Code
},
confirmButton = {
TextButton(
onClick = {
hideDialog()
onRoundIncrement() // New Code
}
) {
Text(stringResource(id = R.string.result_dialog_button_text))
}
},
//...
)
Finally, let’s implement this lambda where we called the ResultDialog composable. Head over to the GameScreen composable. Scroll to the ResultDialog call.
Then update your code to the following:
ResultDialog(
//...
onRoundIncrement = {
currentRound += 1
}
)
This uses the operator assignment to increment the current round. This is the code that would be triggered whenever the dialog is dismissed.
Now, before we try it out, we want to generate a new target value for every new round. Scroll to the top and copy the code that generates a random number.
Then scroll back to the ResultDialog call.
And set the targetValue state to it like so:
ResultDialog(
//...
onRoundIncrement = {
currentRound += 1
targetValue = Random.nextInt(1, 100) // New Code
}
)
With this, whenever the player dismisses the dialog, the current round is incremented and you have a new target value.
Run your app to try it out.
Take note of the round text, it is currently set to 1. Let’s move the slider. Then tap the hit me button. After that, close the dialog by tapping the confirm button.
The game round increments accordingly to a value of 2 and we also have a new target value.
Now go ahead and play multiple rounds and be impressed with how far you’ve come with creating the Bullseye app. All work and no play they say, makes Jack a dull boy. When you’re done, I’ll see you in the next episode for your first challenge.