如何使用HTML5开发Kinect体感游戏开发公司

君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
基于html5和kinect实现体感交互游戏的关键技术研究
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口HTML5魅力演示:未来我们将这样浏览网页
[导读]期待这些轻量级的又不乏视觉魅力的技术能越来越流行。
腾讯科技讯(苏格)北京时间7月6日消息,据国外媒体报道,科技网站Sidebar日前刊登的一篇关于HTML5魅力的文章令人大开眼界。网页开发者大卫·沃尔什(David Walsh)发布了9个演示样本,展示原生web技术的在没有Flash、Silverlight等插件的情况下,网页浏览器所施展出来的神奇能力。以下是其中三个精选演示:配图一第一个演示名为Zen Photon Garden。在动态的画布上,用户可以添加线条,改变光线的传播方向。所有的演算都是即时进行的。如果有兴趣,你可以在上面创造出非常美妙的画面——你不必是一位熟手的画家。配图2第二个演示则更有意思。演示者通过大量的数学演算,搭建了一个高度复杂的动画。在这个动态画面中,字符会不断地变形、消失和形成。而且,你可以用鼠标来改变视角。这个演示是在一台古董设备上进行的,但是并没有发生任何卡顿现象。配图三是一段youtube视频,无法压轴出场的第三个演示是最为复杂的一个。这是一个名为Gestures + Reveal.JS(手势+展示)的Chrome试验项目,利用WebRTC和JavaScript充分发掘摄像头的功能。演示中,用户通过手势就可以进行电脑界面操作,用户的手势显示在屏幕画面的背景上。当然,自从发布了Kinect传感器后,这种手势操作机制不再稀罕。不过,这个演示可以毫无压力地在任何一台2008年制造的电脑上运行。毫无疑问,所有的演示都令人印象深刻。其它6个演示包括文字动画、浏览器游戏、视频控制等内容。期待网页开发者能使用这些轻量级的又不乏视觉魅力的技术,去丰富我们日常浏览的网页。
[责任编辑:quarkqiao]
您认为这篇文章与"新一网(08008.HK)"相关度高吗?
还能输入140字
Copyright & 1998 - 2017 Tencent. All Rights Reserved
还能输入140字使用HTML5开发Kinect体感游戏
我们要做的是怎样一款游戏?
  在前不久成都TGC2016展会上,我们开发了一款《火影忍者手游》的体感游戏,主要模拟手游章节《九尾袭来&》,用户化身四代,与九尾进行对决,吸引了大量玩家参与。 表面上看,这款游戏与其它体感体验无异,实际上,它一直运行于浏览器Chrome下,也就是说,我们只需要掌握前端相应技术,就可以开发基于Kinect的网页体感游戏。
二、实现原理
实现思路是什么?
  使用H5开发基于Kinect的体感游戏,其实工作原理很简单,由Kinect采集到玩家及环境数据,比如人体骨骼,使用某种方式,使浏览器可以访问这些数据。
