3.当たり判定とアニメーション - Youtube:グリフパッチのプラットフォーマー開発チュートリアルをやってみた
2022-7-06
この記事は、griffpatchさんが公開しているYoutube動画Code a Platformer Gameを見ながら、実際にプラットフォーマーゲームを作ってみた記録です。
今回は、3. Hitboxes & Animationをやってみました。
- Code a Platformer Game | 3. Hitboxes & Animation - YouTube
https://www.youtube.com/watch?v=Y6jnwkwLhto
ここでは、今まで四角だったプレイヤーをスクラッチキャットに改良します。もちろんキャラクターのアニメーション付き。そのための当たり判定も作ります。
- Part3で作成したプロジェクト
https://scratch.mit.edu/projects/709557466/
※ゲームなどで、プレイヤーと敵や障害物が衝突したときの処理を「当たり判定」と呼びます。Scratchでは「xxxと触れたとき」などで実現できます。griffpatchさんの動画では、当たり判定を検出する領域をHitBox(ヒットボックス)と呼んでいます。
準備
前回のプロジェクトを開きます。
そして「ファイル」>「コピーを保存」しておきます。動画ではエピソード3(ep3)という名前を付けています。
※第1回で、griffpatchさんの元になるプロジェクトをリミックしました。このプロジェクトは、スクラッチキャットがアニメーションするコスチュームを持っています。今回、このスクラッチキャットのコスチュームを使います。
※ゼロからプロジェクトを作っていた場合は、スクラッチキャットのコスチュームがない状態でしょう。そんなときバックパックを使うと、プロジェクトの間でコスチュームをコピーできます。
0:47 Why we need Hitboxes:なぜ、ヒットボックスが必要なのか
まずは、スクラッチキャットのコスチュームを変更して、どうしてヒットボックスが必要なのか調べてみましょう。
スクラッチキャットのコスチュームを変更する
最初に四角いプレイヤーを28番目のコスチュームに置き換えます。28番目のコスチュームは「stand」という名前のとおり、スクラッチキャットが立っています。
この「stand」コスチュームを選択すると、立ちポーズのスクラッチキャットで遊ぶことができます。
※まだアニメーションはありません。
このとき、スクラッチキャットをキャンバスの中央に配置するよう注意しましょう。
ただ、スクラッチキャットが大きすぎて、これでは自由に動けません。そこでコードエディタで「JUMP FORCE」変数の初期値を「12」から「18」に変更します。
これで、高くジャンプできるようになりました。
ヒットボックスがないと、全体で当たり判定する
じつは、この状態だとスクラッチキャットのヒゲを土台にひっかけられます。スクラッチキャットの全体で、触れているか検出しているからです。四角いプレイヤーなら、飛び出しているところがないので、こんなことは起こりません。
これでは不自然なので、ヒットボックスを使います。
ためしに、スクラッチキャットの背景に四角を描いてみましょう。
- 「stand」コスチュームを右クリック >「複製」
- コピーしたスクラッチキャット全体を選択して、「グループ化」ボタンをクリック
- スクラッチキャットが飛び出さないように四角を描き、「背面」ボタンをクリック
こうすると、スクラッチキャットが背面の四角で当たり判定していることがよく分かります。
4:24 Red when Stuck:引っ掛かった時に赤くする
こういう大きな四角形を使っていると、ステージ間を移動したとき引っ掛って動けなくなる場合があります。デバッグ用に、それを検出できるようにします。
そのために、後ろを四角形にしたスクラッチキャットのコスチュームを「BIG Hitbox」に変えておきます。
それから、Playerの「"Tick - Player"を受け取った時」に「背景を****にする」を配置します。指定する背景に「Levelに触れたら」を設定します。
この「Levelに触れたら」は、実際にPlayerがLevelに触れていた場合に「true」を返し、触れていない場合に「false」を返します。
※これは、「Levelに触れたら」を変数に代入すると確認できます。
そこで、ステージの背景に二つのコスチュームを作り、「false」と「true」という名前にします!
※これはちょっとすごいテクニックです!こうすると「Levelに触れたら」が「true」を返したとき、それが背景のコスチューム名になるんです。
スクラッチキャットを土台の上にドラッグで移動させると、背景が赤色に変わることが分かります。
6:22 Sprite Rotation Style:スプライトの回転方法
これまでの四角いプレイヤーは、とてもシンプルなデザインです。四角なので、右方向でも左方向でもコスチュームの向きを変えずに済みます。
しかし、スクラッチキャットをアニメーションさせると、回転について考える必要があります。
スプライトの「向き」の入力欄をクリックすると、方向を指定できます。このとき次の3種類の回転方法を選択できます。
- 自由に回転
- 左右のみ
- 回転しない
スプライトキャットを左右に歩かせるとき「左右のみ」を選択しておけば良さそうですが、ここでひとつ問題があります。壁の近くで左右反転すると、壁に食い込んでしまう場合があるのです。
そこで、ヒットボックスを使うときは「回転しない」を設定します。
8:51 Time to hide the hitbox:ヒットボックスを隠そう
これをゲームにまとめてみましょう。
「Game Loopを受け取ったとき」の「ずっと」に「Tick - First」を追加します。これは、ゲームループの各フレームで最初に処理します。
「Tick - Firstを付け取ったとき」では、「コスチュームを"BIG Hitbox"にする」とします。その下に「回転方法を"回転しない"にする」を配置します。
それから「Tick - Player」では、コスチュームを実際のスクラッチキャットに戻さなければなりません。そこで「Tick - Playerを受け取ったとき」の一番最後に、この処理を追加します。
そのために、新しく「Set Costume」を定義します。これは「画面を再描画せずに実行する」をオンにします。そして、「Tick - Playerを受け取ったとき」の一番最後に呼び出します。
「Set Costume」の定義ブロックでは、「回転方向を"左右のみ"にする」とします。その後「コスチュームを"stand"にします」
ここには、あとで戻ってきてプレイヤーのアニメーションを追加します。
動作確認すると、見た目はスクラッチキャットの「stand」コスチュームになっていますが、BIG Hitboxを当たり判定に使っています。もう、ヒゲは土台にひっかかりません。
問題点があるとすると、BIG Hitboxが大きすぎて空中を歩けてしまうことです。これは、「Tick - Player」から「Set Costume」を外すと分かります。
11:28 Better Hitbox:よりよいヒットボックス
そこで「BIG Hitbox」のサイズを調整します。横幅をスクラッチキャットの足に合わせて、上と下の位置も調整します。そのあとで、「BIG Hitbox」からスクラッチキャット自体を削除します。
動作確認すると、ヒゲで土台に引っ掛かることはなくなりました。ヒットボックスの位置まで、横からカベに食い込んだり、下から土台に頭をぶつけるようになります。
そこで、griffpatchさんがあらかじめ用意しておいた「hitbox」というコスチュームを使います。ほかにもいくつかヒットボックスがありますが、それは別のエピソードで使います。「BIG Hitbox」は削除してしまいましょう。
それから「Tick - Firstを受け取ったとき」で「コスチュームを"hitbox"にする」とします。
13:47 Left and Right:左と右
このままでは、左側に進むときも右方向を向いたままなので、スプライトの向きを指定しましょう。
「Controls - Left and Right」で、「左向き矢印キーが押されたら」に「-90度に向ける」を追加し、「右向き矢印キーが押されたら」に「90度に向ける」を追加します。
これで、矢印キーに合わせてスクラッチキャットの向きを変更できました。
14:35 Animating the Run Cycle:走るアニメーション
次は、スクラッチキャットに動きを付けましょう。
まず、アニメーションのコマ(frame)番号を記録するため「frame」変数を作ります。
そして「Controls - Left and Right」で、「左向き矢印キーが押されたら」に「"frame"を1ずつ変える」を追加し、「右向き矢印キーが押されたら」にも「"frame"を1ずつ変える」を追加します。
それから「Set Costume」で、アニメーションに合わせてコスチュームを変更します。スクラッチキャットのコスチュームを見ると、1から16までが走る動きになっています。16まで進むと、次は1フレーム目に戻ります。コスチューム名は「run-**」となっています。
そのために「Set Costume」で、「コスチュームを"1 + frame"にする」とします。
これでスクラッチキャットが走るようになりますが、16フレーム目を超えてもコスチュームが変わってしまいます。
そこで、「コスチュームを"1 + (frameを16で割った余り)"にする」とします。この「16で割った余り」を使うと、0から15の間で数値がループします。
実際に、自分で計算してみると分かりやすいと思います。
動作確認すると、スクラッチキャットは走る動作を繰り返しますが、frame変数は増加していきます。
16:56 Changing the Run Cycle Speed:走るサイクルのスピードを変える
では、アニメーションのスピードを調整しましょう。
動画では、いくつかの実験をしています。
まず「Set Costume」にウェイトを入れるとどうなるでしょうか。一番下に「0.1秒待つ」を配置すると、それだけでアニメ―ションはものすごく遅くなり、ヒットボックスを表示したままになります。
次は、独自に「ずっと」ループを追加してみます。繰り返すのは、「frameを1ずつ変える」と「Set Costume」、それから「0.1秒待つ」です。
「ずっと」ループをクリックすると、スクラッチキャットが走るアニメ―ションを表示します。
今度は、別の方法で実験します。「ずっと」ループで、「frameを0.25ずつ変える」として、「0.1秒待つ」を削除します。
この方法でもアニメーションが遅くなりますが、ときどき動きが不連続に見えます。
これは、frame変数に「15.5」といった小数点を持った数値を入れるからです。Scratchでコスチューム番号を指定するとき、小数点を持った数値を使うと最も近い整数として扱います。「16.5」や「16.75」を指定した場合は「17」番目のコスチュームを選択します。「17」番目のコスチュームはジャンプを表しているので、アニメーションが不連続になるんです。
これを解消するには、frame変数を16で割った余りから、小数点以下を切り下げます。
これで「ずっと」ループをクリックすると、走るアニメーションのスピードを落としたまま連続で表示します。frame変数の増加分を調整することで、アニメーションのスピードも調整できます。たとえば、「frameを2ずつ変える」とすると、2倍速になります。
実験が終わったら、「ずっと」ループは削除します。
19:32 Idle Standing Pose:止まったときは立ちポーズ
では、左右のキーを離したとき、止まって立ちポーズにしてみましょう。今のところは、キーを離すと、その時の走るポーズで止まってしまいます。
そこで、移動が終了したときにframe変数を「0」にします。
frame変数に合わせてコスチュームを変える
まず「Set Costume」に「もし**なら***でなければ」を使います。条件は「frame > 0」とします。
そして「なら」で走っているコスチュームを表示して、「でなければ」で「stand」コスチュームを表示します。
左右のキーが押されてないときを検出
次は、左右のキーが押されてないときを検出します。
そのために「KEY X」変数を作ります。これは、すべてのスプライト用にします。
そして「Controls - Left and Right」の一番上に、「KEY Xを"右向き矢印キーが押された" - "左向き矢印キーが押された"にする」とします。
)
実は「右向き矢印キーが押された」と「左向き矢印キーが押された」は、何もキーが押されてないとき「0」になり、キーが押されると「1」になります。そこで「KEY Xを"右向き矢印キーが押された" ひく "左向き矢印キーが押された"」とすると、「KEY X」変数の値は次のようになります。
- 1:右向き矢印キーが押された
- 0:どちらも押されていない
- -1:左向き矢印キーが押された
「KEY X」変数で、左右の方向を表しているんです。
※すげー!
「KEY X」変数に合わせて、プレイヤーの設定を変える
では「KEY X」変数に合わせて、プレイヤーの設定を変えましょう。
「Controls - Left and Right」の2番目の位置に「もし**なら***でなければ」を追加して、条件を「KEY X = 0」とします。
この条件が成立していたなら「frameを"0"にする」とします。
条件が成立していなければ、まず「speed xを"KEY X" * "ACCELARATION"ずつ変える」とします。それから「"KEY X" * "90"度に向ける」を配置して、その下に「frameを"1"ずつ変える」とします。
最後に、「もし**なら***でなければ」の下に、「speed xを"speed x" * "RESISTANCE"にする」を配置します。
動作確認すると、左右のキーに合わせてスクラッチキャットが走り、キーを離すと立ちポーズに変わりますね。
22:28 Things look too slippy:ちょっとすべりやすい
ただし、キーを離すと、立ちポーズのまま少しすべってから止まります。今度は、これを修正しましょう。
「Controls - Left and Right」を見ると、「speed x」変数は「ACCELARATION」ずつ小さくなっています。そのため「frame」変数を「0」にして立ちポーズになっても、「speed x」変数はすぐに「0」になりません。
そこで「KEY X が"0"なら」に、さらに「もし**なら***でなければ」を追加して、条件を「"speed xの絶対値" < 1なら」とします。絶対値は、数値がプラスでもマイナスでもプラスにしてしまう処理です。「"speed xの絶対値" < 1なら」は、「speed x」がプラスでもマイナスでも1未満ならという条件です。
そして、この条件が成立していたら、「frame」変数を「0」にして「speed x」変数も「0」にします。
まだ未完成ですが、この状態で動作確認してみましょう。キーを離したときは、走るアニメーションですべって、それから停止します。だいぶ、自然な動きになってきました。
次は、「でなければ」に「frameを"0.5"ずつ変える」を配置します。
これで、キーを離してもスピードが落ちていない間は、アニメーションが半分のスピードになります。
24:14 Animating a Jump and Fall:ジャンプと落下のアニメーション
あとは、ジャンプと落下のアニメーションの追加です。現在は、ジャンプ中も走るアニメ―ションを表示しています。
ジャンプを検出する
ジャンプ中かどうか検出するには「falling」変数が使えます。「falling」変数は、ジャンプ中は1以上になり、地面に触れたとき「0」になるんでした。
※ 詳しくは、Part1のジャンプの修正を参照してください。
そこで「Set Costume」で「回転方向を"左右のみ"にする」の下に、「もし**なら」を追加して、条件を「falling変数 > 1」とします。これでジャンプを検出できます。
そして、この条件が成立しているなら「コスチュームを"Jump01"にする」とします。
あと「このスクリプトを止める」も追加します。こうすると、この位置でスクリプトが停止して、この下の走るアニメーションや立ちポーズの処理をスキップします。
これで、ジャンプ中にジャンプのコスチュームを表示するようになりました。
落下中はコスチュームを変える
ただし、落下中も同じコスチュームを表示しているので、これを少し変えてみましょう。
コスチュームエディタを見ると「Jump01」の下に、落下中をあらわす「run_j2」というコスチュームがあります。落下中は、これを表示しましょう。
落下中かどうか検出するには「speed y」変数を使います。これは上昇中はプラスになり、落下中はマイナスになります。
そこで「Set Costume」のジャンプを検出する「もし***なら」に、さらに「もし***なら***でなければ」を追加します。そして条件を「speed y > 0」とします。
この条件が成立したなら「コスチュームを"Jump01"にする」とし、でなければ「コスチュームを"run_j2"にする」とします。
「このスクリプトを止める」は、「もし***なら***でなければ」の下に配置します。
これで、落下中のコスチュームが変わるようになりました。
26:14 Final thing to fix:最後の修正
最後に、スクラッチキャットのサイズを調整しましょう。サイズを調整したら、動作の設定値も調整します。
サイズ調整
サイズ調整では、スクラッチキャットの大きさを「40」とします。
それから「緑の旗が押されたとき」の設定値を次のように調整します。
- JUMP FORCE:12
- ACCELARATION:1.5
※ もちろん、これはあなたのステージデザインに合わせて調整してください
ステージ間の移動バグ
実は、もうひとつバグが残っています。これは、ステージ間を行ったり来たりしているとき、ごくたまに発生してステージ間でひっかかります。
前回も同じような現象を直しました。しかし、今回はコスチュームを変えただけなので、そこが関係しているはずです。
そこで、動画では「Game loopを受け取ったとき」の動きを確認しています。
「Tick - First」でPlayerのコスチュームに「hitbox」を設定します。次の「Tick -Player」でPlayerを移動して、その最後でスクラッチキャットのコスチュームに戻しています。そして「Tick - Last」で「Begin Scene」ブロックを呼び出して、ステージ間を移動したのか調べて、「Fix Collisions in Direction」で壁や土台との衝突を解消します。
このとき、前回までは四角いコスチュームを使っていましたが、現在はスクラッチキャットに変わってしまっています! これでは形状が複雑なので、衝突を十分に解消できない可能性があるんです。
この現象を回避するため、次のようにします。
「Begin Scene」ブロックの「Fix Collisions in Direction」の前で、まずコスチュームを「hitbox」に一時的に戻します。それから「回転方法を"回転しない"にする」とします。さらに「Fix Collisions in Direction」の後で「Set Costume」として、コスチュームをスクラッチキャットに戻します。
動作確認すると、もうステージ間の引っ掛かりは発生しないはずです。
これで、スクラッチキャットがアニメーションするようになりました。走ったりジャンプしたりと、動きもいきいきしていますよね。
さて、第4弾ではスロープに合わせてポーズを変える方法を解説する予定です。