スクラッチプログラミングに挑戦している皆さん、どうも!スクラッチコーチです。
前回はバッファリングを実装して欠落のない動きの再現に成功したぞ!これ↓がバッファリングに
成功した
状態だ。
変数「★
送信用データ」をエンコードしてクラウド
変数1に
一括でセットしている
様子が
見て
取れるね。ここからは
他プレイヤーとのクラウド
変数の
共有を
意識した
実装を
進めていく。ややこしくなってきたねぇ!
今回の目標「UIDを実装して別プレイヤーを検知する」
自分と
他人を
区別するためにUID(=ユニークID)を
実装していこう。これを
使えば
誰がクラウド
変数を
更新したのか
分かるようになるんだ。
今のままだと、
別タブで
同じ
作品を
開いてみるとタブAでもタブBでもクラウド
変数1を
更新するため、
誰の
座標データなのか
識別不能な
状態なんだ。そこで
今回は、クラウド
変数1に
渡すデータにUIDというプレイヤーを
識別できるデータを
追加していきたいというわけ。
座標以外のデータをクラウド
変数に
渡す
練習にもなるよ。まぁ
方法は
座標のときと
同じ!エンコードしてクラウド
変数にセットして、
受け
取り
側ではデコードしてデータを
分解して
使うよ。おっと、ただそのまえに1つやることがあるんだ。そのあたりも
順番に
見ていこう。
今回やることをざっくりまとめるとこう↓
- 新しいリスト「★クラウドデータ」を作る
- 長い数字を文字化する
- プレイヤーUIDを送る
- プレイヤーUIDを受け取る
- プレイヤーUIDを調べる
こんな
感じで
進めていくよ。
直前のクラウド変数の中身を保持するリストを作る
このあとの
実装で、クラウド
変数が
更新されたかどうかを
調べる
工程がある。そこで
直前のデータと
最新のデータを
比較しないといけないので、
直前のデータを
保存しておくためのリストを
用意したいと
思う。
リスト「★クラウドデータ」を作る
このリストに
直前のデータを
追加していく。
初期化する
クラウド変数の値をクラウドデータに保管しておく
これでこのあと、クラウド
変数1の
中身が
前のティックから
変わってるかどうかを
判断するのに
役立つ!
長い数字を比較する
しょぼーんってなるけど、ここでみんなにスクラッチの
困った
仕様を1つご
紹介しないといけない。それは
長い
数字の
比較に
関するものだ。
例えばここに250ケタの
超長い
数字があったとする。(
実際クラウド
変数に
色んなデータをエンコードしまくって
入れてると
長くなることはある)これはテストだからみんなはやらなくてもいいけど、
気になったらためしにやってみ。
こういう
長い
数字を
比較してみたいと
思う。
うん、ふつうに「
値 =
値」はTRUE(
真)だね!じゃあこれは?↓
「
値 = (
値 + 1)」だね。いやいや、そりゃあFALSE(
偽)でしょ。
当たり
前じゃん。こんなん
誰でも
分か……
おおおおおい!?なんかTRUE(
真)ってなってるんですけど!?
絶対違うじゃんか……。WHY!?スクラッチピーポー!【
悲報】じつはスクラッチさん、
長い
数字が
理解できません↓
250ケタの
値に1を
加算すると、スクラッチの
限界を
超えてしまって
理解不能な
数字になってしまうんです……。そしてこれを
比較に
使うとさっき
見た
通りなんでもTRUEになっちゃう……。しかも
エラーにもならないっていうバグの
温床でもある。アンビリーバボーだぜ!
何が困るの?
これで
何が
困るのかって
言うと、このあとの
実装で
困る。このあとクラウド
変数1の
値が
変更されたかどうかを
調べていくんだけど、そのときに
直前の
値と
現在の
値を
比較したいんだ。でももしデータが
長すぎてスクラッチの
限界を
超えてたら、なんでもかんでもTRUEになっちゃうんだよね。つまり
直前の
値と
現在の
値は
常に
同じ(=
変更なし)って
判定になってしまう。これでは
正しく
動かないよね。これを
未然に
防ぐために
策を
講じておきたいと
思うぜ。
数字を文字に明示的に直す
長い
数字が
理解できないなら
長い
文字にすればいいじゃない?という
一見するとマリー・アントワネットばりの
理不尽な
見解(※)だけど、スクラッチに
関しては
正解なんだ。
ok-scratch
u003cpu003e※「パンがないならケーキを食べればいいじゃない?」っていうマリー・アントワネットが言ったとされる名言(迷言)がある。ただし本人はそんなこと言ってないという説が有力。ネガティブ・キャンペーンってやつか。u003c/pu003e
明示的に
数字を
文字に
直す
方法はカンタン。
文字と
数字をくっつければOK。
これはアルファベットの「c」と
変数「
値」をくっつけてから
比較してる。(c +
値)=(c + (
値 + 1))こうすると
答えはFALSE(
偽)になるから
正解だね。ふぅ!あっぶね。
文字化する
じゃあクラウド
変数1を
明示的に
文字にしよう。くっつける
文字は
何でもいいんだけど、クラウド(Cloud)の「c」にしとこうか。
テストする
うん、cがついてて
文字になってるね。
文字だからもう
計算には
使えないけど、これを
計算する
予定はないので
問題ない!
別タブでテストしてみる
このタイミングでまたタブを2つ
開いて
隣同士に
並べて
動きを
確認しておこう。
この
動画を
拡大してみてみて。タブ
左が
動いてるときにタブ
右のクラウド
変数1がどんどん
更新されてるよね。これはタブ
左からの
座標データと、タブ
右自身の
座標データが
交互にクラウド
変数1を
更新しているからなんだ。つまり、
2つあるデータのうち1つはタブ左のもの、もう1つはタブ右のものという状態だね。で、どのデータがどっちのデータなのか、それを
明らかにするために
冒頭で
伝えたUIDというものを
実装していくよ。
UIDを実装する「送信編」
UID
自体はランダムな
数字の
羅列にするよ。たとえば214843みたいな
意味のない、だけど
滅多に
重複しない
数字。
変数「★自プレイヤーUID」を作る
すべてのスプライト
用に
新しい
変数を
作ろう。
初期化する
メッセージ「クラウド - セットアップ」を
受け
取ったところに
乱数1から9,999,999(9が7
個)で
初期化しよう。
これで
滅多に
重複しないでしょう!こんな
感じ↓
エンコード文字列の先頭に追加する
今まではXとYの
座標データしかエンコードしてなかったけど、これからは
最初にUIDをエンコードして
入れるようにするよ。ブロック
定義「
同期する」
内にブロックを
追加しよう。
これで
変数「エンコード
文字列」に
自プレイヤーUIDがエンコードされて
追加されたね。ちょっと
見てみようか。
バッチリ。エンコードが
正しく
機能してて、なんか
気持ちいい!
UIDを実装する「受信編」
自分から
送るデータにプレイヤーUIDを
付けることには
成功した。
次はクラウド
変数をデコードしてプレイヤーUIDを
受け
取って、それが
自分のものか
別プレイヤーのものかを
判定するところだ。っとそのまえに1つ
変更したいことがある。
ブロック定義「同期する」の名前を変える
同期するだと
送信する
意味も
受信する
意味も
含まれてて、ちょっとアイマイだから
名前を
変えておきたい。ブロック
定義「
同意する」を
右クリックして
編集を
選ぼう。
明確に「クラウド
変数を
送信する」に
変更しておこうかな!
ブロック定義「クラウド変数を受信する」を作る
これの
対になるブロック
定義「クラウド
変数を
受信する」を
作っていこう。
引数には☁《くも》
番号と
更新データの2つを
取るようにしよう。ちなみに☁はクラウドっていう
意味を
込めてる。
使用する
メッセージ「クラウド - ティック」を
受け
取ったタイミングで
使おう。
1つ
目の
引数に「1」を
入れたね。1はクラウド
変数1を
意味するよ。
別チュートリアルでこの1が
持つ
意味が
明らかになるから、
今はとりあえず1はクラウド
変数1なんだな、って
認識しておいてね。2つ
目の
引数にはクラウド
変数を
文字化したものを
入れるよ。さっきリスト「★クラウドデータ」に
入れた
際に
文字化した
処理と
全く
同じ
演算「c + クラウド
変数1」だよ。よし、じゃあブロック
定義「クラウド
変数を
受信する」の
中を
作り
込んでいこう!
変更がなければ何もしない
もしクラウド
変数の
中身が
直前の
値と
変わってないなら
何もしないよ。とりま「もし」ブロックをカチッと。
条件式を作る
次に、クラウド
変数の
中身を
比較するにはリスト「★クラウドデータ」が
役立つ。これはクラウド
変数の
直前の
値が
格納されているリストだったね。そして
最新の
値は2つ
目の
引数「
更新データ」に
入ってる。だからこの2つを
比較する
演算を
作ってみよう。
これを
条件式にハメよう。
このスクリプトを止める
で、
更新されてないなら
何もしなくてOKと。
変更があれば★クラウドデータを更新する
もしも
変更があったら
直前のデータを
最新のデータで
更新しよう!
テスト
クラウド
変数1とクラウドデータの
値が
同期されるようになったね!
良きかな。
プレイヤーUIDを取得する
更新されたデータが
誰のものなのか
調べていこう!なにげにここはエキサイティングに
感じる!だって
他の
人がいるかどうかってオンラインゲームにとって
重要なことだもんね。どうやって
調べるのか!?そりゃデコードっしょ。デコードしてプレイヤーUIDを
取得していくぞ!
エンコード文字列に値を入れる
デコードするためにはまず
変数「エンコード
文字列」にデコード
対象となるデータを
入れる
必要があったね。
エンコード文字の順番を指定する
さて、この
更新データの
中身ってなんだっけ?さっき★クラウドデータに
入れた
値を
見てみると「c78280511206...」ってなってるね。
前はエンコード
文字の
順番は
素直に1
文字目から
始めてたけど、
今って
文字化で
使った「c」がいるから
エンコードを始めるのは2文字目からじゃないとダメだね。
そうと
分かればカンタン。
マジックナンバーになってしまうのが
気持ち
悪いけどとりあえずOK。
デコードする
ここはブロック
定義を
使い
回す!
再利用、
最高!
これで
変数「
値」にはプレイヤーUIDが
入っていることになるね!
誰のデータなのか調べる
いよいよ
誰のプレイヤーUIDが
送られてきたのか
調べるぞぉ!
バリデーションする
っとそのまえにデータが
壊れていたり、
自分自身のUIDだったりしたら
処理を
止めるようにガード
処理を
作っておこう。こういうデータの
正当性を
調べる
作業をバリデーションって
呼んだりする。
条件ブロックを置いておく
とりあえず「もし」ブロックと
処理を
止めるブロックを
置いておこう。
条件式を作る
処理を
止める
条件1はデータが
壊れている
場合。1
未満みたいな
値だったら
壊れていると
判断しよう。
壊れない、って
思っててもスクラッチは
誰でも
中を
改変できるからね。ひょっとしたら
誰かが
誤った
変更を
加えて
壊れた
値が
飛んでくるなんてことも
十分ありえる。あとは
自分のUIDだった
場合だね。
このどちらかであったら
処理を
止めるってしておこう。
最終的にはこうなる↓
よし、
締めのテストに
移ろうか。
プレイヤー番号を作る
テストも
兼ねて
変数「プレイヤー
番号」を
作るよ。あとで
実装でも
使うから
一石二鳥だよ。
初期化する
空白で
初期化するよ。
配置する
あとで
変えるけど、いったん
変数「
値」を
代入して
様子を
見よう。
テスト
タブを
並べて
動かしてみよう!
おおお!タブ
左のプレイヤーUIDが、タブ
右の
変数「プレイヤー
番号」に
入ってるね。
逆も
同じだ!
完璧ぃ!これで
他のプレイヤーの
座標データを
処理する
準備が
整ったというわけだ!イエス!
次回へ
今回はプレイヤーUIDを
実装して
別プレイヤーを
検知するところが
完成したね。オンラインゲームにとってまさに
重要なキーポイントだったと
思うよ。
今回やったことをカンタンに
振り
返ろう。
- 新しいリスト「★クラウドデータ」を作って、直前のクラウド変数の値を保持できるようにした
- 長い数字を文字化して、正しくデータの比較ができるようにした
- プレイヤーUIDをエンコード文字列の先頭に追加した
- プレイヤーUIDをデコードして自分以外のプレイヤーの存在を検知できるようにした
次からは
別プレイヤーのデータを
処理して、
自分の
画面に
別プレイヤーを
表示させるところを
実装しよう。もちろん
表示するだけじゃなくて
動きも
同期させるぞ!ワクワクが
止まんねぇ!また2,3
日で
更新するので
待っててね。