1、采集数据  Kinect有三个镜头,中间镜头类似普通摄像头,获取彩色图像。左右两边镜头则是通过红外线获取深度数据。我们使用微软提供的SDK去读取以下类型数据:
色彩数据:彩色图像;
深度数据:颜色尝试信息;
人体骨骼数据:基于以上数据经计算,获取到人体骨骼数据。
2、使浏览器可访问到Kinect数据我尝试和了解过的框架,基本上是以socket让浏览器进程与服务器进行通信 ,进行数据传输:
&用C#搭建服务端,色彩数据、尝试数据、骨骼数据均有提供;
&支持H5、U3D、Flash进行开发,API较为完整,貌似收费;
& 以浏览器插件形式提供数据访问;
&以Nodejs搭建服务器端,提供数据比较完整,实例较多。
我最终选用Node-Kinect2,虽然没有文档,但是实例较多,使用前端工程师熟悉的Nodejs,另外作者反馈比较快。
Kinect: 捕获玩家数据,比如深度图像、彩色图像等;
Node-Kinect2: 从Kinect获取相应数据,并进行二次加工;
浏览器: 监听node应用指定接口,获取玩家数据并完成游戏开发。
三、准备工作
先得买个Kinect啊
1、系统要求:这是硬性要求,我曾在不符合要求的环境下浪费太多时间。
支持DX11的显卡
win8及以上系统
支持Web Sockets的浏览器
当然Kinect v2传感器是少不了的
2、环境搭建流程:
连接上Kinect v2
安装 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();
if(kinect.open()) {
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]);
很简单的几行代码,我们便完成了玩家骨骼捕获,有一定 javascript基础的同学应该很容易能看明白,但不明白的是我们能获取哪些数据?如何获取?骨骼节点名称分别是什么?而node-kienct2并没有文档告诉我们这些。
五、开发文档
Node-Kinect2并没有提供文档,我将我测试总结的文档整理如下:
1、服务器端能提供的数据类型;
kinect.on('bodyFrame', function(bodyFrame){});
infraredFrame
longExposureInfraredFrame
类似infraredFrame,貌似精度更高,优化后的数据
rawDepthFrame
未经处理的景深数据
depthFrame
colorFrame
multiSourceFrame
音频数据,未测试
2、骨骼节点类型
body.joints[11]
shoulderLeft
shoulderRight
elbowRight
wristRight
ankleRight
spineShoulder
handTipLeft
左手指(食中无小)
handTipRight
thumbRight
3、手势,据测识别并不是太准确,在精度要求不高的情况下使用
notTracked
未能检测到
剪刀手,并合并中食指
4、骨骼数据body [object] {& bodyIndex [number]:索引,允许6人& joints [array]:骨骼节点,包含坐标信息,颜色信息& leftHandState [number]:左手手势& rightHandState [number]:右手手势& tracked [boolean]:是否捕获到& trackingId}&
5、kinect对象
打开Kinect
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 * origH
var compressedWidth = origWidth /
var compressedHeight = origHeight /
var resizedLength = 4 * compressedWidth * compressedH
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 imageD
function init() {
addEventListener('message', function (event) {
switch (event.data.message) {
case "setImageData":
imageData = event.data.imageD
case "processImageData":
processImageData(event.data.imageBuffer);
function processImageData(compressedData) {
var imageBuffer = pako.inflate(atob(compressedData));
var pixelArray = imageData.
var newPixelData = new Uint8Array(imageBuffer);
var imageDataSize = imageData.data.
for (var i = 0; i & imageDataS 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 });
3.2、接投影仪后,如果渲染面积比较大,会出现白屏,需要关闭浏览器硬件加速。
3.3、现场光线较暗,其它玩家干扰,在追踪玩家运动轨迹的过程中,可能会出现抖动的情况,我们需要去除干扰数据。(当突然出现很大位移时,需要将数据移除)
var tracks = this.
var len = tracks.
if(tracks[len-1] !== window.undefined) {
if(Math.abs(n - tracks[len-1]) & 0.2) {
this.tracks.push(n);
3.4、当玩家站立,只是左右少量晃动时,我们认为玩家是站立状态。
if(this.tracks.length & 5) {
this.tracks.shift();
var dis = 0;
for(var i = 1; i & this.tracks. i++) {
dis += this.tracks[i] - this.tracks[i-1];
if(Math.abs(dis) & 0.01) {
this.stand();
if(this.tracks[4] & this.tracks[3]) {
this.turnRight();
this.turnLeft();
this.run();
1、使用HTML5开发Kinect体感游戏,降低了技术门槛,前端工程师可以轻松的开发体感游戏;2、大量的框架可以应用,比如用JQuery、CreateJS、Three.js(三种不同渲染方式);3、无限想象空间,试想下体感游戏结合webAR,结合webAudio、结合移动设备,太可以挖掘的东西了&&想想都激动不是么!如何使用HTML5开发Kinect体感游戏10 months ago四、实例演示如下图所示,我们演示如何获取人体骨骼,并标识脊椎中段及手势: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]);
很简单的几行代码,我们便完成了玩家骨骼捕获,有一定 javascript基础的同学应该很容易能看明白,但不明白的是我们能获取哪些数据?如何获取?骨骼节点名称分别是什么?而node-kienct2并没有文档告诉我们这些。五、开发文档Node-Kinect2并没有提供文档,我将我测试总结的文档整理如下:1、服务器端能提供的数据类型;kinect.on('bodyFrame', function(bodyFrame){}); //还有哪些数据类型呢?
骨骼数据infraredFrame红外数据longExposureInfraredFrame类似infraredFrame,貌似精度更高,优化后的数据rawDepthFrame未经处理的景深数据depthFrame景深数据colorFrame彩色图像multiSourceFrame所有数据audio音频数据,未测试2、骨骼节点类型body.joints[11] // joints包括哪些呢?
节点类型JointType
spineBase脊椎基部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 =
io.sockets.on('connection', function (socket){
socket.on('startColorFrame', function(data){
emitColorFrame =
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 * origH
var compressedWidth = origWidth /
var compressedHeight = origHeight /
var resizedLength = 4 * compressedWidth * compressedH
var resizedBuffer = new Buffer(resizedLength);
// 照片数据过大,需要压缩提高传输性能
zlib.deflate(resizedBuffer, function(err, result){
if(!err) {
var buffer = result.toString('base64');
io.sockets.emit('colorFrame', buffer);
emitColorFrame =
kinect.openMultiSourceReader({
frameTypes: Kinect2.FrameType.body | Kinect2.FrameType.color
3、客户端客户端业务逻辑较复杂,我们提取关键步骤进行讲解。3.1、用户拍照时,由于处理的数据比较大,为防止页面出现卡顿,我们需要使用web worker(function(){
importScripts('pako.inflate.min.js');
var imageD
function init() {
addEventListener('message', function (event) {
switch (event.data.message) {
case "setImageData":
imageData = event.data.imageD
case "processImageData":
processImageData(event.data.imageBuffer);
function processImageData(compressedData) {
var imageBuffer = pako.inflate(atob(compressedData));
var pixelArray = imageData.
var newPixelData = new Uint8Array(imageBuffer);
var imageDataSize = imageData.data.
for (var i = 0; i & imageDataS 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 });
3.2、接投影仪后,如果渲染面积比较大,会出现白屏,需要关闭浏览器硬件加速。3.3、现场光线较暗,其它玩家干扰,在追踪玩家运动轨迹的过程中,可能会出现抖动的情况,我们需要去除干扰数据。(当突然出现很大位移时,需要将数据移除)var tracks = this.
var len = tracks.
// 数据过滤
if(tracks[len-1] !== window.undefined) {
if(Math.abs(n - tracks[len-1]) & 0.2) {
this.tracks.push(n);
3.4、当玩家站立,只是左右少量晃动时,我们认为玩家是站立状态。// 保留5个数据
if(this.tracks.length & 5) {
this.tracks.shift();
// 位移总量
var dis = 0;
for(var i = 1; i & this.tracks. i++) {
dis += this.tracks[i] - this.tracks[i-1];
if(Math.abs(dis) & 0.01) {
this.stand();
if(this.tracks[4] & this.tracks[3]) {
this.turnRight();
this.turnLeft();
this.run();
七、展望1、使用HTML5开发Kinect体感游戏,降低了技术门槛,前端工程师可以轻松的开发体感游戏;2、大量的框架可以应用,比如用JQuery、CreateJS、Three.js(三种不同渲染方式);3、无限想象空间,试想下体感游戏结合webAR,结合webAudio、结合移动设备,太可以挖掘的东西了……想想都激动不是么!7收藏分享举报{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[],&title&:&如何使用HTML5开发Kinect体感游戏&,&author&:&tgideas&,&content&:&\u003Ch2\u003E\u003Cb\u003E一、简介\u003C\u002Fb\u003E\u003C\u002Fh2\u003E\u003Cp\u003E  在前不久成都TGC2016展会上,我们开发了一款《火影忍者手游》的体感游戏,主要模拟手游章节《九尾袭来 》,用户化身四代,与九尾进行对决,吸引了大量玩家参与。 表面上看,这款游戏与其它体感体验无异,实际上,它一直运行于浏览器Chrome下,也就是说,我们只需要掌握前端相应技术,就可以开发基于Kinect的网页体感游戏。\u003C\u002Fp\u003E\u003Cp\u003E\u003Ca class=\&video-box\& href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002Fx\u002Fpage\u002Fa03594v37wi.html\& target=\&_blank\& data-video-id=\&\& data-video-playable=\&\& data-name=\&巨屏体感游戏体验 - 腾讯视频\& data-poster=\&\u002F\\u002Fqqvideo_ori\u002F0\u002Fa03594v37wi_228_128\u002F0\& data-lens-id=\&\&\u003E
\u003Cimg class=\&thumbnail\& src=\&\u002F\\u002Fqqvideo_ori\u002F0\u002Fa03594v37wi_228_128\u002F0\&\u003E
\u003Cspan class=\&content\&\u003E
\u003Cspan class=\&title\&\u003E巨屏体感游戏体验 - 腾讯视频\u003Cspan class=\&z-ico-extern-gray\&\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&z-ico-extern-blue\&\u003E\u003C\u002Fspan\u003E\u003C\u002Fspan\u003E
\u003Cspan class=\&url\&\u003E\u003Cspan class=\&z-ico-video\&\u003E\u003C\u002Fspan\u003Ehttps:\u002F\\u002Fx\u002Fpage\u002Fa03594v37wi.html\u003C\u002Fspan\u003E
\u003C\u002Fspan\u003E
\u003C\u002Fa\u003E
\u003C\u002Fp\u003E\u003Ch2\u003E二、实现原理\u003C\u002Fh2\u003E\u003Cp\u003E 使用H5开发基于Kinect的体感游戏,其实工作原理很简单,由Kinect采集到玩家及环境数据,比如人体骨骼,使用某种方式,使浏览器可以访问这些数据。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cbr\u003E\u003Cstrong\u003E1、采集数据\u003C\u002Fstrong\u003E\u003Cbr\u003E  Kinect有三个镜头,中间镜头类似普通摄像头,获取彩色图像。左右两边镜头则是通过红外线获取深度数据。我们使用微软提供的SDK去读取以下类型数据:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E色彩数据:彩色图像;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E深度数据:颜色尝试信息;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E人体骨骼数据:基于以上数据经计算,获取到人体骨骼数据。\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cbr\u003E\u003Cstrong\u003E2、使浏览器可访问到Kinect数据\u003C\u002Fstrong\u003E\u003Cbr\u003E我尝试和了解过的框架,基本上是以socket让浏览器进程与服务器进行通信 ,进行数据传输:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002FLightBuzz\u002FKinect-HTML5\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EKinect-HTML5\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 用C#搭建服务端,色彩数据、尝试数据、骨骼数据均有提供;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002Fen\u002Fzdk\u002Foverview\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EZigFu\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 支持H5、U3D、Flash进行开发,API较为完整,貌似收费;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fdoug\u002Fdepthjs\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EDepthJS\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E
以浏览器插件形式提供数据访问;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fwouterverweirder\u002Fkinect2\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ENode-Kinect2\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 以Nodejs搭建服务器端,提供数据比较完整,实例较多。\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E我最终选用Node-Kinect2,虽然没有文档,但是实例较多,使用前端工程师熟悉的Nodejs,另外作者反馈比较快。\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003EKinect: 捕获玩家数据,比如深度图像、彩色图像等;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003ENode-Kinect2: 从Kinect获取相应数据,并进行二次加工;\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E浏览器: 监听node应用指定接口,获取玩家数据并完成游戏开发。\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Ch2\u003E三、准备工作\u003C\u002Fh2\u003E\u003Cp\u003E\u003Cstrong\u003E1、系统要求:\u003C\u002Fstrong\u003E\u003Cbr\u003E这是硬性要求,我曾在不符合要求的环境下浪费太多时间。\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cp\u003EUSB3.0\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E支持DX11的显卡\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003Ewin8及以上系统\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E支持Web Sockets的浏览器\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E当然Kinect v2传感器是少不了的\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E2、环境搭建流程:\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Col\u003E\u003Cli\u003E\u003Cp\u003E连接上Kinect v2\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E安装 KinectSDK-v2.0\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E安装 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fnodejs.org\u002Fen\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ENodejs\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003Cli\u003E\u003Cp\u003E安装 Node-Kinect2 \u003C\u002Fp\u003E\u003C\u002Fli\u003E\u003C\u002Fol\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Enpm install kinect2\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cbr\u003E\u003Ch2\u003E四、实例演示\u003C\u002Fh2\u003E\u003Cp\u003E如下图所示,我们演示如何获取人体骨骼,并标识脊椎中段及手势:\u003Cbr\u003E\u003Cbr\u003E\u003Cstrong\u003E1、服务器端\u003C\u002Fstrong\u003E\u003Cbr\u003E创建web服务器,并将骨骼数据发送到浏览器端,代码如下:\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Evar Kinect2 = require('..\u002F..\u002Flib\u002Fkinect2'),\nexpress = require('express'),\napp = express(),\nserver = require('http').createServer(app),\nio = require('socket.io').listen(server);\n\nvar kinect = new Kinect2();\n\u002F\u002F 打开kinect\nif(kinect.open()) {\n\u002F\u002F 监听8000端口\nserver.listen(8000);\n\u002F\u002F 指定请求指向根目录\napp.get('\u002F', function(req, res) {\nres.sendFile(__dirname + '\u002Fpublic\u002Findex.html');\n});\n\u002F\u002F 将骨骼数据发送给浏览器端\nkinect.on('bodyFrame', function(bodyFrame){\nio.sockets.emit('bodyFrame', bodyFrame);\n});\n\u002F\u002F 开始读取骨骼数据\nkinect.openBodyReader();\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cstrong\u003E2、浏览器端\u003C\u002Fstrong\u003E\u003Cbr\u003E浏览器端获取骨骼数据,并用canvas描绘出来,关键代码如下:\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Evar socket = io.connect('\u002F');\nvar ctx = canvas.getContext('2d');\nsocket.on('bodyFrame', function(bodyFrame){\nctx.clearRect(0, 0, canvas.width, canvas.height);\nvar index = 0;\n\u002F\u002F 遍历所有骨骼数据\nbodyFrame.bodies.forEach(function(body){\nif(body.tracked) {\nfor(var jointType in body.joints) {\nvar joint = body.joints[jointType];\nctx.fillStyle = colors[index];\n\u002F\u002F 如果骨骼节点为脊椎中点\nif(jointType == 1) {\nctx.fillStyle = colors[2];\n}\nctx.fillRect(joint.depthX * 512, joint.depthY * 424, 10, 10);\n}\n\u002F\u002F 识别左右手手势\nupdateHandState(body.leftHandState, body.joints[7]);\nupdateHandState(body.rightHandState, body.joints[11]);\nindex++;\n}\n});\n});\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E很简单的几行代码,我们便完成了玩家骨骼捕获,有一定 javascript基础的同学应该很容易能看明白,但不明白的是我们能获取哪些数据?如何获取?骨骼节点名称分别是什么?而node-kienct2并没有文档告诉我们这些。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Ch2\u003E五、开发文档\u003C\u002Fh2\u003E\u003Cp\u003ENode-Kinect2并没有提供文档,我将我测试总结的文档整理如下:\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E1、服务器端能提供的数据类型;\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ekinect.on('bodyFrame', function(bodyFrame){}); \u002F\u002F还有哪些数据类型呢?\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cbr\u003EbodyFrame
骨骼数据infraredFrame红外数据longExposureInfraredFrame类似infraredFrame,貌似精度更高,优化后的数据rawDepthFrame未经处理的景深数据depthFrame景深数据colorFrame彩色图像multiSourceFrame所有数据audio音频数据,未测试\u003Cbr\u003E\u003Cbr\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E2、骨骼节点类型\u003C\u002Fstrong\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Ebody.joints[11] \u002F\u002F joints包括哪些呢?\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cbr\u003E节点类型JointType
spineBase脊椎基部1spineMid 脊椎中部2neck颈部3head头部4shoulderLeft左肩5elbowLeft左肘6wristLeft左腕7handLeft左手掌8shoulderRight右肩9elbowRight右肘10wristRight右腕11handRight右手掌12hipLeft左屁13kneeLeft左膝14ankleLeft左踝15footLeft左脚16hipRight右屁17kneeRight右膝18ankleRight右踝19footRight右脚20spineShoulder颈下脊椎21handTipLeft左手指(食中无小)22thumbLeft左拇指23handTipRight右手指24thumbRight右拇指\u003Cbr\u003E\u003Cbr\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cstrong\u003E3、手势,据测识别并不是太准确,在精度要求不高的情况下使用\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E0unknown
不能识别1notTracked未能检测到2open手掌3closed握拳4lasso剪刀手,并合并中食指\u003Cp\u003E\u003Cstrong\u003E4、骨骼数据\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cp\u003Ebody [object] {\u003Cbr\u003E
bodyIndex [number]:索引,允许6人\u003Cbr\u003E
joints [array]:骨骼节点,包含坐标信息,颜色信息\u003Cbr\u003E
leftHandState [number]:左手手势\u003Cbr\u003E
rightHandState [number]:右手手势\u003Cbr\u003E
tracked [boolean]:是否捕获到\u003Cbr\u003E
trackingId\u003Cbr\u003E} \u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E5、kinect对象\u003C\u002Fstrong\u003E\u003C\u002Fp\u003Eon
监听数据open打开Kinectclose关闭openBodyReader读取骨骼数据open**Reader类似如上方法,读取其它类型数据\u003Cbr\u003E\u003Cbr\u003E\u003Ch2\u003E六、实战总结\u003C\u002Fh2\u003E\u003Cp\u003E接下来,我总结一下TGC2016《火影忍者手游》的体感游戏开发中碰到的一些问题。\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E1、讲解之前,我们首先需要了解下游戏流程。\u003C\u002Fstrong\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E1.1、通过手势触发开始游戏\u003C\u002Fp\u003E\u003Cp\u003E1.2、玩家化身四代,左右跑动躲避九尾攻击\u003C\u002Fp\u003E\u003Cp\u003E1.3、摆出手势“奥义”,触发四代大招\u003C\u002Fp\u003E\u003Cp\u003E1.4、用户扫描二维码获取自己现场照片\u003C\u002Fp\u003E\u003Cp\u003E\u003Cstrong\u003E\u003Cbr\u003E2、服务器端\u003C\u002Fstrong\u003E\u003Cbr\u003E游戏需要玩家骨骼数据(移动、手势),彩色图像数据(某一手势下触发拍照),所以我们需要向客户端发送这两部分数据。值得注意的是,彩色图像数据体积过大,需要进行压缩。\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Evar emitColorFrame =\nio.sockets.on('connection', function (socket){\nsocket.on('startColorFrame', function(data){\nemitColorFrame =\n});\t\n});\nkinect.on('multiSourceFrame', function(frame){\n\n\u002F\u002F 发送玩家骨骼数据\nio.sockets.emit('bodyFrame', frame.body);\n\n\u002F\u002F 玩家拍照\nif(emitColorFrame) {\nvar compression = 1;\nvar origWidth = 1920;\nvar origHeight = 1080;\nvar origLength = 4 * origWidth * origH\nvar compressedWidth = origWidth \u002F\nvar compressedHeight = origHeight \u002F\nvar resizedLength = 4 * compressedWidth * compressedH\nvar resizedBuffer = new Buffer(resizedLength);\n\u002F\u002F ...\n\u002F\u002F 照片数据过大,需要压缩提高传输性能\nzlib.deflate(resizedBuffer, function(err, result){\nif(!err) {\nvar buffer = result.toString('base64');\nio.sockets.emit('colorFrame', buffer);\n}\n});\t\nemitColorFrame =\n}\n});\nkinect.openMultiSourceReader({\nframeTypes: Kinect2.FrameType.body | Kinect2.FrameType.color\n});\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E\u003Cstrong\u003E3、客户端\u003C\u002Fstrong\u003E\u003Cbr\u003E客户端业务逻辑较复杂,我们提取关键步骤进行讲解。\u003Cbr\u003E3.1、用户拍照时,由于处理的数据比较大,为防止页面出现卡顿,我们需要使用web worker\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E(function(){\nimportScripts('pako.inflate.min.js'); \n\nvar imageD\nfunction init() {\naddEventListener('message', function (event) {\nswitch (event.data.message) {\ncase \&setImageData\&:\nimageData = event.data.imageD\\ncase \&processImageData\&:\nprocessImageData(event.data.imageBuffer);\\n}\n});\n}\nfunction processImageData(compressedData) {\nvar imageBuffer = pako.inflate(atob(compressedData));\nvar pixelArray = imageData.\nvar newPixelData = new Uint8Array(imageBuffer);\nvar imageDataSize = imageData.data.\nfor (var i = 0; i & imageDataS i++) {\nimageData.data[i] = newPixelData[i];\n}\nfor(var x = 0; x & 1920; x++) {\nfor(var y = 0; y & 1080; y++) {\nvar idx = (x + y * 1920) * 4;\nvar r = imageData.data[idx + 0]; \nvar g = imageData.data[idx + 1]; \nvar b = imageData.data[idx + 2]; \n}\n}\nself.postMessage({ \&message\&: \&imageReady\&, \&imageData\&: imageData });\n}\ninit();\n})(); \n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E3.2、接投影仪后,如果渲染面积比较大,会出现白屏,需要关闭浏览器硬件加速。\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E3.3、现场光线较暗,其它玩家干扰,在追踪玩家运动轨迹的过程中,可能会出现抖动的情况,我们需要去除干扰数据。(当突然出现很大位移时,需要将数据移除)\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003Evar tracks = this.\nvar len = tracks.\n\n\u002F\u002F 数据过滤\nif(tracks[len-1] !== window.undefined) {\nif(Math.abs(n - tracks[len-1]) & 0.2) {\\n}\n}\nthis.tracks.push(n);\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E3.4、当玩家站立,只是左右少量晃动时,我们认为玩家是站立状态。\u003C\u002Fp\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-text\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u002F\u002F 保留5个数据\nif(this.tracks.length & 5) {\nthis.tracks.shift();\n} else {\\n}\n\n\u002F\u002F 位移总量\nvar dis = 0;\nfor(var i = 1; i & this.tracks. i++) {\ndis += this.tracks[i] - this.tracks[i-1];\n}\nif(Math.abs(dis) & 0.01) {\nthis.stand();\n} else {\nif(this.tracks[4] & this.tracks[3]) {\nthis.turnRight();\n} else {\nthis.turnLeft();\n}\nthis.run();\n}\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Ch2\u003E七、展望\u003C\u002Fh2\u003E\u003Cp\u003E1、使用HTML5开发Kinect体感游戏,降低了技术门槛,前端工程师可以轻松的开发体感游戏;\u003Cbr\u003E2、大量的框架可以应用,比如用JQuery、CreateJS、Three.js(三种不同渲染方式);\u003Cbr\u003E3、无限想象空间,试想下体感游戏结合webAR,结合webAudio、结合移动设备,太可以挖掘的东西了……想想都激动不是么!\u003C\u002Fp\u003E&,&updated&:new Date(&T07:54:16.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:2,&collapsedCount&:0,&likeCount&:7,&state&:&published&,&isLiked&:false,&slug&:&&,&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002Fv2-5fa81be8a0b3c0309d69_r.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&H5案例&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Kinect&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&体感游戏&}],&adminClosedComment&:false,&titleImageSize&:{&width&:1278,&height&:661},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&tipjarState&:&closed&,&annotationAction&:[],&sourceUrl&:&&,&pageCommentsCount&:2,&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T15:54:16+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&学生&,&isFollowing&:false,&hash&:&b9e426ba6&,&uid&:36,&isOrg&:false,&slug&:&jerryz_93&,&isFollowed&:false,&description&:&未来程序猿,五月天,吉他,摄影。&,&name&:&Jerry&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fjerryz_93&,&avatar&:{&id&:&7c9bc7ffbd69f&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&话多&,&isFollowing&:false,&hash&:&b5d192d93d7cf63e1ddb&,&uid&:92,&isOrg&:false,&slug&:&yang-zheng-yi-13&,&isFollowed&:false,&description&:&&,&name&:&正义大魔王&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fyang-zheng-yi-13&,&avatar&:{&id&:&bede581dfe8c013c41ef7ad9a978dfc9&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&學生&,&isFollowing&:false,&hash&:&c35fd7c7cea022bef3570728fcc6a2bb&,&uid&:44,&isOrg&:false,&slug&:&dan-dan-yin-yin-zuo-teng&,&isFollowed&:false,&description&:&&,&name&:&蛋蛋隱隱作疼&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fdan-dan-yin-yin-zuo-teng&,&avatar&:{&id&:&v2-edfbd082eaf4&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&精通十八般扯淡 相声表演艺术家&,&isFollowing&:false,&hash&:&ee082eefb87491cde4d60f&,&uid&:468200,&isOrg&:false,&slug&:&diao-ke-shi-guang-22&,&isFollowed&:false,&description&:&&,&name&:&雨疏&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fdiao-ke-shi-guang-22&,&avatar&:{&id&:&54348d12fdcf90c878e93cb82272a47c&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&&,&isFollowing&:false,&hash&:&7cc07fa713fcacea2de81&,&uid&:16,&isOrg&:false,&slug&:&mei-jin-86&,&isFollowed&:false,&description&:&&,&name&:&梅觐&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fmei-jin-86&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&\u003Cb\u003E一、简介\u003C\u002Fb\u003E 在前不久成都TGC2016展会上,我们开发了一款《火影忍者手游》的体感游戏,主要模拟手游章节《九尾袭来 》,用户化身四代,与九尾进行对决,吸引了大量玩家参与。 表面上看,这款游戏与其它体感体验无异,实际上,它一直运行于浏览器Chrome下,也就…&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&annotationDetail&:null,&commentsCount&:2,&likesCount&:7,&FULLINFO&:true}},&User&:{&tgideas&:{&isFollowed&:false,&name&:&TGideas&,&headline&:&TGideas隶属于腾讯互动娱乐业务系统,是一支专注于运营和营销领域的用户体验设计团队,工作范围涉及产品包装、广告创意、品牌建设、互动设计等,团队由专业的企划、项目管理、创意、视觉、开发、多媒体人才构成。“努力工作,拼命玩”是我们的信条,比起用飞机稿获奖,我们更乐于通过多样化的作品,帮助产品与用户建立有效的沟通机制与情感链接,实现真正意义上的商业价值。如果你是一个不安于现状的狂热分子,欢迎和TGideas一起来玩出名堂。&,&avatarUrl&:&https:\u002F\\u002F50\u002Fv2-7d4c6ade6be6930cf9dbc7bf_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&tgideas&,&bio&:&视觉设计师\u002F用户体验\u002F创意广告&,&hash&:&eeda25d64f888daa77102&,&uid&:935400,&isOrg&:false,&description&:&TGideas隶属于腾讯互动娱乐业务系统,是一支专注于运营和营销领域的用户体验设计团队,工作范围涉及产品包装、广告创意、品牌建设、互动设计等,团队由专业的企划、项目管理、创意、视觉、开发、多媒体人才构成。“努力工作,拼命玩”是我们的信条,比起用飞机稿获奖,我们更乐于通过多样化的作品,帮助产品与用户建立有效的沟通机制与情感链接,实现真正意义上的商业价值。如果你是一个不安于现状的狂热分子,欢迎和TGideas一起来玩出名堂。&,&badge&:{&identity&:null,&bestAnswerer&:null},&profileUrl&:&https:\u002F\\u002Fpeople\u002Ftgideas&,&avatar&:{&id&:&v2-7d4c6ade6be6930cf9dbc7bf&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}},&Comment&:{},&favlists&:{}},&me&:{},&global&:{&experimentFeatures&:{&ge3&:&ge3_9&,&ge2&:&ge2_1&,&nwebStickySidebar&:&sticky&,&newMore&:&new&,&liveReviewBuyBar&:&live_review_buy_bar_2&,&liveStore&:&ls_a2_b2_c1_f2&,&isOffice&:&false&,&homeUi2&:&default&,&answerRelatedReadings&:&qa_recommend_with_ads_and_article&,&remixOneKeyPlayButton&:&headerButton&,&asdfadsf&:&asdfad&,&qrcodeLogin&:&qrcode&,&newBuyBar&:&livenewbuy3&,&isShowUnicomFreeEntry&:&unicom_free_entry_off&,&newMobileColumnAppheader&:&new_header&,&zcmLighting&:&zcm&,&favAct&:&default&,&appStoreRateDialog&:&close&,&mobileQaPageProxyHeifetz&:&m_qa_page_nweb&,&iOSNewestVersion&:&4.2.0&,&default&:&None&,&wechatShareModal&:&wechat_share_modal_show&,&qaStickySidebar&:&sticky_sidebar&,&androidProfilePanel&:&panel_b&,&nwebWriteAnswer&:&experiment&}},&columns&:{&next&:{}},&columnPosts&:{},&columnSettings&:{&colomnAuthor&:[],&uploadAvatarDetails&:&&,&contributeRequests&:[],&contributeRequestsTotalCount&:0,&inviteAuthor&:&&},&postComments&:{},&postReviewComments&:{&comments&:[],&newComments&:[],&hasMore&:true},&favlistsByUser&:{},&favlistRelations&:{},&promotions&:{},&draft&:{&titleImage&:&&,&titleImageSize&:{},&isTitleImageFullScreen&:false,&canTitleImageFullScreen&:false,&title&:&&,&titleImageUploading&:false,&error&:&&,&content&:&&,&draftLoading&:false,&globalLoading&:false,&pendingVideo&:{&resource&:null,&error&:null}},&drafts&:{&draftsList&:[],&next&:{}},&config&:{&userNotBindPhoneTipString&:{}},&recommendPosts&:{&articleRecommendations&:[],&columnRecommendations&:[]},&env&:{&edition&:{},&isAppView&:false,&appViewConfig&:{&content_padding_top&:128,&content_padding_bottom&:56,&content_padding_left&:16,&content_padding_right&:16,&title_font_size&:22,&body_font_size&:16,&is_dark_theme&:false,&can_auto_load_image&:true,&app_info&:&OS=iOS&},&isApp&:false},&message&:{&newCount&:0},&pushNotification&:{&newCount&:0}}}

我要回帖

更多关于 体感游戏开发 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信