虎の穴開発室ブログ

虎の穴ラボ株式会社所属のエンジニアが書く技術ブログです

MENU

Tween24.jsでアニメーションを実装してみたので解説 #虎の穴ラボ Advent Calendar 2023

  • 本記事は 虎の穴ラボ 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が充実している。エディタ上でメソッドの使い方を確認できる。

ics.media

インストール

$ npm install tween24

github.com

使い方はシンプルでTween24.tween(対象, 秒数, イージング).プロパティ...のように指定します。

例えば、1秒かけてx座標860に移動するアニメーションは下記の通りです。

Tween24.tween(target, 1).x(860).play();

メイドちゃんのジャンプ

さっそく、垂直に動くアニメーションを実装してみましょう!

必要な処理に分解すると下記の4つです。

  1. アニメーション開始時に「ジャンプ中」に状態更新
  2. 上に動くアニメーション
  3. 下に動くアニメーション
  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つです。

  1. 左に動くアニメーション
  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を用いることで、直感的にアニメーションを記述することができました! 本記事で触れた機能はほんの一部で、イージングの調整やループ処理など、アニメーションをより魅力的にするための機能が豊富に用意されています。 気になった方はぜひドキュメントを見てみてください!

参考

ics.media

ics.media

Fantia開発採用情報

虎の穴ラボでは現在、一緒にFantiaを開発していく仲間を積極募集中です!
多くのユーザーに使っていただけるtoCサービスの開発をやってみたい方は、ぜひ弊社の採用情報をご覧ください。
toranoana-lab.co.jp