今回は久しぶりにFlutterでのアプリ開発になります。WWDC2020以来になります。
振り返りとして、これまでFlutterの章では1番から25番を順番にタップするアプリ「ナンバーズ」を開発してきました。前回の続きはだいぶ前になりますがこちらの記事でFlutterで配列データをシャッフルする方法について学びました。
また、今までで出来上がっているgif動画はこちらになります。
今回はListのシャッフル関数を使って1から25番のボタンのテキストをランダム配置させて、そのListをGridViewに渡す処理を実装しようと思います。
game_play_page.dart
/// See: https://stackoverflow.com/questions/13554129/list-shuffle-in-dart
List _shuffle(List items) {
var random = new Random();
for (var i = items.length - 1; i > 0; i--) {
var n = random.nextInt(i + 1);
var temp = items[i];
items[i] = items[n];
items[n] = temp;
}
return items;
}
上記の方法ではlistの配列を引数にとって配列データを渡すとランダム生成されたListヲ』取得する関数になります。
あとは同じクラスの中のbuild関数内でintの1~25のリストを生成して上記のランダム関数を呼び出します。
game_play_page.dart
@override
Widget build(BuildContext context) {
final list = List<int>.generate(25, (i) => i + 1);
final randomList = _shuffle(list);
return Container();
}
このrandomListをゲームの盤面であるGridView.count()のchildrenに渡してやればいいだけです。
つまり、全体のソースコードは次のようになります。
game_play_page.dart
class GamePlayPage extends StatelessWidget {
/// See: https://stackoverflow.com/questions/13554129/list-shuffle-in-dart
List _shuffle(List items) {
var random = new Random();
for (var i = items.length - 1; i > 0; i--) {
var n = random.nextInt(i + 1);
var temp = items[i];
items[i] = items[n];
items[n] = temp;
}
return items;
}
void _updateCurrentNumber(BuildContext context, CounterModel provider) {
if (provider.currentNumber >= 25) {
Navigator.push(
context,
new MaterialPageRoute<Null>(
settings: RouteSettings(name: Constants.clearRoute),
builder: (BuildContext context) => ClearPage(),
),
);
}
provider.updateCurrentNumber();
}
@override
Widget build(BuildContext context) {
final list = List<int>.generate(25, (i) => i + 1);
final randomList = _shuffle(list);
return ChangeNotifierProvider<CounterModel>(
create: (context) => CounterModel(),
child: Consumer<CounterModel>(
builder: (context, provider, child) => Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Padding(
padding: EdgeInsets.only(left: 20.0),
child: CurrentNumberText(),
),
Container(
padding: EdgeInsets.only(right: 20),
child: Center(
child: TimerText()),
)
],
),
SizedBox(
height: 48.0,
),
SizedBox(
height: 400.0,
child: GridView.count(
mainAxisSpacing: 8,
crossAxisSpacing: 8,
physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 5,
children: List.generate(randomList.length, (index) {
final isCorrect = randomList[index] == provider.currentNumber;
return NumberButton(
number: randomList[index],
onPressed: () => _updateCurrentNumber(context, provider),
isOnTouch: isCorrect,
);
})),
)
],
),
),
),
),
),
);
}
}
import部分は省略しました。
この変更を加えてソースコードをビルドすると次のgif動画のようにボタンがランダムに表示されます。
はてなブログからwordpressに移行したことで綺麗なgif動画を表示できるようになりました。個人的にこれが一番移行して良かったと思います。
ここまで来るとゲームアプリっぽく見えてきますね。まだ、gifでは実装が終わってますが、Timer処理の部分の説明が残っていますがこちらは次回に繰り越します。