WebController - Enter フレーム¶
Enter フレームセクションには、各フレームまたは同様の方法でトリガされるメソッドが含まれています。
In This Section
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) {
if (notification.id == "POPULARITY") {
let data = JSON.parse(notification.data);
this.popularities = data.popularity;
} else { // Don't spam popularity.
genvid.log("notification received: ", notification.data);
document.querySelector("#alert_notification").style.visibility = "visible";
document.querySelector("#notification_message").textContent = notification.data;
if (this.showNotificationTimeoutID !== 0) {
clearTimeout(this.showNotificationTimeoutID);
}
this.showNotificationTimeoutID = setTimeout(() => {
document.querySelector("#alert_notification").style.visibility = "hidden";
this.showNotificationTimeoutID = 0
},
this.showNotificationDurationMS);
}
}
}
render¶
render
render 関数は、提供されたゲームデータを使用してシーンを更新します。まず、キューブ名を受け取ったかを確認します。受け取っている場合、対応するタブとサークルスプライトを作成します。この処理は1度だけ行います。次に、受信したカメラデータ、キューブの位置データ、 の機能を使って、2D 空間のスプライトとタグの位置を更新し、レンダリングされたフレーム内のキューブの位置を視覚的に一致させます。位置情報はプレイヤーパネルの更新にも使用します。次に レンダラーを呼び出して、更新されたシーンをレンダリングします。最後に、render を引数として requestAnimationFrame を呼び出して、シーンを更新します。