原文地址:http://www.script-tutorials.com/html5-game-development-lesson-8/

这是我们最新一篇HTML5游戏开发系列文章。我们将继续使用canvas来进行HTML5游戏开发系列的文章。这次我将展示在你的项目中,如何使用Box2D的创建物体。Box2D是一个非常流行的开源物理引擎对于那些需要模拟2D物体的应用来说。在游戏开发中,2D物理引擎是个非常热门的话题。有了物理引擎的帮助,再设定环境和简单的规则,我们可以很容易的创建好玩的游戏。

准备:

首先,你应该这里下载Box2d库。

第一步:HTML

这次我们必须引用所有必需的库文件到我们项目中。

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>HTML5 Game Development - Lesson 8 | Script Tutorials</title>
  6. <link href="css/main.css" rel="stylesheet" type="text/css" />
  7.  
  8. <script src="js/protoclass.js"></script>
  9. <script src="js/jquery-1.6.min.js"></script>
  10.  
  11. <!-- box2djs 文档上说,加载顺序很重要,所以直接从box2d提供的index.html中copy过来-->
  12. <script src='js/box2d/common/b2Settings.js'></script>
  13. <script src='js/box2d/common/math/b2Vec2.js'></script>
  14. <script src='js/box2d/common/math/b2Mat22.js'></script>
  15. <script src='js/box2d/common/math/b2Math.js'></script>
  16. <script src='js/box2d/collision/b2AABB.js'></script>
  17. <script src='js/box2d/collision/b2Bound.js'></script>
  18. <script src='js/box2d/collision/b2BoundValues.js'></script>
  19. <script src='js/box2d/collision/b2Pair.js'></script>
  20. <script src='js/box2d/collision/b2PairCallback.js'></script>
  21. <script src='js/box2d/collision/b2BufferedPair.js'></script>
  22. <script src='js/box2d/collision/b2PairManager.js'></script>
  23. <script src='js/box2d/collision/b2BroadPhase.js'></script>
  24. <script src='js/box2d/collision/b2Collision.js'></script>
  25. <script src='js/box2d/collision/Features.js'></script>
  26. <script src='js/box2d/collision/b2ContactID.js'></script>
  27. <script src='js/box2d/collision/b2ContactPoint.js'></script>
  28. <script src='js/box2d/collision/b2Distance.js'></script>
  29. <script src='js/box2d/collision/b2Manifold.js'></script>
  30. <script src='js/box2d/collision/b2OBB.js'></script>
  31. <script src='js/box2d/collision/b2Proxy.js'></script>
  32. <script src='js/box2d/collision/ClipVertex.js'></script>
  33. <script src='js/box2d/collision/shapes/b2Shape.js'></script>
  34. <script src='js/box2d/collision/shapes/b2ShapeDef.js'></script>
  35. <script src='js/box2d/collision/shapes/b2BoxDef.js'></script>
  36. <script src='js/box2d/collision/shapes/b2CircleDef.js'></script>
  37. <script src='js/box2d/collision/shapes/b2CircleShape.js'></script>
  38. <script src='js/box2d/collision/shapes/b2MassData.js'></script>
  39. <script src='js/box2d/collision/shapes/b2PolyDef.js'></script>
  40. <script src='js/box2d/collision/shapes/b2PolyShape.js'></script>
  41. <script src='js/box2d/dynamics/b2Body.js'></script>
  42. <script src='js/box2d/dynamics/b2BodyDef.js'></script>
  43. <script src='js/box2d/dynamics/b2CollisionFilter.js'></script>
  44. <script src='js/box2d/dynamics/b2Island.js'></script>
  45. <script src='js/box2d/dynamics/b2TimeStep.js'></script>
  46. <script src='js/box2d/dynamics/contacts/b2ContactNode.js'></script>
  47. <script src='js/box2d/dynamics/contacts/b2Contact.js'></script>
  48. <script src='js/box2d/dynamics/contacts/b2ContactConstraint.js'></script>
  49. <script src='js/box2d/dynamics/contacts/b2ContactConstraintPoint.js'></script>
  50. <script src='js/box2d/dynamics/contacts/b2ContactRegister.js'></script>
  51. <script src='js/box2d/dynamics/contacts/b2ContactSolver.js'></script>
  52. <script src='js/box2d/dynamics/contacts/b2CircleContact.js'></script>
  53. <script src='js/box2d/dynamics/contacts/b2Conservative.js'></script>
  54. <script src='js/box2d/dynamics/contacts/b2NullContact.js'></script>
  55. <script src='js/box2d/dynamics/contacts/b2PolyAndCircleContact.js'></script>
  56. <script src='js/box2d/dynamics/contacts/b2PolyContact.js'></script>
  57. <script src='js/box2d/dynamics/b2ContactManager.js'></script>
  58. <script src='js/box2d/dynamics/b2World.js'></script>
  59. <script src='js/box2d/dynamics/b2WorldListener.js'></script>
  60. <script src='js/box2d/dynamics/joints/b2JointNode.js'></script>
  61. <script src='js/box2d/dynamics/joints/b2Joint.js'></script>
  62. <script src='js/box2d/dynamics/joints/b2JointDef.js'></script>
  63. <script src='js/box2d/dynamics/joints/b2DistanceJoint.js'></script>
  64. <script src='js/box2d/dynamics/joints/b2DistanceJointDef.js'></script>
  65. <script src='js/box2d/dynamics/joints/b2Jacobian.js'></script>
  66. <script src='js/box2d/dynamics/joints/b2GearJoint.js'></script>
  67. <script src='js/box2d/dynamics/joints/b2GearJointDef.js'></script>
  68. <script src='js/box2d/dynamics/joints/b2MouseJoint.js'></script>
  69. <script src='js/box2d/dynamics/joints/b2MouseJointDef.js'></script>
  70. <script src='js/box2d/dynamics/joints/b2PrismaticJoint.js'></script>
  71. <script src='js/box2d/dynamics/joints/b2PrismaticJointDef.js'></script>
  72. <script src='js/box2d/dynamics/joints/b2PulleyJoint.js'></script>
  73. <script src='js/box2d/dynamics/joints/b2PulleyJointDef.js'></script>
  74. <script src='js/box2d/dynamics/joints/b2RevoluteJoint.js'></script>
  75. <script src='js/box2d/dynamics/joints/b2RevoluteJointDef.js'></script>
  76.  
  77. <script src="js/script.js"></script>
  78. </head>
  79. <body>
  80. <header>
  81. <h2>HTML5 Game Development - Lesson 8</h2>
  82. <a href="http://www.script-tutorials.com/html5-game-development-lesson-8/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
  83. </header>
  84. <div class="container">
  85. <canvas id="game" width="800" height="600"></canvas>
  86. </div>
  87. </body>
  88. </html>

