スクラッチで正確にピタッと着地できるジャンプを作る【ピタッとジャンプ】

基本きほん情報じょうほう

紹介日
2022.9.9

ジャンプはカンタンに作ることもできれば、複雑に作ることもできます。

簡単に作ったジャンプは着地したタイミングで足が地面にめりこんでしまったり、わずかに足が浮いた状態で止まってしまったり、微妙なバグが発生する余地があります。

そこでここでは、ちょこっと難しいジャンプを作って正確な着地ができる方法をご紹介します。

ジャンプの基本を作る

ジャンプは変数で高さを管理します。Y座標をダイレクトに使わない点がポイントです。

変数「スピードY」を作る

X軸のときと同じように変数でスピードを管理していきます。スピードYという変数を作ってください。

Y座標に変数「スピードY」を加算し続けます

緑の旗を押したらY座標にもスピードYを加算し続けるようにブロックを組んでください。

上を押したら変数「スピードY」に加算する

上キーを押したらスピードYを一定の数値にセットします。ひとまず10にしておきます。

変数「★重力」を追加する

これだけでは上を押したらプレイヤーがずっと上に浮いている状態が続いてしまうので、プレイヤーを下に落下させる処理を追加します。

ここでは重力という変数を作り、常にプレイヤーを下に引っ張る力を加えます。

スクラッチで正確にピタッと着地できるジャンプを作る【ピタッとジャンプ】を語るok-scratch ok-scratch

僕の場合は、「すべてのスプライト用」変数には必ず★を付けておきます。今回はスプライトは1つだから別に気にしなくてもいいのですが、重力は他のスプライトでも使う事が多いので。

初期化する

マイナス1になるように初期化してください。

プレイヤーを重力で落とし続ける

変数「スピードY」を変数「★重力」で変え続けます。こうすることでプレイヤーは常に重力の影響を受けることになります。

テストすると↓みたいな感じになっているかなと思います。(地面にめりこんでます)

上キーを押すと変数「スピードY」は10になりますよね。それが「ずっと」ループの中で変数「★重力」(ー1)されつつY座標にも加えられます。ちょっと計算してみましょう。

前提として、分かりやすさのためにプレイヤーのY座標は0から始まると仮定します。

  1. 上キーを押して、スピードYが10になる。
  2. ループ1回目:スピードY(10)を★重力(−1)ずつ変える=9 → 次にY座標をスピードY(9)ずつ変える=プレイヤーのY座標は9になる。
  3. ループ2回目:スピードY(9)を★重力(−1)ずつ変える=8 → 次にY座標をスピードY(8)ずつ変える=プレイヤーのY座標は17になる。
  4. ループ3回目:スピードY(8)を★重力(−1)ずつ変える=7 → 次にY座標をスピードY(7)ずつ変える=プレイヤーのY座標は24になる。
  5. ……
  6. ループ12回目:スピードY(0)を★重力(−1)ずつ変える=−1 → 次にY座標をスピードY(−1)ずつ変える=プレイヤーのY座標は44になる。
  7. ループ13回目:スピードY(−1)を★重力(−1)ずつ変える=−2 → 次にY座標をスピードY(−2)ずつ変える=プレイヤーのY座標は42になる。

このように最初はY座標がプラス方向に上がっていって、スピードYがマイナスに転じたタイミングで今度はY座標がマイナス方向に下がっていくような挙動になります。

着地できるようにする

動かしてみると、プレイヤーが画面の下まで落ちてしまいましたね。ずっと重力の影響を受けているので、際限なく下に移動してしまうのです。

そこで、「もし」ブロックを使ってプレイヤーが着地できるようにしましょう。

これには調べるブロックの1つである「○に触れた」ブロックが有効です。画面端に触れたら変数「スピードY」をゼロにして、これ以上の落下を止めます。

しかし、こうすると動かなくなってしまいますよね。

初期位置を指定する

これで緑の旗を押したら上から地面まで落ちて着地する動きになりました。でもまだ動きませんね。

着地判定に条件をつける

まずは動かなくなってしまう問題にタックルします。

動かなくなった原因は、地面に触れている間はずっと変数「スピードY」がゼロに固定されてしまうので、落下したタイミングだけではなく、そのあともずっと変数「スピードY」がゼロから変わらなくなってしまうからです。

そこで、さらに条件を追加します。

変数「スピードY」がゼロよりも大きいときだけ、この着地判定が行われるようにします。こうすることで、着地したあとにまた上キーを押せば、変数「スピードY」は10に戻ることができます。

ブロック定義に処理を移す

すこしループ内が混雑してきたので、このタイミングで今までの処理をブロック定義に変えておきます。オプションの「画面を再描画せずに実行する」にチェックをお忘れなく。

スクラッチで正確にピタッと着地できるジャンプを作る【ピタッとジャンプ】を語るok-scratch ok-scratch

あとからでも変更できるので、完成したら付けたり外したりして処理の違いを見ても面白いかも知れません。

ブロック定義に移し終わったら、動作確認をしてとりあえずここまでの動きが壊れていないか確認しましょう。

これで再びジャンプができるようになったと思います!

でもまだまだです。↓を見てください。

毎回着地するY座標が違いますよね。これはたまに地面に埋まったり空中に浮いてしまったりしていることを意味します。

