Snake游戏异常:extraWalls无重新赋值却变动,蛇坐标未更新
Snake游戏问题修复方案
核心问题分析
你的代码存在两个关键问题导致墙体持续变动、蛇身不更新:
- UI重组语法错误:ColorGrid中Lambda表达式的参数写法错误,导致蛇身坐标更新后UI无法刷新;
- 墙体状态管理不当:
extraWalls未用State包装,若存在隐性重复调用walls()的情况(比如自定义getter),会导致每次访问都生成随机墙体。
具体修复步骤
1. 修复蛇身不更新的问题
ColorGrid中items的Lambda参数语法错误,将index -改为index ->,确保Composable能正确响应状态变化:
@Composable fun ColorGrid(colors: List<Color>, modifier: Modifier = Modifier) { LazyVerticalGrid( columns = GridCells.Fixed(gridWidth), modifier = modifier .size(gridWidth * cellSize, gridLength * cellSize) ) { items(colors.size) { index -> // 修正语法错误 Box( modifier = Modifier .background(colors[index]) .size(cellSize) ) } } }
2. 解决墙体持续变动的问题
确保extraWalls仅在ViewModel初始化时生成一次,并使用State包装以保证UI能感知其值:
class ExampleViewModel : ViewModel() { // ... 其他代码保持不变 private val eachExtraWallWidthPlusOne = 4 // 用mutableStateOf包装,确保初始值仅生成一次 var extraWalls by mutableStateOf<List<Pair<Int, Int>>>(walls()) private set // ... 其他代码保持不变 }
如果后续需要动态更新墙体(比如关卡切换),可添加主动更新的方法:
fun regenerateWalls() { extraWalls = walls() }
同时检查是否存在以下错误写法:
// 错误:每次访问extraWalls都会调用walls()生成新墙体 var extraWalls: List<Pair<Int, Int>> get() = walls() private set
这种自定义getter会导致每次UI重组都生成随机墙体,必须改为初始化赋值的方式。
额外性能优化建议
- 改用Set存储坐标:将
coordinates同步维护为Set,避免any()遍历带来的性能损耗:
class ExampleViewModel : ViewModel() { var coordinates = mutableStateListOf(Pair(14, 14), Pair(15, 14), Pair(16, 14)) private set private val coordinatesSet = mutableStateSetOf<Pair<Int, Int>>().apply { addAll(coordinates) } private fun coordinatesUpdation() { val head = coordinates[0] val newHead = Pair(head.first - 1, head.second) coordinates.add(0, newHead) coordinatesSet.add(newHead) val removedTail = coordinates.removeLast() coordinatesSet.remove(removedTail) } }
在生成颜色网格时改用contains()判断:
else if (coordinatesSet.contains(Pair(i, j))) { coloursList.add(Color.DarkGray) }
- 将网格计算移至ViewModel:避免在Composable中执行计算逻辑,在ViewModel中生成颜色列表并转为State,减少UI层压力:
class ExampleViewModel : ViewModel() { // ... 其他代码 val colorGrid by derivedStateOf { difficultGenerateColorGrid(coordinates, extraWalls) } } // Composable中直接读取 @Composable fun Display(exampleViewModel: ExampleViewModel, modifier: Modifier = Modifier) { ColorGrid(colors = exampleViewModel.colorGrid, modifier = modifier) }
内容的提问来源于stack exchange,提问作者user24809029
相关产品推荐
相关产品推荐

