本ワークショップにはPlayCanvasアカウントが必要です!
PlayCanvasアカウントをお持ちでない方はこちら↓
2017.07.27 PlayCanvas運営事務局 Photon運営事務局
※卓上のVRゴーグルはワークショップで使用します!
組み立ててお待ちください!
津田良太郎 portal
GMOクラウド
PlayCanvas運営事務局,Photon運営事務局
デベロッパーエバンジェリスト
Webはほぼ未経験でしたが
最近はPlayCanvasでWebコンテンツを作ってます
エンジン + エディタ + コミュニティ 一体型の
クラウド型ゲーム開発プラットフォーム
オープンソース | JavaScript |
3Dゲームエンジン | エクストリームプログラミング |
HTML5 + WebGL | リアルタイムマルチプレイ |
クロスプラットフォーム | ブラウザゲーム |
リッチメディア広告 | WebVR |
コード全文 | 8MB |
ランタイムコード | 2.43MB |
gZip圧縮後 | 147KB |
2016.12
WebVRも搭載!
コンパイル・リロードなしで反映!
3Dビジュアルエディター/コードエディター
チーム開発
エクスプローラー
コミュニティ
NEW!
Ponta Dozer
ネットワークゲームを作るための機能を提供した
サービス&ミドルウェア
photon cloud(クラウド型) | ロビー,ルーム,RPC |
photon server(ミドルウェア型) | WebRPC/Webhooks |
Free Start | マルチプラットフォーム対応 |
クライアント/サーバ通信 | 全世界対応 |
協力・対戦ゲームを支えるPhotonの新リリース情報、最新事例の詳解 : GTMF2015
マルチプレイを実現するネットワークエンジンの決定版『Photon』の本音を語るディベロッパー座談会&最新情報 : CEDEC2015
Cocos2d-x/Marmalade&Photon最新事例 : GTMF2016
ネットワークエンジンの現在・過去・未来 ~Photonもあるよ!~ :CEDEC2016
Photon
SDK
SDK
SDK
Client
Client
Client
Facebook Spaces
ということで
複数人参加型のソーシャルVRアプリを開発します
①VR Starter Kitを選択
③CREATE
②名前を
[socialVR]にする
1. シーン(SCENE) シーンビューには製作中のゲーム世界(シーン)が表示され、自由な位置・角度から眺めることができます。
4. アセット(ASSETS) 製作中のプロジェクト(ゲーム全体)に含まれるモデル、スクリプト、グラフィックやサウンドなどのデータ、その他のリソースがファイル単位で表示されます。
2. インスペクター(INSPECTOR) シーンの中で選択肢中のオブジェクトが持つ属性を表示・編集するためのビューです。 属性には座標やメッシュといった見た目上のものから、衝突判定や物理制御に関するパラメーターなどもあり、その他ユーザー定義のものもここに表示されます。
3. ヒエラルキー(HIERARCHY) シーン内に存在するオブジェクトの一覧が表示されます。 編集中のシーン内でオブジェクトをコピー/ペーストしたり、適切な名前をつけて整理することもできます。
5. メニュー(MENU) シーンのビューモードやプロジェクトセッティング等の作業が行えます。
①
②
③
①ASSETS [+]
> Folder を新規作成
②名前をworkspaceに変更
downloadが表示されない方はこちら
①/workspace/model/を選択
②objをドラック&ドロップ
①マテリアルを選択
②EMMISIVEを選択
③Colorを設定
①app.jsを選択
②インスペクターから
PARSEを実行
③Settingを選択
④インスペクターから
SCRIPT LOADING ORDERを選択、並び順を変更
ルームとカメラのみ!
空の状態になっていればOK!
①Entityを新規作成
②名前を変更
[PhotonController]
③ADD COMPONENT
Scriptを追加
④ADD SCRIPT
appを追加
①AppIDを設定
②AppVersionに
自分のATND名を入力
③Regionを
Japan, Tokyoに
①/workspace/srcを選択
②Camera offset
> Cameraを選択
③ADD SCRIPT > New Scriptから
"player.js"を新規作成・追加
var Player = pc.createScript('player');
var istouch = false; //タッチしているかどうか
// initialize code called once per entity
Player.prototype.initialize = function() {
this.entity.parent.setLocalPosition((Math.random() - 0.5) * 10,1.5,(Math.random() - 0.5) * 10); //初期化時に位置をランダムに設定
if(this.app.touch){//もしタッチデバイスなら
this.app.touch.on("touchstart",this._touchstart,this);//タッチした瞬間のイベントハンドラを設定
this.app.touch.on("touchend",this._touchend,this);//タッチが離れた瞬間のイベントハンドラを設定
}
};
// update code called every frame
Player.prototype.update = function(dt) {
if(istouch){//タッチしていたら
this.locomotion();//前方向に移動
}
};
/*プレイヤー移動の関数*/
Player.prototype.locomotion = function(){
var rot = playangleToRealangle(this.entity.getEulerAngles());//プレイヤーの向いている角度をY軸オイラー角のみ抽出
if(rot){
this.entity.parent.translate(-0.1 * Math.sin(rot / 180 * Math.PI),0,-0.1 * Math.cos(rot / 180 * Math.PI));//向いている方向に移動
}
};
Player.prototype._touchstart = function(ob){//タッチした瞬間に呼ばれる
istouch = true;
};
Player.prototype._touchend = function(ob){//タッチが離れた瞬間に呼ばれる
istouch = false;
};
var playangleToRealangle = function(playangle){//PlayCanvasで得られるオイラー角のうちYが取りうる範囲を0-360に変換して返す関数
//playangle is eulerAngles Vec3
//vec3を度数法に変換する
var ans;
if(playangle.x < 100 && playangle.x > -100){
//angle 0 - 90 , 270 - 360
if(playangle.y >= 0 ){
//angle 0 - 90
ans = playangle.y;
}else{
//angle 270 - 360
ans = 360 + playangle.y;
}
}
if(playangle.x <= -100 && playangle.x >= -170){
ans = 90 + (90 - playangle.y);
}
if(playangle.x >= 100){
//angle 90 -180
ans = 180 - playangle.y;
}
if(playangle.x < -170){
//angle 180 - 270
ans = 180 - playangle.y;
}
return ans;
};
// swap method called for script hot-reloading
// inherit your script state here
// Player.prototype.swap = function(old) { };
// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/
①Entity作成
②名前を
[otherPlayerPool]に
③ADD COMPONENT
-> Script
④ADD SCRIPT
-> new [playerpool.js]
①Entity作成
②名前を
[otherPlayer]に
③[otherplayer]を選択
④モデルをシーンに
ドラッグ&ドロップ
[otherPlayer > モデル]
Position[0.071, 0.124, -0.105]
Rotation[0, 180, 0]
Scale[5, 5, 5]
var Playerpool = pc.createScript('playerpool');
Playerpool.attributes.add("ptemplate",{type:"entity"}); //他プレイヤーのオブジェクト
var photonObject;//photonオブジェクト
var _self;//自分自身
// initialize code called once per entity
Playerpool.prototype.initialize = function() {
photonObject = this.app.root.findByName("PhotonController");//PhotonControllerを格納
_self = this;//自分自身を格納(スコープが外れるため)
};
// update code called every frame
Playerpool.prototype.update = function(dt) {
//in update method...
photonObject.photon.onActorJoin = function(actor){//アクターがジョインしたときに呼ばれるコールバック
if(actor.actorNr == this.myActor().actorNr)
{//もし入ったアクターが自分自身なら
//if other player joined room before you join
for(var i = 1;i < this.myActor().actorNr;i++){//アクターナンバーの数だけまわす
if(this.myRoomActors()[i]){//もしそのアクターナンバーのアクターがまだ存在したら
if(!this.myRoomActors()[i].isLocal){//そのアクターがlocal(自分自身)でなければ
//loop num of players in the room
_self.addplayer(i);//自分が入った以前に入ったアクターを生成
}
}
}
}
else
{//もし他のアクターが入ったら
_self.addplayer(actor.actorNr);//アクターを生成
}
};
//in update method...
photonObject.photon.onActorLeave = function(actor,cleanup){//アクターが退室したときに呼ばれるコールバック
if(actor.actorNr == this.myActor().actorNr)
{//自分自身
//if player leave room
}
else
{//他プレイヤー
//other player leave room
_self.removePlayer(actor.actorNr);//他プレイヤーを削除
}
};
};
Playerpool.prototype.addplayer = function(name){//プレイヤーを追加する関数 引数は名前
var object = this.ptemplate.clone();
object.setName(name);
this.entity.addChild(object);
object.enabled = true;
};
Playerpool.prototype.removePlayer = function(name){//引数で指定したプレイヤーを削除するメソッド
var object = this.app.root.findByName(name);
if(object){
object.destroy();
}
};
// swap method called for script hot-reloading
// inherit your script state here
// Playerpool.prototype.swap = function(old) { };
// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/
①playerpool > ptemplateに
otherPlayerをアタッチ
②otherPlayerをdisableに
var Player = pc.createScript('player');
var istouch = false; //タッチしているかどうか
var serialstring = "";//判別用シリアル文字列
var photonObject;//Photonオブジェクト
// initialize code called once per entity
Player.prototype.initialize = function() {
photonObject = this.app.root.findByName("PhotonController");//Photonオブジェクトを格納
this.entity.parent.setLocalPosition((Math.random() - 0.5) * 10,1.5,(Math.random() - 0.5) * 10); //初期化時に位置をランダムに設定
if(this.app.touch){//もしタッチデバイスなら
this.app.touch.on("touchstart",this._touchstart,this);//タッチした瞬間のイベントハンドラを設定
this.app.touch.on("touchend",this._touchend,this);//タッチが離れた瞬間のイベントハンドラを設定
}
};
// update code called every frame
Player.prototype.update = function(dt) {
var sendstring = "";//送信用シリアル文字列
var position = this.entity.getPosition();//自身の座標を取得
var rotation = this.entity.getEulerAngles();//自身のオイラー角を取得
sendstring += position.x + ";" + position.y + ";" + position.z + ";" + rotation.x + ";" + rotation.y + ";" + rotation.z;//座標とオイラー角をシリアライズしsendstringに格納
if(serialstring != sendstring){//座標・角度の更新があれば
sendMyPosition();//送信
serialstring = sendstring;//判別用文字列に格納
}
if(istouch){//タッチしていたら
this.locomotion();//前方向に移動
}
};
/*プレイヤー移動の関数*/
Player.prototype.locomotion = function(){
var rot = playangleToRealangle(this.entity.getEulerAngles());//プレイヤーの向いている角度をY軸オイラー角のみ抽出
if(rot){
this.entity.parent.translate(-0.1 * Math.sin(rot / 180 * Math.PI),0,-0.1 * Math.cos(rot / 180 * Math.PI));//向いている方向に移動
}
};
Player.prototype._touchstart = function(ob){//タッチした瞬間に呼ばれる
istouch = true;
};
Player.prototype._touchend = function(ob){//タッチが離れた瞬間に呼ばれる
istouch = false;
};
function sendMyPosition(){//Photonを用いて座標・角度の送信を行う関数
photonObject.photon.raiseEvent(1,serialstring);//イベントコード1でserialstringを送信
}
var playangleToRealangle = function(playangle){//PlayCanvasで得られるオイラー角のうちYが取りうる範囲を0-360に変換して返す関数
//playangle is eulerAngles Vec3
//vec3を度数法に変換する
var ans;
if(playangle.x < 100 && playangle.x > -100){
//angle 0 - 90 , 270 - 360
if(playangle.y >= 0 ){
//angle 0 - 90
ans = playangle.y;
}else{
//angle 270 - 360
ans = 360 + playangle.y;
}
}
if(playangle.x > 170){
//angle 90 -180
ans = 180 - playangle.y;
}
if(playangle.x < -170){
//angle 180 - 270
ans = 180 - playangle.y;
}
return ans;
};
// swap method called for script hot-reloading
// inherit your script state here
// Player.prototype.swap = function(old) { };
// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/
var Playerpool = pc.createScript('playerpool');
Playerpool.attributes.add("ptemplate",{type:"entity"}); //他プレイヤーのオブジェクト
var photonObject;//photonオブジェクト
var _self;//自分自身
// initialize code called once per entity
Playerpool.prototype.initialize = function() {
photonObject = this.app.root.findByName("PhotonController");//PhotonControllerを格納
_self = this;//自分自身を格納(スコープが外れるため)
};
// update code called every frame
Playerpool.prototype.update = function(dt) {
photonObject.photon.onEvent = function(code, content, actorNr){//メッセージを受信したときに呼ばれるコールバック
if(code == 1){//もしイベントコードが1なら
for(var l = 0;l<_self.entity.children.length;l++){//自身の子の数(他プレイヤーの数)だけまわす
if(_self.entity.children[l].name == actorNr){//送信元のプレイヤーと他プレイヤーオブジェクトの関連付け
var position = new pc.Vec3(parseFloat(content.split(";")[0],10),parseFloat(content.split(";")[1],10),parseFloat(content.split(";")[2],10));//座標情報のデシリアライズ
var rotation = new pc.Vec3(parseFloat(content.split(";")[3],10),parseFloat(content.split(";")[4],10),parseFloat(content.split(";")[5],10));//角度情報のデシリアライズ
_self.entity.children[l].setPosition(position);//座標を指定
_self.entity.children[l].setEulerAngles(rotation);//角度を指定
}
}
}
};
//in update method...
photonObject.photon.onActorJoin = function(actor){//アクターがジョインしたときに呼ばれるコールバック
sendMyPosition();//座標を送信
if(actor.actorNr == this.myActor().actorNr)
{//もし入ったアクターが自分自身なら
//if other player joined room before you join
for(var i = 1;i < this.myActor().actorNr;i++){//アクターナンバーの数だけまわす
if(this.myRoomActors()[i]){//もしそのアクターナンバーのアクターがまだ存在したら
if(!this.myRoomActors()[i].isLocal){//そのアクターがlocal(自分自身)でなければ
//loop num of players in the room
_self.addplayer(i);//自分が入った以前に入ったアクターを生成
}
}
}
}
else
{//もし他のアクターが入ったら
_self.addplayer(actor.actorNr);//アクターを生成
}
};
//in update method...
photonObject.photon.onActorLeave = function(actor,cleanup){//アクターが退室したときに呼ばれるコールバック
if(actor.actorNr == this.myActor().actorNr)
{//自分自身
//if player leave room
}
else
{//他プレイヤー
//other player leave room
_self.removePlayer(actor.actorNr);//他プレイヤーを削除
}
};
};
Playerpool.prototype.addplayer = function(name){//プレイヤーを追加する関数 引数は名前
var object = this.ptemplate.clone();
object.setName(name);
this.entity.addChild(object);
object.enabled = true;
};
Playerpool.prototype.removePlayer = function(name){//引数で指定したプレイヤーを削除するメソッド
var object = this.app.root.findByName(name);
if(object){
object.destroy();
}
};
// swap method called for script hot-reloading
// inherit your script state here
// Playerpool.prototype.swap = function(old) { };
// to learn more about script anatomy, please read:
// http://developer.playcanvas.com/en/user-manual/scripting/
var App = pc.createScript('app');
App.attributes.add("PHOTON CLOUD",{type:"title"});
App.attributes.add("appid",{type:"string",default:"",title:"AppId",description:"Please input your AppId"});
App.attributes.add("appversion",{type:"string",default:"1.0",title:"Appversion",description:"Application version. You can not be matching if you set diferense version."});
App.attributes.add("Region",{
type: 'string',
default: 'default',
description: 'Photon Cloud has servers in several regions, distributed across multiple hosting centers over the world.You can choose optimized region for you.',
enum: [
{ "Select Region" : 'default'},
{ "Asia, Singapore" : 'asia'},
{ "Australia, Melbourne": 'au'},
{ "Canada, East Montreal": 'cae'},
{ "Europe, Amsterdam":'eu'},
{ "India, Chennai": 'in'},
{ "Japan, Tokyo": 'jp'},
{ "South America, Sao Paulo":'sa'},
{ "South Korea, Seoul":'kr'},
{ "USA, East Washington":'us'},
{ "USA, West San José":'usw'}
]
});
App.attributes.add("PHOTON SERVER",{type:"title"});
App.attributes.add("Masterserver",{type:"string",title:"Server Address",description:"use Photon Server if you input server address."});
App.attributes.add("GENERAL",{type:"title"});
App.attributes.add("ConnectOnStart",{type:"boolean",default:true,title:"Auto-Join Lobby",description:"Define if PhotonNetwork should join the 'lobby' when connected to the Master server"});
var DemoWss;
var DemoMasterServer;
var connectRegion;
var ConnectOnStart;
// initialize code called once per entity
App.prototype.initialize = function() {
//////////////////////////////////////////////////
//Photon Cloud
//////////////////////////////////////////////////
if(this.appid){
if(document.domain == "playcanvas.com"){
localStorage.setItem("appid",this.appid);
}
DemoAppId = this.appid;
}else
{
if(localStorage.getItem("appid")){
DemoAppId = localStorage.getItem("appid");
}
else if(!this.Masterserver)
{
if(window.confirm("Thank you for your forking! \n Please get and enter your AppId if you started development \n Do you want to acquire AppId now?") === true){
window.location.href = 'https://www.photonengine.com/en/Account/Signup';
}else{
window.open('about:blank','_self').close();
}
}
}
DemoAppVersion = this.appversion;
connectRegion = this.Region;
//////////////////////////////////////////////////
//Photon Server
//////////////////////////////////////////////////
if(this.Masterserver){
DemoMasterServer = this.Masterserver;
DemoAppId = "using photon server";
}
//////////////////////////////////////////////////
//General
//////////////////////////////////////////////////
ConnectOnStart = this.ConnectOnStart;
//////////////////////////////////////////////////
//load and seting UI
//////////////////////////////////////////////////
//html load and initialize
var htmlAsset = this.app.assets.find('index.html');
var div = document.createElement('div');
div.innerHTML = htmlAsset.resource;
document.body.appendChild(div);
htmlAsset.on('load', function () {
div.innerHTML = htmlAsset.resource;
});
// css load and initialize
var cssAsset = this.app.assets.find('style.css');
var stylecss = document.createElement('style');
stylecss.innerHTML = cssAsset.resource;
document.head.appendChild(stylecss);
cssAsset.on('load', function() {
style.innerHTML = cssAsset.resource;
});
//////////////////////////////////////////////////
//Photon start
//////////////////////////////////////////////////
this.entity.photon = new DemoLoadBalancing();
this.entity.photon.start();
};
//////////////////追加 オートジョインルーム//////////////////////
App.prototype.update = function(dt){
this.autojoinroom();
};
App.prototype.autojoinroom = function(){
var isFullhouse = true;//満室かどうか
for(var l = 0;l < this.entity.photon.availableRooms().length;l++){
var room = this.entity.photon.availableRooms()[l];
if(room.maxPlayers > room.playerCount){
isFullhouse = false;
console.log(room);
}
}
var canJoin = this.entity.photon.isInLobby() && !this.entity.photon.isJoinedToRoom() && this.entity.photon.availableRooms().length > 0 && !isFullhouse;//入れるかどうか
if (this.entity.photon.isInLobby()) {
if (canJoin) {//もし入れるなら
this.entity.photon.output("Random Game...");
this.entity.photon.joinRandomRoom();//適当なルームにジョイン
}else{//入れないなら
var name = document.getElementById("newgamename");
this.entity.photon.output("New Game");
this.entity.photon.createRoom(name.value.length > 0 ? name.value : undefined,{maxPlayers:5});//最大5名の部屋を作成し入室
}
}
};
body {
font-family: "Courier New", Courier, monospace;
text-align: center;
}
.container {
position: absolute;
background-color: rgba(255,255,255,0.6);
border-radius: 30px;
top: 200%;
left: 200%;
width: 320px;
}
.log {
position: absolute;
text-align:left;
font-size:5px;
color:#fff;
border-radius: 30px;
top: 0%;
left: 0%;
width: 320px;
}
input {
background-color: transparent;
border: 2px solid #666;
color: #111;
line-height: 20px;
margin: 2px; padding: 2px;
}
select {
background-color: transparent;
border: 2px solid #666;
color: #111;
line-height: 20px;
margin: 2px; padding: 2px;
}
button {
background-color: transparent;
border: 2px solid #666;
color: #111;
line-height: 20px;
margin: 2px; padding: 2px;
}
button[disabled] {
background-color: transparent;
border: 2px solid #666;
color: #888;
line-height: 20px;
margin: 2px; padding: 2px;
}
button:hover {
background-color: rgba(255, 255, 255, .4);
}
input:hover {
background-color: rgba(255, 255, 255, .4);
}
select:hover {
background-color: rgba(255, 255, 255, .4);
}
button[disabled]:hover {
background-color: transparent;
}
.white{
color: #ffffff;
}
.black{
color: #000000;
}
* {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-touch-callout: none;
-webkit-user-select: none;
}
app.js
style.css
var DemoLoadBalancing = (function (_super) {
__extends(DemoLoadBalancing, _super);
function DemoLoadBalancing() {
_super.call(this, DemoWss ? Photon.ConnectionProtocol.Wss : Photon.ConnectionProtocol.Ws, DemoAppId, DemoAppVersion);
this.logger = new Exitgames.Common.Logger("Demo:");
this.output(this.logger.format("Init", this.getNameServerAddress(), DemoAppId, DemoAppVersion));
this.logger.info("Init", this.getNameServerAddress(), DemoAppId, DemoAppVersion);
this.setLogLevel(Exitgames.Common.Logger.Level.DEBUG);
}
DemoLoadBalancing.prototype.start = function () {
this.setupUI();
// connect if no fb auth required
if (ConnectOnStart) {
if (DemoMasterServer) {
this.setMasterServerAddress(DemoMasterServer);
this.connect();
}
else {
this.connectToRegionMaster(connectRegion);
}
}
};
DemoLoadBalancing.prototype.onError = function (errorCode, errorMsg) {
this.output("Error " + errorCode + ": " + errorMsg);
};
DemoLoadBalancing.prototype.onStateChange = function (state) {
// "namespace" import for static members shorter acceess
var LBC = Photon.LoadBalancing.LoadBalancingClient;
var stateText = document.getElementById("statetxt");
stateText.textContent = LBC.StateToName(state);
this.updateRoomButtons();
this.updateRoomInfo();
};
DemoLoadBalancing.prototype.updateRoomInfo = function () {
var stateText = document.getElementById("roominfo");
var message;
if(this.isJoinedToRoom()){
message = "room: " + this.myRoom().name;
}
else
{
message = "not joined room";
}
stateText.innerHTML = message;
stateText.innerHTML = stateText.innerHTML + "<br>";
this.updateRoomButtons();
};
DemoLoadBalancing.prototype.onActorPropertiesChange = function (actor) {
this.updateRoomInfo();
};
DemoLoadBalancing.prototype.onMyRoomPropertiesChange = function () {
this.updateRoomInfo();
};
DemoLoadBalancing.prototype.onRoomListUpdate = function (rooms, roomsUpdated, roomsAdded, roomsRemoved) {
this.logger.info("Demo: onRoomListUpdate", rooms, roomsUpdated, roomsAdded, roomsRemoved);
this.output("Demo: Rooms update: " + roomsUpdated.length + " updated, " + roomsAdded.length + " added, " + roomsRemoved.length + " removed");
this.onRoomList(rooms);
this.updateRoomButtons(); // join btn state can be changed
};
DemoLoadBalancing.prototype.onRoomList = function (rooms) {
var menu = document.getElementById("gamelist");
while (menu.firstChild) {
menu.removeChild(menu.firstChild);
}
var selectedIndex = 0;
for (var i = 0; i < rooms.length; ++i) {
var r = rooms[i];
var item = document.createElement("option");
item.textContent = r.name;
menu.appendChild(item);
if (this.myRoom().name == r.name) {
selectedIndex = i;
}
}
menu.selectedIndex = selectedIndex;
this.output("Demo: Rooms total: " + rooms.length);
this.updateRoomButtons();
};
DemoLoadBalancing.prototype.onJoinRoom = function () {
this.output("Game " + this.myRoom().name + " joined");
this.updateRoomInfo();
};
DemoLoadBalancing.prototype.onActorJoin = function (actor) {
this.output("actor " + actor.actorNr + " joined");
this.updateRoomInfo();
};
DemoLoadBalancing.prototype.onActorLeave = function (actor) {
this.output("actor " + actor.actorNr + " left");
this.updateRoomInfo();
};
DemoLoadBalancing.prototype.sendMessage = function (message) {
try {
this.raiseEvent(1, { message: message, senderName: "user" + this.myActor().actorNr });
}
catch (err) {
this.output("error: " + err.message);
}
};
DemoLoadBalancing.prototype.setupUI = function () {
var _this = this;
this.logger.info("Setting up UI.");
var btnJoin = document.getElementById("joingamebtn");
btnJoin.onclick = function (ev) {
if (_this.isInLobby()) {
var menu = document.getElementById("gamelist");
var gameId = menu.children[menu.selectedIndex].textContent;
_this.output(gameId);
_this.joinRoom(gameId);
}
else {
_this.output("Reload page to connect to Master");
}
return false;
};
var btnJoin2 = document.getElementById("joinrandomgamebtn");
btnJoin2.onclick = function (ev) {
if (_this.isInLobby()) {
_this.output("Random Game...");
_this.joinRandomRoom();
}
else {
_this.output("Reload page to connect to Master");
}
return false;
};
var btnNew = document.getElementById("newgamebtn");
btnNew.onclick = function (ev) {
if (_this.isInLobby()) {
var name = document.getElementById("newgamename");
_this.output("New Game");
_this.createRoom(name.value.length > 0 ? name.value : undefined);
}
else {
_this.output("Reload page to connect to Master");
}
return false;
};
var btn = document.getElementById("leavebtn");
btn.onclick = function (ev) {
_this.leaveRoom();
_this.updateRoomInfo();
return false;
};
this.updateRoomButtons();
};
DemoLoadBalancing.prototype.output = function (str, color) {
// var log = document.getElementById("theDialogue");
// if(log.clientHeight / window.parent.screen.height > 0.9){
// log.innerHTML = "";
// }
// var escaped = str.replace(/&/, "&").replace(/</, "<").
// replace(/>/, ">").replace(/"/, """);
// if (color) {
// escaped = "<FONT COLOR='" + color + "'>" + escaped + "</FONT>";
// }
// log.innerHTML = log.innerHTML + escaped + "<br>";
// log.scrollTop = log.scrollHeight;
};
DemoLoadBalancing.prototype.updateRoomButtons = function () {
var btn;
btn = document.getElementById("newgamebtn");
btn.disabled = !(this.isInLobby() && !this.isJoinedToRoom());
var canJoin = this.isInLobby() && !this.isJoinedToRoom() && this.availableRooms().length > 0;
btn = document.getElementById("joingamebtn");
btn.disabled = !canJoin;
btn = document.getElementById("joinrandomgamebtn");
btn.disabled = !canJoin;
btn = document.getElementById("leavebtn");
btn.disabled = !(this.isJoinedToRoom());
};
return DemoLoadBalancing;
}(Photon.LoadBalancing.LoadBalancingClient));
demoloadbalancing.js
ソーシャルVR体験を是非共有してみてください!
大変駆け足になってしまいましたが
ご質問は随時募集しております。
日時 | タイトル | 場所 |
---|---|---|
8/30-9/1 | CEDEC2017 セッション/ブース/ハンズオン | パシフィコ横浜 |
9月以降各月 | Photon + PlayCanvas 全国行脚 | 札幌・福岡 名古屋・大阪 |
今後もイベント続々参加/開催予定!
アンケートにお答えください