- 本記事は 虎の穴ラボ Advent Calendar 2023 10日目の記事です。(予約投稿)
- 前回は よしださんの「「アジャイルプラクティスガイドブック」を読んだ感想」でした。
- 次回は tzさんの「笑って泣いて、品質改善:新規開発プロダクトのローラーコースター」です。 ご期待ください!
こんにちわ、虎の穴ラボの後藤です。
アニメーション実装に入門したいフロントエンジニアへオススメのTween24.jsを紹介します。
Tween24.jsでシンプルにアニメーションを実装!
アニメーションをコードに組み込むと手間がかかりがちで、すぐに複雑な森に迷い込んでしまいます。
しかし、Tween24.jsを使えばその悩みも解消!シンプルな文法で、アニメーションをスラスラと軽快に実装できます。
本記事では、ゲーム内で動くキャラクターをTween24.jsでどのように実装するか解説します。
作ったもの
可愛いメイドちゃんがジャンプするだけのシンプルなゲームです。
- メイドちゃんがその場でジャンプ
- 流れてくる敵をかわしてスコアを稼ぐ
メイドちゃんのジャンプや敵の動きをTween24.jsで実装しています。
使用フレームワーク・ライブラリ
小規模でサクッと作れる構成になっています
- Vite:HMRやビルドが速くてとっても快適!
- React:コンポーネントベースでUIを構築。
- TypeScript:多少雑でも入れておくとコード補完で開発効率が上がる!
- Tween24.js:今回の主役、複雑なアニメーションを直感的なコードでシンプルに記述できる!!
- Redux Toolkit:面倒な設定なしにシンプルなストアを扱える。
- Storybook:コンポーネントを個別に挙動確認できデバッグしやすい。
Tween24.jsでアニメーションを実装する
Tween24.js はアニメーションを作る時の、「動きはイメージで出来ているのに実装方法がわからない...🫠」「ライブラリの設定がわかりづらい...🫠」といった問題を解決してくれます!
- メソッドチェーンで記述する。エディタの補完機能でスラスラと記述できる。
- JSDocが充実している。エディタ上でメソッドの使い方を確認できる。
インストール
$ npm install tween24
使い方はシンプルでTween24.tween(対象, 秒数, イージング).プロパティ...
のように指定します。
例えば、1秒かけてx座標860に移動するアニメーションは下記の通りです。
Tween24.tween(target, 1).x(860).play();
メイドちゃんのジャンプ
さっそく、垂直に動くアニメーションを実装してみましょう!
必要な処理に分解すると下記の4つです。
- アニメーション開始時に「ジャンプ中」に状態更新
- 上に動くアニメーション
- 下に動くアニメーション
- アニメーション終了時に「ジャンプなし」に状態更新
上 -> 下のアニメーション順序制御や、アニメーション終了時に処理発火などは難しく見えるかもしれません。
しかし、Tween24.js には便利なメソッドが用意されています。
serial
:複数のアニメーションを連続で直列再生onComplete
:アニメーション完了時に呼び出される処理
これらを用いると、下記のようにシンプルな記述ができます!
import { Ease24, Tween24 } from 'tween24'; // 上に動くアニメーション // playerを1.0秒でy座標-100に移動 const jumpUpTween = Tween24.tween(player, 1.0, Ease24._1_SineOut).y(-100); // 下に動くアニメーション // playerを1.0秒でy座標0に移動 const jumpUpTween = Tween24.tween(player, 1.0, Ease24._1_SineIn).y(0); // 1 -> 2 でアニメーションを直列再生に設定 const tween = Tween24.serial(jumpUpTween, jumpDownTween) .onComplete(() => { // 終了時に「ジャンプなし」に状態更新 // redux-toolkitのストア更新処理 dispatch(setIsJumping(false)) }); // 「ジャンプ中」に状態更新 // redux-toolkitのストア更新処理 dispatch(setIsJumping(true)) // アニメーション発火 tween.play();
このように一見複雑なアニメーションも、メソッドチェーンでサクッと書ける点がとても魅力的です!
※ 画像の切り替えはReactコンポーネントがストア状態に応じて切り替わるよう実装しています。
敵の動き
次に、水平に動くアニメーションを実装します。
必要な処理に分解すると下記の2つです。
- 左に動くアニメーション
- アニメーション終了時に自身を削除
この処理もTween24.jsでシンプルに記述できます!
Tween24.tween(obstacle, 1.0) // obstacle を 1.0秒かけてアニメーション .x(-600) // x座標-600へ移動 .onComplete(() => { // 終了時に自身を削除 // redux-toolkitのストア更新処理 dispatch(removeObstacle(myId)); }) .play();
ゲームオーバー時にアニメーションを止める
敵にぶつかった際に、すべてのアニメーションを止めるよう実装しています。
「複数アニメーションを同じタイミングでストップさせる」という一見難しい処理ですが、 こちらも簡単に実装できるものが用意されています。
groupId
:トゥイーンのグループIDを設定stopByGroupId
:指定したグループIDのトゥイーンのstop()
を実行
したがって、メイドちゃんや敵を動かすアニメーションにグループIDを指定して、
ゲームオーバー処理内でstopByGroupId
を呼び出すことで実装できます!
// ID:group01 でグルーピング const jumpTween = Tween24.serial(jumpUpTween, jumpDownTween).groupId("group01") const moveTween = Tween24.tween(obstacle, 1.0).x(-600).groupId("group01") // redux-toolkit でのゲームオーバー処理 gameOver: (state) => { state.isGameOver = true; // ID:group01 のグループをストップ Tween24.stopByGroupId('group01'); }
まとめ
Tween24.jsを用いることで、直感的にアニメーションを記述することができました! 本記事で触れた機能はほんの一部で、イージングの調整やループ処理など、アニメーションをより魅力的にするための機能が豊富に用意されています。 気になった方はぜひドキュメントを見てみてください!
参考
Fantia開発採用情報
虎の穴ラボでは現在、一緒にFantiaを開発していく仲間を積極募集中です!
多くのユーザーに使っていただけるtoCサービスの開発をやってみたい方は、ぜひ弊社の採用情報をご覧ください。
toranoana-lab.co.jp