国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > HTML > 正文

HTML5開發Kinect體感游戲實例詳解

2020-03-24 15:58:26
字體:
來源:轉載
供稿:網友
一、簡介

我們要做的是怎樣一款游戲?

在前不久成都TGC2016展會上,我們開發了一款《火影忍者手游》的體感游戲,主要模擬手游章節《九尾襲來 》,用戶化身四代,與九尾進行對決,吸引了大量玩家參與。 表面上看,這款游戲與其它體感體驗無異,實際上,它一直運行于瀏覽器Chrome下,也就是說,我們只需要掌握前端相應技術,就可以開發基于Kinect的網頁體感游戲。

二、實現原理

實現思路是什么?

使用H5開發基于Kinect的體感游戲,其實工作原理很簡單,由Kinect采集到玩家及環境數據,比如人體骨骼,使用某種方式,使瀏覽器可以訪問這些數據。

1、采集數據

Kinect有三個鏡頭,中間鏡頭類似普通攝像頭,獲取彩色圖像。左右兩邊鏡頭則是通過紅外線獲取深度數據。我們使用微軟提供的SDK去讀取以下類型數據:

色彩數據:彩色圖像;

深度數據:顏色嘗試信息;

人體骨骼數據:基于以上數據經計算,獲取到人體骨骼數據。

2、使瀏覽器可訪問到Kinect數據

我嘗試和了解過的框架,基本上是以socket讓瀏覽器進程與服務器進行通信 ,進行數據傳輸:

Kinect-HTML5 用C#搭建服務端,色彩數據、嘗試數據、骨骼數據均有提供;

ZigFu 支持H5、U3D、Flash進行開發,API較為完整,貌似收費;

DepthJS 以瀏覽器插件形式提供數據訪問;

Node-Kinect2 以Nodejs搭建服務器端,提供數據比較完整,實例較多。

我最終選用Node-Kinect2,雖然沒有文檔,但是實例較多,使用前端工程師熟悉的Nodejs,另外作者反饋比較快。

Kinect: 捕獲玩家數據,比如深度圖像、彩色圖像等;

Node-Kinect2: 從Kinect獲取相應數據,并進行二次加工;

瀏覽器: 監聽node應用指定接口,獲取玩家數據并完成游戲開發。

三、準備工作

先得買個Kinect啊

1、系統要求:

這是硬性要求,我曾在不符合要求的環境下浪費太多時間。

USB3.0

支持DX11的顯卡

win8及以上系統

支持Web Sockets的瀏覽器

當然Kinect v2傳感器是少不了的

2、環境搭建流程:

連接上Kinect v2

安裝 KinectSDK-v2.0

安裝 Nodejs

安裝 Node-Kinect2

npm install kinect2

四、實例演示

說什么都不如給我一個例子!

如下圖所示,我們演示如何獲取人體骨骼,并標識脊椎中段及手勢:

1、服務器端

創建web服務器,并將骨骼數據發送到瀏覽器端,代碼如下:

var Kinect2 = require( ../../lib/kinect2 ), express = require( express ), app = express(), server = require( http ).createServer(app), io = require( socket.io ).listen(server);var kinect = new Kinect2();// 打開kinectif(kinect.open()) { // 監聽8000端口 server.listen(8000); // 指定請求指向根目錄 app.get( / , function(req, res) { res.sendFile(dirname + /html' target='_blank'>public/index.html  // 將骨骼數據發送給瀏覽器端 kinect.on( bodyFrame , function(bodyFrame){ io.sockets.emit( bodyFrame , bodyFrame); // 開始讀取骨骼數據 kinect.openBodyReader();}

2、瀏覽器端

瀏覽器端獲取骨骼數據,并用canvas描繪出來,關鍵代碼如下:

var socket = io.connect( / var ctx = canvas.getContext( 2d socket.on( bodyFrame , function(bodyFrame){ ctx.clearRect(0, 0, canvas.width, canvas.height); var index = 0; // 遍歷所有骨骼數據 bodyFrame.bodies.forEach(function(body){ if(body.tracked) { for(var jointType in body.joints) { var joint = body.joints[jointType]; ctx.fillStyle = colors[index]; // 如果骨骼節點為脊椎中點 if(jointType == 1) { ctx.fillStyle = colors[2]; ctx.fillRect(joint.depthX * 512, joint.depthY * 424, 10, 10); // 識別左右手手勢 updateHandState(body.leftHandState, body.joints[7]); updateHandState(body.rightHandState, body.joints[11]); index++;});

很簡單的幾行代碼,我們便完成了玩家骨骼捕獲,有一定 javascript基礎的同學應該很容易能看明白,但不明白的是我們能獲取哪些數據?如何獲取?骨骼節點名稱分別是什么?而node-kienct2并沒有文檔告訴我們這些。

五、開發文檔

Node-Kinect2并沒有提供文檔,我將我測試總結的文檔整理如下:

1、服務器端能提供的數據類型;

kinect.on( bodyFrame , function(bodyFrame){}); //還有哪些數據類型呢?

bodyFrame骨骼數據infraredFrame紅外數據longExposureInfraredFrame類似infraredFrame,貌似精度更高,優化后的數據rawDepthFrame未經處理的景深數據depthFrame景深數據colorFrame彩色圖像multiSourceFrame所有數據audio音頻數據,未測試

2、骨骼節點類型

body.joints[11] // joints包括哪些呢?

節點類型JointType節點名稱0spineBase脊椎基部1spineMid脊椎中部2neck頸部3head頭部4shoulderLeft左肩5elbowLeft左肘6wristLeft左腕7handLeft左手掌8shoulderRight右肩9elbowRight右肘10wristRight右腕11handRight右手掌12hipLeft左屁13kneeLeft左膝14ankleLeft左踝15footLeft左腳16hipRight右屁17kneeRight右膝18ankleRight右踝19footRight右腳20spineShoulder頸下脊椎21handTipLeft左手指(食中無小)22thumbLeft左拇指23handTipRight右手指24thumbRight右拇指

3、手勢,據測識別并不是太準確,在精度要求不高的情況下使用

0unknown不能識別1notTracked未能檢測到2open手掌3closed握拳4lasso剪刀手,并合并中食指

4、骨骼數據

body [object] {

bodyIndex [number]:索引,允許6人

joints [array]:骨骼節點,包含坐標信息,顏色信息

leftHandState [number]:左手手勢

rightHandState [number]:右手手勢

tracked [boolean]:是否捕獲到

trackingId

}

5、kinect對象

on監聽數據open打開Kinectclose關閉openBodyReader讀取骨骼數據open**Reader類似如上方法,讀取其它類型數據六、實戰總結

火影體感游戲經驗總結

接下來,我總結一下TGC2016《火影忍者手游》的體感游戲開發中碰到的一些問題。

1、講解之前,我們首先需要了解下游戲流程。

1.1、通過手勢觸發開始游戲

1.2、玩家化身四代,左右跑動躲避九尾攻擊

1.3、擺出手勢“奧義”,觸發四代大招

1.4、用戶掃描二維碼獲取自己現場照片

2、服務器端

游戲需要玩家骨骼數據(移動、手勢),彩色圖像數據(某一手勢下觸發拍照),所以我們需要向客戶端發送這兩部分數據。值得注意的是,彩色圖像數據體積過大,需要進行壓縮。

var emitColorFrame = false;io.sockets.on( connection , function (socket){ socket.on( startColorFrame , function(data){ emitColorFrame = true; }); kinect.on( multiSourceFrame , function(frame){ // 發送玩家骨骼數據 io.sockets.emit( bodyFrame , frame.body); // 玩家拍照 if(emitColorFrame) { var compression = 1; var origWidth = 1920; var origHeight = 1080; var origLength = 4 * origWidth * origHeight; var compressedWidth = origWidth / compression; var compressedHeight = origHeight / compression; var resizedLength = 4 * compressedWidth * compressedHeight; var resizedBuffer = new Buffer(resizedLength); // ... // 照片數據過大,需要壓縮提高傳輸性能 zlib.deflate(resizedBuffer, function(err, result){ if(!err) { var buffer = result.toString( base64  io.sockets.emit( colorFrame , buffer); });  emitColorFrame = false;kinect.openMultiSourceReader({ frameTypes: Kinect2.FrameType.body | Kinect2.FrameType.color});

3、客戶端

客戶端業務邏輯較復雜,我們提取關鍵步驟進行講解。

3.1、用戶拍照時,由于處理的數據比較大,為防止頁面出現卡頓,我們需要使用web worker

(function(){ importScripts( pako.inflate.min.js  var imageData; function init() { addEventListener( message , function (event) { switch (event.data.message) { case setImageData : imageData = event.data.imageData; break; case processImageData : processImageData(event.data.imageBuffer); break; function processImageData(compressedData) { var imageBuffer = pako.inflate(atob(compressedData)); var pixelArray = imageData.data; var newPixelData = new Uint8Array(imageBuffer); var imageDataSize = imageData.data.length; for (var i = 0; i imageDataSize; i++) { imageData.data[i] = newPixelData[i]; for(var x = 0; x 1920; x++) { for(var y = 0; y 1080; y++) { var idx = (x + y * 1920) * 4; var r = imageData.data[idx + 0];  var g = imageData.data[idx + 1];  var b = imageData.data[idx + 2];  self.postMessage({ message : imageReady , imageData : imageData }); init();})();

3.2、接投影儀后,如果渲染面積比較大,會出現白屏,需要關閉瀏覽器硬件加速。

3.3、現場光線較暗,其它玩家干擾,在追蹤玩家運動軌跡的過程中,可能會出現抖動的情況,我們需要去除干擾數據。(當突然出現很大位移時,需要將數據移除)

var tracks = this.tracks;var len = tracks.length;// 數據過濾if(tracks[len-1] !== window.undefined) { if(Math.abs(n - tracks[len-1]) 0.2) { return;this.tracks.push(n);

3.4、當玩家站立,只是左右少量晃動時,我們認為玩家是站立狀態。

// 保留5個數據if(this.tracks.length 5) { this.tracks.shift();} else { return;// 位移總量var dis = 0;for(var i = 1; i this.tracks.length; i++) { dis += this.tracks[i] - this.tracks[i-1];if(Math.abs(dis) 0.01) { this.stand();} else { if(this.tracks[4] this.tracks[3]) { this.turnRight(); } else { this.turnLeft(); this.run();}

七、展望

1、使用HTML5開發Kinect體感游戲,降低了技術門檻,前端工程師可以輕松的開發體感游戲;

2、大量的框架可以應用,比如用JQuery、CreateJS、Three.js(三種不同渲染方式);

3、無限想象空間,試想下體感游戲結合webAR,結合webAudio、結合移動設備,太可以挖掘的東西了……想想都激動不是么!

以上就是HTML5開發Kinect體感游戲實例詳解的詳細內容,其它編程語言

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 兴国县| 石河子市| 静安区| 桦南县| 射洪县| 紫金县| 江华| 翁牛特旗| 枣庄市| 陆川县| 西藏| 治多县| 广灵县| 张掖市| 吐鲁番市| 拉萨市| 道孚县| 隆回县| 松原市| 盐亭县| 河间市| 邹平县| 浪卡子县| 尤溪县| 台东县| 绍兴市| 青岛市| 扶沟县| 彭州市| 阿图什市| 西畴县| 临沧市| 海南省| 钟祥市| 白山市| 平乐县| 娱乐| 日喀则市| 华蓥市| 自贡市| 株洲县|