キャラクターが歩くアニメーション

キー入力に合わせて、キャラクターがアニメーションする仕組みを作ってみます。動きが加わると、楽しさが段違いです。

キャラクターを移動させる際、アニメーションがあると楽しさが一段と増します

今回は、歩行アニメーションの基本的な実装方法の一例を紹介します。

サンプルcart

歩行アニメーションサンプルcart

この画像(character_anime.p8.png)をPCにダウンロードして、PICO-8で開いてください。

このcartには以下のデータが含まれています:

  • サンプルコード
  • 8×8ピクセルのアニメーションスプライト(上下左右それぞれ3枚ずつ計9枚)
  • モンスターのアニメーション(上下横各2枚ずつ計6枚)

歩くアニメーションであれば、通常は3枚もあれば動きとしては十分だと思います。
2枚でも、問題なく動いているようには見えるはずです。

アニメーション作成のコツ

  • キャラクターの頭の位置を固定しない(上下に揺らすなど)
  • 「ゆれもの」を用意する(髪、リボン、服、腕、足など動いてみえるもの)
  • ゆれもののドットが、前後のフレームと同じ位置にならないよう工夫する

個人的には、このような点に気をつけています。
絵が小さいほど、動きはダイナミックにしないと上手く動いて見えません。

サンプルコード

function _init()
	counter=0-- カウンター。1フレームごとに増やしていく
	x,y=58,58-- キャラクターの初期位置
	dx,dy=0,0-- 移動差分
	f=false-- スプライトを反転するかどうか(左右に同じ絵を使うため)
	spr_num={1,2,3,2}-- スプライトの番号(テーブルで設定)
end

function _update()
	dx,dy=0,0-- 加速していかないよう、移動差分を一旦0にする
 if btn(0) then
 	dx-=2
 	f=true-- 左に移動する際、キャラクターの絵が右向きなので反転する
 	spr_num={1,2,3,2}-- 横移動の時のスプライト番号
 end
 if btn(1) then
 	dx+=2
 	f=false-- 右に移動する際、絵が反転しないようにする
 	spr_num={1,2,3,2}}-- 横移動の時のスプライト番号
 end
 if btn(2) then
 	dy-=2
 	spr_num={7,8,9,8}}-- 上移動の時のスプライト番号
 end
 if btn(3) then
 	dy+=2
 	spr_num={4,5,6,5}}-- 下移動の時のスプライト番号
 end
 
 if dx!=0 or dy!=0 then
 	counter+=0.5-- カウンターの数字を増やす。大きくすれば絵の切り替えがが速くなる
 end

 -- キャラの座標を変える
 x+=dx
 y+=dy
end

function _draw()
	cls()
	local idx=flr(counter%4)+1-- 何コマ目の絵を出すかを算出する
	print(idx,0,0)
	spr(spr_num[idx],x,y,1,1,f)-- spr_numのテーブルのidx番目の絵を出す
end

サンプルコードの解説

アニメーション用のスプライトをテーブルに定義する

spr_num={4,5,6,5}

{}はテーブル(いわゆる配列)で、複数のデータを一塊にして取り扱うことができます。
このテーブルを使って、アニメーションで使用するスプライトの番号を、向きごとに一塊のデータとして定義しています。

上記の場合、spr_numには、4、5、6、5という数字がセットで入っており、spr_num[インデックス番号]という形で、中のデータを取り出すことができます。

spr_num[1]とすると1番目の4を、spr_num[4]とすると二つ目の5が取り出せます。
インデックス番号は整数で、1から始まります(0スタートではありません)。

スプライトの番号を切り替える(%を使って「余り」を計算する)

local idx=flr(counter%4)+1

local は、その関数内でのみ使える変数(ローカル変数)を定義するものです。
xやyはlocalをつけずに定義しているのでプログラム全体から参照できますが、このidxは、localがついているので、_draw()の中でしか使えません。

counter%4 が今回最も重要な式です。
%は「剰余(余り)演算子」といい、割り算をした余りを出す演算子です。

_update()のなかで、counterは、毎フレーム0.5ずつ増えていきますが、counter%4を通すと、

counter=0  のとき→ 0
counter=0.5 のとき→ 0.5
counter=1  のとき→ 1
counter=1.5 のとき→ 1.5
counter=2  のとき→ 2
counter=2.5 のとき→ 2.5
counter=3  のとき→ 3
counter=3.5 のとき→ 3.5
counter=4  のとき→ 0
counter=4.5 のとき→ 0.5
counter=5  のとき→ 1

となります。
counterを4で割った余りなので、出てくる答えはかならず4未満になることがわかりますでしょうか。
つまり、0〜4未満を延々とループする値を得ることができるのです。
この数字を使えば、先ほどのスプライト番号のテーブルから、任意のタイミングで順に数字を取り出すことができます。

テーブルのインデックスとして使うには整数である必要があるため、flr()で小数点を切り捨てています。
また、インデックスは1から始まるので、+1をしています。

まとめ

  • テーブルと余剰演算子でループするアニメーションが作れる
  • 小さいスプライトでも、動きをダイナミックにすれば表情が豊かになる
  • どんどん動かして楽しもう!