13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FlutterとFirebaseでオセロの対戦アプリをつくってみる ~UI作成を通してウィジェットについて学習編~

Last updated at Posted at 2019-12-02

雑談

簡単に自己紹介します。どうも!生産技術部の筋肉系FXオセロプログラマーです。
プログラムは初心者ですが、Advent Calenderのテーマが「オセロ」という事で、今回イベントに初参加してみました。

私は中部オセロクラブに所属し、子供の頃からオセロを競技としてプレイしています。現在は、あまり大会には参加せず、大須定例会の運営を主に行っています。大須定例会には、オセロ好きが集まるのはもちろんですが、様々な分野で活躍するエンジニアが集まります。その代表として、ScoreNowの開発者が所属しています。また、Orcaの開発者も在籍していました。

こんな素晴らしきエンジニア達が集う定例会は毎月第2日曜日に大須コミュニティセンターで開催されます。ぜひ遊びにきてください。詳細はこちら → 大須定例会

本題

さて、今回は表題の通りflutterとfirebaseでオセロの対戦アプリをつくってみました。Flutter、Firebaseの学習を目的に作り始め、学習と実装期間を含めて約2週間程度でオセロの対戦ができるところまで完成しました。早速、出来上がったものがこちらです。
画面収録.gif

難しい技術紹介は優秀な方達にお任せし、プログラムの初心者向けに、Flutter、Firebaseの学習手順や学習した内容を紹介したいと思います。本稿では、実装開始から3日目までに学習したFlutterウィジェットを取り上げます。

ソースコードは雑ですが、一応載せておきます。 → othelloNet
注:Firebaseの構成ファイルはアップロードしていませんので、そのままでは動きません。

実装の流れと学んだ事

実装のポリシーは、

  • オセロが出来て、
  • 2人で交互に打てる、

だけが出来る事とし、細かいことは無視して作りました。初心者の自分は早く動かないと面白くないからですw
完成まではこんな感じに実装を進めました。

image.png

アプリ作成から学んだ事

  • 1日目 - Flutterの導入
    Flutterの公式チュートリアルに従ってすすめ、便利なHot Reloadを学びました。
  • 2日目 - Firebaseの導入
    Firebaseの公式チュートリアルに従ってすすめ、Google CodelabsでFirestoreの使い方を学習しました。短時間で効率的に使い方を学習出来ましたのでおススメです。
  • 3日目 - オセロ盤のUIを作成
    UI作成を通して、ウィジェットの使い方を学習しました。 ← 次の章以降で紹介する内容です。
  • 4日目 - オセロ盤にタップイベントを追加
    イベントリスナーの使い方を学習しました。
  • 5日目 - オセロのロジックを作成
    Dart言語の書き方を学習しました。
  • 6日目 - Firestoreから棋譜読み出し
    2日目のCodelabsから学んだ事を実際に使って理解度を深めました。
  • 7日目 - Firestoreに棋譜書き込み
    2日目のCodelabsから学んだ事を実際に使って理解度を深めました。
  • 8日目 - ロビー追加
    Flutterでの画面遷移の仕方を学びました。
  • 9-11日目 - バグ修正
    デバッガの使い方、iOSシミュレータ、Androidエミュレータを使ったデバッグについて学びました。

他にも、FlutterのHot Reloadやdartdocを使ったドキュメントの作成について学びました。

オセロ盤をウィジェットで作ってみる

Flutterは、ウィジェットと呼ばれる様々なテンプレートのデザインを提供します。これらの予め用意されたテンプレートを組み合わせアプリケーションを作成します。オセロ盤は、画像で作成すれば簡単にできてしまいますが、折角なのでウィジェットのみで表現してみます。まずは、オセロ盤っぽい形をつくります。

image.png

Row、Column、Container、Expandedウィジェットでつくりました。Flutterで実装する上で各ウィジェットの役割を知っている必要があります。

Widget 役割
Row 子ウィジェットを水平方向に並べる
Column 子ウィジェットを垂直方向に並べる
Container 描画や、位置・サイズの調整に用いる
Expanded RowやColumnの子を引き延ばし、空間を埋める

これらを使ったレイアウトのイメージはこんな感じになります。Rowを使ってExpandedされたContainerを水平方向に8個並べます。作成した一行の盤をColumnを使って垂直方向に8個並べて完成です。

image.png

プログラムは全部書くだけでダサい感じになりましたw
List.genetateを使えばもっとすっきりまとまります。

return Container(
      margin: const EdgeInsets.all(10.0),
      color: Colors.blue,
      width: 320,
      height: 320,
      child: Column(children: <Widget>[
        // Containerは不要??
        Expanded(child:Container(
          child:drawOneLine()
        ),),
        Expanded(child:Container(
          child:drawOneLine()
        ),),
        Expanded(child:Container(
          child:drawOneLine()
        ),),
        Expanded(child:Container(
          child:drawOneLine()
        ),),
        Expanded(child:Container(
          child:drawOneLine()
        ),),
        Expanded(child:Container(
          child:drawOneLine()
        ),),
        Expanded(child:Container(
          child:drawOneLine()
        ),),
        Expanded(child:Container(
          child:drawOneLine()
        ),),
      ]),
    );
Widget drawOneLine(){
  return Row(children: <Widget>[
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
        Expanded(child:Container(
          margin: EdgeInsets.all(1.0),
          color: Colors.white,
        ),),
      ]);
}

オセロっぽくしてみる

色をオセロっぽく緑、黒、白に変更します。打てるマスを灰色にしてみます。円形のコマ(オセロ では、コマじゃなく石って呼びます笑)を追加します。

image.png

コマを円形にするには、BoxDecorationを使って円を作ります。これで、オセロ盤のUIが完成になります。(タップした時のイベントはまだついてないですけど、、、)

Container(
            margin: EdgeInsets.all(1.0),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(20.0),
              color: Colors.black,
            ),
          )

最後に

Flutterの一部の基本的なウィジェットについて学びました。Flutterのイベントリスナ、画面遷移、Firestoreについては今後記事にしたいと思います。

ご参考

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?