热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HTML5开发Kinect体感游戏的示例分析

小编给大家分享一下HTML5开发Kinect体感游戏的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章

小编给大家分享一下HTML5开发Kinect体感游戏的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

HTML5开发Kinect体感游戏的实例应用

一、简介

我们要做的是怎样一款游戏?

  在前不久成都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,另外作者反馈比较快。

HTML5开发Kinect体感游戏的示例分析

  • 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

四、实例演示

说什么都不如给我一个例子!

如下图所示,我们演示如何获取人体骨骼,并标识脊椎中段及手势:
HTML5开发Kinect体感游戏的示例分析

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();
// 打开kinect
if(kinect.open()) {
  // 监听8000端口
  server.listen(8000);
  // 指定请求指向根目录
  app.get('/', function(req, res) {
    res.sendFile(__dirname + '/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打开Kinect
close关闭
openBodyReader读取骨骼数据
open**Reader类似如上方法,读取其它类型数据

 六、实战总结

火影体感游戏经验总结

接下来,我总结一下TGC2016《火影忍者手游》的体感游戏开发中碰到的一些问题。

1、讲解之前,我们首先需要了解下游戏流程。

HTML5开发Kinect体感游戏的示例分析

1.1、通过手势触发开始游戏

HTML5开发Kinect体感游戏的示例分析

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

HTML5开发Kinect体感游戏的示例分析

1.3、摆出手势“奥义”,触发四代大招

HTML5开发Kinect体感游戏的示例分析

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、接投影仪后,如果渲染面积比较大,会出现白屏,需要关闭浏览器硬件加速。
HTML5开发Kinect体感游戏的示例分析

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体感游戏的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程笔记行业资讯频道!


推荐阅读
  • 本文详细介绍了如何使用OpenSSL自建CA证书的步骤,包括准备工作、生成CA证书、生成服务器待签证书以及证书签名等过程。 ... [详细]
  • 本文详细介绍了在 React Native 开发过程中遇到的 'Could not connect to development server' 错误及其解决方法。该问题不仅影响开发效率,而且难以通过网络资源找到确切的解决方案。本文将提供详细的步骤,帮助开发者快速解决这一常见问题。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 本文深入解析了 Kubernetes 控制平面(特别是 API 服务器)与集群节点之间的通信机制,并对其通信路径进行了详细分类。旨在帮助用户更好地理解和定制其安装配置,从而增强网络安全性,确保集群的稳定运行。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 【实例简介】本文详细介绍了如何在PHP中实现微信支付的退款功能,并提供了订单创建类的完整代码及调用示例。在配置过程中,需确保正确设置相关参数,特别是证书路径应根据项目实际情况进行调整。为了保证系统的安全性,存放证书的目录需要设置为可读权限。值得注意的是,普通支付操作无需证书,但在执行退款操作时必须提供证书。此外,本文还对常见的错误处理和调试技巧进行了说明,帮助开发者快速定位和解决问题。 ... [详细]
  • Silverlight 实战指南:深入解析用户提交数据的验证与捕获机制
    本文深入探讨了Silverlight中用户提交数据的验证与捕获机制,详细分析了四种主要的验证方法:基本异常处理、DataAnnotation注解、IDataErrorInfo客户端同步验证以及自定义验证策略。通过实例解析,帮助开发者更好地理解和应用这些机制,提升应用程序的数据处理能力和用户体验。 ... [详细]
  • 本指南详细介绍了在Linux环境中高效连接MySQL数据库的方法。用户可以通过安装并使用`mysql`客户端工具来实现本地连接,具体命令为:`mysql -u 用户名 -p 密码 -h 主机`。例如,使用管理员账户连接本地MySQL服务器的命令为:`mysql -u root -p pass`。此外,还提供了多种配置优化建议,以确保连接过程更加稳定和高效。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • Spring框架的核心组件与架构解析 ... [详细]
  • 本文探讨了如何通过检测浏览器类型来动态加载特定的npm包,从而优化前端性能。具体而言,仅在用户使用Edge浏览器时加载相关包,以提升页面加载速度和整体用户体验。此外,文章还介绍了实现这一目标的技术细节和最佳实践,包括使用User-Agent字符串进行浏览器识别、条件加载策略以及性能监控方法。 ... [详细]
  • 在 PHP 中使用 Restler 3 框架为不同方法添加身份验证时,可以根据方法参数的特定值来限制访问。例如,在 `Simple.php` 文件中定义的 `Simple` 类中,可以通过检查 `$name` 参数的值来决定是否允许调用 `item` 方法。这种细粒度的认证机制可以提高系统的安全性和灵活性。具体实现方式包括在方法内部进行条件判断,并结合框架提供的认证工具来实现访问控制。 ... [详细]
  • SQL Server 2005 在安装过程中通常会伴随 VS2005 一起安装,并且为了便于数据库管理,还会安装 Management Studio Express 管理工具。然而,在实际使用中,用户可能会遇到登录故障。本文综合分析了这些登录问题的常见原因,并提供了多种有效的解决方法,包括检查配置设置、验证账户权限和网络连接等。通过这些措施,用户可以有效地诊断并解决 SQL Server 2005 的登录问题。 ... [详细]
  • 本文详细介绍了在 Vue.js 前端框架中集成 vue-i18n 插件以实现多语言支持的方法。通过具体的配置步骤和示例代码,帮助开发者快速掌握如何在项目中实现国际化功能,提升用户体验。同时,文章还探讨了常见的多语言切换问题及解决方案,为开发人员提供了实用的参考。 ... [详细]
  • 在 Kubernetes 中,Pod 的调度通常由集群的自动调度策略决定,这些策略主要关注资源充足性和负载均衡。然而,在某些场景下,用户可能需要更精细地控制 Pod 的调度行为,例如将特定的服务(如 GitLab)部署到特定节点上,以提高性能或满足特定需求。本文深入解析了 Kubernetes 的亲和性调度机制,并探讨了多种优化策略,帮助用户实现更高效、更灵活的资源管理。 ... [详细]
author-avatar
finessi_739
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有