Flutterでビンゴゲームをつくる
こんな感じで
妄想レベルで、Admob入れて、各プラットフォームでストア公開することも考えた。
やることとしては、↑こんな感じでできそう。
まあでもこのレベルのアプリに広告入れて出すのはちょっと嫌な感じがするので、やめます。
ビンゴのルール理解してなかった。75までらしい
一般的にビンゴカードは縦・横5マスずつ、計25個のマス目が書かれている。その内、中央を除く24マスには1から75までの番号のうち24個の番号が書かれており、中央はフリースポットとして最初から有効な番号として扱われる。1枚のカードの中で同じ番号が重複することはない。
とりあえずリポジトリつくった
とりあえずText返させようとしたら、
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Bingo!',
theme: ThemeData(
// Add the 3 lines from here...
primaryColor: Colors.black,
),
home: StartWindow(),
);
}
}
class StartWindow extends StatelessWidget {
Widget build(BuildContext context) {
return Text("Bingo");
}
}
こんなデザインになった
Scaffold
使わないと、どうも↑色合いになるみたい
VSCode、[Command]+[K]→[V]
でMarkdownがプレビューできる。便利だ
今日はここまで
ファイル分割してみた
import 'package:bingo/game_page.dart';
呼び出すファイルに対して、これが必要みたい
こんなメソッドでonPressed
に指定したが、contextが読めなかった。
チュートリアルのときはこれで読めていたが……?
void _temp() {
Navigator.of(context).push(
MaterialPageRoute<void>(
builder: (BuildContext context) {
return GamePage;
}
)
);
}
チュートリアルと今の違いがよくわからなかったが、とりあえず↓のように書き換えた。
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
ビンゴゲームはどうやら1...75が数字の範囲らしい。
状態変数として、1〜75を持って、ユーザータップのたびに数字を一つずつ別の配列に移動、最終的に配列がカラになったらビンゴ終了、というのがいいかな
Dart、Rangeオブジェクトがなさそう。
こんな感じで代替できる
乱数でランダムに配列から取り出すには、↓でやればできそう
レイアウトで迷ったが、
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
で等間隔にスペースをあけてくれた
今日はここまで
ビンゴ画面、戻るボタンをこんな感じにしたい。
FloatingActionButtonを使うと実現できそう。
FloatingActionButtonLocation.startTop:
で、タップアクションで戻る
うーんでも正直ナビゲーションバーでも別にいいかなあ。
このカスタマイズで時間取られるの嫌だし、AppBarのまま進めよう
引数を取るStatelessWidgetを書いたら、ワーニングが出た。
class NumberRouletteButton extends StatelessWidget {
final String _number;
NumberRouletteButton(this._number);
The field doesn't override an inherited getter or setter.
Try updating this class to match the superclass, or removing the override annotation.dart(override_on_non_overriding_member)
イマイチよくわからないが、@override
を消した
文字サイズをいい感じに大きくするの、fontSizeFactor
が良さそう
Text(
_number,
style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 10.0),
),
このドキュメントに色々書いてある
ウィジェットのイニシャル時に一度だけ処理を行いたいときはここでいいらしい
void initState() {
super.initState();
// todo: ここに処理を書く
}
Dartのコンストラクタ、難しさを感じる
配列からWidgetを複数生成したいとき、どう返せばいいかわからなかった。
mapを使えばできそうだと思ったが、どう書いてもコンパイル通らなくて困った。
どうもtoList()
でWidgetのListとして渡すといいようだ。
Widget _buildRow(int start, int end) {
return Row(
children: _saved.map((e) => Text(e.toString())).toList()
);
}
というかmapとtoListがセットなのか?
よくわからない……
レイアウト関連、↓は必読だな
Dartの配列操作方法、何回もググってしまった
とりあえず粗々はできた。
既出の数字を下に表示してるところが、思い通りの増え方に調整できない。
どうしても増えたときに見づらくなってしまう。
Timer処理をつくろう
タイマー処理、こんなかんじで実装した
void initState() {
super.initState();
_numbers = List<int>.generate(74, (i) => i + 1);
_saved = [];
Timer.periodic(const Duration(milliseconds: 200), _change);
}
void dispose() {
_timer.cancel();
super.dispose();
}
void _change(Timer timer) {
_timer = timer;
setState(() {});
}
画面の更新したいがために、setState()を空で呼んでるけど、このやり方どうなんだ……?
だからと言って更新する状態変数もないし……
完成したのでクローズ