Flutter, Flame を使った画像表示(その3)
今回の目標
画面をタップしている間、画像がアニメーションを行い、画像から指を離すとアニメーションが止まるアプリに変える。
用意するもの
- 前回のプロジェクト
- 静止画
- アニメーション画像
今回は動作時のアニメーション画像、静止画の2種類が必要となります。
アニメーション画像は前回の画像を使います。
静止画は前々回利用した画像を 1/10 にした画像を使います。
(80ピクセルx80ピクセルの画像サイズにします)
不要なオブジェクトを除去する
まず、main
関数から、今回使わなくなるNouka
クラスを削除します。import
も必要なくなるので一緒に削除します。
-import 'nouka.dart';
・・・・・
class MyApp extends FlameGame {
+ late NoukaSpin noukaSpin
Future<void> onLoad() async {
- final nouka = Nouka();
- add(nouka);
-
- final noukaSpin = NoukaSpin();
+ noukaSpin = NoukaSpin();
add(noukaSpin);
}
}
これで左上の農家画像が削除されました。
noukaSpin
変数は今後を考えて、onLoad
関数の外に出します。
画像の準備
次にアニメーションを動作させるための静止画とアニメーション画像を準備します。
アニメーション画像はその2で利用したものを使いましょう。
静止画はその1で利用した画像を使いましょう。
静止画、アニメーション画像を読み込む
まず初めにenum
で、状態を定義します。
import 'package:flame/components.dart';
import 'package:flame/game.dart';
+enum NoukaState {
+ idle,
+ spin,
+}
次にNoukaSpin
クラスで静止画、アニメーション画像の読み込みを追加しますが、どちらの画像も前回、NoukaSpin
クラスで利用した読み込み方法を削除した上で、別の読み込み方法を使います。
class NoukaSpin extends FlameGame {
+ late SpriteAnimationGroupComponent nouka;
Future<void> onLoad() async {
await super.onLoad();
- final noukaSpin = await images.load('nouka_renkon_syukaku_spin.png');
-
- final noukaSpinComponent = SpriteAnimationComponent.fromFrameData(
- noukaSpin,
- SpriteAnimationData.sequenced(
- amount: 4,
- textureSize: Vector2(80.0, 80.0),
- stepTime: 0.5,
- loop: true,
- ),
- size: Vector2(80.0, 80.0),
- position: size / 2,
- anchor: Anchor.center,
- );
-
- add(noukaSpinComponent);
-
+ final spin = await loadSpriteAnimation(
+ 'nouka_renkon_syukaku_spin.png',
+ SpriteAnimationData.sequenced(
+ amount: 4,
+ stepTime: 0.5,
+ textureSize: Vector2.all(80.0),
+ loop: true,
+ ),
+ );
+
+ final idle = await loadSpriteAnimation(
+ 'nouka_renkon_syukaku_mini.png',
+ SpriteAnimationData.sequenced(
+ amount: 1,
+ stepTime: 1,
+ textureSize: Vector2.all(80.0),
+ ),
+ );
+
+ nouka = SpriteAnimationGroupComponent<NoukaState>(
+ animations: {
+ NoukaState.idle: idle,
+ NoukaState.spin: spin,
+ },
+ current: NoukaState.idle,
+ position: size / 2,
+ size: Vector2.all(80.0),
+ anchor: Anchor.center,
+ );
+ add(nouka);
}
}
変数spin
はアニメーション画像の定義になります。
変数idle
は静止画の定義になります。
アニメーション画像は前回、SpriteAnimationComponent
にて読み込んでいましたが、今回はloadSpriteAnimation
を利用して読み込みます。
静止画も同様にloadSpriteAnimation
を利用して読み込みます。
最後に両方のコンポーネントを持つ、SpriteAnimationGroupComponent
を定義します。
画像の読み込みはこれで完了です。
タップのイベントを検知する
タップのイベントはTapDetector
を宣言することで検知できます。
以下のようにすることで、TapDetector
の関数が利用可能となります。
-class MyApp extends FlameGame {
+class MyApp extends FlameGame with TapDetector {
TapDetector
を宣言したら、MyApp
に関数を追加しましょう。
class MyApp extends FlameGame with TapDetector {
late NoukaSpin noukaSpin;
Future<void> onLoad() async {
noukaSpin = NoukaSpin();
add(noukaSpin);
}
+
+ void onTapDown(TapDownInfo info){
+ super.onTapDown(info);
+
+ }
+
+
+ void onTapUp(TapUpInfo info){
+ super.onTapUp(info);
+
+ }
}
これでタップを検知出来るようになりました。
タップした時の処理を追加する
タップを検知出来るようになっても、処理がなければ意味がありません。
まずはNoukaSpin
クラスに処理を追加しましょう。
class NoukaSpin extends FlameGame {
late SpriteAnimationGroupComponent nouka;
・・・・・・・・・・
+
+ void noukaSpin() {
+ nouka.current = NoukaState.spin;
+ }
+
+
+ void noukaIdle() {
+ nouka.current = NoukaState.idle;
+ }
}
静止画とアニメーション画の切り替えは状態を変更することで行えます。
次に先ほど追加したMyApp
のonTapDown
, onTapUp
にNoukaSpin
クラスの処理を記述します。
void onTapDown(TapDownInfo info){
super.onTapDown(info);
+ noukaSpin.noukaSpin();
}
void onTapUp(TapUpInfo info){
super.onTapUp(info);
+ noukaSpin.noukaIdle();
}
以上で完了になります。
これでタップしている間は回転し、離すと静止画に戻るようになりました。
使ってみると思っていた動きと違う部分もあります。
僕の場合はタップした状態から指を動かして、指を離すと動きが止まりませんでした。
おそらく必要な処理が足りていないのだと思います。
ただ、まだその辺りの調査が完了していないため、終わり次第ここに載せたいなと考えています。
Discussion