第二步:CSS

css/main.css

这次就不打算显示出CSS文件的内容了,因为仅仅只是些页面布局样式。你可以在源代码包里找到该文件。

第三步:JS

js/jquery-2.0.0.min.js  和 js/protoclass.js

上面两个js文件都在源代码包里。下面的js文件是最重要的,是我们游戏的主要代码。

js/script.js

  1. var canvas, ctx;
  2. var canvasWidth;
  3. var canvasHeight;
  4. var world;
  5. var iBorder = 5;
  6.  
  7. //随机产生介于x和y之间的数
  8. function getRand(x, y) {
  9. return Math.floor(Math.random() * y) + x;
  10. }
  11.  
  12. $(function() {
  13. world = createWorld();
  14.  
  15. canvas = document.getElementById('game');
  16. ctx = canvas.getContext('2d');
  17. canvasWidth = parseInt(canvas.width);
  18. canvasHeight = parseInt(canvas.height);
  19.  
  20. createGround(canvasWidth / 2, canvasHeight - iBorder, canvasWidth / 2, iBorder, 0);
  21. createGround(iBorder, canvasHeight / 2, iBorder, canvasHeight / 2, 0); //左边界
  22. createGround(canvasWidth - iBorder, canvasHeight / 2, iBorder, canvasHeight / 2, 0); //右边界
  23.  
  24. addObjects();
  25.  
  26. frame();
  27. });
  28.  
  29. function addObjects() {
  30. var iVar = getRand(1, 2);
  31.  
  32. if (iVar == 1) { //圆圈
  33. var x = getRand(100, 600);
  34. var y = 0;
  35. var r = getRand(10, 40);
  36. createCircleAt(x, y, r);
  37. } else if(iVar == 2) { //方块
  38. var x = getRand(100, 600);
  39. var y = 0;
  40. var w = getRand(5, 40);
  41. var h = getRand(5, 40);
  42. createBoxAt(x, y, w, h);
  43. }
  44.  
  45. setTimeout(addObjects, 500);
  46. }
  47.  
  48. function frame() {
  49. world.Step(1.0 / 60, 1);
  50. ctx.clearRect(0, 0, canvasWidth, canvasHeight);
  51.  
  52. drawWorld(world, ctx);
  53.  
  54. setTimeout(frame, 10);
  55. }
  56.  
  57. function createWorld() {
  58. //创建世界边界
  59. var worldAABB = new b2AABB();
  60. worldAABB.minVertex.Set(-1000, -1000); //上限
  61. worldAABB.maxVertex.Set(1000, 1000); //下限
  62.  
  63. //确定重力
  64. var gravity = new b2Vec2(0, 200);
  65.  
  66. //不允许引擎睡眠
  67. var doSleep = false;
  68.  
  69. return new b2World(worldAABB, gravity, doSleep);
  70. }
  71.  
  72. function createGround(x, y, width, height, rotation) {
  73. var groundSd = new b2BoxDef();
  74. groundSd.extents.Set(width, height);
  75. groundSd.restitution = 0.4; //弹性
  76.  
  77. var groundBd = new b2BodyDef();
  78. groundBd.AddShape(groundSd);
  79. groundBd.position.Set(x, y);
  80. groundBd.rotation = rotation * Math.PI / 180; //角度
  81. return world.CreateBody(groundBd);
  82. }
  83.  
  84. function createBoxAt(x, y, w, h) {
  85. var boxSd = new b2BoxDef();
  86. boxSd.density = 1.0; //密度
  87. boxSd.friction = 1.0; //摩擦力
  88. boxSd.restitution = .5; //弹性
  89. boxSd.extents.Set(w, h);
  90.  
  91. var boxBd = new b2BodyDef();
  92. boxBd.AddShape(boxSd);
  93. boxBd.position.Set(x, y);
  94. return world.CreateBody(boxBd);
  95. }
  96.  
  97. function createCircleAt(x, y, r) {
  98. var boxSd = new b2CircleDef();
  99. boxSd.density = 1.0;
  100. boxSd.friction = 1.0;
  101. boxSd.restitution = .5;
  102. boxSd.radius = r;
  103.  
  104. var boxBd = new b2BodyDef();
  105. boxBd.AddShape(boxSd);
  106. boxBd.position.Set(x, y);
  107. return world.CreateBody(boxBd);
  108. }
  109.  
  110. function drawWorld(world, context) {
  111. //循环的绘制出世界里的物体
  112. for (var b = world.m_bodyList; b != null; b = b.m_next) {
  113. for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
  114. drawShape(s, context);
  115. }
  116. }
  117. }
  118.  
  119. function drawShape(shape, context) {
  120. context.strokeStyle = '#0000ff';
  121. context.fillStyle = 'rgba(100, 100, 255, 0.8)';
  122. context.beginPath();
  123.  
  124. switch (shape.m_type) {
  125. case b2Shape.e_circleShape:
  126. var circle = shape;
  127. var pos = circle.m_position;
  128. var r = circle.m_radius;
  129. var segments = 16.0;
  130. var theta = 0.0;
  131. var dtheta = 2.0 * Math.PI / segments;
  132. context.moveTo(pos.x + r, pos.y);
  133. for (var i = 0; i < segments; i++) {
  134. var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
  135. var v = b2Math.AddVV(pos, d);
  136. context.lineTo(v.x, v.y);
  137. theta += dtheta;
  138. }
  139. context.lineTo(pos.x + r, pos.y);
  140. context.moveTo(pos.x, pos.y);
  141. var ax = circle.m_R.col1;
  142. var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
  143. context.lineTo(pos2.x, pos2.y);
  144. break;
  145. case b2Shape.e_polyShape:
  146. var poly = shape;
  147. var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
  148. context.moveTo(tV.x, tV.y);
  149. for (var i = 0; i < poly.m_vertexCount; i++) {
  150. var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
  151. context.lineTo(v.x, v.y);
  152. }
  153. context.lineTo(tV.x, tV.y);
  154. break;
  155. }
  156. context.fill();
  157. context.stroke();
  158. }

