スクラッチに挑戦している皆さん、どうも!スクラッチコーチです。
前回はクラウド変数を受信して新規プレイヤーなら入場処理とデータ更新を、既知プレイヤーならデータ更新のみを実行するようにプレイヤー管理ができる仕組みを作ったぞ!
でもまだまだリストのデータが更新されただけで、見た目は何も変わってないんだよねぇ。っということでここから見た目も変えていくぞ。これでオンラインゲーム感がグッと増してワクワクが大爆発すること間違いなしだ!
今回からスクラッチ公式サイトでブロックのカラーが更新されたエディターを使っていくね。なので前回までとスクショ内のブロックカラーなど違うけど機能的には全く同じなので問題ないよ。
今回の目標「クローンを作って別プレイヤーを表示させる」
別プレイヤーを表示させる一番いい方法はクローンを使うことだよね。今回はクローンを使って別プレイヤーを自分の画面に表示させる。ただまぁクローンを使うと物事がより複雑になっていくんだよねぇ。仕方ないけど。焦らず急がず、じっくり取り組めば大丈夫。それに実は今までのコーディングはクローンを使うことを想定して作ってきているから、思ってるより複雑にならないかも。
なにより僕も一緒にいるから絶対大丈夫だって!
チラッと完成動画を見せちゃう↓
やってみよう!
クローンを作る
いきなりクローンを作っていくよ。
最初に作戦を伝える。各クローンには異なる変数「プレイヤー番号」を持たせて管理していくんだ。プレイヤー番号さえ分かれば「★プレイヤーUID一覧」と「★プレイヤーデータ一覧」のどこを見ればいいか分かるから、これだけで他プレイヤーとの区別が行えるようになっているんだ。
クローンを作るときによくある手法として、スプライト自身は非表示のままにしてクローンだけ表示するっていう方法をここでも採用するぞ。スプライト自身の変数「プレイヤー番号」は空白のままにしておくことで、クローンかどうかを区別もできる。おいおい変数「プレイヤー番号」めっちゃ優秀じゃんか!?最高だね!
クローンブロックを置く
変数「プレイヤー番号」をセットした直後にクローンを作ろう。
こうすればクローンはプレイヤー番号を保持した状態で生成されるね。そしてスプライト自身はこのあとの処理でプレイヤー番号を空白に戻してあるのでバッチリだ。
クラウド - ティックを受け取ったときの処理を分ける
さて、クローンを使う時の問題点として、本体側で実行されているループ処理をクローンも実行してしまうというのは有名だよね。問題ないケースもあるんだけど、例えば今回のメッセージ「クラウド - ティック」をうけとった時の処理は本体だけしか実行してほしくない。いや、もっと正確に言うと、本体のティック処理とクローンのティック処理は別々にしたいと思ってる。
本体とクローンを区別する
ここで再び役立つのが変数「プレイヤー番号」だったね!条件分岐させてみよう!
条件ブロックを置く
とりあえずクラウドティックを受け取るところに「もし」ブロックを置こう。
条件式を作る
変数「プレイヤー番号」が空白でなければクローンだね。この作り方は何通りかあるけど今回は下記のような方法でOKだ。
否定ブロックを使う方法もあるけど、こっちのほうがシンプルじゃない?これを条件式として使うとこうなる↓
うん、いいね。この中の条件ブロックの中にはクローンしか来れない状態ができたね。では中身も作り込んでいこう!
ブロック定義「クローンティック」を用意する
クローン専用のティック処理をブロック定義にまとめておくよ。
使う
条件ブロック内に置いて、さらにそれ以降の処理は実行されないように「このスクリプトを止める」ブロックも置こう。
これで「もし」ブロック内はクローンだけが実行できて、「もし」ブロック以降は本体だけが実行できるようになったね!
クローンティックを作る
よし、じゃあココからはクローンだけが実行するティック処理を作るよ。
ちなみに、ココに至るまでにすでにブロック定義「順番にデコードする」を1回実行してるのは覚えてる?そう、プレイヤーUIDをエンコード文字列から取得するときに1回実行したんだよね。
じゃあ次にデコード処理を実行したら何が取れるか覚えてるかな?そう、X座標だね!ではさらにもう1回実行したら?うん、Y座標だよね。じゃあさ、続けてもう1回実行したら何が取れるっけ?答えは次のイメージを見てみてね。
うん、取れるのは次のX座標だね。
この図を参考にどんどん順番にデコードしていって、そのたびに座標データを割り当ててみよう。
デコードしてX座標を割り当てる
ブロック定義「順番にデコードする」を実行しよう。
X座標に割り当てる
これで変数「値」にはX座標が入ったから、これを割り当てよう。
デコードしてY座標を割り当てる
2回デコードしたから下記のようになってるわけだ。
じゃあ続けてY座標も取り出して割り当てよう。
カンタンだね!
カラになったかどうか調べる
これでXとYが取り出されたからエンコード文字列は下記のようになったね。
ティック処理はどんどん実行されるから、次回もまたX座標とY座標を割り当てる処理が実行されるよね!
そしてこのティック処理は変数「エンコード文字列」がカラになる(=デコードできなくなる)まで続くわけだ。
カラになったらどうしようか?
大丈夫、安心して!その頃にはきっと本体側のクラウドティック処理で次のクラウド変数を受信してるだろうから、またリスト「★プレイヤーデータ一覧」にデータが届いてるはずだよ。データをまたエンコード文字列にセットすれば、連続してデコード処理が実行していけるね。
これでエンコード文字の順番を2にセットしてから余分なデータ(プレイヤーUID)をスキップするために1回デコードしておけば……そう、またXとYを取りたい放題だね!めっちゃスムーズに動きが再現できそうな予感がしてきた……ワクワクっ!
条件ブロックを置こう
じゃあエンコード文字列がカラかどうか調べよう。
条件式を作る
カラかどうか、どうやって調べる?気を付けてほしいのは、実際には変数「エンコード文字列」の中身はデータが入ったままってこと。だからエンコード文字列が空白かどうか、という条件式は使えない。そこで変数「エンコード文字の順番」を使って次のような演算を作ってみよう。
現状だと、変数「エンコード文字の順番」は変数「エンコード文字列」の長さより1つ大きい値になっているよね!そこを利用すればエンコード文字列がカラ(=全部デコード済み)かどうかが分かるっていう算段だよ。
次のプレイヤーデータをエンコード文字列に移そう
この中ではプレイヤーデータをエンコード文字列に移す処理を作っていくよ。
ブロック定義を用意する
ブロック定義「次のプレイヤーデータを移す → エンコード文字列」に処理をまとめておこう。
使う
とりあえず置いてみよう。
プレイヤーデータを取得する
各クローンが持っている変数「プレイヤー番号」を使って、自分のプレイヤーデータを取得しよう。
これを変数「エンコード文字列」に反映するよ。
元のプレイヤーデータは消す
なにかのはずみで2回同じデータを取得してしまわないように、元の場所は空白にしておこう。
プレイヤーUIDをスキップしておく
この段階ではプレイヤーUIDは不要なので一度デコードを行ってしまおう。もちろん直前で変数「エンコード文字の順番」を2にセットすることも忘れずに。
この処理はとりあえずこれでOK!
仕上げる
ところで、★プレイヤーデータ一覧にデータが届いてなかったらどうなるだろうか。その場合はエンコード文字列に空白がセットされることになるんだ。
このことを利用してブロック定義「クローンティック」にストップ処理を追加しておこう。
条件ブロックを置こう
プレイヤーデータを移した直後に条件分岐を作ろう。
条件式を作ろう
エンコード文字列が空白かどうかを調べよう。
処理を止めよう
何も取れなかったら今回のティックではなにもしない、っということだね。
表示も忘れずに
おっとこのままだと本体と同じくクローンが隠れたままだね。しっかり表示させよう。表示させるタイミングはここかな。
テストターイム!
ここまで一気通貫で作ってきたから、もうテストしたくてウズウズしてたんじゃないかな?!よしよし、またタブを2つ開いてテストしてみませう!
た・の・し・いーーーーーぃ!
動いた?動いた?ちょっと感動じゃない!?これはやばいよね!
次回へ
今回は別プレイヤーを自分の画面に表示させて動きを同期させるためにクローンを使ったね!クローンを使うと一気に複雑になる……と心配したけど、元々クローンを想定して作っておいたから思いの外スッキリした構造を保てたと思わない?大改造したっていうよりは、ちょっと追加しただけ、みたいな印象だったんじゃないかな。
さてさて、まだ終わらないよ。もっと高みへ行こう!
現状だとタブを3つとか4つとか開くとカクカクしちゃうときがあるよね。そう、ラグいんだよ。次回はこのラグをスケールアップという技で直す!
あとプレイヤーを追加する入場処理ができているけど、次回か次次回でオフラインになったプレイヤーを除去する退場処理も実装しようと思う!こうすることで入れ代わり立ち代わり遊ぶ人が途切れないオンラインゲームになるってことよ。
近日中に更新するので待っててね〜。
- ① クラウド変数の使い方
- ② エンコードする
- ③ デコードする
- ④ マイナス値に対応する
- ⑤ バッファリングを実装する
- ⑥ 別プレイヤーを検知する
- ⑦ プレイヤーを管理する
- ⑧ クローンを使おう (いまここ)
- ⑨ スケールアップする
- ⑩ 退場処理を作る
- ⑪ 自作ゲーム「鬼ごっこ」を作る
- ⑫ MMO鬼ごっこに改造する
- ⑬ クラウド変数でユーザー名を共有する方法