我正在做一个益智游戏项目,我已经有1个空单元格,它与旁边的所有单元格交换位置,但我希望有2个空单元格。我已经尝试了一切,我可以无济于事。是否可以在jetpackcompose中实现这一点?我尝试创建2个空单元格,但只有一个工作
nle07wnf1#
是的,你可以创建一个有多个空单元格的益智游戏,这些空单元格与相邻的单元格交换位置。要实现这一点,你需要管理你的益智单元格的状态并相应地更新它们。你可以看到下面的代码,它可能会帮助你理解如何处理益智网格中的两个空单元格:
import android.os.Bundleimport androidx.activity.ComponentActivityimport androidx.activity.compose.setContentimport androidx.compose.foundation.backgroundimport androidx.compose.foundation.layout.*import androidx.compose.foundation.lazy.LazyColumnimport androidx.compose.foundation.lazy.itemsimport androidx.compose.foundation.shape.CircleShapeimport androidx.compose.material3.MaterialThemeimport androidx.compose.material3.Surfaceimport androidx.compose.material3.SurfaceColorimport androidx.compose.material3.icons.Iconsimport androidx.compose.material3.icons.filled.Refreshimport androidx.compose.material3.icons.filled.SwapHorizimport androidx.compose.material3.icons.filled.SwapVertimport androidx.compose.material3.materialIconimport androidx.compose.material3.rememberAppBarConfigurationimport androidx.compose.material3.rememberBottomSheetStateimport androidx.compose.material3.rememberScaffoldStateimport androidx.compose.material3.rememberSwipeableStateimport androidx.compose.material3.swipeableimport androidx.compose.material3.textfield.TextFieldDefaultsimport androidx.compose.material3.*import androidx.compose.runtime.*import androidx.compose.ui.Alignmentimport androidx.compose.ui.Modifierimport androidx.compose.ui.draw.clipimport androidx.compose.ui.graphics.Colorimport androidx.compose.ui.platform.LocalDensityimport androidx.compose.ui.res.painterResourceimport androidx.compose.ui.text.input.TextFieldValueimport androidx.compose.ui.tooling.preview.Previewimport androidx.compose.ui.unit.dpimport com.example.featherandroidtasks.ui.theme.FeatherAndroidTasksThemedata class PuzzleCell( val value: Int, val isEmpty: Boolean,)@Composablefun 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") } } }}@Composablefun 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) } ) } } } }}@Composablefun 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 } } }}@Composablefun 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)@Composablefun PuzzleGamePreview() { PuzzleGame()}
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")
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) }
fun PuzzleCell(
cell: PuzzleCell,
onCellClick: () -> Unit
Box(
.size(50.dp)
.clickable { onCellClick() }
.background(MaterialTheme.colorScheme.primary)
.clip(CircleShape)
if (!cell.isEmpty) {
Text(
text = cell.value.toString(),
color = MaterialTheme.colorScheme.onPrimary,
.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
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)
fun PuzzleGamePreview() {
PuzzleGame()
字符串在上面,我创建了一个PuzzleCell数据类来表示谜题网格中的每个单元格。PuzzleGame可组合函数管理谜题单元格的状态,并提供一个具有可点击单元格的网格。onCellClick函数处理将空单元格与其相邻单元格交换的逻辑。此外,这是一个简单的示例,您可能需要根据特定的益智游戏需求对其进行调整。此外,您可能需要考虑使用更高级的状态管理解决方案,具体取决于游戏的复杂性。请让我知道它是否有效,希望它有帮助!
PuzzleCell
PuzzleGame
onCellClick
1条答案
按热度按时间nle07wnf1#
是的,你可以创建一个有多个空单元格的益智游戏,这些空单元格与相邻的单元格交换位置。要实现这一点,你需要管理你的益智单元格的状态并相应地更新它们。你可以看到下面的代码,它可能会帮助你理解如何处理益智网格中的两个空单元格:
字符串
在上面,我创建了一个
PuzzleCell
数据类来表示谜题网格中的每个单元格。PuzzleGame
可组合函数管理谜题单元格的状态,并提供一个具有可点击单元格的网格。onCellClick
函数处理将空单元格与其相邻单元格交换的逻辑。此外,这是一个简单的示例,您可能需要根据特定的益智游戏需求对其进行调整。此外,您可能需要考虑使用更高级的状态管理解决方案,具体取决于游戏的复杂性。
请让我知道它是否有效,希望它有帮助!