1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PlayCanvasでスプライトアニメーション作成、そしてアニメーションからイベント発火

Last updated at Posted at 2020-03-26

最初に

昔作ったゲームをブラウザゲームとして作り直そうと思っていて、

kuchiinu_a_attack03.png

こんなアニメーションをする画像をPlayCanvas上で使えるようにしたいなと考えています。

ちなみに以前作った環境ではメインループの中に入力も当たり判定も描画もぶっ込んでいるような、パワータイプなプログラムを書いていました。

今回はGUI環境に合わせてプログラムしていきたいと思います。

アセットへスプライトの原料をアップロード

画像は透過PNGで行きます。
スクリーンショット 2020-03-26 1.20.23.png

透過PNGってゲーム作るとき便利よね・・・
256色ビットマップしかゲームプログラムで使える選択肢がなくて、256色の中から透過色を一つ選ばねばならなかった頃が懐かしい・・・

テクスチャーアトラスを作成

アップした画像で右クリックして「Create Texture Atlas」を選択
スクリーンショット 2020-03-26 1.20.59.png

もとの画像はtypeが「texture」ですが、
スクリーンショット 2020-03-26 1.21.20.png

新しく生成した方はtypeが「textureatlas」となっていて、アイコンが左上にあります。
スクリーンショット 2020-03-26 1.21.30.png

もとの画像の方はもう不要なので削除しても構いません。

テクスチャアトラスをフレーム分けする

作成したテクスチャアトラスをダブルクリックするとスプライトエディタが開きます。
スクリーンショット 2020-03-26 1.23.11.png

この画像をスプライトアニメーションのコマとなるフレームに分けていきます。

スクリーンショット 2020-03-26 1.23.33.png

本来はマウスドラッグで1個1個作っていくのですが、とっっっても面倒くさいのでここで手品を使います。
(同じ大きさの矩形がお行儀よく並んでいること前提なのですが)

以下のJSONファイルを「UPLOAD TEXTURE PACKER JSON」というボタンからアップロードしてください。

spritesheet.json
{
	"frames": {
		"rei_00": {
			"frame": {"x": 0,"y": 0,"w": 256,"h": 256}
		},
		"rei_01": {
			"frame": {"x": 256,"y": 0,"w": 256,"h": 256}
		},
		"rei_02": {
			"frame": {"x": 512,"y": 0,"w": 256,"h": 256}
		},
		"down_00": {
			"frame": {"x": 0,"y": 256,"w": 256,"h": 256}
		},
		"down_01": {
			"frame": {"x": 256,"y": 256,"w": 256,"h": 256}
		},
		"down_02": {
			"frame": {"x": 512,"y": 256,"w": 256,"h": 256}
		},
		"down_03": {
			"frame": {"x": 768,"y": 256,"w": 256,"h": 256}
		},
		"a_stand_00": {
			"frame": {"x": 0,"y": 512,"w": 256,"h": 256}
		},
		"a_front_00": {
			"frame": {"x": 256,"y": 512,"w": 256,"h": 256}
		},
		"a_back_00": {
			"frame": {"x": 512,"y": 512,"w": 256,"h": 256}
		},
		"a_parry_00": {
			"frame": {"x": 0,"y": 768,"w": 256,"h": 256}
		},
		"a_parry_01": {
			"frame": {"x": 256,"y": 768,"w": 256,"h": 256}
		},
		"a_receive_00": {
			"frame": {"x": 512,"y": 768,"w": 256,"h": 256}
		},
		"a_receive_01": {
			"frame": {"x": 768,"y": 768,"w": 256,"h": 256}
		},
		"a_attack_x00": {
			"frame": {"x": 0,"y": 1024,"w": 256,"h": 256}
		},
		"a_attack_x01": {
			"frame": {"x": 256,"y": 1024,"w": 256,"h": 256}
		},
		"a_attack_x02": {
			"frame": {"x": 512,"y": 1024,"w": 256,"h": 256}
		},
		"a_attack_y00": {
			"frame": {"x": 0,"y": 1280,"w": 256,"h": 256}
		},
		"a_attack_y01": {
			"frame": {"x": 256,"y": 1280,"w": 256,"h": 256}
		},
		"a_attack_y02": {
			"frame": {"x": 512,"y": 1280,"w": 256,"h": 256}
		},
		"a_attack_z00": {
			"frame": {"x": 0,"y": 1536,"w": 256,"h": 256}
		},
		"a_attack_z01": {
			"frame": {"x": 256,"y": 1536,"w": 256,"h": 256}
		},
		"a_attack_z02": {
			"frame": {"x": 512,"y": 1536,"w": 256,"h": 256}
		},
		"b_stand_00": {
			"frame": {"x": 0,"y": 1792,"w": 256,"h": 256}
		},
		"b_front_00": {
			"frame": {"x": 256,"y": 1792,"w": 256,"h": 256}
		},
		"b_back_00": {
			"frame": {"x": 512,"y": 1792,"w": 256,"h": 256}
		},
		"b_parry_00": {
			"frame": {"x": 0,"y": 2048,"w": 256,"h": 256}
		},
		"b_parry_01": {
			"frame": {"x": 256,"y": 2048,"w": 256,"h": 256}
		},
		"b_receive_00": {
			"frame": {"x": 512,"y": 2048,"w": 256,"h": 256}
		},
		"b_receive_01": {
			"frame": {"x": 768,"y": 2048,"w": 256,"h": 256}
		},
		"b_attack_x00": {
			"frame": {"x": 0,"y": 2304,"w": 256,"h": 256}
		},
		"b_attack_x01": {
			"frame": {"x": 256,"y": 2304,"w": 256,"h": 256}
		},
		"b_attack_x02": {
			"frame": {"x": 512,"y": 2304,"w": 256,"h": 256}
		},
		"b_attack_y00": {
			"frame": {"x": 0,"y": 2560,"w": 256,"h": 256}
		},
		"b_attack_y01": {
			"frame": {"x": 256,"y": 2560,"w": 256,"h": 256}
		},
		"b_attack_y02": {
			"frame": {"x": 512,"y": 2560,"w": 256,"h": 256}
		},
		"b_attack_z00": {
			"frame": {"x": 0,"y": 2816,"w": 256,"h": 256}
		},
		"b_attack_z01": {
			"frame": {"x": 256,"y": 2816,"w": 256,"h": 256}
		},
		"b_attack_z02": {
			"frame": {"x": 512,"y": 2816,"w": 256,"h": 256}
		}
	},
	"meta": {
		"app": "",
		"version": "1.0",
		"image": "nuemaru.png",
		"format": "RGBA8888",
		"size": {"w": 1024,"h": 4096},
		"scale": "1"
	}
}

