見出し画像

Among Us Scratch の解析5:ゲーム選択

今回は、タイトルのある intro 画面で ONLINE ボタンを押したときに進む先である、online モードを見ていく。

online 画面モード

次の動画の、host、public、join by code の3つのボタンのある画面が online モードだ。確認のために表示している画面モードを持つ modus 変数が "online" になっている。

画像1

3つのボタンそれぞれで、次の3つのプレイ方法を選択できる。

host:自分で部屋(game)を作って、他人が入ってくるのを待つ。

public:誰かが作った game を選んで、そこで遊ぶ。

join by code:game についているコードを使って遊ぶ gameを直接選び、そこで遊ぶ。

今回は、この画面の主な処理をしている Online_ スプライトを調べていく。

名前の最期になぜ _(アンダースコア)がついているかは不明。もとは Online_host、Online_public のようにバラバラのスプライトだったところ1つにまとめたときに消し忘れたのかも?

Online_ スプライト:コスチューム

Online_ スプライトには、8つのコスチュームがある。

画像2

このうち、6つは2つ一組で、第3回の「最初の画面の3つのボタン」のボタンと同じく、通常の状態とマウスカーソルが乗ってハイライトした状態の2つで1つのボタンの絵になっている。次は、画面一番上に出る「host」のボタンの2つのコスチュームだが、左は通常状態、右はハイライトした状態の絵になっている。

画像3

public のボタンと、join by code のボタンも同じく2つのコスチュームがセットだ。

画像4

画像5

また、Unbenannte Zeichnung (12) という、ドイツ語で「名前のない図面」という名前の次のコスチュームもある。

画像6

このコスチュームはプレイしても出てこないので何に使用しているかは不明だ。名前がなぜかドイツ語なのも気になる。作者がドイツ語話者で普段はドイツ語でスクラッチを使っているからもしれないが、プロフィールからはわからなかった。

関係ないが、作者のTimMcCoolさんは15歳(らしい)。15歳の少年が作ったプログラムにいい歳したおっさんが、四の五のいちゃもんつけているのはあまりかっこいいものではないとは思う。

画像7

コスチュームにはもう一つ、Join by code3 という、 Join by code2 コスチュームと何が違うのかわからないものもある。

画像8

なんとなく、できてしまって放置しているだけに見えるが、コードを見ればわかるだろう。

コスチューム見る限り、Online_ スプライトは、タイトルのボタンを処理する Buttons スプライトによく似ている。1つのスプライトに3種類のボタンのコスチュームがあるので、Buttons スプライトと同じように残り2つをクローンして動いていると予想もできる。

Online_ スプライト:コード全体

次の写真は、Online_ スプライトのコード全体だ。

画像9

スクリプトそれぞれをざっと見た感じ、コードも Buttons に似たもののようだ。Buttons にしかなかったり、Online_ にしかないものもあるが、1つ1つ確認していく。

Online_ スプライト:最初のスクリプト

Online_ スプライトには、アプリケーション起動時に実行される「旗が押されたとき」イベントで動作するスクリプトは、次の1つしかない。

画像10

Online_ スプライトは intro モードの後に表示されるべきスプライトなので、起動時は「隠す」で非表示にしておかないと、intro モードでいきなり表示されてしまう。

Online_ スプライト:intro モードに来た時の処理

Online_ スプライトには、 intro 画面(最初の画面、online 画面の1つ前)になった時に実行される次のスクリプトがある。

画像11

処理内容は、見えなくした上で、Online_ スプライトが何もしないようにするため動作をすべて停止し、最後に作ったクローンをすべて削除する。

クローンを消している所は、Buttons と同じようにクローンを作って3つのボタンを実装しているからというのはわかるのだが、Among Us Scratch には online 画面から intro 画面へ戻る導線は実装されていない。つまり、intro 画面にいくことは無いのだ。ゴミだろうか?

ためしで、次のコードを作って intro 画面へ戻る機能を作ってみた。

画像12

これで実行して、intro 画面と online 画面を行ったり戻ったり繰り返してみた。次の動画はそのテストを連続20回ぐらいやってみたところだ。

画像13

背景のクルーが異常に増えてしまった。

背景のクルーはまだ未解析だが、intro 画面で自分をクローンしたのち、ゲームが始まって待機部屋に来るまでの画面すべてで消えずにずっとくるくる回り続けている。intro へ戻ると、この clue が、intro画面だと思って再度クローンするので、それで増え続けてしまうのだろう。

