WebController - Enter フレーム
Enter フレームセクションには、各フレームまたは同様の方法でトリガされるメソッドが含まれています。
onNewFrame
onNewFrame(frameSource)
onNewFrame メソッドは、常に更新が必要な様々なタスクを実行します。作成した Genvid クライアント用に、フレームごとに呼び出します。
まず updateOverlays(compositionData) を使用して、ビデオストリームの構成に合わせてオーバーレイを更新します。そこで、受信した構成データのソース数や構成データのレイアウトタイプを確認します。マルチソース (ChromaKey/PiP) やシングルソースのストリーミングに合わせてオーバーレイを更新することができます。
次に updateStreamsInfoFromSession(session) を呼び出して、フレームからゲームデータのストリームを抽出します。抽出したデータは、位置、色、カメラなどに分割されており、Web ページのオーバーレイの更新に使用します。
最後に、GenvidClient にクエリを送り、遅延、遅延オフセット、ボリュームの可視性などの情報で UI を更新します。
onStreamsReceived
onStreamsReceived(dataStreams)
onStreamsReceived メソッドはループを使ってゲームデータを取得し、ゲームデータの形式を確認します。フォーマットが UTF-8 の場合は、ストリーム ID を確認して、受信した文字列が著作権データであることを確認し、著作権データであればコンソールに表示します。残りのデータストリームは JSON でフォーマットされます。その場合、"Names"ストリームを探し、名前データを initPlayerTable(cubeNames) のパラメータとして渡すことで、情報パネルを構築することができます。次に、ストリームデータにアノテーションがないかをチェックします。 "Colors" ID を持つ JSON フォーマットのアノテーションを見つけたら、どのキューブが色を変えたかというデータを抽出してオーバーレイを更新します。
initPlayerTable
initPlayerTable(cubeData)
initPlayerTable は、各オブジェクトのストリームウィンドウの下にテーブルを作成します。
受信したゲームデータに基づいて、各オブジェクトの情報について繰り返すループ処理から始めます。
あとで HTML タグに追加するノードを複製します。
次に、テーブル、応援、リセットのクリック機能のイベントリスナーを追加します。
最後に、使用可能な色のループ処理を行い、クリックイベントリスナーを追加します。
// Method used to display the appropriate number of players with their proper buttons initPlayerTable(cubeNames) { const cubePanel = document.getElementById("cube_panel_prototype"); // The prototype panel gets removed after init. if (cubePanel === null) { // We already have real pannels. No need for more. return; } this.cubeNames = cubeNames; for (const idx in cubeNames) { const name = this.cubeNames[idx]; let cubePanelClone = cubePanel.cloneNode(true); cubePanelClone.id = idx; cubePanelClone.getElementsByClassName("cube_name")[0].innerText = name; let cheerButton = cubePanelClone.querySelector(".cheer"); cheerButton.addEventListener("click", () => this.onCheer(name), false); let cubeDiv = cubePanelClone.querySelector(".cube"); cubeDiv.addEventListener( "click", () => this.selectCube(parseInt(idx)), false ); this.cubePanelDiv.push(cubeDiv); // will stop triggering initPlayerTable from onNewFrame() indefinitely let resetButton = cubePanelClone.querySelector(".reset"); resetButton.addEventListener("click", () => this.onReset(name), false); for (let colorSelect of this.tableColor) { let colorButton = cubePanelClone.querySelector("." + colorSelect[0]); colorButton.addEventListener( "click", () => this.onColorChange(name, colorSelect[1]), false ); } document.querySelector(".gameControlsDiv").append(cubePanelClone); const panel = { panel: cubePanelClone, x: cubePanelClone.getElementsByClassName("position_x")[0], y: cubePanelClone.getElementsByClassName("position_y")[0], z: cubePanelClone.getElementsByClassName("position_z")[0], popularity: cubePanelClone.getElementsByClassName("cheer_value")[0], }; this.panels.push(panel); } // We don't need the prototype panel anymore. We now have real panels. cubePanel.remove(); }
onNotificationsReceived
onNotificationsReceived(message)
onNotificationsReceived メソッドは通知の ID が Popularity であるかどうかを調べ、その際に JSON データを JavaScript に変換し、オーバーレイを更新します。また、Web サイトが通知を受信したときにこのメソッドを呼び出します。
// Upon receiving a notification, gets the notification content
onNotificationsReceived(message) {
for (let notification of message.notifications) {
switch (notification.id) {
case "RESET":
try {
let obj = JSON.parse(notification.data);
this.showNotification(`${notification.id} - Velocity, position, and orientation were reset for ${obj.cube}.`);
} catch (e) {
genvid.log("Error when parsing JSON:", notification.data);
}
break;
case "SPEED":
try {
let obj = JSON.parse(notification.data);
this.showNotification(`${notification.id} - Speed ${obj.speed.toPrecision(3)} applied to ${obj.cube}.`);
} catch (e) {
genvid.log("Error when parsing JSON:", notification.data);
}
break;
case "DIRECTION":
try {
let obj = JSON.parse(notification.data);
let direction = '|X:' + obj.direction[0] + ' Y:' + obj.direction[1] + ' Z:' + obj.direction[2] + '|';
this.showNotification(`${notification.id} - Direction ${direction} applied to ${obj.cube}.`);
} catch (e) {
genvid.log("Error when parsing JSON:", notification.data);
}
break;
case "POPULARITY":
try {
let obj = JSON.parse(notification.data);
this.popularities = obj.popularity;
} catch (e) {
genvid.log("Error when parsing JSON:", notification.data);
}
break;
default:
genvid.warn("Unrecognized notification: " + notification.id);
}
}
}
render
render
render 関数は、提供されたゲームデータを使用してシーンを更新します。まず、キューブ名を受け取ったかを確認します。受け取っている場合、対応するタブとサークルスプライトを作成します。この処理は1度だけ行います。次に、受信したカメラデータ、キューブの位置データ、 の機能を使って、2D 空間のスプライトとタグの位置を更新し、レンダリングされたフレーム内のキューブの位置を視覚的に一致させます。位置情報はプレイヤーパネルの更新にも使用します。次に レンダラーを呼び出して、更新されたシーンをレンダリングします。最後に、render を引数として requestAnimationFrame を呼び出して、シーンを更新します。