スクラッチに挑戦している皆さん、どうも!スクラッチコーチです。
ここからは敵モブを追加していきます!今までと違う動きをする敵モブを追加します。
そう、ジャンプする敵モブです!ギャー😫!!
ジャンプは今までと違う動きですね。
今までと違う動き、ということはスライムとゴーストで使ってた「移動する」ブロックでは要件を満たせません😥
どうすれば新しい動きを追加することができるか、それも今回のチュートリアルで見ていきましょう。違う動きを追加する手順を押さえておけば、みんなのゲームでもユニークな敵モブを追加する役に立つと思います😁
ここではパタパタを実装していきます。といってもスーパーマリオのパタパタをガッツリ真似するのではなく、今回もスクラッチが用意してくれたコスチュームを利用して、パタパタっぽい動きの敵モブを作ります。
よぉし!スクラッチオン!(←スクラッチオンって使いたいだけ😋)
仕様を決める
今回のパタパタ風の敵モブは、カエルで代用しようと思います。
完成品を見る
ジャンプの完成サンプルはこんな感じ↓
上のカエルを見ると、ピョンと一定の高さでジャンプして、しばらくしてまたピョンとしてます。空中ではジャンプしません。地面に足が着いてるときだけジャンプします。
また、ジャンプ中は上がっているときも下がっているときもX方向に進んでいます。
下のカエルを見ると、頭がブロックに当たるとジャンプが中断されている様が見て取れます。
自分のオリジナル作品を作るときは完成動画なんてないので、頭の中にある動きをなんとなく文字で書き出しておくと便利。
仕様一覧
仕様(要件とも言う)をまとめると次のようになります。
- 一定の高さでY方向に上がり、そのあとは接地するまでY方向に下がる。
- ジャンプ中は、X方向にも進む
- ジャンプは連続して行われず、一定間隔を置いて繰り返される
- ジャンプ中にブロックなど障害物に当たると、ジャンプは中断される。
- 壁にあたったら反対方向にジャンプをする
コスチュームを作る
まずは外見から作っていきます。外見が決まるとイメージが湧くので、コーディングの効率も上がります。
ではコス(コスチューム)を選んでいきましょう!
キャラを選ぶ
スプライト「敵モブ」を選択する
デフォルトのキャラを探す
コードからコスチュームのタブに切り替えて、左下にあるネコマークにマウスを持っていきます。
絞り込みする
Frog 2-aを選ぶ
コスチューム名をカエル1にカエル
草
チョウチョウを消す
カエルのコスに含まれるチョウチョウは今回使わないので、削除しちゃってOKです。
カエルの全身をグループ化する
真ん中の+に合わせる(センタリング)
グループ化してから選択ツールでドラッグすると、真ん中にある+マークにピタッとくっつきます。
このセンタリング作業を行わないと、上下の動きや回転などがおかしくなります。(今回、回転する予定はありません)
弱点コスを用意する
カエル1を複製する
コス名を「カエル_弱点」にする
グループを解除する
胴体以外を消す
ここを踏まれたらカエルはダメージを受ける。それ以外ならプレイヤーがダメージを受ける。
カエルをスポーンさせよう
引き続きスプライト「敵モブ」を使います。コスチュームからコードのタブに切り替えてください。
スポーン位置を指定する
イベント「レベルの初期化が終わりました」を受け取ったときにブロックを追加します。
スタンバイさせる
「クローンされたとき」にブロックを追加します。
ブロック定義「敵モブ_カエル」を作る
定義位置を分かりやすい場所に移動する
サンプルのプロジェクトではブロックの役割によって配置場所を変えてあります。こうすることで散乱しやすいスクラッチのコードをまとめています。
スライムの処理をコピペする
とりあえずここまでをテストしたいので、サクッとスライムのブロック定義をコピペしてしまいましょう😁
ブロック定義を使う
「クローンされたとき」で「敵モブ_カエル」を使おう。
テストする
これで動きをチェック!
問題なければ、とりまOK😁
ジャンプ処理を作ろう
いよいよジャンプです!今回の目玉。
ブロック定義「ジャンプする」を作る
定義を分かりやすい位置に移動する
今回は「移動する関連」のあたりで定義していきます。
下にブロック定義「移動する」があって、ブロックの追加がしづらいですよね。そういうときはいったん「ジャンプする」は横に置いて、できあがったらエディタの「きれいにする」機能で整列させればOKです。
使う
先にカエルのブロック定義内で使っておきましょう。これから度々テストすることになるので。
ブロック定義「移動する」の代わりに「ジャンプする」を設置しました。
テストする
この段階で緑の旗を押してみてください。あれれ?カエルがいなくなってしまいましたね……。
位置を更新する処理をコピペする
ブロック定義「移動する」から位置更新の2ブロックをコピペします。ちと見づらいね……画像をクリックしてからダブルクリックすると拡大できるかも。
(あ、スクショがちょっと違うかも……突発的な間違い探しゲーム!どこが違うでしょうw 緑の枠は正しいのでご心配なくm(_ _)m)
テストする
ツーっと移動してますねwスポーンはしてくれましたのでOK😁
重力を効かせる
空中でツーっと動くだけなので、しっかり地面に落ちてもらいましょう。
カンタンです。ブロック定義「Y軸に移動する」置くだけ。
テストすると……。
重力で落下してますね😁
高さを変える
ジャンプするからには高さをコントロールする必要があります。
地面にいるかどうか調べる
地面にいるときだけジャンプしたいので、ブロック定義「障害物に触れているか調べる」を再利用します。
変数「■はい(YES)」は定数として使っている変数で、中身は1です。定数については別チュートリアルを参照してください。
変数「スピードY」を変える
テストする
なかなかいい感じ😍
レンガにハマっても動き続けたり連続でジャンプしまくったり、直すところは多いけど基本的な動きはかなり近づきましたね!
まだ全然コード追加してないのに、今まで作ったブロック定義を駆使したおかげで楽にここまで来れました。
一定間隔を空けてジャンプさせる
ピョンピョン連続でジャンプしているので、間隔を空けたいと思います。そのためにはまず、移動距離Xを変えるブロックを消します。
変数「移動距離X」を変えるブロックを消す
しかし、こうするとカエルがジャンプしなくなってしまいました。なぜでしょうか。
Y座標を少し下げる
テストする
どうでしょう、いい感じにジャンプとジャンプの間隔が空きました😝
X方向に移動する
垂直にピョンピョンするだけではなく、横にも移動したいですよね。
ブロック定義「移動する」からコードを拝借する
テストする
怖い怖い怖いw黙々と迫るカエル怖いw
ところで、ジャンプしなくなってしまいましたね……。
解決策としてY方向にプラスの補正値を追加します。
Y座標に補正値を追加する
以前、坂の判定用にプラス3をY座標に追加してあったので、ここでもプラス3を補正値として追加します……。いや、バリバリのマジックナンバーですね……😅
後で直そう、うん。
テストする
埋もれを修正する
ついでに!ブロック定義「埋もれを修正する」という処理を作ったの覚えていますか?これはブロック定義「リスポーンする」内で呼ばれています。
ジャンプでも埋もれは発生しやすいので、ここでも再利用していきます。
ブロック定義「リスポーンする」を再利用する
ジャンプ中にX方向に移動する
垂直にピョンピョンする動きはバグも直って落ち着きました。しかし、今回の仕様では、X方向に進まなければなりません。
じつは今でもちょこっとずつX方向に動いてます。でもパタパタのようにジャンプしながらプレイヤーに襲いかかる敵モブを目指しているので、もっと大胆に横移動するように改変していきます😁
自スプライト内でしか使わないイベントを作る
ジャンプしている間はずっとX方向にも移動する処理を作る必要があります。
Y方向の動きとX方向の動きは同時並行で行われて、楕円を描くようにジャンプさせたいと考えています。
2つの動きを同時にループ処理をしたいので、1つのループでは実現できません。
そこで、イベントを使いたいと思います。(同時に◯◯したい、はイベントを使うときによくあるニーズ)
ということで、イベント「_敵モブ)ジャンプした」を作ります。
マイルールなのですが、自スプライト内でしか使わないイベントの接頭語はアンダーバー「_」と「スプライト名)」にしてます。
「_敵モブ)◯◯した」みたいなイベントは、敵モブ内でしか使わないイベントであることを暗に示しています。
(自スプライト内だけだから「◯◯しました」ではなく「◯◯した」という表現にもなってる、細かいけど……😅)
いわゆるコーディング規約の1つです。ただしマイルールなので、世間一般で「こうすべき」というルールではありません。
イベントを受け取る
このままでは特に動きに変わりはありません。
滞空時間を管理する
「ジャンプ中はずっと」という条件を作りたいので、プレイヤーでも使った「滞空時間」という変数を作ります。
初期化する
マイナス1なので、ちょっと気持ち悪いですけど、とりあえず。あとでリファクタリングします。
ふと思った。進行方向のマイナス1は左向きに進む進行方向を意味しているので、マジックナンバーですね……。定数にしておけばよかった。これもあとで直すかもしれません。
滞空時間をセットする
ジャンプしたら変数「滞空時間」にプラスの値をセットします。
滞空時間を徐々に減らす
ジャンプ中に滞空時間がだんだん減るようにします。
地面にいるときだけジャンプする
ジャンプするのは、地面に接触しているときのみに限定します。
テストする
よぉく見ると、楕円ではなく分度器みたいな形でジャンプしてます。
Y軸の頂点まで行ったら、ストンと落ちていますね。なぜでしょうか。
滞空時間をスピードYの2倍にする
このマジックナンバーはあとで変数に直すので、20と直書きするのではなく演算で2倍にしておきます。
テストする
なんか2回続けてジャンプしてるし!w
リファクタリング(改善)
ちょっとマジックナンバーが増えてきたので、一度リファクタリングに時間を使います。
リファクタリング)ブロック定義「ジャンプする」を改修する
引数を2つ作ります。
定義箇所を置き換える
呼び出し元を置き換える
これだけでもちょっと分かりやすくなりました。
リファクタリング)マジックナンバー「高さの調整値」を潰す
初期化する
置き換える
ブロック定義「ジャンプする」
ブロック定義「方向転換する」
リファクタリング)マジックナンバー「進行方向の−1」を潰す
右向きは今のところ不要です。
初期化する
置き換える
リファクタリング)滞空時間の判定をブロック定義化しておく
ブロック定義「障害物に触れているか調べる」と同じような使い方になります。
「画面を再描画せずに実行する」にチェックを忘れずに。
変数「滞空時間内かどうか」を作る
ブロックを定義する
置き換える
ブロック定義「ジャンプする」
イベント「_敵モブ)ジャンプした」を受け取ったとき
ふぅ、すっきりしました😁
まとめ
これでジャンプのベースは整いました。しかし、まだ今回の仕様のすべてをカバーしていません。
- ブロックに当たったらジャンプを中止する
- 壁に当たったら方向転換する
これらのヘビーな仕様が残ってます。さらには……
このようなバグも残ってます。
これらは次回チュートリアルにてタックルしていきます。まずはここまで完成させてください。
- ① 横スクロールを制覇せよ
- ② ジャンプせよ
- ③ 壁・坂を攻略せよ
- ④ ゴールして次へ
- ⑤ ブロックを壊せ
- ⑥ スタックを回避せよ (バグ修正の回)
- ⑦ コインをゲットせよ
- ⑧ 敵モブを召喚せよ1 (クローン化、スポーン、横移動など)
- ⑨ 敵モブを召喚せよ2 (方向転換や重力)
- ⑩ 敵モブを召喚せよ3 (アニメーション)
- ⑪ バトル開始1 (ダメージを受ける・与える)
- ⑫ バトル開始2 (ダメージのアニメーション、フィードバック)
- ⑬ 敵モブをリスポーンさせる
- ⑭ iPadに対応する
- ⑮ 迫りくるパタパタ (いまここ)
- ⑯ パタパタのバグ修正 (ジャンプのバグを直す)
- ⑰ 壁に埋もれるバグ修正 (バグがバグを呼ぶ、でも諦めない)