この不具合が面倒で online モードは intro に戻れないのかもしれない。プレイが始まるまでは、背景にずっとくるくるするクルーが漂わせているので、「introに戻ってきたときにクローン」と「introに戻ってきたときに全部消す」の共存は面倒そうなのでこうなっているのかもしれない。

Online_ スプライト:onlineモードになったとき

online モードになったら、Online_ スプライトは、online、public、join by code の3つのボタンを表示しなければならない。online イベントを受け取った時のスクリプトは次の写真だ。

画像14

大きいように見えるが、第3回の3つのボタンの Buttons スプライトが intro 画面でするのとほぼ同じ構造のスクリプトになっている。

このコードの先頭部分は次の写真で、2つクローンを作っている。

画像15

「0秒待つ」は何をしているのか不明だ。何らかのバグを回避するための秘密の「殺虫剤」コードかと思って試しで消してプレイしてみたが特に何も問題はなかった。

残りの部分は、クローンを2つ作っている。クローンを作るときに、スプライト用変数 i を 0 と 1 に変えているので、出来上がるクローン2つの変数 i も0と1になる。最後にスプライト自身の i を2にするので、結果は次のようになる。

■ クローン1つ目:変数 i =0

■ クローン2つ目:変数 i =1

■ Online_ スプライト自身:変数 i = 2

intro モードの Buttons と同じく、クローン2つと Online_ スプライトの3つで3つのボタンを実装する。ボタンの見た目や動作違いは、スプライト用変数 i の値で区別できる。

クローンのコードの後には、「ずっと」ループのコードが続く。この部分は後程クローンのコードとともに見ていくことにする。

Online_ スプライト:クローンの処理

Online_ スプライトには、クローンだけで動作するスクリプトが2つある。1つ目は次のスクリプトだ。

画像16

クローンはまず最初に「表示」する。Online_ スプライトはクローンする時点では「旗が押されたとき」以降、一度も「表示する」を実行していないので、クローンも「隠す」したままの状態だ。そこで、クローンはまず自分を「表示する」。

次にクローンは自分の位置を設定している。初期化として必要そうではあるが、Online_ コード中ではスプライトやクローンの位置が変わるようなコードは他にないので、特に役に立たない「おまじないコード」に見える。

2つ目のクローンの処理をするスクリプトは、少し長めの次の写真のものだ。

画像18

長いが、このスクリプトもintro画面のボタン Buttons スプライトと構造はほぼ同じで、全体は、①と②のマウスポインタがボタンに入ったかどうか(通常色と緑色ハイライトの表示)と、③と④のボタン操作(ボタンを押して離す)の4つの部分に分かれる。

また、先ほどのクローンをするスクリプトの中のクローン後の処理も、Outline_ スプライトについて次の写真のように同じ構造になっている。

画像19

どちらもよく観察してみると、「modus 変数が online」=「online 画面モード」の時だけ動作するようになっているが、online モード以外で Online_スプライトもボタンも表示されずコードも動かないので(後ほど説明)、判定は実質無意味だ。開発中のバージョンでは必要だったものがそのままなのかもしれない。

この構造のボタン自体の動作ついては、第3回のButtonsで解析しているので省略し、ここでは、①~④のそれぞれについて、_Outline スプライトとクローン2つの処理部分を見ていく。

Online_ スプライト:①ボタンの通常コスチューム表示

Online_ スプライトと、クローンの2つは、最初に「①通常コスチューム表示」のコードを実行する。次の写真の左が Online_ スプライト、右はクローンの部分だ。

画像20

コスチュームの設定から、Online_ スプライト本体とクローン2つは次の分担をされていることがわかる。

画像21

■ Outline_スプライト本体 = host ボタン

■ 変数 i = 0のクローン = public ボタン

■変数 i = 1のクローン = join by code ボタン

また、最初に書いた絵が少し大きかったためかもしれないが、3つとも大きさを90% と少し小さく表示している。

3つのボタンとも、明るさ効果は無し(0)としているが、Online_ スプライトだけ幽霊効果も無しにしている。ボタン3つとも同じ見た目動作をするべきのように思うが、Online_ スプライトだけ何か特別な表示をしていたことがあったのかもしれない。そもそも、ボタンは「明るさ」効果も使っていないので、「明るさ」も「幽霊」も不要で、なんとなくゴミコードっぽい。

