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

原文地址: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>
View Code

第二步: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完成了这次的教程,恭喜!

原文地址:https://www.cnblogs.com/pigzhu/p/3234255.html