藉助近距離通訊,實現手機作為遊戲控制器掌控大屏遊戲
一、前言
隨著移動互聯網時代的深入發展,人們對電子產品的體驗效果要求越來越高,各種遊戲體驗和效果都得到很大的提升。本文主要介紹使用手機或者平板作為遊戲控制器,藉助近距離通訊(Nearby Service),通過藍牙和WIFI技術,實現控制大屏遊戲的效果。
二、場景描述
在實際使用過程中,可以通過大屏遊戲主頁提供的二維碼鏈接去下載控制器程式,遊戲的所需操作都可以進行數據傳輸,本文主要演示如何將手機陀螺儀數據進行傳輸。
通過該方案,可以解決普通遊戲控制器功能單一,使用成本高等問題。同時,由於無需Internet連接,不會造成額外流量消耗或者傳輸效果受到Internet網路品質的影響。此外,允許手機控制器程式輕鬆地與附近的設備(大屏遊戲)進行發現、連接及數據交換,靈活支援多人同時參與同一遊戲。
三、整體流程
使用手機或者平板電腦作為遊戲控制器,通過集成近距離通訊能力,將手機或者平板電腦中的感測器的實時數據,無線傳輸到顯示遊戲的大屏設備上,實現對遊戲角色的控制。
下圖中的發現端對應手機遊戲控制器,廣播端對應大屏遊戲。雙方對應的流程總體一致,都要經過:
廣播掃描 -> 建立連接 -> 傳輸數據 -> 斷開連接。
下圖中廣播掃描階段,進行設備發現,需要基於BLE(低功耗藍牙)雙向廣播技術。傳輸數據階段,設備之間的高速傳輸,直接基於傳統的P2P協議實現。
四、集成關鍵步驟說明和程式碼
您需要按照流程來完成應用的開發工作,完整的開發流程可以參考鏈接。開發準備完成後,就可以進行編碼了,關鍵步驟及程式碼如下:
步驟一、開始廣播
public void doStartBroadcast(View view) {
Context context = getApplicationContext();
mDiscoveryEngine = Nearby.getDiscoveryEngine(context);
BroadcastOption.Builder advBuilder = new BroadcastOption.Builder();
advBuilder.setPolicy(Policy.POLICY_STAR);
mDiscoveryEngine.startBroadcasting(myNameStr, myServiceId, mConnCb, advBuilder.build());
}
步驟二、開始掃描
public void doStartScan(View view) {
ScanOption.Builder discBuilder = new ScanOption.Builder();
discBuilder.setPolicy(Policy.POLICY_STAR);
mDiscoveryEngine.startScan(myServiceId, mDiscCb, discBuilder.build());
步驟三、請求連接
private void connect(View view) {
mDiscoveryEngine.requestConnect(myNameStr, mEndpointId, mConnCb)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Toast.makeText(SensorActivity.this,"connect Success",Toast.LENGTH_SHORT).show();
Log.d(TAG, "connect Success:");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Toast.makeText(SensorActivity.this,"connect Failure",Toast.LENGTH_SHORT).show();
Log.d(TAG, "connect Failure");
}
步驟四、發送數據
控制器:發送陀螺儀獲取的實時數據
private void sendData(Data bytesData){ Nearby.getTransferEngine(getApplicationContext()).sendData(mEndpointId, bytesData);}
遊戲大屏:接收數據
private DataCallback mDataCb =
new DataCallback() {
@Override
public void onReceived(String string, Data data) {
Log.d(TAG, "onReceived, Data.Type = " + data.getType());
Log.d(TAG, "onReceived, string ======== " + string);
switch (data.getType()) {
case Data.Type.BYTES:
String str = new String(data.asBytes(), UTF_8);
receiveMessage(data);
break;
default:
Log.i(TAG, "the other Unknown data type, please check the uploaded file.");
return;
}
}
@Override
public void onTransferUpdate(String string, TransferStateUpdate update) {
Log.d(TAG, "onTransferUpdate.Status=======" + update.getStatus());
return;
}
}
};
private void receiveMessage(Data data) {
msgStr = new String(data.asBytes(), UTF_8);
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
String dateStr = dateFormat.format(new Date());
tvData.append("\n" + dateStr + msgStr);
}
步驟五、斷開連接
private void disconnect(){
mDiscoveryEngine.disconnect(mEndpointId);
}
五、效果展示
由於硬體條件限制,使用兩台手機進行效果測試,一台手機用作控制器發送手機陀螺儀的實時數據,另一台設備作為遊戲大屏進行數據的接收,在接收數據後,可以根據數據計算得出控制器的姿態等數據,實現對遊戲的控制功能。
在兩台設備距離三米左右時,發送和接收數據的對比如下:
在設備間距離差距不大時(例如相距3米或4米),數據傳輸的時延變化不是很大,基本都在1s以內,數據傳輸依舊具有實時性;即使兩台手機都處在移動中,也能夠為用戶提供良好的使用體驗。
注意,當前大部分手機藍牙在兩台設備間無大的障礙物的情況下,距離7米遠時也能保證很好的傳輸品質,超過8米將會出現斷點,超過10米會斷開連接。
六、注意事項
1、此示例需要填寫接收雙方的設備名稱,進行連接。可以根據您的需要,掃描過程中,您可以向用戶展示發現的設備列表,並允許他們選擇連接哪些設備。
2、此示例顯示了一種掃描和連接方式(1-N或者星型連接拓撲的點到點策略)。根據您的需要,您可以使用其他兩種連接方式:M-N或者網狀連接拓撲的點到點連接策略,和1-1連接拓撲的點到點連接策略。三種策略適用的場景,可以參考該鏈接。
3、此示例傳輸的數據格式是位元組序列(BYTES),該類型數據的長度大小不能超過32KB。可以根據您的需要,選擇其他另外兩種數據類型:文件(FILE)和流(STREAM)。
4、此示例手機控制器應用發送的數據是手機陀螺儀數據,未進行任何處理。可以根據您的需要,計算得出手機姿態等數據,實現對遊戲角色的控制。
5、此示例中,接收雙方接收數據會存在時延,該時延僅供參考,不作為近距離通訊的性能的標準。
原文鏈接://developer.huawei.com/consumer/cn/forum/topic/0204428876579660015?fid=18
原作者:胡椒