このくらいOK?そうですね、とくに気にしなくてもいいケースも十分あると思います。ただ今回はもっと正確な着地を実現していきたいと思います。

地面に触れているかどうかを1座標ずつ調べる

ここからは、着地時にプレイヤーが地面に埋まってしまう、または地面から少し浮いている問題にタックルしていきます。

様々な方法がありますが、プレイヤーが次に移動する位置に地面があるかどうかを1座標ずつチェックしていく作戦でいきます。

Y座標を−1ずつ変えるように微調整する

きっと猫がズブズブ地面に沈んでいってしまうと思いますが、とりあえずOKです。

変数「直前のY座標」を作る

Y座標を-1してプレイヤーがステージに触れているか調べて、触れていたら移動を中断するために直前のY座標に戻したいと思います。

そこで、チェック前のY座標を変数「直前のY座標」に預けておきます。

変数「直前のY座標」のおかげで、Y座標を-1する処理を何回繰り返しても、カンタンにY座標を元に戻せます。

変数「直前のY座標」を初期化する

処理の直前にY座標の値で初期化します。

画面端に触れたら元に戻す

画面端に触れたタイミングで、直前のY座標に戻します。こうすることで地面に触れた瞬間に落下が止まります。

しかし、これだと再びジャンプができなくなってしまいます

なぜなら、「もし」ブロックのせいで変数「スピードY」がゼロより大きくなる前にプレイヤーのY座標を-1して画面端に触れたか判定するので、必ず画面端に触れている判定になってしまうからです。

これを改善するには2ステップ必要です。見ていきましょう。

スクラッチで正確にピタッと着地できるジャンプを作る【ピタッとジャンプ】を語るok-scratch ok-scratch

この段階では初期位置が高すぎると、ゆーーーっくり下降していく動きになっていると思うので、初期位置は低めにしておくといいでしょう。-100とか。

変数「スピードY」がゼロなら、という条件をやめる

原因の1つである「もし」ブロックを除去します。

進行方向の1つ先にある座標をチェックするよう変える

いまは「Y座標を-1ずつ変える」と直接入力しているので、これでは必ず下方向しかチェックしません。しかしジャンプするときは上方向に向かっているので、下をチェックする必要はなく、むしろ邪魔です。

そこで上に向かうときはY座標をプラス1して、下に向かうときはY座標をマイナス1したいと思います。

それには絶対値が有効です。

この式はどうなっているのでしょうか。

たとえば変数「スピードY」の値が10だったとします。これは上に向かっているときの値ですね。プラス10の絶対値は10なので、このときの式は「10 ÷ 10」つまり1です。

そして変数「スピードY」の値が-5だったとします。これは下に向かっているときの値です。マイナス5の絶対値は5なので、このときの式は「-5 ÷ 5」つまりマイナス1となります。

これにより上に向かうときはプラス1、下に向かうときはマイナス1という要件を実現できました。

しかし、動きを試してみるとジャンプが小さくなってしまっていませんか?それに上キーをずっと押していたらやっぱり空中浮遊してしまいます。どうやらまだまだ改善しないといけないようですね。

判定処理を繰り返す

ジャンプが小さくなっている理由は、スピードYの値が10であろうと100であろうと、絶対値で割って1にしてしまっているので、Y座標が1ずつしか変わらないという点です。

そこで、この処理を変数「スピードY」の絶対値の分だけ繰り返します。

これでジャンプは予定通り10座標分動くようになりました。

どの高さから着地してもY座標がおなじになりました。ピタッと着地を実現できました!一歩進んだクオリティにたどり着きましたね。

上手く動かないひとは「○回繰り返す」ブロックに変数「スピードY」の絶対値が入っているかチェックしてください。

空中ジャンプをできなくする

さて、ジャンプはいい感じになってきましたが、ジャンプ中に上キーを押すと好きなだけ空中ジャンプができてしまうのが現状です。

これはこれで面白い発想に繋がりそうですが、ここでは空中ジャンプは禁止したい思います。

考え方としては、空中にいるかどうかを判定して、空中にいたら上キーを押しても効かなくするという感じです。

変数「滞空時間」を作る

空中にいるかどうかを判定するために、滞空時間という変数を作ります。

  • 「○かどうか」 「○かどうか」

    「○かどうか」を判定するときは、よく0か1が入る変数を用意するのが一般的ですが、ここでは別の作戦でいきます。

加算し続ける

滞空時間に1を加算し続けるようにします。

着地したら滞空時間をゼロにする

上キーの条件に滞空時間を使う

滞空時間が3未満のときだけ変数「スピードY」が10になるように調整します。

この3という数値は感覚的なものですから、自分で動きを確かめながらどのくらいの数値が良いか見定めてもOKです。

完成すると↓このようになります!上キーを押しっぱなしにしても滞空時間が3未満であればジャンプが1度に制限されました。そうでないときはまだ二段ジャンプになるので、もっと値を調整してみてもいいかもしれません。

スクラッチで正確にピタッと着地できるジャンプを作る【ピタッとジャンプ】を語るok-scratch ok-scratch

3ではなく10とか大きい数字にするとジャンプのタイミングによっては多段ジャンプができる仕様も作れます。

紹介日
2022.9.9