IvanK 库介绍
PUBLISHED
本文介绍一种IvanK JavaScript库,以及在Tizen上如何使用它。
简介
IvanK库是一个开源的JavaScript图形库。 它小,简单且很轻。 它使用WebGL渲染图形,并且在浏览器(也在移动设备)中运行,且支持WebGL。
要在你的Tizen Web应用程序中使用IvanK库:
- 从下载区下载库,
或者
- 直接链接你的应用程序到最新的版本:
<script type="text/javascript" src="js/ivank.js"></script>
用IvanK库看一些演示和工程。 其中的两个用于创建本文中的Tizen Web示例应用程序。
你可以在这个向导中找到很有用的关于IvanK库的信息。 API文档可以在这里找到。
示例应用程序
从这篇文章中,我们使用IvanK主页上的演示源代码("Box2D" 和 "Pseudo 3D"),创建两个Tizen Web示例应用程序(IvanKBox2D 和 IvanKPsuedo3D)。
该示例应用程序使用完全Tizen 视图(720x1280),并且在Tizen SDK 2.2.1上测试过。
如何用IvanK库工作
这节描述一些关于用IvanK库工作的基本问题。 请参考IvanK Lib主页以获取更多信息。
关于IvanK的座标系统如下所示:
图1 IvanK 的座标系统
这个是以像素为单位。
IvanKPseudo3D
首先,我们集中关注IvanKPseudo3D示例应用程序。 如何创建这样的一个应用程序呢?
第一步就是在你的DOM结构中创建一个<canvas>元素。
<canvas id="c" width="720" height="1280"></canvas>
正如你所看见的,canvas 适合HD(720x1280)分辨率。 canvas id 属性用来创建一个Stage对象,这个对象是为了IvanK作显示树的根源(请看IvanK向导的类层次一节)。
stage = new Stage("c");
当我们有Stage的时候,我们就可以创建其他对象。 我们将他们作为Stage的后代来显示他们。 我们创建一个新的Sprite,且设置它的座标:
s = new Sprite(); s.x = stage.stageWidth/2; s.y = stage.stageHeight/2;
我们也可以如下设置它的旋转和大小:
s.rotation = Math.random()*360; s.scaleX = s.scaleY = 0.5 + Math.random();
我们将新创建的对象添加到Stage中:
stage.addChild(s);
然而,在IvanKPseudo3D示例应用程序中,它看起来更复杂一点,这是因为我们的地球应用有一个特别的形状。 下面的代码片断用于给出在我们的地球工程上的形状和3D效果:
vrt = []; ind = []; uvt = []; var lat, lon, x, y, z, p; for (var i=0; i<=n; i++) // rows for (var j=0; j<=n; j++) // cols { lat = -Math.PI/2 + i*Math.PI/n; lon = Math.PI + j*Math.PI/n; x = Math.cos(lat) * Math.cos(lon); y = Math.sin(lat); z = Math.cos(lat) * Math.sin(lon); p = 9/(8+z); // perspective vrt.push(p*x, p*y); uvt.push(0.5*j/n, i/n); if(i<n && j<n) // 6 indices for 2 triangles ind.push(nn*i+j, nn*i+j+1, nn*(i+1)+j, nn*i+j+1, nn*(i+1)+j, nn*(i+1)+j+1); }
vrt, ind, uvt 分别是 vertices, indices 和 coordinates,它们应用在纹理映射上。
注意:本文不会去解释上面的代码片断是如何工作的。 如果你想要知道更多,请看这篇文章。 它描述了你可以在ActionScript(IvanK库是基于Flash API)中如何为了3D效果来使用三角形。
现在我们可以使用已计算的数据(vrt, ind, uvt)来描绘一个合适的形状,以及以期望的方式来画一个位图(见图4):
// static shading layer var sh = new Sprite(); s.addChild(sh); sh.graphics.beginBitmapFill(new BitmapData("images/shade.png")); sh.graphics.drawTriangles(vrt, ind, uvt);
上面的代码片断用来为我们的地球对象画一个遮蔽层。
图2:shade.png 位图
图3: earth.jpg 位图
我们以相似的方式用一个地球位图来填充Sprite:
s.graphics.beginBitmapFill(bd); s.graphics.drawTriangles(vrt, ind, uvt);
上面的代码片断是onEF()函数的一部分,该函数通过 Event.ENTER_FRAME 事件触发:
stage.addEventListener(Event.ENTER_FRAME, onEF);
完整的 onEF() 函数如下所示:
function onEF(e) { s.scaleX = s.scaleY = zoom = (3*zoom + 50 + stage.mouseY)*0.25; var vel = 0.00005*(stage.mouseX - s.x); for(var i=0; i<uvt.length; i+=2) uvt[i] += vel; // shifting X coordinate s.graphics.clear(); s.graphics.beginBitmapFill(bd); s.graphics.drawTriangles(vrt, ind, uvt); }
它用于放大和旋转地球对象。 stage.mouseX 和 stage.mouseY 表示触摸座标。
图4 IvanKPseudo3D 示例应用程序截图(设备)
注意:这个应用程序在设备和模拟器上面看起来不同。 在设备上背景是白色的,在模拟器上是黑色。 这是因为IvanK的背景是透明的,因此它和父背景(在设备和模拟器上不同)一样。
IvankBox2D
IvankBox2D 示例应用程序使用IvanK 库和Box2dWeb(2.1a.3版本)的物理引擎。 Box2dWeb 物理引擎可执行所有的仿真程序。 IvanK库展示其結果。
注意:更多的关于Box2dWeb物理引擎的信息都可以在 Box2dWeb 主页上找到,或者在 developer.tizen.org 上发表的两篇文章中找到:"Box2DWeb 在 Cocos2D-HTML5 游戏中"("Box2dWeb" 章节) 和 "在Tizen 上的 Custom 3D 图形“ ("物理引擎 - Box2dWeb" 章节)。
学习Box2dWeb物理引擎的基本知识也不是本文的讨论范围。 我们建议你在阅读本节之前先看前面的文章,以理解Box2dWeb物理引擎。
var bodies = []; // instances of b2Body (from Box2D) var actors = []; // instances of Bitmap (from IvanK)
"bodies" 和 "actors" 表格保存Box2D 和 IvanK 对象的实例,用以允许简单地访问他们。 如前所述,我们创建一个画面元素和一个Stage对象(请看前面章节)。 下面我们需要为我们的应用程序创建一个背景:
// background var bg = new Bitmap( new BitmapData("images/winter2.jpg") ); bg.scaleX = bg.scaleY = stage.stageHeight/512; stage.addChild(bg);
我们用box 和 ball 对象来创建一个Box2D世界,这些对象相互之间可能会冲突。 我们可以定义他们的形状,位置,大小等。
当你有了所有已创建的Box2D对象,你就可以使用IvanK库来画他们。 你需要创建一个新的Sprite对象(演员),设置位图到该对象,对它作刻度,并且将其作为Stage对象的后来进行添加。
// both images are 200 x 200 px var bxBD = new BitmapData("images/box.jpg"); var blBD = new BitmapData("images/bigball.png"); (...) var bm = new Bitmap(i<15 ? bxBD : blBD); bm.x = bm.y = -100; var actor = new Sprite(); actor.addChild(bm); if(i<15) { actor.scaleX = hw; actor.scaleY = hh; } else { actor.scaleX = actor.scaleY = hw; } actor.addEventListener(MouseEvent.MOUSE_MOVE, Jump); stage.addChild(actor); actors.push(actor);
"hw"和"hh"分别表示Box2D实体的半宽和半高。
另外,我们在Sprite对象上添加一个事件监听器。 MouseEvent.MOUSE_MOVE 事件触发 Jump()函数:
up = new b2Vec2(0, -5); (...) function Jump(e) { var a = e.currentTarget; // current actor var i = actors.indexOf(a); // cursor might be over ball bitmap, but not over a real ball if(i>=15 && Math.sqrt(a.mouseX*a.mouseX + a.mouseY*a.mouseY) > 100) return; bodies[i].ApplyImpulse(up, bodies[i].GetWorldCenter()); }
Jump()函数负责对运动物体产生一个波。
如前所述,我们需要如下所示的onEF()函数:
function onEF(e) { world.Step(1 / 60, 3, 3); world.ClearForces(); for(var i=0; i<actors.length; i++) { var body = bodies[i]; var actor = actors [i]; var p = body.GetPosition(); actor.x = p.x *100; // updating actor actor.y = p.y *100; actor.rotation = body.GetAngle()*180/Math.PI; } }
已经完成的 IvanKBox2D 示例应用程序:
图5 IvanKBox2D 示例应用程序截图
总结
我们希望本文向你展示了,如何在你的Tizen Web 应用程序中使用 IvanK 图形库。 用它来创建不可思议的游戏和应用程序吧!