我可以在jetpack compose viewModel中创建2个空单元格网格吗?

问题描述 投票:0回答:1

我正在开发一个益智游戏项目,我已经有 1 个空单元格,它与它旁边的所有单元格交换位置,但我希望有 2 个空单元格。我已经尝试了一切,但没有成功。在jetpackcompose中可以实现这一点吗?

我尝试创建 2 个空单元格,但只有一个有效

android viewmodel jetpack
1个回答
0
投票

是的,您可以创建一个包含多个空单元格的益智游戏,这些空单元格与相邻单元格交换位置。为此,您需要管理拼图单元的状态并相应地更新它们。您可以看到以下代码,它可能会帮助您了解如何处理拼图网格中的两个空单元格:

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.SurfaceColor
import androidx.compose.material3.icons.Icons
import androidx.compose.material3.icons.filled.Refresh
import androidx.compose.material3.icons.filled.SwapHoriz
import androidx.compose.material3.icons.filled.SwapVert
import androidx.compose.material3.materialIcon
import androidx.compose.material3.rememberAppBarConfiguration
import androidx.compose.material3.rememberBottomSheetState
import androidx.compose.material3.rememberScaffoldState
import androidx.compose.material3.rememberSwipeableState
import androidx.compose.material3.swipeable
import androidx.compose.material3.textfield.TextFieldDefaults
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.featherandroidtasks.ui.theme.FeatherAndroidTasksTheme

data class PuzzleCell(
    val value: Int,
    val isEmpty: Boolean,
)

@Composable
fun PuzzleGame() {
    var puzzleCells by remember { mutableStateOf(generateInitialPuzzle()) }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Grid(cells = puzzleCells) { row, col ->
            onCellClick(row, col, puzzleCells)
        }

        Spacer(modifier = Modifier.height(16.dp))

        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically
        ) {
            IconButton(
                onClick = {
                    puzzleCells = generateInitialPuzzle()
                }
            ) {
                Icon(imageVector = Icons.Default.Refresh, contentDescription = "Restart")
            }
        }
    }
}

@Composable
fun Grid(
    cells: List<List<PuzzleCell>>,
    onCellClick: (row: Int, col: Int) -> Unit
) {
    Column {
        for (row in cells.indices) {
            Row {
                for (col in cells[row].indices) {
                    PuzzleCell(
                        cell = cells[row][col],
                        onCellClick = { onCellClick(row, col) }
                    )
                }
            }
        }
    }
}

@Composable
fun PuzzleCell(
    cell: PuzzleCell,
    onCellClick: () -> Unit
) {
    Box(
        modifier = Modifier
            .size(50.dp)
            .clickable { onCellClick() }
            .background(MaterialTheme.colorScheme.primary)
            .clip(CircleShape)
    ) {
        if (!cell.isEmpty) {
            Text(
                text = cell.value.toString(),
                color = MaterialTheme.colorScheme.onPrimary,
                modifier = Modifier
                    .align(Alignment.Center)
                    .padding(8.dp)
            )
        }
    }
}

fun generateInitialPuzzle(): List<List<PuzzleCell>> {
    val size = 4
    val values = (1..size * size - 1).shuffled() + listOf(0) // 0 represents the empty cell
    return values.chunked(size)
        .mapIndexed { row, list ->
            list.mapIndexed { col, value ->
                PuzzleCell(value = value, isEmpty = value == 0)
            }
        }
}

fun moveEmptyCell(
    puzzleCells: List<List<PuzzleCell>>,
    emptyCellRow: Int,
    emptyCellCol: Int,
    newRow: Int,
    newCol: Int
): List<List<PuzzleCell>> {
    return puzzleCells.mapIndexed { row, list ->
        list.mapIndexed { col, cell ->
            if ((row == emptyCellRow && col == emptyCellCol) ||
                (row == newRow && col == newCol)
            ) {
                PuzzleCell(value = cell.value, isEmpty = !cell.isEmpty)
            } else {
                cell
            }
        }
    }
}

@Composable
fun onCellClick(row: Int, col: Int, puzzleCells: List<List<PuzzleCell>>) {
    val emptyCell = puzzleCells.flatten().first { it.isEmpty }
    val emptyCellRow = puzzleCells.indexOfFirst { it.contains(emptyCell) }
    val emptyCellCol = puzzleCells[emptyCellRow].indexOf(emptyCell)

    // Check if the clicked cell is a neighbor of the empty cell
    if ((row == emptyCellRow && (col == emptyCellCol - 1 || col == emptyCellCol + 1)) ||
        (col == emptyCellCol && (row == emptyCellRow - 1 || row == emptyCellRow + 1))
    ) {
        puzzleCells = moveEmptyCell(puzzleCells, emptyCellRow, emptyCellCol, row, col)
    }
}

@Preview(showBackground = true)
@Composable
fun PuzzleGamePreview() {
    PuzzleGame()
}

在上面,我创建了一个

PuzzleCell
数据类来表示拼图网格中的每个单元格。
PuzzleGame
可组合函数管理拼图单元的状态并提供包含可点击单元的网格。
onCellClick
函数处理将空单元格与其邻居交换的逻辑。

此外,这是一个简单的示例,您可能需要根据您的特定益智游戏要求进行调整。此外,您可能需要考虑使用更高级的状态管理解决方案,具体取决于游戏的复杂性。

请告诉我是否有效,希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.