はじめに
「Flame」っていう言葉、最近そこそこ目にするようになりましたよね?
「Flame?なにそれ?食べられるの?」という方に簡単に説明しますと、Flutterでゲームをつくるための一番メジャーなパッケージです。
https://pub.dev/packages/flame
話題になっている割には日本語の記事が少なすぎるので、Flutter初学者が3週間Flameいじった感想をかきます。
この3週間で100時間近く、Flameに費やしました!
正直、かなり苦労したのであまり人に軽々と教えたくないなあという気持ちもあるんですが、私自身これまで多くの記事に助けられてきたので、その恩返しとして書き記します!
学んだことをすべて放出するのでぜひみていってください!!
この記事に書いてあること
「Flameでどんなものが作れるの?」
「Flame、今はまだあんまりオススメできない理由3つ」
「初学者必見!Flameでつまづかないためのお役立ち情報4選!」
私は単純に「ゲーム自分でつくってみたいな」という無邪気な気持ちから、気軽にFlameに手を出しました。ところがどっこい、想定よりもかなり手こずったので、「Flame、今はまだあんまりオススメできない理由」と、それでもFlameでゲームをつくりたい!という方のために「初学者必見!Flameでつまづかないためのお役立ち情報4選!」を記事にしようと思います。
以下に書く通り、私はFlutterはじめたてのペーペーなので、「Flameの問題じゃなくておまえの能力が低いだけじゃけえ!」という可能性も大いにあります。そういった場合は「Flame、今はまだあんまりオススメできない理由」の部分を、単純に「初心者のつまずきやすい部分」として読み替えてください。
・Flameをはじめる前のFlutterの学習歴は3ヶ月ほど(=プログラミングの学習歴)
・Flameはそこから3週間毎日さわりつづけた
#「Flameでどんなものが作れるの?」
まず、私の作っているゲームから。
本当は「ここに作ったゲームはっといたから、みんなダウンロードしてくれよな!」としたかったのですが、まだ完成していないので画像からどんなゲームかを感じてください。プレイヤー(ウマ)を動かして、上からふってくる毒りんごをよけながら、りんごとピザをあつめるゲームです。
メニュー画面やキャラを操作するボタンなどのUIはFlutterのwidgetで構成されていますが、メインゲームの画面でのキャラが動く処理などは「クラスをかいて、インスタンスを生成して、メソッドをかいて・・・」という風にFlutterっぽさはなく、普通にプログラミングをします。
↓下記のウマのようにHitBoxPolygonをつかえば当たり判定を複雑な形にもできます。
ほかに何ができそうかは、以下の公式サイトのFlameのサンプル集をみてください。
https://examples.flame-engine.org/#/
このほかにもFlameから派生したパッケージがあり、rigidbody(剛体)をいじりたい場合はflame_forge2dなどのパッケージをつかうとよいです。
#「Flame、今はまだあんまりオススメできない理由3つ」
Flame、思ったよりしんどい部分が今は多いです。もう少しまってから触り始めてもよいのかなという気もします。
理由①日本語記事が少ない!
とにかく日本語記事が少ないです。ググっても両手で収まる程度しか日本語記事がでてこないです。「英語みると蕁麻疹がでます!」や「ゲームまったく作ったことない!」って方は苦労するかと思います。逆に私は、今回Flameをいじったおかげで英語でプログラミング記事を読む抵抗が多少減った気がします。そういうメリットはありますね。
理由②バージョンによって話がぜんぜん違うじゃないか!
Flameのバージョンの話をします。
Flameには現在stable版の「flame 0.29.4」とFlameStaffが目標としている Flame 1.00のstable版をつくるための更新が激しい「flame 1.0.0-releasecandidate.数字」があります。
安定版をぜひとも使いたいところなのですが、「flame 0.29.4」はNullSaftyに対応しておりません。また、「flame 0.29.4」は現在の最新版「flame 1.0.0-releasecandidate.18」とはコードが大きく異なっており、そのうち「Flame 1.00のstable版」がでるのに今から「flame 0.29.4」を学習するのは気が引けます。
じゃあ、「flame 1.0.0-releasecandidate.18」をつかおう!という話にもなりません。というのは、「flame 1.0.0-releasecandidate.18」のチュートリアルはほとんどネット上に転がっておりません。また、同じ「flame 1.0.0-releasecandidate」でも数字が違えば根本的なところから変わっている場合もあります。さらにバグも多いです。例えば「flame 1.0.0-releasecandidate.14」以降は画面からアイテムを取り除くremove関数がうまく作用しない致命的なバグが発生することがあります。(FlameStaffによるとバグらしいです。以下のエラーが発生。)
The following StateError was thrown during a scheduler callback:
Bad state: Cannot find reference FlameGame in the component tree
というわけで、個人的に「flame 1.0.0-releasecandidate.13」をつかうことをおすすめしています。
が・・・
理由③バージョンが16以前の公式ドキュメントが読めない!
これは私が開発している途中に起きました。ある日突然、flame 1.0.0-releasecandidate.16以下のドキュメント(APIリファレンス)がよめなくなってしまったのです。少なくとも2021/12/6現在、以下のサイトにアクセスしても404 Not foundがかえってきます。(17と18は読めます)
https://pub.dev/documentation/flame/1.0.0-releasecandidate.13/
releasecandidate.18のバグをさけ、releasecandidate.13によって開発していた私は大変こまり、FlameStaffに連絡したところ、確かにそのような問題は生じているらしく、
「That is really weird, I wonder if this is a pub dev characteristic?」
という返信をいただきました。
パッケージのgithubで実装方法がみられるのでここから頑張りましょう!
#「初学者必見!Flameでつまづかないためのお役立ち情報4選!」
Flameをオススメしない理由を書き連ねましたが、以下の情報を利用すればそこまで苦労しないでゲームをつくれるようになるはず!
私の100時間弱の学習でえたものを凝縮しました。
Flameの勉強の手順
私がFlameのチュートリアル記事をあさりまくった結果生まれた手順です。
①Building Games in Flutter with Flame: Getting Started
Flameについて情報収集をしているといろんなチュートリアルがありますが、オススメは「Building Games in Flutter with Flame: Getting Started」です。このチュートリアルでは先に素材をダウンロードしてから(登録が必要)、ページを読み進めていくことでRPGっぽい世界でPlayerを動かす方法を学びます(初期のポケモンのゲーム的な)。量も少なく、丁寧なのでオススメです。(ただし、ジョイスティックあたりの実装は「おまじない」感がある)
https://www.raywenderlich.com/27407121-building-games-in-flutter-with-flame-getting-started
Flameのサンプル集のコードをクローンして手元で動かしていじってみましょう!なにができるのか、どういう風にできているのか、と言うのがざっくりつかめるようになります。合わせて基本的なしくみはFlameの公式サイトをみて頑張って学びましょう。
バージョンに関しては適当なものを選んでやってください。
Flameの公式サイト
https://docs.flame-engine.org/1.0.0-releasecandidate.18/index.html
Flameのサンプル集
https://examples.flame-engine.org/#/
Flameのサンプル集のコード
https://github.com/flame-engine/flame/tree/flame-1.0.0-releasecandidate.18/examples/lib
③Spacescape(シューティングゲームをつくるyoutube動画)
もうすでに「オリジナルゲーム作れそう!チュートリアルあきた」って方は④に進んでください。
この動画では、かなり本格的なシューティングゲームがつくれます。コードの書き方もうまいので参考になります。
1本1本の動画が短いように見えますが、動画をとめて、理解して、写経するというのを繰り返すと尋常じゃない時間がかかります。(しかもPart20まである)
そこでこの動画を適当なところまでこなしたら、あとは実装したい機能に応じて動画を再生するのがよいと思います。
動画ではちょうどNullSaftyに対応し始めたFlame 1.0.0-rc8でコードをかいていますが、githubのほうにはflame: 1.0.0-releasecandidate.13で書き直したものも載っています。参考にしましょう。
また、動画作成者はDino Runという横スクロールランゲームをつくる動画も載せています。これはバージョンがflame: 0.280のパッケージをもちいているのでSpacescapeのほうがよいでしょう。また、この完成したDino Runをflame: 1.0.0-releasecandidate.13で書き直す動画もありますが、初学者が学ぶのに適していないのでオススメしません。
https://www.youtube.com/playlist?list=PLiZZKL9HLmWPL0URlq9WLng1A_g1LDuxx
④オリジナルゲームをつくる
頑張って作りましょう!最初はあんまり難しそうなゲームをつくらないことが懸命です。まずはなにか設置して動かしてみるところから!
やっぱり自分で考えて手をうごかし、わからないことを調べて解決するのが一番力がつくと感じました。
その他の使えそうなチュートリアル
・flame_forge2dのexample集
rigidbodyを使いたい方はこれをクローンしていじってみましょう!Flameのexampleよりおもしろいです!
これは注意なんですが、flame_forge2dで生成したrigidbodyのpositionは読み取り専用のため、一度生成したあとはpositionを指定して更新するような処理はできません。(つまりテトリスのテトリミノを左右に動かすような処理ができない。Unityなどではできるようです。)それができないことに気づかなくて長い時間を無駄にしました。生成したrigidbodyを動かしたいなら、力を加えて移動するしかないようです。
https://github.com/flame-engine/flame/tree/main/packages/flame_forge2d/example/lib
・Moon Landerをつくるチュートリアル
Part2以降は有料なので見ていないですが、Part1はわかりやすくてよかったです。
https://medium.com/flutter-community/flutter-flame-step-1-create-your-game-b3b6ee387d77
・数少ない日本語記事たち
偉大なる先駆者たちが記事です。日本語でFlameがよめることに感謝しましょう!
https://zenn.dev/7oh/articles/245db375f2e618
https://qiita.com/keidroid/items/8b99c20fdf39dfd7b54b
https://zenn.dev/razokulover/articles/799c1352b56260f0309b
https://qiita.com/LAGALIN/items/65e9a6ca5ffcb2f34073
※英語サイトでチュートリアルはたくさんあるのですが、パッケージのバージョンがいまいちだったりしたのであまり載せませんでした。
Flameをつかう上でのコツ・注意点
・パッケージのバージョンには気をつける。バージョンが違えば話はかなり違う。
・APIリファレンスが読めない場合はエディタでわからないワードをクリックして、定義元をよむ。(なれてくると説明がなくても単語名から機能や使い方が推測できるようになってくる)
・githubの検索をうまくつかう。advanced searchでdartを指定し、検索ワードの欄で使い方を知りたいクラス・関数名とflameと入力して検索し、誰かのコードからクラス・関数の使い方を学べる(普通のことかもしれないが、初心者の私がこの方法を思いついたときは革命的だった。プログラミングを勉強するときに一番最初に教えてほしかった技術である)
・BlueFire(Flameの作成Staff)が運営するDiscordに入る。スタッフに直接質問できるのでよい。ほかの人の質問からも学べる。
https://discord.gg/pxrBmy4
1.0.0-releasecandidate.13と18での違い対応表
バージョン違いでエディタ上が赤線だらけになった際にご使用ください。
頻出例をあげときます。
ver | 13 | 18 |
---|---|---|
画面上のコンポーネント | components | children |
コンポーネントの削除 | インスタンス名.remove() | remove(this) |
Flame使う際に必ずextendsするやつ | BaseGame | FlameGame |
あたりはんていをいれるのにつかうmixin | Hitbox | HasHitboxes |
コンポーネントにHitBoxをあたえる関数 | addShape | addHitbox |
Timer関数の引数の関数の指定 | callback | onTick |
#最後に
Flameに対してネガティブなようにみえる箇所もありますが、Flameが盛り上がって日本語記事がふえることを願っております。
ちょっとだけサンプルをクローンしていじってみるとかでも、普通のアプリ開発とは違った楽しみを感じられると思うのでぜひFlameをさわってみてください。キャラが初めて動いたときはなかなかの感動がえられます。
また、今回の記事に反響があれば、もっとFlameについての記事をかいていきたいと考えております。
なにか間違っている点があれば、ぜひご指摘ください。
Twitterもやっているのでぜひフォローしてください。
https://twitter.com/7x7x7__343
ここまでよんでいただきありがとうございました!!