ほぞぼそと作ってるマグロのゲーム、
ボタンの動きをゲームっぽくしたくて、
いろいろ調べたときの備忘録(*´ω`*)
動きとしてはこんな感じで、ピョコンとなる感じ
ちょっとはゲームっぽい動きのボタンになった(*´ω`*) pic.twitter.com/zsQinyJzj1
— きらぷか@スプシAPI化&積読のサービス運営中🔥 (@kira_puka) May 26, 2024
やりかた
できたのはこんな感じ。このあたりを使って実装するっぽい
- AnimatedBuilder class - widgets library - Dart API
- アニメーションさせるWidget
- AnimationController class - animation library - Dart API
- アニメーションの時間経過をコントロールするクラス
- Tween class - animation library - Dart API
- 実際のアニメーション
- TickerFuture class - scheduler library - Dart API
- 進行中のアニメーションのTicker
import'package:flutter/material.dart'; import'package:flutter_hooks/flutter_hooks.dart'; import'package:hooks_riverpod/hooks_riverpod.dart'; classGameButtonWrapperextendsHookConsumerWidget { constGameButtonWrapper({ super.key, requiredthis.child, requiredthis.onPressed, }); // ボタンのWidgetfinalWidget child; // クリック時の処理finalFunction()? onPressed; @overrideWidgetbuild(BuildContext context, WidgetRef ref) { TickerFuture? downTicker; // AnimationControllerの準備final animController = useAnimationController( duration:constDuration(milliseconds:100), ); // Tweenアニメーションの準備final pressAnim = Tween<double>(begin:0.0, end:1.0).animate( CurvedAnimation(parent: animController, curve:Curves.easeInOut), ); // RepaintBoundaryで再描画範囲を制限returnRepaintBoundary( child:GestureDetector( // tap downしたときにアニメーションを開始// 実行中のTickerFutureを保持しておく// onPressedはまだ呼ばない onTapDown: (_) { if (onPressed ==null) return; downTicker = animController.animateTo(1.0); }, // tap upしたときに、// tap downのアニメーションが終了するまで待って、// アニメーションを逆再生し、// 逆再生が終わったら、onPressedを呼ぶ onTapUp: (_) { if (onPressed ==null) return; downTicker?.whenComplete(() { animController.animateTo(0.0).whenCompleteOrCancel(() { onPressed?.call(); }); }); }, // キャンセルされたときは、resetする onTapCancel: () { if (onPressed ==null) return; animController.reset(); }, // 実際のアニメーションするWidget部分 child:AnimatedBuilder( animation: pressAnim, builder: (context, child) { // Transform.translateを使って、// 経過時間分、下にずらすreturnTransform.translate( offset:Offset(0.0, pressAnim.value *10), child: child, ); }, child: child, ), ), ); } }
AnimatedBuilder
やAnimationController
の例はあるけど、
それだけだと、いい感じにクリック動作(onPressed
)が実行されない...
TickerFuture
を使って、アニメーションを待つのがポイントっぽい
downTicker?.whenComplete(() { animController.animateTo(0.0).whenCompleteOrCancel(() { onPressed?.call(); }); });
以上!! Flutterでもゲームっぽくできるようになったぞ(*´ω`*)