flutter flameメモ
onLoad -> onMount -> onRemoveの順番
onLoadは初回に1度呼び出される。onMountはobject※が読み込まれたタイミングで呼ばれる。onRemoveはComponentTreeから削除されたタイミングで呼ばれる。
※このオブジェクトはonLoad(), onMount(), onRemove()をoverrideされており、Componentをextendsしている。
つまり、stateごとにアクションしたいオブジェクトはextends Componentしておけばいい。
update, renderはfpsごとに呼ばれる。
renderはcanvasオブジェクトを必要とし、canvasは描画を行う。描画にはPaintクラスを用いる。
renderではオブジェクトの位置情報を指定でき、update()で位置情報を更新するとrenderで描画される。
位置情報の更新幅にdtを入れてあげると、fpsごとに等速で動くので良い。
位置情報の更新にはPositionComponentが役にたつ。このコンポーネントはpotitionをメンバに持っているため、クラス内で変更できる。
またvector2を引数にとるが、これは位置の加算や情報のコピーなどの機能を持っていて便利基本vector2を用いて場所を変えるのが良い(x,yを直接変更すべきでない。)
_gravityを設定してあげることで重力を表現できる。onMountで初期位置を設定できる。
TapCallbacksを持つとtap時の挙動を制御できる。マイナスにすることでジャンプを表現できる。
カメラについて
カメラはオブジェクトを追従する、表示幅がありその範囲でrenderされる(?)
FlameGameはデフォルトでcameraとworldを持っている。内部的にcamera.world = _worldとしておりcameraはworldを内包している。
GameWidgetをインスタンス化するときにcameraを定義しているが、この中でviewportを指定しているはずで、これはworldに対して表示範囲を定めるwindowの役割を果たす。viewwport内にhudComponentを追加した場合、これは画面の移動の影響を受けない。
カメラはworldを基準に表示している。
componentはworld.add()とすることがで、その場合addしたコンポーネントのカメラポジションは中央になる。
rectangleComponentは四角形をaddできる。これはaspect ratioを維持する
描画する範囲と内部的に持つ領域は異なる。
これはdebugModeで確認できる。必要に応じてcanvas.drawCircleで修正できる。
anchor 場所を指定できるっぽい。あとで調査
camera.followでオブジェクトをフォローできる。onMountやupdateなどで指定できる。positionの調整と似た方法で、follow条件は範囲をカスタムできる。その場合はupdateに書くことになる
各クラスはコンストラクタなどでkeyを設定できる。ComponentKey.named(Srtring)で設定したkeyを参照してオブジェクトを呼び出せる
参照する際はwith HasGameRef<MyGame>をmixinすると参照できる
呼び出す際は、gameRef.findByKeyを使う
オブジェクトの停止位置を制御(gravityをzeroにするなど)するためにはpositionOAnchor(Anker)を使う。(13:10-)
dartのassertはコンストラクタの後(superの前)につけることができる。
描画されるものと実際の判定には差がある。(2回目)
canvas.drawCircle((size/2).toOffset(),...)として合わせられる
with ParentIsA<T>で任意のクラスを親にできる。
設定したクラスは他のクラスから追加できない(?) link
描画したオブジェクトに対してEffectsでエフェクトをかけることができる。
画像の読み込みにはFuture asyncが必要
衝突検知を行う場合、game本体(MyGame)にHasCollisionDetection, コンポーネント(例えばPlayerクラス)にCollisionCallBacksを持たせる。CollisionCallBacksをextendしたクラスはonCollision、onCollisionEndをを実装できるこれらはは衝突したオブジェクトを引数に持つ。これはPositionComponent。
衝突検知を行うクラスはCirclehitBox()これをaddできる。これは設定した任意のオブジェクトがhitBoxの領域に踏み込んだときにcallされる。検知の方法はいくつかありCollisionTypeで指定する。(xxHitboxクラスの引数)。例えば検知が不要なタイミングでinactiveを利用することでパフォーマンスを向上できる。衝突検知したオブジェクトのうち、処理を行うのが1つだけの場合、他方のcomponentでonCollisionを呼ぶ必要はないのでpassiveにできる。
hitboxはポリゴンのように詳細に設定できる(略)
オブジェクトをremoveする方法はいくつかあり、その中にremoveFromParentがある。
memo
#30DaysMasterFlutter
pause, resumeなどのUIはflamegameの外側で実装できる。通常のflutter widgetのonPressedなどでFlameGameの内部状態を管理する。(FlameGameクラスにpauseEngine(), resumeEngine()メソッドがあり、適宜呼び出せば良い)
HasDecoratorsをmixinするとDecoratorsできる。これで停止中の画面を暗くしたりできる。PositionComponentはデフォでmixinしているので前述以外でもブラーなどをかけたりもできる。mixinされた(した)クラスのdecorator=PaintDecorator.~すれば良い
HasTimeScale をmixinすると、ゲームの実行速度を高速化することができる。pauseEngineの代わりにmixinしたクラスでtimeScale=0としてもいいかも。
memo
flame document
見ておいた方が良さそうなreference
effects
events
component
ゲームに立体感を持たせる
parellelx
sprite
scrollTextBox
-
componentに優先度をつけられる。
-
componentに子componentをwrapできる。親がレンダリングされたとき、子もレンダリングが呼び出される。シンプルにaddするか、children: に記載する
-
ParentIsAで特定の親であることを保証できる。ここでしか使わないコンポーネントはつける方が良さそう。HasAncestorをmixinするとその親を確認できる。
-
componentにkeyをつけられる。
-
Query関連はパフォーマンスの向上によさそう
-
HUDを作成する場合、viewpointはPositionType.viewportにすることが多い
-
コントローラなどはPositionType.widgetとするかも
-
この設定はMroot class(MyGame)に追加されたときに反映される。
-
表示/非表示でadd/removeできるが、await myChildComponent.removedなどでwatchするようにして
-
HasVisibilityをmixinするとremoveせずに非表示にできる
-
spriteアニメーションは複数の画像or spritesheetから作成できる。
-
spritesheet の場合はSpriteAnimationData.sequencedを使って読み込む
-
animationTickerで振る舞い、onCompleteでコールバックできる
-
spriteGroupComponentがある、複数のanimationを管理したいとき
- Playerの歩く/攻撃/などの制御によさそう
-
SpawnComponentでarea内にcomponentをランダム生成できる。factory
-
自分のユースケースだと不要かも
inventoryの作成などは
memo
ちょっとbloc実装大変そうなので、flame_riverpodを検討。
かなり分かりやすい。
blocはevent発火時の更新がfunctionalになるっぽいとも言われており、可読性も下がりそうかなという感じ
上記の構成図(雑)
- riverpodとflame_riberpodを両方使っている
- riverpodをflameのライフサイクルで利用するには、
RiverpodAwareGameWidget
,RiverpodGameMixin
,RiverpodGameMixin
を設定する - watchは発火時に再構築する、listenは再構築せずにfunctionを実行する
参考: https://blog.markvideon.dev/the-genesis-and-rebirth-of-flame_riverpod/
blocパターンの実装例(書きかけ)
複雑め....
spritesheet slicer
piskel
ゲームループについて
見た目まわりでやりたいこと
characterに影をつける -> Shadow3D
画面の外側に黒いモヤを作るれる?
app 参考
game example
flutter widget