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

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

准备:

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

第一步:HTML

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

index.html

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>HTML5 Game Development - Lesson 8 | Script Tutorials</title>
<link href="css/main.css" rel="stylesheet" type="text/css" /> <script src="js/protoclass.js"></script>
<script src="js/jquery-1.6.min.js"></script> <!-- box2djs 文档上说,加载顺序很重要,所以直接从box2d提供的index.html中copy过来-->
<script src='js/box2d/common/b2Settings.js'></script>
<script src='js/box2d/common/math/b2Vec2.js'></script>
<script src='js/box2d/common/math/b2Mat22.js'></script>
<script src='js/box2d/common/math/b2Math.js'></script>
<script src='js/box2d/collision/b2AABB.js'></script>
<script src='js/box2d/collision/b2Bound.js'></script>
<script src='js/box2d/collision/b2BoundValues.js'></script>
<script src='js/box2d/collision/b2Pair.js'></script>
<script src='js/box2d/collision/b2PairCallback.js'></script>
<script src='js/box2d/collision/b2BufferedPair.js'></script>
<script src='js/box2d/collision/b2PairManager.js'></script>
<script src='js/box2d/collision/b2BroadPhase.js'></script>
<script src='js/box2d/collision/b2Collision.js'></script>
<script src='js/box2d/collision/Features.js'></script>
<script src='js/box2d/collision/b2ContactID.js'></script>
<script src='js/box2d/collision/b2ContactPoint.js'></script>
<script src='js/box2d/collision/b2Distance.js'></script>
<script src='js/box2d/collision/b2Manifold.js'></script>
<script src='js/box2d/collision/b2OBB.js'></script>
<script src='js/box2d/collision/b2Proxy.js'></script>
<script src='js/box2d/collision/ClipVertex.js'></script>
<script src='js/box2d/collision/shapes/b2Shape.js'></script>
<script src='js/box2d/collision/shapes/b2ShapeDef.js'></script>
<script src='js/box2d/collision/shapes/b2BoxDef.js'></script>
<script src='js/box2d/collision/shapes/b2CircleDef.js'></script>
<script src='js/box2d/collision/shapes/b2CircleShape.js'></script>
<script src='js/box2d/collision/shapes/b2MassData.js'></script>
<script src='js/box2d/collision/shapes/b2PolyDef.js'></script>
<script src='js/box2d/collision/shapes/b2PolyShape.js'></script>
<script src='js/box2d/dynamics/b2Body.js'></script>
<script src='js/box2d/dynamics/b2BodyDef.js'></script>
<script src='js/box2d/dynamics/b2CollisionFilter.js'></script>
<script src='js/box2d/dynamics/b2Island.js'></script>
<script src='js/box2d/dynamics/b2TimeStep.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactNode.js'></script>
<script src='js/box2d/dynamics/contacts/b2Contact.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactConstraint.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactConstraintPoint.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactRegister.js'></script>
<script src='js/box2d/dynamics/contacts/b2ContactSolver.js'></script>
<script src='js/box2d/dynamics/contacts/b2CircleContact.js'></script>
<script src='js/box2d/dynamics/contacts/b2Conservative.js'></script>
<script src='js/box2d/dynamics/contacts/b2NullContact.js'></script>
<script src='js/box2d/dynamics/contacts/b2PolyAndCircleContact.js'></script>
<script src='js/box2d/dynamics/contacts/b2PolyContact.js'></script>
<script src='js/box2d/dynamics/b2ContactManager.js'></script>
<script src='js/box2d/dynamics/b2World.js'></script>
<script src='js/box2d/dynamics/b2WorldListener.js'></script>
<script src='js/box2d/dynamics/joints/b2JointNode.js'></script>
<script src='js/box2d/dynamics/joints/b2Joint.js'></script>
<script src='js/box2d/dynamics/joints/b2JointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2DistanceJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2DistanceJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2Jacobian.js'></script>
<script src='js/box2d/dynamics/joints/b2GearJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2GearJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2MouseJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2MouseJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2PrismaticJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2PrismaticJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2PulleyJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2PulleyJointDef.js'></script>
<script src='js/box2d/dynamics/joints/b2RevoluteJoint.js'></script>
<script src='js/box2d/dynamics/joints/b2RevoluteJointDef.js'></script> <script src="js/script.js"></script>
</head>
<body>
<header>
<h2>HTML5 Game Development - Lesson 8</h2>
<a href="http://www.script-tutorials.com/html5-game-development-lesson-8/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
</header>
<div class="container">
<canvas id="game" width="800" height="600"></canvas>
</div>
</body>
</html>

第二步:CSS

css/main.css

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

第三步:JS

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

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

js/script.js

 var canvas, ctx;
