我正在flutter中制作snake game,但遇到了一个问题。我在gameTick方法(snake变量)中更改了snake的位置-运行正常,然后我在build方法(grid变量)中生成了新的网格-运行正常,最后build方法应该返回widget tree。但我在屏幕上看不到更改。看起来build方法正在使用旧的网格变量构建应用程序。
我删除了一些无关的代码。谢谢你的帮助。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:swipe/swipe.dart';
void main() {
runApp(
MaterialApp(
title: 'snake',
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.blueGrey,
),
home: Game(),
),
);
}
class Game extends StatefulWidget {
const Game({Key? key}) : super(key: key);
@override
State<Game> createState() => _GameState();
}
class _GameState extends State<Game> {
List<List<int>> snake = [
[5, 5],
[6, 5],
[7, 5]
];
List<Container> grid = List.filled(121, Container());
Timer? timer;
@override
void initState() {
Timer.periodic(Duration(seconds: 1), (Timer t) => gameTick());
super.initState();
}
@override
void dispose() {
timer?.cancel();
super.dispose();
}
void gameTick() {
for (List<int> pair in snake) {
setState(
() {
pair[0]--;
},
);
}
}
@override
Widget build(BuildContext context) {
for (int i = 0; i < 121; i++) {
int row = (i / 11).floor();
int col = i % 11;
for (List<int> pair in snake) {
int snakeRow = pair[0];
int snakeCol = pair[1];
if ((snakeRow == row) && (snakeCol == col)) {
grid[i] = Container(
decoration: BoxDecoration(
color: Colors.greenAccent,
border: Border.all(color: Color(0xFF383434), width: 2),
),
);
break;
} else {
grid[i] = Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.greenAccent, width: 2),
),
);
}
}
}
return Scaffold(
body: SizedBox.expand(
child: Swipe(
onSwipeUp: () {SOMECODE});
}
},
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: GridView.count(
physics: NeverScrollableScrollPhysics(),
crossAxisCount: 11,
children: grid,
),
),
],
),
),
),
);
}
}
1条答案
按热度按时间wgx48brx1#
我认为不缓存容器会更容易。创建121个新容器,并标记那些是蛇的部分。你甚至可以在“GameTick”中这样做,因为它只在“GameTick”中真正改变,没有必要在每个构建中都这样做。
此外,gametick只需要一个
setState
,而不是在一个循环中有多个setState
,你不想在构造新游戏状态时多次调用build方法。你的gametick方法应该完成所有的计算,然后创建一个新的网格(也许从头开始比修改旧的网格更容易),然后调用
setState
once。