スクリーンショット 2020-03-26 2.03.59.png

JSONをアップロードすると自動で256×256のフレームに切り分けられます。
スクリーンショット 2020-03-26 15.09.08.png

使ったJSONファイルは1024×4096サイズの画像を256×256のフレームを切り分けるように記述してあります。
使う際は書き換えてください。

スプライトを作る

前項のフレーム分けでできたrei_00,rei_01,rei_02をつなげてスプライトをつくります。

一番最初にくるフレームを選択して「NEW SPRITE FROM SELECTION」をクリック。
スクリーンショット 2020-03-26 15.16.32.png

「SPRITE ASSETS」に「rei_00」というスプライトが作成されます。
続けてフレームを追加する場合は「ADD FRAMES TO SPRITE ASSET」をクリック。
スクリーンショット 2020-03-26 15.19.44.png

追加したいフレームを選択して「ADD SELECTED FRAMES」をクリック。
スクリーンショット 2020-03-26 15.24.49.png

追加完了。
スクリーンショット 2020-03-26 15.25.02.png

スプライトアニメーションの土台を作る

Root直下で「Animated Sprite」のエンティティを追加します。
スクリーンショット 2020-03-26 1.19.30.png

スプライトをエンティティにセットする。

スクリーンショット 2020-03-26 15.34.29.png

これでLaunchするとアニメーションしているのが確認できます。

スプライトからイベントを発火してみる。

ここまでくると攻撃などのアニメーション開始時に移動や攻撃判定などの処理を追加したくなるはずです。

ちょっとだけ試してみましょう。

AnimatedSpriteにスクリプトを追加し、以下のコードを追加します。

CtrlPlayer.prototype.initialize = function() {

/* 中略 */

this.entity.sprite.clip("Clip 1").on("loop",this.looploop);

}

CtrlPlayer.prototype.looploop = function(){
    console.log("looploop");
    return;
};

これで"Clip 1"のスプライトがループするときにイベントが起きるようになるので、イベントハンドラ内に移動なり当たり判定を発生させるなり煮るなり焼くなり好きにできるようになります。

他のスプライトアニメーションにイベントハンドラをセットしたい場合は、clipメソッドの引数を別のスプライトアニメーションの名前に変えてみましょう。

pc.SpriteAnimationClipの説明によるとイベントは繰り返し発生時のloop以外にも

  • end
  • pause
  • play
  • resume
  • stop

があります。

わがままを言えば、各アニメーションのフレームが変わる時・・・例えば4フレーム目だけで起こすイベントなんかを設定できたらいいんだけどなあーと思っています。(こういうのは自分で作るべき?)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?