var canvasWidth;
var canvasHeight;
var world;
var iBorder = 5; //随机产生介于x和y之间的数
function getRand(x, y) {
return Math.floor(Math.random() * y) + x;
} $(function() {
world = createWorld(); canvas = document.getElementById('game');
ctx = canvas.getContext('2d');
canvasWidth = parseInt(canvas.width);
canvasHeight = parseInt(canvas.height); createGround(canvasWidth / 2, canvasHeight - iBorder, canvasWidth / 2, iBorder, 0);
createGround(iBorder, canvasHeight / 2, iBorder, canvasHeight / 2, 0); //左边界
createGround(canvasWidth - iBorder, canvasHeight / 2, iBorder, canvasHeight / 2, 0); //右边界 addObjects(); frame();
}); function addObjects() {
var iVar = getRand(1, 2); if (iVar == 1) { //圆圈
var x = getRand(100, 600);
var y = 0;
var r = getRand(10, 40);
createCircleAt(x, y, r);
} else if(iVar == 2) { //方块
var x = getRand(100, 600);
var y = 0;
var w = getRand(5, 40);
var h = getRand(5, 40);
createBoxAt(x, y, w, h);
} setTimeout(addObjects, 500);
} function frame() {
world.Step(1.0 / 60, 1);
ctx.clearRect(0, 0, canvasWidth, canvasHeight); drawWorld(world, ctx); setTimeout(frame, 10);
} function createWorld() {
//创建世界边界
var worldAABB = new b2AABB();
worldAABB.minVertex.Set(-1000, -1000); //上限
worldAABB.maxVertex.Set(1000, 1000); //下限 //确定重力
var gravity = new b2Vec2(0, 200); //不允许引擎睡眠
var doSleep = false; return new b2World(worldAABB, gravity, doSleep);
} function createGround(x, y, width, height, rotation) {
var groundSd = new b2BoxDef();
groundSd.extents.Set(width, height);
groundSd.restitution = 0.4; //弹性 var groundBd = new b2BodyDef();
groundBd.AddShape(groundSd);
groundBd.position.Set(x, y);
groundBd.rotation = rotation * Math.PI / 180; //角度
return world.CreateBody(groundBd);
} function createBoxAt(x, y, w, h) {
var boxSd = new b2BoxDef();
boxSd.density = 1.0; //密度
boxSd.friction = 1.0; //摩擦力
boxSd.restitution = .5; //弹性
boxSd.extents.Set(w, h); var boxBd = new b2BodyDef();
boxBd.AddShape(boxSd);
boxBd.position.Set(x, y);
return world.CreateBody(boxBd);
} function createCircleAt(x, y, r) {
var boxSd = new b2CircleDef();
boxSd.density = 1.0;
boxSd.friction = 1.0;
boxSd.restitution = .5;
boxSd.radius = r; var boxBd = new b2BodyDef();
boxBd.AddShape(boxSd);
boxBd.position.Set(x, y);
return world.CreateBody(boxBd);
} function drawWorld(world, context) {
//循环的绘制出世界里的物体
for (var b = world.m_bodyList; b != null; b = b.m_next) {
for (var s = b.GetShapeList(); s != null; s = s.GetNext()) {
drawShape(s, context);
}
}
} function drawShape(shape, context) {
context.strokeStyle = '#0000ff';
context.fillStyle = 'rgba(100, 100, 255, 0.8)';
context.beginPath(); switch (shape.m_type) {
case b2Shape.e_circleShape:
var circle = shape;
var pos = circle.m_position;
var r = circle.m_radius;
var segments = 16.0;
var theta = 0.0;
var dtheta = 2.0 * Math.PI / segments;
context.moveTo(pos.x + r, pos.y);
for (var i = 0; i < segments; i++) {
var d = new b2Vec2(r * Math.cos(theta), r * Math.sin(theta));
var v = b2Math.AddVV(pos, d);
context.lineTo(v.x, v.y);
theta += dtheta;
}
context.lineTo(pos.x + r, pos.y);
context.moveTo(pos.x, pos.y);
var ax = circle.m_R.col1;
var pos2 = new b2Vec2(pos.x + r * ax.x, pos.y + r * ax.y);
context.lineTo(pos2.x, pos2.y);
break;
case b2Shape.e_polyShape:
var poly = shape;
var tV = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[0]));
context.moveTo(tV.x, tV.y);
for (var i = 0; i < poly.m_vertexCount; i++) {
var v = b2Math.AddVV(poly.m_position, b2Math.b2MulMV(poly.m_R, poly.m_vertices[i]));
context.lineTo(v.x, v.y);
}
context.lineTo(tV.x, tV.y);
break;
}
context.fill();
context.stroke();
}

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

结论:

就是这样了,你已经用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. 在Servlet处理请求的方式为。(选择1项)

    A.以进程的方式 B.以程序的方式 C.以线程的方式 D.以响应的方式 解答:C

  2. 整理:java定时器。

    本文纯属个人思路,如有错误,请指正. java的Timer依赖Thread,每一个Timer实际上都是一个Thread. import java.util.TimerTask; /** * 本类仅为实 ...

  3. 学习:erlang读取文件中的terms

    参考:http://diaocow.iteye.com/blog/1766128 1. file:consult(Filename) -> {ok, Terms} | {error, Reaso ...

  4. 基于struts2框架文件的上传与下载

    在开发一些社交网站时,需要有允许用户上传自己本地文件的功能,则需要文件的上传下载代码. 首先考虑的是文件的储存位置,这里不考虑存在数据库,因为通过数据库查询获取十分消耗资源与时间,故需将数据存储在服务 ...

  5. sdut 面向对象程序设计上机练习十(运算符重载)

    面向对象程序设计上机练习十(运算符重载) Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 定义一个复数类Complex,重载运算符"+" ...

  6. linux系统命令记录

    系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ho ...

  7. hdu 2019:数列有序!(数据结构,直接插入排序+折半插入排序)

    数列有序! Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submiss ...

  8. 0.0.0.0:80端口被系统System占用

    用netstat -ano命令查看,可以找到0.0.0.0:80占用的PID假设为4,然后在任务管理器中的详细信息面板中可以找到PID等于4的进程,如果用户名为SYSTEM, 不能直接终止掉,需要去注 ...

  9. Android测试:从零开始3—— Instrumented单元测试1

    Instrumented单元测试是指运行在物理机器或者模拟机上的测试,这样可以使用Android framework 的API和supporting API.这会在你需要使用设备信息,如app的Con ...

  10. Android之ListView中的分割线

    ListView中每个Item项之间都有分割线,设置android:footerDividersEnabled表示是否显示分割线,此属性默认为true. 1.不显示分割线只要在ListView控件中添 ...