Scratchで空中から落下したり、ジャンプするような挙動を作りたい場合には重力を表現する必要があります。
今回は重力のような動作を表現するコードの作り方について紹介していきます。
方針
まず、「重力」というともちろん重力加速度の9.8m/s^2で落下するような計算をして実装するのが正しいと思いますが、そこまでやるのも大変なため、大きく次の二つを実現することで重力を表現したいと思います。
- 上から落ちて地面についたら速度が0になり止まる
- 等速でおちるのではなく落下速度が徐々に早くなる
これだけでも重力ぽっさは出ると思います。
それでは早速試していきたいと思います。
地面を作る
ではまず最初に地面から作っていきます。今回は単純に四角形を下の方に配置して地面としたいと思います。画面右下の「スプライトを選ぶ」から「描く」を選択します。
「描く」を選ぶとコスチュームタブで図形を描くことができますので、四角形を選んで適当なサイズで作ります。
出来上がったスプライトの名前をgroundに変更しておきます。
以上で地面の準備は終了です。
落ちて止まる動作を作る
続いて、CATのスプライトが上から落下して地面で止まるというコードを作っていきます。
方法としては、プログラムをスタートすると落下位置から落ちていき、先ほど作成した地面(ground)に触れたら止まる、つまり速度が0になるというようにします。実際に作成したコードがこちらになります。
動きを確認すると次のようになります。
「上から落ちて地面についたら速度が0になり止まる」という挙動に関してはこれで実現できていることになります。y座標の変化量を調整することで早く落ちたり、遅く落ちたりすることもできます。
ただし、やはり等速で落ちているため、重力で落下しているような動きには見えないところが課題です。
落下を加速させる
こんどはより重力で落下しているような表現にするため、落下中に徐々に速度が上がっていくようなコードに改善していきたいと思います。
落下速度が上がる、つまり加速を表現するための工夫として変数を使用したいと思います。
現状は落下する速度を定数にしていますが、これを変数化し、この変数の値を徐々に変えていくことで加速を表現する方法をとります。
まず、速度を格納するための変数としてy_diffを定義します。これはとりあえず「すべてのスプライト用」でも「このスプライトのみ」で作ってもどちらでもいいです。
そして、作成した変数y_diffを使って次のようなコードに改善します。
スタートの落下位置に移動した後にy_diffの値を一旦0にします。これは初速を0にしていることに相当します。
そしてその後、地面にぶつかればy_diffを0にし、ぶつからない場合は繰り返し-2づつ変数の中の値を変更し、その値の分だけy座標を変更するようにします。
これにより落下の時間とともにyの移動距離も大きくなることが表現できます。
実際に動かしてみた様子がこちらです。
等速で落ちる場合に比べて自然に落下するようにできました。
地面に埋まってしまう問題への対処
これで、やりたいことは一通りできたのですが、落下の加速度を大きくすると繰り返しの実行周期の間に地面の中まで埋まりこんでしまう場合があることがわかりました。
例えばyの変化値を-10にした場合は地面で停止した際に以下のようにスプライトが少し埋まってしまいました。
この問題に対処するため、コードを少し改善したいと思います。
方針としては、ある地面のラインを定義しておき、そのラインより下に行ってしまった場合はラインまで戻すというプログラムにします。
まずは、地面のラインを定義する変数groundlineを定義します。
そしてプログラムをスタートした際にgroundlineで地面のラインの値を代入し、そのラインを割った場合は速度を0にし、かつgroundlineまで戻すという処理を加えます。
この方法にした場合、もはや地面用に用意した四角形のスプライトとの接触判定をしていないので、四角形が無くても落下が停止します。
ただし、見た目としては地面があった方が良いので、groundlineに合わせて地面用の四角のスプライトの位置を手動で微調整して配置します。
これで完了です。実際に動かした様子はこちらです。
これで落下速度を早くした場合でも地面に埋まらないようにできました。
まとめ
速度を徐々に早くする、地面に接触したら速度を0にして停止することで重力による落下と着地を表現することができました。また、地面のラインを変数で定義して下に行き過ぎた場合には地面のラインに戻すことで、埋まりこむことへの対処ができました。
そのほかのscratchの小技についても以下で紹介していますので参考にしていただければと思います。
コメント