しかし、もっと何をしているのかわからないのが、クローンの最期にある「~と言う」コードだ。「言う」はスプライトに吹き出しを出す。次の動画は「言う」コードの例だ。

画像22

「おはよう!と言う」は吹き出しで「おはよう!」と表示する。「言う」に何も指定しないと吹き出しは消える。

Online_ スプライトのコード中、「言う」はここにしか使っておらず、表示もしない吹き出しを消そうとしている。もしかしたら昔はここでボタンの動作について説明を入れたりした名残かもしれない(かもしれないだらけだが...)。

Online_ スプライト:②緑のハイライト表示

ボタンにマウスポインタが重なったときの「②緑色にハイライトする」部分は次のコードだ。「表示する」コードが不要そうに見えること以外は特に難しくなく、緑ハイライトのはいったコスチュームに切り替えているだけである。

画像23

Online_ スプライト:③音を鳴らす

マウスボタンを押したときの「③音を鳴らす」処理は、Online_スプライトもクローンも同じだ。intro 画面のボタンと同じ音を鳴らしている。

画像24

Online_ スプライト:④ボタンをクリックした処理

マウスポインタがボタンの内部にいるままボタンを離すと「④ボタンをクリックした処理」を実行する。

Online_ スプライト本体(hostボタン)のクリック時の処理

次の写真のコードは Online_ スプライト本体のクリック時の処理部分だ。Among Us Scratch の画面切り替えルール(第1回参照)と、切替時のフェードアウト・イン処理(第4回参照)を使用している。

画像25

before.cng モードは次の写真の画面で、自分でゲームを立てるために参加人数などを決めるところだ。

画像26

modus 変数には "before.cng" を設定するが、イベント名は "before.createnewgame" と少し名前が違う。タイプが面倒で create new game を cng と省略してしまったか、最初につけた名前を思い出せず確認が面倒で適当にしたら違ってしまったかもしれない。中途半端な無精が引き起こした不統一性の例と言えるだろう。対応性が悪くなることでコードの見通しも悪くなるので良いコードとはいえない。ただ、もし先にイベントの before.createnewgame を作っていたのなら、面倒になって途中で省略形を使いたくなった気持ちは理解できる。

クローンの方は、変数 i = 0の public を選んだ場合と、i = 1の join by code を選んだ場合で少し異なるので別々に見ていく。

変数 i = 0のクローン(publicボタン)のクリック時の処理

まず、次の写真は、変数 i = 0の public のクローンのコードだ。

画像27

少しコード順序が違うところもあるが、find モードへ画面モード切替している。「隠す」コードがあるが、画面モード切り替わるとクローンはすべて消されてしまうので「隠す」は不要そうに見える(消されるところは後程説明する)。

変数 i = 1のクローン(join by codeボタン)のクリック時の処理

次に、変数 i = 1の join by code のクローンのクリックしたときを説明するが、少し複雑なので、まずクリックしたときの動作から見る。画面モードの modus も表示してある

画像29

ボタンを押した後の流れは次の通り。

■ 「Please enter your game code:」という表示とともに、参加するゲームのコードを入力させる。

■ 何も入力せずに決定(右のチェックマーク)したら、元の画面に戻る(モードがonlineのまま)

■ コードを入力したら、そのコードのゲームへ参加する joining 画面モードへ進む。

実装部分のコードは次の写真だ。

画像28

まず「隠す」している。よく見ると、コード入力のときに背景にある join by code のボタンは消えている。

「隠す」の下の、⑤の部分でコードの入力をさせるコード「~と聞いて待つ」を実行する。このコードは動画のようにユーザーに文字列を入力させ、決定(チェックボタン)するまで待つ。入力結果はあらかじめ用意されている「答え」という変数に入る。

Please enter your game code: に何も入力しなければ、「答え」変数は空となり、上のコードでは⑥と⑦を含む「もし」により判定されて「答え=空ではない」⑦の方へ進む。

画像33

⑦では、消したボタンを再表示し、幽霊効果でふわっと再出現させている。

反対に、Please enter your game code: に何か入力したなら、⑥の方が実行される。

画像32

⑥は room.joincode 変数に入力したコード「答え」変数の内容を設定してから、joining モードへ遷移する。joining 画面モードの切り替え時のイベント名が joining ではなく join game となっているところは、createnewgame が cng になっているのと同じく気持ち悪い。