我已经在很多地方添加了注释,希望这些代码很容易理解。

结论:

就是这样了,你已经用HTML5和Box2D完成了这次的教程,恭喜!

HTML5游戏开发系列教程8(译)的更多相关文章

  1. HTML5游戏开发系列教程7(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-7/ 今天我们将完成我们第一个完整的游戏--打砖块.这次教程中,将 ...

  2. HTML5游戏开发系列教程6(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-6/ 这是我们最新一篇HTML5游戏开发系列文章.我们将继续使用c ...

  3. HTML5游戏开发系列教程5(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-5/ 最终我决定准备下一篇游戏开发系列的文章,我们将继续使用can ...

  4. HTML5游戏开发系列教程4(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-4/ 这篇文章是我们继续使用canvas来进行HTML5游戏开发系 ...

  5. HTML5游戏开发系列教程10(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-10/ 最后我们将继续使用canvas来进行HTML5游戏开发系列 ...

  6. HTML5游戏开发系列教程9(译)

    原文地址:http://www.script-tutorials.com/html5-game-development-lesson-9/ 今天我们将继续使用canvas来进行HTML5游戏开发系列的 ...

  7. cocos2d-x游戏开发系列教程-前言

    cocos2d-x游戏开发前景: 最近企业对于Cocos2D-X开发人才的用人需求很大,而且所提供的薪资相当可观. 为满足广大向往游戏开发行业同学的需求,特推出适合新手的Cocos2D-X手游开发教程 ...

  8. cocos2d-x游戏开发系列教程-超级玛丽07-CMGameMap

    背景 在上一篇博客中,我们提到CMGameScene,但是CMGameScene只是个框架,实际担任游戏逻辑的是CMGameMap类,这个博文就来了解下CMGameMap 头文件 class CMGa ...

  9. cocos2d-x游戏开发系列教程-超级玛丽06-CMGameScene

    背景 在CMMenuScene中,当用户点击开始游戏时,导演让场景进入到CMGameScene 头文件 class CMGameScene : public cocos2d::CCLayer,publ ...

随机推荐

  1. 005杰信-factory删除数据

    factory表的删除分为两种:单行删除,以及批量删除. 过程:在jFactoryCreate.jsp页面上两个按钮,单行删除以及批量删除.

  2. centos7安装avahi

    sudo yum install avahi sudo yum install avahi-tools 转自: http://unix.stackexchange.com/questions/1829 ...

  3. error C2678: 二进制“+”: 没有找到接受“const char [22]”类型的左操作数的运算符(或没有可接受的转换)没有与这些操作数匹配的“+”运算符

    错误:没有与这些操作数匹配的“+”运算符,操作数类型为const char [20]+CString 分析原因:其提示操作数类型为const char [20]+CString 可见是类型有问题 故加 ...

  4. VC++:ActiveX Test Container

    VC++6.0安装后包含了ActiveX Test Container工具,位置为: "C:\Program Files (x86)\Microsoft Visual Studio\Comm ...

  5. hdu 2918(IDA*)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2918 思路:这道题与前面几道类似,可以说是被秒杀了!!!构造启发式函数h()=(cnt+3)/4(cn ...

  6. 使用 composer 下载更新卸载类库

    前言:要下载什么包,可以去 https://packagist.org/ 找一下包名及其版本信息 1)配置composer.json文件,并使用composer install 命令下载类包,下面以下 ...

  7. flex布局,input点击软键盘激活,底部按钮上移

    安卓手机的问题,原本表单没有超出一屏的时候,上移的现象也是存才的,只是需要滑动body才能看得到,现在,超出一屏了,现象就很明显了 body明显上移: 点击input修改价格: 软键盘出现: 先尝试了 ...

  8. Location 对象的assign()和replace()有什么区别?

    window.location.assign(url) : 加载 URL 指定的新的 HTML 文档. 就相当于一个链接,跳转到指定的url,当前页面会转为新页面内容,可以点击后退返回上一个页面. w ...

  9. Nginx之静态资源WEB服务

    本篇主要记录学习Nginx的静态资源WEB服务的几种常见的功能记录学习 Nginx开发常用的命令 nginx -tc /etc/nginx/nginx.conf vim /etc/nginx/conf ...

  10. 装饰器模式(Decorator)

    一.装饰模式介绍 装饰模式(decorator):表示动态的给一个对象添加一些新的功能(利用子类继承父类也可以实现),但是比生成子类方式更灵活. 也叫装饰者模式或者装饰器模式 例如:我们每个人身上穿的 ...