mugeda動畫平台還可以用來制作跨屏互動的動畫應用,比如在PC端的大屏幕上顯示動畫的主界面,同時會顯示出供手機掃描的二維碼,手機掃描後會在手機上顯示手機端動畫界面。通過手機就可以和PC端的顯示界面跨屏互動操作。這種動畫應用在類似一些商場搞活動,或者戶外宣傳等常見可以使用。可以制作一對一玩的跨屏互動應用,也可以制作一對多玩(多個玩家同時玩)的跨屏互動應用。為了更好的理解跨屏互動應用的使用,本文檔將通過一個簡單的例子來演示跨屏動畫的制作過程。
一、制作動畫
1.PC端動畫制作
a.在PC端,設置舞台尺寸為寬700、高480
b.在舞台中放在一個文字對象,並命名為info(用於顯示連接及通訊信息)
c.在舞台中放在一個二維碼的圖片。(該二維碼會在運行時被用真實的客戶端連接的二維碼替換)。給該圖片命名qrc。
如圖:
2.移動端動畫制作
a.設置舞台尺寸為寬320、高416
b.在舞台中放一個用圓角矩形和文字組成的按鈕,文字內容為connectPC。為該按鈕設置動作為回調函數,觸發方式:單擊,函數名字:connectPC
如圖:
c.用同步驟b相同的方式,再創建兩個按鈕,文字分別為sayHello、sayOK,函數名字分別為sayHello、sayOK。
最後舞台如圖:
3.導入腳本
a.PC端,點擊菜單欄的文件-》導入-》腳本。在彈出的導入腳本對話框中,勾選jquery.js、socketio.js、jquery.qrcode.JS。點擊確定。
如圖:
b.用同樣的方式在移動端導入socketio.JS
導入文件說明:
跨屏動畫通訊用到的Mugeda.Socket對象是基於socket.io封裝的,所以PC端和移動端都需要導入socketio.js文件。PC端需要在游戲開始時動態更換二維碼圖片,所以需要導入與二維碼相關的庫文件jquery.js、jquery.qrcode.JS
二、編寫代碼
用到的主要對象說明:
Mugeda.Socket對象,用於維護存連接相關數據和操作。
Mugeda.Socket.ClIEnt對象,用於維護存匿名認證客戶的信息和操作。
實現通訊的主要步驟:
1.PC端先向服務器發起連接請求,產生連接
2.然後PC端通過偵聽authorization事件獲取到非認證用戶(即客戶端)帶request和token的地址,進而通過replaceQrcode將動畫中的圖片對象替換為二維碼。
3.玩家通過手機等移動設備掃描二維碼,在自己的設備中打開客戶端,
4.客戶端向服務器發起連接請求,並產生連接
5.客戶端與PC端通訊
連接服務器
通過實例化Mugeda.Socket對象,產生連接。Mugeda.Socket類的構造函數為:
Mugeda.Socket(request, token, isRegisteredUser, guestURL, server, port)
其中:
request:{string}請求字符串
token:{string}令牌
isRegisteredUser:{bool,缺省false}是否為認證客戶。
server:{string,缺省為SERVER_URL常量} 服務器地址
port:{string,缺省為SERVER_PORT常量}服務器端口
1. 認證用戶的實例化:認證用戶擁有request、token以及非認證客戶的游戲地址url,使用以下方式實例化Mugeda.Socket
var a = new Mugeda.Socket(request, token, true, url)
2. 匿名用戶的實例化:匿名用戶通常來自二維碼的掃描,網頁地址中包含request和token,可通過以下方式直接從地址中獲取
var a = new Mugeda.Socket()
a.getReqestAndTokenFromUrl()
實例化Mugeda.socket對象後,認證用戶和匿名用戶都使用以下形式的方式連接服務器。
a.connect(function(err){})
在回調函數中,查看err字符串,如果為空,說明連接成功,否則,可能是token不對。
認證用戶(即PC端)獲取匿名用戶(即客戶端)隊列
認證用戶通過a.clients獲取匿名用戶數組,最早連接的用戶在隊列前面。數組的每一個元素都為Mugeda.Socket.ClIEnt實例。
偵聽cliententer和clIEntleave事件,這兩個事件在匿名用戶連接和斷開時刻發生。
a.addEventListener('cliententer', function(clIEnt){
})
a.addEventListener('clientleave', function(clIEnt){
})
認證用戶對匿名用戶的操作
1. 發送消息
對ClIEnt實例發送消息:
clIEnt.send(event, data, callback)
其中:
event{stirng},自定義事件名
data{string、number、object、null}發送的數據,其中number和string在發送前會被轉化為{data: string}或{data.number}的形式。
callback{function},對需要匿名用戶立即回復的情形,callback函數會傳遞到匿名客戶,由匿名客戶直接調用。
對全體ClIEnt發送消息
a.sendAll(event, data)
參數含義同上。
2. 檢測ClIEnt是否有回應
clIEnt.checkAvailable(callback, timeout)
其中:
callback{function}回調
timeout{number,缺省10}超時秒數
檢測非認證用戶是否有回應,若有,callback回調,回調函數的第一個參數為true;否則,timeout後,callback回調,回調函數的第一個參數為false。
3. 不斷檢測ClIEnt的存在性
clIEnt.checkAvailableContinuously(callback, interval, timeout)
匿名用戶將每隔interval秒(缺省5秒)向認證用戶發送一個心跳包,當timeout(缺省20秒)後,callback回調且第一個參數為false。
4. 得到Client實例在a.clIEnts數組中的Index
a.getClientIndexByUserId(clIEnt.user)
匿名用戶的操作
1. 發送消息
a.send(event, data, callback)
參數含義同上。
2. 檢測與服務器的連接訊速度
a.benchmark(callback, times, timeout)
匿名用戶多次向服務器發送數據,服務器收到後返回數據,測試數據來回所用時間/2。
其中:
callback{function}回調函數,格式為function(averageTime, timeArray),其中timeArray記錄了每一次的時間,averageTime為平均時間,單位均為ms。
times{number,缺省為3}測試的次數。
timeout{number,缺省2000}超時的時間,單位ms。
其他事件
1. 認證何用戶消息偵聽
a.addEventListener('message', function(clIEnt, event, data, callback){
console.log(event, data)
})
偵聽匿名用戶通過a.send發送的消息。client為發送消息的用戶的ClIEnt對象,其余參數同上。
2. 匿名用戶消息偵聽
a.addEventListener('message', function(event, data, callback){
console.log(event, data)
})
形式與上面類似,但是回調少了clIEnt參數。
3. 匿名用戶偵聽PC斷開事件
a.addEventListener(‘disconnected’, function(){
})
1.PC端代碼
a.定義SocketComm對象
var mugeda=Mugeda.getMugedaObject();
var scene = null;
var info = null;
var isConnect = false;
var SocketComm = function(){//定義SocketComm對象
this.socket = null;
this.scene = null;
this.connected = null;
this.name = (new Date()).getTime();
var _=this;
this.setup = function(callback, scene){
connect = new Mugeda.Socket('dejipuzzle','d2f7335a19ecc3ed2a0cbe66580fdd05', true,
'https://cn.mugeda.com/client/prevIEw_CSS3.Html?id=d20c8a20');//通過實例化Mugeda.Socket類,產生連接
this.scene = scene;
connect.connect(function(err){//認證用戶(PC端)連接服務器
if(err){
Mugeda.log(err);
}
else{
_.connected = true
callback({
event: 'connect'
})
}
})
connect.addEventListener('authorization',function(){//認證用戶(PC端)偵聽authorization事件
var replaceQrcode = function(imgObj, url) {//將動畫中的圖片對象替換為二維碼
var cvs, height, width;
var holder = document.createElement('div');
holder.width = imgObj.width;
holder.height = imgObj.height;
if (url) {
$(holder).empty().qrcode({
text: url,
ecLevel: 'L'
});
width = imgObj.width;
height = imgObj.height;
$(imgObj.dom).CSS('background-image', 'none');
$(imgObj.dom).CSS('background-color', 'white');
$(imgObj.dom).CSS('padding', '4px');
cvs = $(holder).find('canvas');
cvs.CSS('margin', '2px');
cvs.CSS('width', (width - 4) + 'px');
cvs.CSS('height', (height - 4) + 'px');
imgObj.dom.src = cvs[0].toDataURL();
}
};
var qrc = scene.getObjectByName('qrc');//獲取舞台中原來的二維碼圖片對象
replaceQrcode(qrc, this.clientURL);//通過this.clIEntURL獲取非認證用戶帶request和token的地址,並替換二維碼
console.log(this.clIEntURL);
})
connect.addEventListener('cliententer', function(client){//偵聽clIEntenter在匿名用戶連接時觸發。
info.text = ("用戶接入成功。");
console.log(clIEnt);
})
connect.addEventListener('clientleave', function(client){//偵聽clIEntleave事件,在匿名用戶斷開時觸發。
info.text = ("用戶離開。");
console.log(clIEnt);
})
connect.addEventListener('disconnect', function () {//偵聽disconnect事件
callback({
'event':'disconnect'
});
_.connected = false;
isConnect = false;
});
connect.addEventListener('message', function(clIEnt, event, data){
//偵聽匿名用戶通過a.send發送的消息。並調用在setup的回調函數中處理
callback({
'event':event,
'client':clIEnt,
'data':data
});
})
};
}
b.在renderReady監聽回調中調用SocketComm實例的setup方法
var cross = new SocketComm();//實例化SocketComm對象
mugeda.addEventListener("renderReady", function () {
scene = mugeda.scene;
info = scene.getObjectByName('info');//獲取info對象,顯示連接狀態和移動端發來的消息
var processMessage = function(msg){//setup處理消息的回調函數
if(!mugeda || !scene)
return;
msg = msg || {};
if(msg.event == "connect"){
info.text = ("連接成功。等待用戶接入。");
}
else if(msg.event == "disconnect"){
info.text = ("連接斷開");
}
else if(msg.event == "update"){
console.log(msg.data);
}
else if(msg.event == 'mobilemessage') {//處理匿名用戶(客戶端)發來的消息
var data = msg.data;
info.text = data;
}
}
cross.setup(processMessage, scene);//調用SocketComm實例的setup方法
});
2.移動端代碼
var mugeda=Mugeda.getMugedaObject();
mugeda.addEventListener("renderReady", function () {
scene = mugeda.scene;
var hello = scene.getObjectByName('hello');//獲取sayHello按鈕對象
var ok = scene.getObjectByName('ok');//獲取sayOK按鈕對象
var connectButton = scene.getObjectByName('connect');//獲取connectPC按鈕對象
hello.left = -700;//sayHello按鈕移到舞台外
ok.left = -700;//sayOK按鈕移到舞台外
var socket = new Mugeda.Socket();//實例化Mugeda.Socket對象
socket.getReqestAndTokenFromUrl();//獲取request和token
socket.addEventListener('authorization', function(){//偵聽authorization事件
console.log(this.clIEntURL);
});
socket.addEventListener('message', function(event, data, callback){//偵聽PC端通過send發送的消息
console.log(event, data);
processMessage(event,data, callback);
})
socket.addEventListener('disconneted', function(){//匿名用戶(移動端)偵聽PC斷開事件
console.log('disconneted');
error.text = "連接失敗,請重新刷二維碼";
scene.gotoAndPause(errorFrame);
})
window.connectPC = function(){//connectPC按鈕的回調函數
socket.connect(function(err){//回調中,查看err字符串,為空,說明連接成功。
if(err){
console.log(err);
if(err.indexOf && err.indexOf('handshake')>=0){
console.log("無效的二維碼。請重新刷二維碼。")
}
}
else{
console.log('connect OK');
connectButton.left = -700;//connectPC按鈕移到舞台外
hello.left = 76;//sayHello按鈕移到舞台內
ok.left = 76;//sayOK按鈕移到舞台內
}
});//匿名用戶(移動端)連接服務器
};
window.sayHello = function(){//sayHello按鈕的回調函數
socket.send('mobilemessage', "Hello,World!");//向PC端發送消息
};
window.sayOK = function(){//sayOK按鈕的回調函數
socket.send('mobilemessage', "I'm OK!");//向PC端發送消息
};
});
二、運行程序
先運行PC端程序,用移動設備掃描PC端的二維碼來運行移動端。
移動端點擊connectPC按鈕連接服務器。
點擊sayHello和sayOK按鈕,可以在PC端看到交互結果。