I am working on a very basic snake game using kotlin and jetpack compose. To make it more efficient, I thought of using coroutines, but I keep getting the above mentioned error.
Full project is shared at: https://github.com/tauqirnizami/SnakeGame
ViewModel is:
class DifficultSnakeViewModel : ViewModel() {
/*Pair(length/y-coordinate, width/x-coordinate)*/
var coordinates = mutableStateListOf(Pair(31, 14), Pair(32, 14), Pair(33, 14))
private set
private var gameGoing by mutableStateOf(true)
var extraWallsCoordinates: List<Pair<Int, Int>>
init {
foodCoordinates = Pair(10, 9)
score = 0L
directions = mutableStateListOf(0) //Using a list instead of a single int to keep track when user changes directions too quickly while the viewModel is on delay (the one for speed controlling). Eg., if user enter up and suddenly left as well, the game earlier used to only register the latter command. Using a mutable list would keep track of all the given commands that currently hasn't been acted on.
giantFoodCoordinates = null
giantFoodCounter = 1
extraWallsCoordinates = walls()
viewModelScope.launch(Dispatchers.Default) {
delay(1000L) //This is to let the viewModel to setup properly before being used. I was getting error due to usage of state variable (probably "coordinates") before waiting for the viewModel to be able to initialize properly first
while (gameGoing) {
delay(if (score < 250) 500 - (score *2) else if(score<500) 1 else 0) //This controls the snake speed
coordinatesUpdation() //This is used to update the snake's coordinates according to the direction, i.e., user input.
}
}
}
//other code
}
As you can see, in easy and medium mode of the game, using a simple delay(550L) was enough to keep the error away, but it isn't working for the difficult level even if I increased the delay duration from 550 to 1000 or even 3000 millis.
My composable file is:
@Composable
fun DifficultDisplayGrid(
modifier: Modifier,
snakeViewModel: DifficultSnakeViewModel
) {
val colors = difficultGenerateColorGrid(coordinates = snakeViewModel.coordinates, walls = snakeViewModel.extraWallsCoordinates) //This function returns a list of colours according to snake, food, etc's coordinates, which would be used to display the grid
Column {
ColorGrid(colors = colors, modifier = modifier) //snake game grid
Text(text = "Score = $score")
}
}
@Composable
fun DifficultScreen(
modifier: Modifier = Modifier,
snakeViewModel: DifficultSnakeViewModel = DifficultSnakeViewModel()
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
) {
DifficultDisplayGrid(modifier, snakeViewModel = snakeViewModel)
Row(
modifier = Modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Button(onClick = { directions.add(2) }) {
Icon(imageVector = Icons.Filled.KeyboardArrowLeft, contentDescription = "Left")
}
Column {
Button(onClick = { directions.add(0) }) {
Icon(imageVector = Icons.Filled.KeyboardArrowUp, contentDescription = "Up")
}
Spacer(modifier = Modifier.height(13.dp))
Button(onClick = { directions.add(1) }) {
Icon(imageVector = Icons.Filled.KeyboardArrowDown, contentDescription = "Down")
}
}
Button(onClick = { directions.add(3) }) {
Icon(imageVector = Icons.Filled.KeyboardArrowRight, contentDescription = "Right")
}
}
}
}
//other code
I tried to use delay() function, Thread.sleep(). Tried to use thread.sleep before the viewModelScope .launch line, tried to do it inside this scope. But nothing was working. From 1000millis to 50000 milis, no function or no duration seems to be working.
try this
viewModelScope.launch(Dispatchers.Main) {
// delay(1000L) //This is to let the viewModel to setup properly before being used. I was getting error due to usage of state variable (probably "coordinates") before waiting for the viewModel to be able to initialize properly first
while (gameGoing) {
delay(if (score < 250) 500 - (score *2) else if(score<500) 1 else 0) //This controls the snake speed
coordinatesUpdation()
}
}
To understand more about the Dispachers you can read here -> https://developer.android.com/kotlin/coroutines/coroutines-adv?hl=es-419#main-safety