1. 基本 - Youtube:グリフパッチのプラットフォーマー開発チュートリアルをやってみた
2022-6-14
この記事は、griffpatchさんが公開しているYoutube動画「Code a Platformer Game」を見ながら、実際にプラットフォーマーゲームを作ってみた記録です。
最終的に、スクラッチキャットがアニメーションしながら複数のステージをとびまわるゲームが完成するみたいです。
複数の動画がありますが、とりあえず1から3をやりました。今回は 1. The Basics をレポートします。
- Code a Platformer Game | 1. The Basics - YouTube
https://www.youtube.com/watch?v=D16hTnDGweo
プレイヤーの動きと床やカベとの当たり判定を作ります。
- Part1で作成したプロジェクト
1. 基本:グリフパッチのプラットフォーマーゲーム開発 on Scratch
https://scratch.mit.edu/projects/704219852/
griffpatch(グリフパッチ)さんは、38万人以上のフォロワーがいる人気のスクラッチャーです。たくさんの面白いプロジェクトを共有していて、その作り方をgriffpatch_tutorという別アカウントで公開しています。Youtubeのgriffpatchチャンネルで本格的なゲームの作り方とテクニックを紹介しているので見たことがある人もいるでしょう。
でも、英語の動画なのでちょっと分かりにくく感じるかも知れません。字幕を自動翻訳で日本語にできるので雰囲気はつかめますが、これだけでは不十分な人も多いかも。スクラッチのブロックも英語版です。
ということで、このチュートリアル動画を実際にやってみて、どんな説明をしているか整理してみました。
準備
最初に、元になるプロジェクトをリミックします。このプロジェクトは、スクラッチキャットがアニメーションするコスチュームを持っています。Part1とPart2では使いませんが、Part3より後でキャラクターのアニメーションに使います。
- Platforming Resources (YouTube) on Scratch
https://scratch.mit.edu/projects/560596896/
リミックスしたら、タイトル画面のスプライトは削除します。
それから、スクラッチキャットのコスチュームに、正方形のキャラクターを描きます。
正方形は、中央に配置するよう気をつけましょう。
スプライトには「Player」(プレイヤー)と名前を付けました。
2分38秒 backdrop:背景
それからステージの背景を描きます。今回は、スプライトではなくステージを使っています。
長方形を組み合わせて、こんな感じで描いています。
3分15秒 Gravity:重力
では、プレイヤーを動かします。
緑の旗で最初の位置を指定したら、「ずっと」ブロックでy座標を動かします。
でも、これだと一定のスピードでしか動きません。
そこで落下しているように見せるために、「speed y」(スピードy)という変数を作って、「ずっと」ブロックのなかで少しずつ移動する量を早くしています。下方向なのでマイナス1になっています。
ただし、このままでは地面を通り越してしまいます!
4分33秒 Ground Collisions:地面との衝突
※ このチャプターは楽しくてチョット長いです。試行錯誤を繰り返しながら作っていきます。
次の目標は、地面に着いたときに止まることです。
そこで「もし」ブロックを追加します。条件には「( )色に触れたら」ブロックを使います。このとき条件にする色として地面の色を指定します。地面の色に触れたら、とりあえず「すべてを止める」ブロックで停止します。これで、地面を検出できているか一応確認できます。
なんと・・・停止しても、まだ少し地面にくいこんでいます!!
スクラッチでは「()色に触れたら」ブロックを使ったとき、そのスプライトが相手と重なった場合に「触れた」となります。ちょうど地面に接する位置で止めたいのですが、それでは触れたことになりません。
地面に触れたら、ひとつ前に戻す
そこで地面の色に触れたら、ひとつ前の位置に戻します・・・でも、触れる前に戻るので、すき間ができてしまいます。
なので、プレイヤーが地面と衝突しなくなるまで、1ステップずつ慎重に戻す必要があります。そのために、「()まで繰り返す」ブロックを「地面の色に触れた」と「ではない」ブロックで使います。
とはいえ、これだけだと何度も地面に触れるを繰り返してしまうので、地面の色に触れなくなったら、「speed y」変数をゼロにします。
これを実行すると・・・今度は、地面に触れたとき浮き上がるところが見えてしまいます。
浮き上がるところが見えてしまう
これを修正するにはブロック定義を使います。「Fix Overlap」(重なりを直す)というブロックを定義するのですが、このとき「画面を再描画せずに実行する」をオンにしておきます。こうすると、定義したブロックの処理中の様子を再描画せずに実行するため、地面に触れたとき浮き上がるところが見えなくなります。
あとは、落下スピードを調整しやすくするため、「GRAVITY」変数を作っておきます。「GRAVITY」は重力という意味ですね。こうすると、落下スピードを変えたいとき、どこを調整すればいいかわかりやすくなります。
※ グリフパッチさんは、ほかのスプライトでも使う変数の名前を、すべて大文字にしているみたいです。「GRAVITY」変数はすべて大文字で、「speed y」変数はすべて小文字になっています。
8分46秒 Jumping:ジャンプ
次は簡単。上向き矢印キーを押したとき、プレイヤーをジャンプさせます。「もし」ブロックで、上向き矢印キーを押していたら「speed y」変数を「12」にします。
これで、上向き矢印キーを押したとき、プレイヤーがジャンプするようになりました。
ただし、上向き矢印キーを押しつづけると、ジャンプし続けてしまいます。これは後ほど直します。
9分27秒 Walking:歩く
さらに、左右の動きを加えます。
「speed x」変数を追加して、左向き矢印キーが押されたら「speed x」変数を「-1.5」ずつ変えて、右向き矢印キーが押されたら「speed x」変数を「1.5」ずつ変えます。
あとは、プレイヤーが左右に移動するよう、「x座標を"speed x"ずつ変える」ブロックを配置します。
これで、左右の向き矢印キーで横移動できましたが・・・残念ながら停止しません。ステージの端まで動き続けてしまいます。
そこで、床に抵抗を追加します。この抵抗によって「speed x」変数の値を少しずつ小さくするんです。そのために「speed x を"speed x * 0.8"にする」ブロックを追加します。
これで、左右の向き矢印キーで横移動して、キーを離すと少しすべってから停止します。ジャンプもできるので、かなりプラットフォーマーゲームらしくなってきました。
11分14秒 Rethink and Innovate!:再考と革新
でも、いろいろと問題があります。たとえば、空中の段に下から接触すると上に突き抜けてしまう、横の階段に接触すると勝手に登ってしまう、といった具合です。
一応動くようになりましたが、少し違ったやり方で物事を改善できるか試してみましょう。もっといい方法で作り直します。
ここでは、移動と衝突の処理を次のように考え直します。
これまでプレイヤーは、衝突するまで大きなステップで移動して、小さなステップで衝突から戻っていました。
その代わり、プレイヤーを動かしている間は常に小さなステップを使います。この方法なら、衝突を検出したらすぐに反応できます。
Y方向の移動と衝突処理を作り直す
それでは、Y方向の移動と衝突を置き換えるところから始めます。
「Move - in steps」というブロックを定義して、引数を「steps」とします。このブロックは「画面を再描画せずに実行する」をオンにしておきます。
そして「"steps"回繰り返す」ブロックを用意します。
このとき、最後の値を覚えておくと便利なので「last value」変数を用意します。「last value」は最後の値という意味ですね。
「"steps"回繰り返す」ブロックのなかでは、次の処理を実行します。
まず「last valueを"y座標"にする」で最後の位置を覚えておきます。
続いて「y座標を"speed y / steps"ずつ変える」で、小さく移動。
それから、地面に触れたかチェックして、触れていたら「y座標を"last value"にする」で前の位置に戻ります。あとは「speed yを"0"にする」でy方向の移動スピードをゼロにします。
「Fix Overlap」は、使わなくなったので削除します。
あとは「Move - in steps」を呼び出すところで、引き数を「100」として試してみます。
これで、Y方向の移動ができました。天井に頭をぶつけても、もう上に突き抜けません。
動作確認と調整
でも、ちょっとスピードが遅くなったような感じがします。100回繰り返すのは、多すぎるのかも。
そこで、グリフパッチさんは、引数を「speed yの絶対値」にすることをすすめています。一定間隔で動く距離がちょうど「speed y」なので、それを使うのです。ただ繰り返し回数がマイナスになっているとヘンなので、絶対値を使ってマイナスを削除します。
こんどは、滑らかな動きになりました。
左右に動いても勝手に階段を登らなくなりました。ただ、階段で止まらずにすり抜けてしまいます。
15分24秒 Horizontal Collisions:水平方向の衝突
今度は、水平方向の衝突処理を追加します。これは、Y方向の処理とよく似ています。動画では、Y方向の移動処理のブロックをいったん右に配置して、比較しながら組み立てています。
「"steps"回繰り返す」ブロックのなかでは、次の処理を実行します。
まず「last valueを"x座標"にする」。
続いて「x座標を"speed x / steps"ずつ変える」で、小さく移動。
それから、カベに触れたか色をチェックして、触れていたら「x座標を"last value"にする」で前の位置に戻ります。あとは「speed xを"0"にする」でx方向の移動スピードをゼロにします。
本当に、Y方向の処理と同じで、X方向に置き換えただけです。
これができたら、「"steps"回繰り返す」ブロックのなかで、X方向の処理の下にY方向の処理を配置します。
それから、「Move - in steps」を呼び出しているところに戻って、「x座標を"speed x"ずつ変える」を削除します。「Move - in steps」のなかで、水平方向に移動するからです。
最後に、「Move - in steps」の引数を「speed xの絶対値」+「speed yの絶対値」にしています。
これで、階段をすり抜けなくなりました!
※ この方法を引数の計算に採用した理由が分かりませんでした。もう少し厳密にやるとしたら、「speed xの絶対値」と「speed yの絶対値」の大きい方を取るような気もします。
17分14秒 Fix Jumping:ジャンプの修正
最後の問題は、ジャンプの仕方です。今のところ、上向き矢印キーの長押しで、空中を飛べてしまいます。
これを単純なジャンプに限定します。
そこで、「falling」変数を追加します。これは「落下」という意味ですね。
そして、「Move - in steps」の先頭で「fallingを"1"ずつ変える」として、地面に触れたときに「fallingを"0"にする」とします。
「falling」変数を表示しておくと、「falling」変数の動作を確認できます。着地している間「falling」変数はゼロになっています。ジャンプに合わせて「falling」変数の値が増加して、着地と同時にゼロに戻ることがわかります。
この値を使うと、地面と接触しているか簡単に判定できそうです。
上向き矢印キーを調べているところに「もし」ブロックを追加して、条件を「falling < 3」とします。
これで、連続ジャンプはできなくなりました。床のカドから飛び出しても、少しだけジャンプできます。
コヨーテジャンプ
ところで、条件を「falling < 3」としているのは、なぜでしょうか。
グリフパッチさんは、土台からはみ出したとき2フレームだけ空中を歩けるようになって、ゲーム中のイライラを和らげるのに役立つと説明しています。このテクニックをコヨーテジャンプと呼ぶそうです。
※ アメリカのアニメ「ワイリー・コヨーテとロード・ランナー」(Wile E. Coyote and the Road_Runner)にコヨーテが登場します。このアニメで、ロードランナーを追っかけるコヨーテが勢いあまって崖から飛び出しても、しばらくそれに気づかないところからコヨーテジャンプと呼ぶんじゃないかな。
- ワイリー・コヨーテとロード・ランナー - Wikipedia
- The Road Runner Show | Road Runner vs Wile E. Coyote - Full Episode | Classic Funny Cartoons - YouTube
18分37秒 Stuck to ceiling bug:天井にはりつくバグ
動作確認してみると、さらにバグが見つかることがあります。
この段階では、上矢印キーを押し続けると天井に張り付くことができます!
原因は、天井に張り付いたとき「falling」変数がゼロになって、ジャンプ可能になるからです。
こういう動きのゲームでもいいかもしれませんが、今回は修正してしまいましょう。
「fallingを"0"にする」ブロックに「もし」ブロックをかぶせて、条件を「speed y < 0」だったらとします。そして「speed yを"0"にする」ブロックと順番を入れ替えます。
「speed y < 0」だったらということは、下方向に移動つまり落下中ということですね。天井にぶつかるときは上昇中なので、そのときは「fallingを"0"にする」を実行しません。
19分32秒 Mess around with the Physics:物理パラメーターの調整
エピソード1は、これでほぼ終わりです。最後に、動きの調整について説明しています。すでにある変数や新しい変数を次のように一ヶ所にまとめています。
- GRAVITY変数(グラビティ):下方向に引き寄せられる力
「-1」から「-1.5」にすると、プレイヤーはすばやく地面に引き寄せられるが、
高くジャンプできなくなる。 - JUMP FORCE変数(ジャンプ フォース):ジャンプする力を指定する
上向き矢印キーで「speed y」を変える量に使う。
大きくすると高くジャンプするが、とりあえず「12」 - ACCELERATION変数(アクセラレーション):左右の加速しやすさを指定する
右矢印キーで「speed x」を変える量に使う。
左矢印キーのところで使う場合はマイナスにする。
デフォルトで「1.5」 - RESISTANCE変数(レジスタンス):左右の抵抗・減速しやすさを指定する
右矢印キーで「speed x」を減速させる量に使う。
デフォルトで「0.8」
こうするとパラメータの調整が一ヶ所でまとめてできるので便利です。
最初の動画は、これで終了です。
シンプルなコードですが、とりあえずプラットフォーマゲームらしくなりました。ステージを工夫すれば、これだけでもゲームになりそうです。
プラットフォーマーの開発の参考になればうれしいです。