我正在开发一个益智游戏项目,我已经有 1 个空单元格,它与它旁边的所有单元格交换位置,但我希望有 2 个空单元格。我已经尝试了一切,但没有成功。在jetpackcompose中可以实现这一点吗?
我尝试创建 2 个空单元格,但只有一个有效
是的,您可以创建一个包含多个空单元格的益智游戏,这些空单元格与相邻单元格交换位置。为此,您需要管理拼图单元的状态并相应地更新它们。您可以看到以下代码,它可能会帮助您了解如何处理拼图网格中的两个空单元格:
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
函数处理将空单元格与其邻居交换的逻辑。
此外,这是一个简单的示例,您可能需要根据您的特定益智游戏要求进行调整。此外,您可能需要考虑使用更高级的状态管理解决方案,具体取决于游戏的复杂性。
请告诉我是否有效,希望有帮助!