また、join game イベントを送って待っているところが、これまで見てきた画面モードの切り替え処理とは違う。この間に joining モードの処理をするコードが room.joincode のゲームを探す処理をしているのだろう。「答え」変数をそのまま使えばよいように思えるが、joining の先の画面で別の文字列入力をすると消えてしまうし、joining 先のコードで「答え」変数を使うと、どこで入力したものかわかりづらいだろう。

その後、joining モードに対応する「join game を送って待つ」をしている。待っているのは、おそらく joining が終わったら、不要な room.joincode をリセット(空)するためと思われる。処理が終わったなら、不要な情報を消したり廃棄するのは、プログラムを誤動作させない重要なプログラミングルールだ。「初期化」があるなら「廃棄」も必ず必要だ。

しかし、このあと、この⑦のコードはモード切替以外には意味がなく、room.joincode のクリアは無用なことが判明する。

Outline_ スプライト:画面モードが切り替わった時の処理

Outline_ スプライトは、Buttons の消す処理と類似した、ほかのモードへ切り替わるときにボタンを消す処理がある。次の写真の6つのスクリプトが消す処理担当コードだ。

画像30

6つのどのイベントでも、ボタンを「隠す」してスプライトのすべてのスクリプトを停止して、クローンも削除する。

処理内容に問題はないが、この中で join game イベントでも停止してクローンを削除しているのは、先ほどの joining モードへ切り替える次の部分のコードに少し問題が出る。

画像33

join game を待っている間に、6つのうちの「join game」イベントスクリプトが全スクリプトを停止してしまうので、最後のroom.joincode を空にするコードは実行されない。次の動画は bbbbb と入力して戻ってきたところだが、空にならずに bbbbb は残ったままである。

画像34

不要なものはクリアしたり廃棄すること自体は良いことだが、その処理が全く動かないとなると、「クリアしているはずなのに動作がおかしい」というバグの原因になるかもしれない。「はずなのに」バグは、頭の中でバグの原因を排除しているので気づくのが難しい。このクリアコードを作ったあとに join game イベントでスクリプト停止を作ったなら、このコードが動かなくなったことに気づくのは難しいかもしれない。バグは作ったやつが責任とって賠償すると発言していたエライ政治家さんなら、すぐ見つけられるのかもしれないが。

Online_ スプライト:FREEPLAYすると突然発動するスクリプト

Online_ スプライトには、ここまでに見てきたもの以外に2つのスクリプトがある。どちらも微妙だ。そのうちの1つは、freeplay イベントを受け取ると動くスクリプトだ。たしかにFREEPLAYのときだけ動いている。

画像35

「ずっと」なのでずっと動いているが、やっていることは「ペン」(前回のスタンプ等)で書いたものを消し続け、さらに、tick1、tick2、tick3 イベントを送り続ける。これだけでは意図が全くつかめない。

しかし、フェードアウト・インなどの処理をする Transitions スプライトには、tick3 を処理する次のコードがあった。

画像36

このコードは、tick3 イベントと変数 m の条件に応じてスタンプを押す。Transitions スプライトは真っ黒か、真っ黒にエラーメッセージを描いた全画面絵なのでスタンプに意味があるか不明だし、m = 1とはどういう条件か全くわからないが、tick3 イベントは、画面を消しては誰かに何かをペン等で描かせる、という意味に見える。謎は深いが少し解決の糸口が見えてきたかもしれない。

Online_ スプライト:set_volume イベントで音量調整するスクリプト

もうおなじみになってきたが、Online_ スプライトにも音量調整する次のスクリプトがあった。

画像37

このスクリプトも当然、背景から常に送られている set_volume イベントに応じて常に実行され続けている。何か大事な理由があるのかもしれないが、やはり、変な動作をしないただのバグ、のように見える。

Online_ スプライトまとめ

細かいところに違いはあるが、Online_ スプライトは3つのボタンを出すところは intro 画面の Buttons スプライトと同じ動作をし、コスチュームやコードも似通っていた。

すこし変なコードも散見されるが、特にボタンの処理が次の4つに分けられている所は Buttons と全くおなじで、ほかの画面でも使われているだろうと予想される。

画像38

これからこの構造がでてきたら、「Buttonsパターン」と呼ぶことにして、コスチューム以外は、④の「ボタンをクリックしたときの処理」だけに注目するようにしたい。

ところで、Join by code3 コスチュームは結局使われていなかった。

次の記事

Among Us Scratch の解析6:回転するクルー達

いいなと思ったら応援しよう!