Admin.js
admin ページにアクセスするには、index.html の Admin をクリックします。ユーザー名とパスワード (どちらも admin) を入力後、プレイヤーテーブルを操作して、ゲームコンテンツを操作できます。web-admin.js のドキュメントに、アクションに使用するコードがすべて含まれています。
このファイルには 1 つの class があります。
このセクションの内容
class AdminController
AdminController class には、ストリームへの接続、適切な情報表示、ゲームへのコマンド送信を行うすべてのメソッドが含まれています。
class 以外では、 AdminController のインスタンスを作成し、それに対して start() を実行してストリームへの接続を開始します。
let admin = new AdminController("video_player_hidden");
admin.start();
以下のセクションでは、AdminController class の内容について説明します。
start
start()
start メソッドがサービスへの接続を開始します。接続が適切に実行できると、検出した IChannelJoinResponse()
で``onChannelJoin`` メソッドを実行します。この処理は、 web.js
ファイルがファイルと同一のものです。
// Starts the connection to the services
start() {
fetch("/api/public/channels/join", {
method: "POST",
})
.then((data) => data.json())
.then((res) => this.onChannelJoin(res))
.catch((error) => genvid.error(`Can't get the stream info: ${error}`));
}
onChannelJoin
onChannelJoin(joinRep)
onChannelJoin メソッドは、サービスとチャネルに接続後、Genvid クライアントを作成します。このプロセスで見つかった情報と、class 作成プロセスで送信された videoPlayerId を使用してクライアントを作成します (これは AdminController class の引数です)。この処理は web.js
ファイルでも同様に行いますが、この場合不必要なメソッドもあります。
その後、この class に特定のイベントを関連付ける必要があります。
- onStreamsReceived
ストリームコンテンツを受信した時にトリガされます。(ゲームデータの取得に使用)
次に、start()
メソッドでクライアントを開始します。
// Creates the genvid Client and the function listening to it
onChannelJoin(joinRep) {
this.client = genvid.createGenvidClient(
joinRep.info,
joinRep.uri,
joinRep.token,
this.videoPlayerId
);
this.client.onStreamsReceived((streams) => {
this.onStreamsReceived(streams);
});
this.client.onNotificationsReceived((notifications) => {
this.onNotificationsReceived(notifications);
});
this.client.start();
}
onStreamsReceived
onStreamsReceived(dataStreams)
onStreamsReceived メソッドは、常に更新が必要な様々なタスクを実行します。作成したGenvidクライアントのストリームと各フレームをWebサイトが受信したときにこのメソッドを呼び出します。この処理は web.js
ファイルで全く同じように行います。
まず、プレイヤーテーブルが作成されていないことを確認します。
さまざまな処理を行う前に、ゲームデータを取得してから、そのデータが有効であることを確認する必要があります。
データの妥当性が確認できたら、データ (キューブ) からオブジェクトリストを取得し、JSON データを変換します。
オブジェクトごとにループ処理を作成し、それぞれにプレイヤーテーブルを作成します。
プレイヤーテーブルのボタンクリックを検知するためのイベントリスナーも追加します。
ループ処理後に、シーンとカメラ変更のための 2 つのボタンを作成します。
シーンとカメラ変更ボタンのクリックを検知するためのイベントリスナーを追加します。
onStreamsReceived(dataStreams) {
for (const stream of dataStreams.streams) {
switch (stream.id) {
case "Ability":
for (const frame of stream.frames) {
let abilities = JSON.parse(frame.data).ability;
if (abilities) {
this.canChangeCamera = abilities[0]; // will be used by changeCamera
this.canChangeScene = abilities[1]; // will be used by changeScene
}
}
if (this.canChangeCamera) {
let cameraButton = document.getElementById("cameraChange");
cameraButton.removeAttribute("disabled");
cameraButton.addEventListener(
"click",
() => {
this.changeCamera();
},
false
);
}
if (this.canChangeScene) {
let sceneButton = document.getElementById("sceneChange");
sceneButton.removeAttribute("disabled");
sceneButton.addEventListener(
"click",
() => {
this.changeScene();
},
false
);
}
break;
case "Names":
for (const frame of stream.frames) {
const cubeNames = JSON.parse(frame.data).name;
let cubeControlPanel = document.getElementById(
"admin_prototype_panel"
);
for (const name of cubeNames) {
let cubeControlPanelClone = cubeControlPanel.cloneNode(true);
cubeControlPanelClone.id = name;
cubeControlPanelClone.querySelector(
".table_name"
).innerText = name;
document
.querySelector(".admin_table_section")
.append(cubeControlPanelClone);
let upButton = cubeControlPanelClone.querySelector(
".upDirection"
);
upButton.addEventListener(
"click",
() => {
this.setDirection(name, 0, 1);
},
false
);
let downButton = cubeControlPanelClone.querySelector(
".downDirection"
);
downButton.addEventListener(
"click",
() => {
this.setDirection(name, 0, -1);
},
false
);
let leftButton = cubeControlPanelClone.querySelector(
".leftDirection"
);
leftButton.addEventListener(
"click",
() => {
this.setDirection(name, -1, 0);
},
false
);
let rightButton = cubeControlPanelClone.querySelector(
".rightDirection"
);
rightButton.addEventListener(
"click",
() => {
this.setDirection(name, 1, 0);
},
false
);
let resetButton = cubeControlPanelClone.querySelector(".reset");
resetButton.addEventListener(
"click",
() => {
this.reset(name);
},
false
);
let slowerButton = cubeControlPanelClone.querySelector(".slower");
slowerButton.addEventListener(
"click",
() => {
this.changeSpeed(name, 0.8);
},
false
);
let fasterButton = cubeControlPanelClone.querySelector(".faster");
fasterButton.addEventListener(
"click",
() => {
this.changeSpeed(name, 1.25);
},
false
);
}
cubeControlPanel.remove();
this.cubesStreamReceived = true;
}
break;
}
if (this.cubesStreamReceived) {
this.client.onStreamsReceived(null);
this.playerTableSetup = true;
}
}
}
sendCommands
sendCommands(bodyCommands, successMessage, errorMessage)
sendCommands メソッドは AdminController クラスのメソッドから受け取ったコマンドをゲームに送信します。表示するすべてのメッセージを displayMessage と displayErrorMessage メソッドに転送します。
sendCommands(bodyCommands, successMessage, errorMessage) {
fetch("/api/admin/commands/game", {
method: "POST",
body: JSON.stringify(bodyCommands),
headers: {
"Content-Type": "application/json",
},
})
.then(() => {
this.displayMessage(successMessage);
})
.catch((err) => {
this.displayErrorMessage(`Failed with error ${err} ${errorMessage}`);
});
}
setDirection
setDirection(cubeName, x, z)
setDirection メソッドはゲームにコマンドを送信し、プレイヤーの向きを設定します。プレイヤーの向きをクリックしたときに呼び出します。
// Changes the direction of the cube
setDirection(cubeName, x, z) {
const commands = {
id: "direction",
value: `${cubeName}:${x}:0:${z}`,
};
const successMessage = `Command sent.`;
const errorMessage = `to set direction to ${cubeName}:${x}:${z}`;
this.sendCommands(commands, successMessage, errorMessage);
}
changeSpeed
changeSpeed(cubeName, factor)
changeSpeed メソッドは、ゲームにコマンドを送信し、オブジェクトの低速化、または高速化を指示します。プレイヤーの Slower または Faster をクリックしたときに呼び出します。
// Changes the speed of the cube
changeSpeed(cubeName, factor) {
const commands = {
id: "speed",
value: `${cubeName}:${factor}`,
};
const successMessage = `Command sent.`;
const errorMessage = `to changeSpeed ${cubeName}:${factor}`;
this.sendCommands(commands, successMessage, errorMessage);
}
reset
reset(cubeName)
reset メソッドは、ゲームにコマンドを送信し、オブジェクトを元の位置に戻します。プレイヤーの Reset をクリックしたときに呼び出します。
// Resets the position of the cube
reset(cubeName) {
const commands = {
id: "reset",
value: cubeName,
};
const successMessage = `Command sent.`;
const errorMessage = `to reset ${cubeName}`;
this.sendCommands(commands, successMessage, errorMessage);
}
changeCamera
changeCamera()
changeCamera メソッドは、ゲームにコマンドを送信し、現在のカメラを変更します。プレイヤーの Camera change ボタンをクリックしたときに呼び出します。
changeCamera() {
const commands = {
id: "camera",
value: "change",
};
const successMessage = "Camera change done";
const errorMessage = "to change the camera";
this.sendCommands(commands, successMessage, errorMessage);
}
changeScene
changeScene()
changeScene メソッドは、ゲームにコマンドを送信し、現在のシーンを変更します。プレイヤーの Scene change ボタンをクリックしたときに呼び出します。
changeScene() {
const commands = {
id: "scene",
value: "change",
};
const successMessage = "Scene change done";
const errorMessage = "to change the scene";
this.sendCommands(commands, successMessage, errorMessage);
}
displayMessage
displayMessage()
displayMessage メソッドは、実行した操作が正常に行われたことを示すメッセージを表示します。ストリームから適切にデータを取得するかどうかを確認したり、コマンド操作が成功したかどうかを確認する場合に役立ちます。
displayMessage(message) {
let messageErrorDiv = document.querySelector("#alert_error_cube");
messageErrorDiv.style.visibility = "hidden";
let messageNotificationDiv = document.querySelector(
"#alert_notification_cube"
);
messageNotificationDiv.style.visibility = "hidden";
let messageDiv = document.querySelector("#alert_success_cube");
messageDiv.style.visibility = "visible";
let messageSpan = document.querySelector("#success_message_cube");
messageSpan.textContent = message;
}
displayErrorMessage
displayErrorMessage()
displayErrorMessage メソッドは、実行した操作のエラーメッセージを表示します。ストリームから適切にデータを取得できなかったことを確認したり、コマンド操作が失敗したかどうかを確認する場合に役立ちます。
displayErrorMessage(message) {
let messageNotificationDiv = document.querySelector(
"#alert_notification_cube"
);
messageNotificationDiv.style.visibility = "hidden";
let messageDiv = document.querySelector("#alert_success_cube");
messageDiv.style.visibility = "hidden";
let messageErrorDiv = document.querySelector("#alert_error_cube");
messageErrorDiv.style.visibility = "visible";
let messageSpan = document.querySelector("#error_message_cube");
messageSpan.textContent = message;
}