前言
红球球~ 蓝球球~
家里的宝宝就喜欢玩球球,特别是蓝色的,而最近正好找到了一个优秀的物理引擎,就拿它来做了一个下落的小球,宝宝玩的不亦乐乎~
起初我是想模拟一个小球在不同曲线上的运动状态,一直在找一个简易的重力引擎,找了一段时间没有什么收获,也想过自己写个重力系统,可是仔细想想觉得有点太麻烦,后来玩了一些flash游戏,发现这类依靠重力的作为主要玩法的游戏还真不少,肯定有一个好的引擎可以直接拿来用,然后就发现了 Box2D
这个物理引擎,不但带有重力系统,还支持碰撞。
box2dweb
其实 cocos2dx 和 unity 中都有使用 Box2D
引擎,只不过自己进行了封装,如果使用这些客户端引擎做出来的东西依赖性比较强,还好顺着 Box2D
这条线发现了一个 box2dweb
引擎,是一个 Box2D
的 js 版本,这就非常方便了,有个浏览器就可以直接运行了,还免去了编译安装的麻烦。
下落的小球
开局一张图,后面接着编。。。
把这个下落的小球叫做一个游戏确实有些勉强,但是宝宝就是很喜欢玩啊,游戏本来就是让人开心的,开心就好咯!接下来记录一下这个小球是怎么实现的吧~
具体实现
下载引擎
box2dweb
引擎只有一个js文件,可以在github上搜索下载 hecht-software/
box2dweb ,不过最近访问缓慢,也可以下载这个我备份的版本 Box2dWeb-2.1.a.3.min.js,下载之后直接引用即可。
引入js引擎
新建一个 html 文件命名为 fallball-game.html
,编写如下内容,引入 Box2dWeb-2.1.a.3.min.js
文件
1 |
|
编写小球逻辑
在上面的 html 文件中不仅引入了 Box2dWeb-2.1.a.3.min.js
这个物理引擎,还引入了一个 fallball.js
文件,这是一个新建的自定义的js文件,需要我们在这个文件中编写小球的逻辑。
引入常用类型并简写
1 | var b2Vec2 = Box2D.Common.Math.b2Vec2 |
以上这些都是 Box2D
引擎中常用的类,使用简写的变量来引用这些类,这样在后面使用时会方便很多。
创建Box2D世界
b2World
是 Box2D
系统模拟物理世界的核心,可以想象成我们生活中的地球,在地球上有各种各样的物理环境,比如从空中自由落体的小球,在水中航行的轮船等等,使用 b2World
就可以创建这样一个世界。
在物理世界中首先需要的是重力,那么先定义一个有方向的力:
1 | var gravity = new b2Vec2(0, 9.8); |
作为一个模拟物理环境的引擎,效率使我们需要考虑的问题,对于静止不动的对象,最好不进行模拟计算来节省CPU运算,这种静止的对象可以让他们在 Box2D 环境中睡觉。1
2
var doSleep = true;
需要的参数都准备好了,这样可以new出一个Box2D世界了。
1 | var world = new b2World(gravity, doSleep); |
创建一个小球
- 先创建一个物体
1 | var bodydef = new b2BodyDef(); |
- 再创建一个材质
1 | var fixDef = new b2FixtureDef(); |
- 为材质添加一个形状并创建小球
1 | fixDef.shape = new b2CircleShape(0.5); |
- b2PolygonShape为多边形,设置形状大小时对应着SetAsBox(halfWidth, halfHeight)函数,参数半长和半宽,如果自定义多边形可以使用一个SetAsArray(vertexArray,vertexCount),其中vertexArray为顶点矢量(b2Vec2)数组,vertexCount为顶点数,最多8个
- b2CircleSharp为圆形,对应的设置属性为半径,函数为SetRadius(radius)
- 需要注意的是Box2d中的单位是米,1米是30像素,在绘制材质图片时需注意单位换算
- 使用 bomb.ApplyForce(force, point); 可以添加一个外力,force是一个b2Vec2的向量代表外力,point一个b2Vec2的向量代表物体的着力点。使用 bomb.SetMassFromShapes(); 可以根据形状计算质量
创建背景刚体物理
1 | var vertices = [ |
参照小球创建的方式创建两个三角形物体,这里注意一个问题,三角形的坐标需要顺时针给出,否则两个刚体的碰撞会出现问题。
创建调试环境
实际上,Box2D只是集成了各种算法,对b2Body对象进行物理模拟计算,并将计算结果存储到这个对象中,但是它并不是DisplayObject的子类,也就意味着我们无法通过addChild()将它添加到舞台上,这时可以借助b2DebugDraw类,绑定一个Sprite对象,Box2D就能帮我们在这个Sprite中,用绘图API绘制出模拟图形,方便我们进行调试。
1 | var debugDraw = new b2DebugDraw(); |
世界更新
1 | function update () { |
定义更新函数,注册定时器,用来定时更新。物理引擎的 world.Step
函数是整个 Box2D
引擎的核心, 它驱动了物理世界的运行。而上述代码中 for
循环的部分处理了材质跟随刚体运动的逻辑,可以自定义显示图片,这个已经实验成功,改天可以接着写一写。
总结
Box2D
是一个优秀易用的物理引擎,而box2dweb
是一个js版本,可以很方便的在html引入使用box2dweb
不仅能模拟重力环境,还能模拟物体之间的碰撞,可以通过参数调整物体的密度、摩擦力和弹力- 物体的形状可以多边形,可以通过给出顶点坐标的形式设置,不过要注意按照顺时针方向给出,否则碰撞失败,具体原因还不太清楚
这个世界上,还有很多不被认可的梦想,不被祝福的感情,不被眷顾的孩子,他们不曾犯错,却只能颤颤巍巍,单薄地行走在路上。你我都一样 要承认 我们都很平凡 并且在负重~
2021-7-25 18:59:01