WebフロントエンジニアがFlutterで卓球の得点板を開発した話
皆さんこんにちは。suginokoです。
BrewusでWebフロントエンジニアしてます。
最近ではWebフロントエンジニアでReactやNext.jsを扱うよりも、Linuxと仲良くしていることが多いのですが、Flutterも触り始めてたりしてます。
弊社ではReact Nativeを扱う案件もあるので、Webフロントの人間がいわゆるiOSやAndroidのアプリを作ってみたい!となればReact Nativeを触るのでも問題はないのですが、上司からも「Flutterやってみたら?」という提案もあり、なんとなく『やってみるか~!』という気持ちになったので何か作ってみることにしたのが事の始まりです。
普段、技術記事は自分のQiitaに書くのですが、Flutterってありふれていますし、仕事の話でもなければ趣味の話なので今回はNoteに書こうと思います。
何を作るかを考えてみる
「Flutterやってみたら?」と言われて、すぐに思いついたのは弊社で扱ったReact Nativeの案件のアプリの模倣だったのですが、言語仕様やお作法を知らずに作業に入った結果(公式ドキュメント読みましょうね)、いきなり案件レベルの模倣は難しいと感じ1ヵ月くらいで断念しました。後日もう少し言語仕様など理解してから取り掛かりましたがそれでも難しいと感じました。
断念した理由としまして、弊社が担当したアプリのUIがWebの技術だと問題ないのですがDart言語だけで組むのは難しいと感じたからです。学ぶ教材としてはちょっと良くなかったと。あまり複雑なUIを作るのには向いてないのかな?と思いつつ……
でもせっかくFlutterを勉強するのだから楽しく作りたいなと思ったので、自分の趣味に関するものを作ることにしました。
私の趣味は卓球なのですが、週1で練習して多いときは2週か3週に1回は大会に出て商品券を持って帰ってくるくらいの実力で(もう少し本気で練習できれば)全国大会も目指せたらいいな、というくらい打つのが好きです。
なので、卓球に関する何かを作ろう(勉強しよう)と決めました。
卓球の何を作ろうとしている?
色々な大会に出場するそんな中でp4matchという自分のレートを元にそのレートと近い方と試合を行うサービスがあることを知りました。
こちらのサービスを利用して1回だけですが大会に出場したことがありまして、サービスから提示される試合の順番に従って試合を行います。
このサービスは試合の順番も提示してくれるのですが、空いている人は審判係の表示も提示されるので審判をしなければならないこともあります。
審判は当然ながら得点を計算するので通常であれば得点板を使って点数を数えるのですが、この会場には得点板がありませんでした。得点板がない場合は手で数えます。これが非常に面倒くさいです。
別に自分で以下のリンクにあるような得点板を持っていればよかったのですが初出場で持ち合わせておらずでしたので手で対応しました。(中には貸して下さった方もいました。ありがとうございました。)
手で数える時の数え方はルールで決まっており、詳しくは載せませんがそのルールに従って点数を数えます。この点数の数え方で私は3-3、3-8(逆も然り)、8-8の手が苦手です。
皆さんもやってみると分かると思いますが、これらの点数の時の手が痛いのです。特に3や8の点数が動かないときはもう腕が辛いです。なので早急に解決したい気持ちがありました。
別に値段も言うほど高くはないっちゃないので得点板を買ってもいい、でもせっかくだからFlutterの課題にならないかな?と思いました。UIとしてもほぼ四角形で構成されてますし、卓球ルールがわかっており仕様も決めやすいのでちょうどいいと感じました。
これらの問題を解決すべくタブレットを想定して卓球の得点板を作ろうと決めたのでした。
※あくまで練習で作りますので、リリースはする予定もありません。他の得点板アプリも参考にして実装しています。似ているようなUIも実装あるかと思いますがご了承ください。
仕様を決める
弊社のアプリの模倣を1ヵ月で断念したので、「何を作るか考えてみる」でも記載したように改めてちゃんとお作法や実装方法をもう少し読んでから取り掛かることにしました。
実装する前にあったら便利だと思う機能と卓球ルールに基づいた仕様を書きだします。
あったら便利な機能としては以下を設けました。
ゲームのセット数を決めたい
3,5,7セットを選択
名前を入力したい(p4matchでは名前も表示されていたのであってもいいのかなと)
サーブ権を選択したい
得点板の仕様としては以下で進めました。
n(3or5or7)セット先取
1セット11点マッチ、デュース(10-10~)の時は2点差ができるまで
サーブは2球交代
デュースのときは1球交代
サーブ権は赤い丸のマークとしてどこかに設置する
点数は1点ずつ加算
圧倒的に加算する方が多いので加算の際はタップの範囲を広めに
間違えた時用に得点マイナスボタンも設置する
1セットごとにコートチェンジ
名前も表示するので、名前もチェンジする
セットカウントもチェンジさせる
セットオール(例:5セットマッチで2-2の場合)、5点獲得でコートチェンジがあるので自由にコートチェンジできる機能を持っておく
ゲームが決まった時にはどちらが勝者かダイアログを出す
ダイアログを出したあとはTOPに戻る
いざFlutterで得点板を作ってみる
得点板を作ってみましょう。
やはりWebフロントエンジニアの人間なので、CSSを分けてUIを作りたくなります。なんで1言語でロジックもUIも作らないといけないの…?という気持ちを抱えながら構築していました。(ここでCSSは神だったんだなと感じる)
Dart言語は若干JavaScriptにも似てなくは無いので書くことはそこまで苦労してないのですが、UIの構築がCSSほど融通が利かず「CSSだったら〇〇使って簡単にできるのに!」ということをロジックとUIと合わせて書くものだから、いわゆるスパゲッティみたいなソースになりつつありました。
多分コンポーネント分けれると思うのですが、一旦作り切りたかったので勢いで書いていました。
今回UIが四角形や丸形で済むようなUIになりますし、複雑なUIはないものの、CSSのようなdisplay: flexやgrid、position: absoluteのような融通は(やろうと思えば出来はするのだけど)難しさを感じました。
Flutterで言うとAlign()やPositioned()なのですが、はっきりとCSSのposition: relativeのように基準点を決められたらよかったものの決め方がいまいちわからない。
複雑なUIになるほどスパゲッティ化する(ファイル分けなさいよというツッコミは無しとして)。それでも進めていきつつ。
今回UIのパッケージはpackage:flutter/material.dartしか使用しなかったのでもう少しUI構築がマシになるライブラリもあったかもしれなかったですが、今回特に四角と丸だけでしたので使用せず。
なんだかんだ進めていって最低限まで作れたかなというところまで出来たので動かしてみました。(本当はGIFでアニメーションで動きを見せたかったが、投稿ができなかったので画像で紹介します)
反省点
Dartにおける配列操作がいまいちわからず、変な書き方をした
counter[0] = A counter[1] = Bのようなプログラム初心者ですか?みたいな書き方
今回タブレット端末(iPad)向けに作ったが、実際iPhoneやAndroid端末に向けて作るってなった時の、Web業界でいうレスポンシブの対応の仕方は知っておいた方がいいなと思ったものの、そこまで至らず
ファイルの規模大きくなりそうならWeb開発の時みたいにファイルを厳密に分けたかったが分け方がわからずそのまま進めてしまった
ライフサイクルの概念があるっぽい?がそこまで理解が至らず
Flutterあんまり好きではないかもしれない(CSSが好きすぎて……という意味では)
もう少しやってみて好きになれるように勉強したい
UX的なことでいうと、1セット終わるごとのコートチェンジもう少し早くチェンジできるようにしたい
自分で「次のセットへ」ってタップしないといけないのもよくないので自動で切り替えたかった
今後もう少しやりたいことと感想
上記の反省点を活かしつつ今回まだUIとUIロジックを作っただけなので、今度はfirebaseなど使ってやりたいことをやってみようと思います。この卓球版を使って引き続きやりたいことがあるのでこの記事の第二弾に向けて開発をしてみようと思います。(次の記事のために具体的にやりたいことは書きません)
慣れない言語かつアプリ開発はWeb開発と違ってお作法も違う感じなのでまだまだわからないことだらけです。さすがに趣味レベルであるためもう少し実力をつけたいところでした。
この記事が気に入ったらサポートをしてみませんか?