WebController - Enter フレーム

Enter フレームセクションには、各フレームまたは同様の方法でトリガされるメソッドが含まれています。

onNewFrame

onNewFrame(frameSource)

onNewFrame メソッドは、常に更新が必要な様々なタスクを実行します。作成した Genvid クライアント用に、フレームごとに呼び出します。

  1. まず updateOverlays(compositionData) を使用して、ビデオストリームの構成に合わせてオーバーレイを更新します。そこで、受信した構成データのソース数や構成データのレイアウトタイプを確認します。マルチソース (ChromaKey/PiP) やシングルソースのストリーミングに合わせてオーバーレイを更新することができます。

  2. 次に updateStreamsInfoFromSession(session) を呼び出して、フレームからゲームデータのストリームを抽出します。抽出したデータは、位置、色、カメラなどに分割されており、Web ページのオーバーレイの更新に使用します。

  3. 最後に、GenvidClient にクエリを送り、遅延、遅延オフセット、ボリュームの可視性などの情報で UI を更新します。

onStreamsReceived

onStreamsReceived(dataStreams)

onStreamsReceived メソッドはループを使ってゲームデータを取得し、ゲームデータの形式を確認します。フォーマットが UTF-8 の場合は、ストリーム ID を確認して、受信した文字列が著作権データであることを確認し、著作権データであればコンソールに表示します。残りのデータストリームは JSON でフォーマットされます。その場合、」Names」ストリームを探し、名前データを initPlayerTable(cubeNames) のパラメータとして渡すことで、情報パネルを構築することができます。次に、ストリームデータにアノテーションがないかをチェックします。 「Colors」 ID を持つ JSON フォーマットのアノテーションを見つけたら、どのキューブが色を変えたかというデータを抽出してオーバーレイを更新します。

initPlayerTable

initPlayerTable(cubeData)

initPlayerTable は、各オブジェクトのストリームウィンドウの下にテーブルを作成します。

  1. 受信したゲームデータに基づいて、各オブジェクトの情報について繰り返すループ処理から始めます。

  2. あとで HTML タグに追加するノードを複製します。

  3. 次に、テーブル、応援、リセットのクリック機能のイベントリスナーを追加します。

  4. 最後に、使用可能な色のループ処理を行い、クリックイベントリスナーを追加します。

      // 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 を呼び出して、シーンを更新します。