web前端|H5教程
HTML5,游戏开发
web前端-H5教程
jsp购物网站前端源码,ubuntu安装qq邮箱,地板爬虫怎么消灭,php切面,德令哈网站seolzw
A、简介
我们要做的是怎样一款游戏?
matrix xmpp 源码,vscode错误曲线,ubuntu支持哪种显卡,jar放到tomcat,sqlite3 软件,免费日历插件,前端框架模块教程学习,安居客最新爬虫,php 取域名,南通seo营销,云免网站源码,微信网页版 机器人,企业手机版前端模板,页面高度代码,租房管理系统代码,104规约 java程序lzw
在前不久成都TGC展会上,我们开发了一款《火影忍者手游》的体感游戏,主要模拟手游章节《九尾袭来 》,用户化身四代,与九尾进行对决,吸引了大量玩家参与。 表面上看,这款游戏与其它体感体验无异,实际上,它一直运行于浏览器Chrome下,也就是说,我们只需要掌握前端相应技术,就可以开发基于Kinect的网页体感游戏。
转发阅读网站源码,ubuntu优秀软件推荐,tomcat最大连接数越高,爬虫服务是什么,php电商项目面试题,seo嘉兴优化lzw
B、实现原理
实现思路是什么?
使用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应用指定接口,获取玩家数据并完成游戏开发。
C、准备工作
先得买个Kinect啊
1、系统要求:
这是硬性要求,我曾在不符合要求的环境下浪费太多时间。
USB3.0
支持DX11的显卡
win8及以上系统
支持Web Sockets的浏览器
当然Kinect v2传感器是少不了的
2、环境搭建流程:
连接上Kinect v2
安装 KinectSDK-v2.0
安装 Nodejs
安装 Node-Kinect2
npm install kinect2
D、实例演示
说什么都不如给我一个例子!
下图例,我们演示如何获取人体骨骼,并标识脊椎中段及手势:
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 + /public/index.html);});// 将骨骼数据发送给浏览器端kinect.on(odyFrame, function(bodyFrame){io.sockets.emit(odyFrame, bodyFrame);});// 开始读取骨骼数据kinect.openBodyReader();}
2、浏览器端
浏览器端获取骨骼数据,并用canvas描绘出来,关键代码如下:
var socket = io.connect(/);var ctx = canvas.getContext(2d);socket.on(odyFrame, 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并没有文档告诉我们这些。
E、开发文档
Node-Kinect2并没有提供文档,我将我测试总结的文档整理如下:
1、服务器端能提供的数据类型;
kinect.on(odyFrame, function(bodyFrame){}); //还有哪些数据类型呢?
2、骨骼节点类型
body.joints[11] // joints包括哪些呢?
3、手势,据测识别并不是太准确,在精度要求不高的情况下使用
4、骨骼数据
body [object] {
bodyIndex [number]:索引,允许6人
joints [array]:骨骼节点,包含坐标信息,颜色信息
leftHandState [number]:左手手势
rightHandState [number]:右手手势
tracked [boolean]:是否捕获到
trackingId
}
5、kinect对象
F、实战总结
火影体感游戏经验总结
接下来,我总结一下TGC《火影忍者手游》的体感游戏开发中碰到的一些问题。
1、讲解之前,我们首先需要了解下游戏流程。
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(odyFrame, 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(ase64);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) this.tracks[3]) {this.turnRight();} else {this.turnLeft();}this.run();}
G、展望
1、使用HTML5开发Kinect体感游戏,降低了技术门槛,前端工程师可以轻松的开发体感游戏;
2、大量的框架可以应用,比如用JQuery、CreateJS、Three.js(三种不同渲染方式);
3、无限想象空间,试想下体感游戏结合webAR,结合webAudio、结合移动设备,太可以挖掘的东西了……想想都激动不是么!