用了好长一阵字 Box2d 最近乘热打铁 开始研究下 Chipmunk.
首先 这两个引擎在概念上还是有很多相通的地方的,比如 box2d 中的 world chipmunk中称之为 space , 都有body,shape 等最基本的刚体概念.
这次我只要是做一下 chipmunk 的 js版本的学习心得. 在js版本中 API 还是有一些变化的.
首先 您可能需要有一些 最基本的知识,比如说 刚体的概念 , 空间的概念 等等.如果您一点物理引擎的概念都没有的话, 也不要着急,您可以先看一下 box2d 他在国内的相关资料比 chupmunk要多一些.
首先不得不看的是 国人翻译的 chipmunk 手册 感谢 iTyran https://github.com/iTyran/ChipmunkDocsCN/blob/master/Chipmunk2D.md
step 1 创建 space 以及 一般刚体.
var Balls = function() {
Demo.call(this);
var space = this.space;
//iterations 指的是物体 模拟的仿真度
// 简单来讲就是这个 值越高 模拟的越真实,但运算量越大
space.iterations = 60;
space.gravity = v(0, -500); // 定义重力
space.sleepTimeThreshold = 0.5; // 物体休眠的阀值,简单来讲就是当物理动作趋近于静止时,物体会休眠,
space.collisionSlop = 0.5; //支持形状间的重叠量。鼓励将这个值设置高点而不必在意重叠,因为它提高了稳定性。它默认值为0.1。
this.addFloor();
this.addWalls();
var width = 50;
var height = 60;
var radius = 25;
var mass = width * height * 1 / 1000;
//cp.momentForBox 计算质量分配
var boxRock = space.addBody(new cp.Body(mass, cp.momentForBox(mass, width, height)));
boxRock.setPos(v(500, 100)); //初始 坐标
boxRock.setAngle(1); //初始 角度
boxRock.setVel(v(10, 10)); //初始 速度
boxShape = space.addShape(new cp.BoxShape(boxRock, width, height));
boxShape.setFriction(0.3); //摩擦力
boxShape.setElasticity(0.3); //弹性
//是否碰撞 同group不碰撞. 默认是 0 与所有group碰撞
boxShape.group = 3;
//碰撞过滤ID
// space.addCollisionHandler(过滤ID_A, 过滤ID_B, null, null, function (arb, space, ptr) {
// console.log(arb);
// }, null);
//此时说明 具备 ID_A 和 过滤ID_B的物体碰撞后 会被捕捉到.
//
//
boxShape.collision_type = 8;
//下面创建一个圆形物体
var circleRock = space.addBody(new cp.Body(mass, cp.momentForCircle(mass, 0, radius, v(0, 0))));
circleRock.setPos(v(100, 80));
circleRock.setAngle(1);
circleRock.setVel(v(600, 600)); //初始 速度
circleShape = space.addShape(new cp.CircleShape(circleRock, radius, v(0, 0)));
circleShape.setFriction(2); //摩擦力
circleShape.setElasticity(1); //弹性
circleShape.collision_type = 9; //见上文
circleShape.group = 2;
};
Balls.prototype = Object.create(Demo.prototype);
addDemo('Balls', Balls);
step 2 创建 静态刚体.
ar Balls = function() {
Demo.call(this);
var space = this.space;
space.iterations = 60;
space.gravity = v(0, -500); // 定义重力
space.sleepTimeThreshold = 0.5; // 物体休眠的阀值,简单来讲就是当物理动作趋近于静止时,物体会休眠,
space.collisionSlop = 0.5; //支持形状间的重叠量。鼓励将这个值设置高点而不必在意重叠,因为它提高了稳定性。它默认值为0.1。
this.addFloor();
this.addWalls();
var width = 50;
var height = 60;
var radius = 25;
var mass = width * height * 1 / 1000;
var boxRock = space.addBody(new cp.Body(mass, cp.momentForBox(mass, width, height)));
boxRock.setPos(v(500, 100)); //初始 坐标
boxRock.setAngle(1); //初始 角度
boxRock.setVel(v(10, 10)); //初始 速度
boxShape = space.addShape(new cp.BoxShape(boxRock, width, height));
boxShape.setFriction(0.3); //摩擦力
boxShape.setElasticity(0.3); //弹性
boxShape.group = 3;
boxShape.collision_type = 8;
var circleRock = space.addBody(new cp.Body(mass, cp.momentForCircle(mass, 0, radius, v(0, 0))));
circleRock.setPos(v(100, 80));
circleRock.setAngle(1);
circleRock.setVel(v(500, 400)); //初始 速度
circleShape = space.addShape(new cp.CircleShape(circleRock, radius, v(0, 0)));
circleShape.setFriction(2); //摩擦力
circleShape.setElasticity(1); //弹性
circleShape.collision_type = 9; //见上文
circleShape.group = 2;
//这里需要创造一个
var staticBody = new cp.Body(Infinity, Infinity);
staticBody.nodeIdleTime = Infinity;
staticBody.setPos(v(320, 340));
var staticShape = new cp.BoxShape(staticBody, 50, 50) staticShape.setFriction(0.3);
staticShape.setElasticity(2);
space.addStaticShape(staticShape);
};
Balls.prototype = Object.create(Demo.prototype);
addDemo('Balls', Balls);
step 3 监听碰撞事件.
只有当方块和圆球 碰撞的时候 才会被捕捉到
var Balls = function() {
Demo.call(this);
var space = this.space;
space.iterations = 60;
space.gravity = v(0, -500); // 定义重力
space.sleepTimeThreshold = 0.5; // 物体休眠的阀值,简单来讲就是当物理动作趋近于静止时,物体会休眠,
space.collisionSlop = 0.5; //支持形状间的重叠量。鼓励将这个值设置高点而不必在意重叠,因为它提高了稳定性。它默认值为0.1。
this.addFloor();
this.addWalls();
var width = 50;
var height = 60;
var radius = 25;
var mass = width * height * 1 / 1000;
var boxRock = space.addBody(new cp.Body(mass, cp.momentForBox(mass, width, height)));
boxRock.setPos(v(500, 100)); //初始 坐标
boxRock.setAngle(1); //初始 角度
boxRock.setVel(v(10, 10)); //初始 速度
boxShape = space.addShape(new cp.BoxShape(boxRock, width, height));
boxShape.setFriction(0.3); //摩擦力
boxShape.setElasticity(0.3); //弹性
boxShape.group = 3;
boxShape.collision_type = 8;
var circleRock = space.addBody(new cp.Body(mass, cp.momentForCircle(mass, 0, radius, v(0, 0))));
circleRock.setPos(v(100, 80));
circleRock.setAngle(1);
circleRock.setVel(v(500, 400)); //初始 速度
circleShape = space.addShape(new cp.CircleShape(circleRock, radius, v(0, 0)));
circleShape.setFriction(2); //摩擦力
circleShape.setElasticity(1); //弹性
circleShape.collision_type = 9; //见上文
circleShape.group = 2;
//这里需要创造一个静态刚体
var staticBody = new cp.Body(Infinity, Infinity);
staticBody.nodeIdleTime = Infinity;
staticBody.setPos(v(320, 340));
var staticShape = new cp.BoxShape(staticBody, 50, 50) staticShape.setFriction(0.3);
staticShape.setElasticity(2);
space.addStaticShape(staticShape);
var NUM_VERTS = 5;
var verts = new Array(NUM_VERTS * 2);
for (var i = 0; i < NUM_VERTS * 2; i += 2) {
var angle = -Math.PI * i / NUM_VERTS;
verts[i] = 30 * Math.cos(angle);
verts[i + 1] = 30 * Math.sin(angle);
}
var canvas = document.getElementsByTagName("canvas")[0];
var body = space.addBody(new cp.Body(mass, cp.momentForPoly(mass, verts, v(0, 0))));
body.setPos(v(350 + 60, 220 + 60));
space.addShape(new cp.PolyShape(body, verts, v(0, 0)));
space.addCollisionHandler(8, 9, null, null,
function(arb, space, ptr) {
//当碰撞接触时
canvas.style.backgroundColor = "#ccc"console.log(arb);
},
function(arb, space, ptr) {
//当碰撞离开时
canvas.style.backgroundColor = ""console.log(arb);
});
};
Balls.prototype = Object.create(Demo.prototype);
addDemo('Balls', Balls);