[初心者向け][Flutter][Tips] Flutter for webで出たエラーの解消法など

以前、Flutterで2Dゲーム開発を始めることにしたシリーズで、開発の合間に調べたことを備忘録に綴ってある下書きを発見しました。結局あの後、グダグダになってゲーム開発もやめちゃってたんですが、消しちゃうのももったいないので公開します。ときにはエンジニアらしい記事も、ね。

ちなみに、私はコミュ障ぼっちでフリーランスのエンジニアをやっています、34歳です。私のプロフィールに興味を持ってくださった方は、ページ下部の筆者紹介、Twitter(@suekiaoi)やInstagram(@aoi.sueki)などからご確認いただければと思います。

 

今年もいろんなことグダグダになるんだろうなぁ……でも、そのうち一つでもちゃんと形になれば御の字ですよ!うん!

 

ホットリロードの話

アプリの実行中は、ソースコードに加えたほとんどの変更が実行中のアプリに反映されます。 ほぼ瞬時に。

Eclipseの時代からは考えられないですねぇ。いいですねぇいいですねぇ〜。

 

同期・非同期の話

update(アクションの計算)とrender(画面描画)のゲームサイクルの話でちょいと触れましたが、そもそもゲームアプリにおける「同期」がなぜ必要なのか。

render(画面描画)のときに全てのアクションが同期されていないと、クソゲーになるからです。

 

例えば西部劇の決闘シーンだと、こんな感じ。

・キャラAの目の前に、キャラBの放った弾があるとします。死ぬ間際、キャラAがBに向けて弾を撃ちます。

・次のフレームでは、キャラAに弾が当たるので弾は描画されません。

・次のフレームでは、キャラAが死にますが、キャラBもAが撃った弾によって死にます。

キャラBの死因は永遠に謎のままになるのです。しょっぱい。

 

キャラを動かす = アクション計算 + 位置の更新 + 画面描画

たとえば、マリオ的なメインのキャラクター)の位置を更新することを考えます。

ジャンプさせるとか、前に進める、ということを実装したい時、内部の処理では以下3つの流れを行います。

アクションの計算:次の瞬間のマリおの位置を計算(ジャンプの場合は上に1マス、前に進む場合は右に1マス、みたいな。まぁ実際の単位はマスじゃないけど、イメージしやすくするために便宜的に)

表示位置の更新:上で計算した座標をマリオ・オブジェクトに適用します

画面描画:マリオ・オブジェクトの座標が更新されたことを察知して、Flutterライブラリが勝手に画面描画を再リロードしてくれます

という処理になります。

 

もう少し踏み込んだ話

次に、マリオのほんの数ピクセル離れたところにキラーがいるとします。マリオの死のコンマ1秒前。。

描画されているのはマリオだけではなく、キラーも同様です。

キラーの位置を更新すると、マリオに命中します。

命中したらマリオは死んでいるので、キラーは描画しません。この瞬間までに、マリオが死ぬアニメーションの最初のフレームを描画する必要があります。

なので、次のサイクルでは、死んでいるマリオの更新をスキップします。代わりに、(2番目のフレームではなく)マリオが死ぬアニメーションの最初のフレームを描画(レンダリング)します。

ただし、この実装だと、ゲームにぎくしゃくした感じを与えます。

キラーがマリオに当たる前にマリオが死亡しちゃう感じです。クソゲー感がでますでしょ。

 

特に毎秒60フレームを実行していると、非同期レンダリングのぎくしゃくした動きは目立たない場合もありますが、これが頻繁に発生するとクソゲーっぽくなります。

すべてを計算し、すべてのオブジェクトの状態を計算して確定すると、画面が描画されます。こうやって中を覗いてみると、ゲームってホント、すごい高度なことやってんだなぁって頭がさがるばかりです。

 

futures、async、await

futures、async、awaitは、他のすべてをブロックせずに長いプロセスが完了するまで「待機」できるようにするコーディングプラクティス。

futureを待つことができるようにするには、futureメソッドが非同期関数内に書かれている必要があります。ということで、asyncでくくりましょう。

ゲームの起動と並行して実行されるため、方向と全画面の線のawaitキーワードは必要なくなりました。 したがって、main関数のasyncキーワードを削除することもできます。

 

画面サイズとオブジェクトサイズの話

画面に描画する前に、画面のサイズを事前に知っておく必要があります。 Flutterは画面上に描画するときに論理ピクセルを使用するため、ゲームオブジェクトのサイズ変更について心配する必要はありません。今のところ。

リリースプラットフォームとしてスマートフォンをターゲットにしているとすると、デバイスの1インチには、約96の論理ピクセルが含まれています。

まぁ今回つくってみたテトリスのようにシンプルなゲームな場合、あんまりサイズを気にする必要はありませんけどね。

 

for webを使うためにflutter bata版を使っていたら実行時エラー!

Error: The non-abstract class 'FlameBiding' is missing implementations for these members:

ググったところ、どうやらstableの最新版に切り替えれば良さそう。(んだよ…web使えないじゃん

Flutter のバージョンをstable latestに切り替える

ひとまず動かすことを優先してFlutterチャンネルを切り替えます。

切り替えは簡単で、Flutterのインストールディレクトリで下記を実行するだけ。

flutter channel stable

flutter upgrade

Flutterチャネルの切り替え

Flutterには、安定版、ベータ版、開発版、マスターの4つのリリースチャネルがあります。 より新しいリリースが必要でない限り、安定したチャネルを使用することをお勧めします。

 

ここまで読んでいただき、ありがとうございました!

参考になったよ、という方はTwitter(@suekiaoi)やInstagram(@aoi.sueki)などでフォローしていただけると励みになります。

不明点・ご質問などありましたらわたしのTwitter DM(@suekiaoi)にお気軽にどうぞ!

それでは!

末岐 碧衣
  • 末岐 碧衣
  • フリーランス のシステムエンジニア。独立後、一度も営業せずに月収 96 万円を達成。1986年大阪生まれ。早稲田大学理工学部卒。システムエンジニア歴 12年。
    2009年、ITコンサルティング企業に入社。3年目でコミュ障が爆発し人間関係が崩壊。うつにより休職するも、復帰後はコミュ障の自覚を持ち、「チームプレイ」を徹底的に避け、会社組織内においても「一人でできる仕事」に専念。社内外から評価を得た。
    無理に「チームプレイ」するよりも「一人でできる仕事」に専念した方が自分も周囲も幸せにできることを確信し、2015年フリーランスとして独立。