一、基本概念

  • 空间:在Chipmunk中,空间是所有对象容器。因此,刚体、形状、链接节点等对象都需要添加到空间中。空间控制这些对象的相互作用。
  • 刚体:物理上的刚体指的是在运动和受力作用后,形状和大小不改变的物体。Chipmunk中的刚体拥有质量、位置、速度、角速度等物理性质。须注意的是,添加到空间中的刚体只是一个质点,需要为其赋予形状后,它才有面积或体积的性质。
  • 形状:形状定义了物体碰撞的外形,同时包括物体如弹性系数、摩擦系数等表面的性质;你可以对一个刚体赋予多个形状,同一物体的形状不会碰撞。
  • 连接节点:连接节点定义刚体之间的连接方式。

二、Chipmunk-js与Chipmunk的区别

  • 运行速度下降了,Chipmunk-js大概比Chipmunk慢了3倍的样子,Chipmunk的作者说用纯C写的部分原因就是它运行速度很快哈哈
  • Chipmunk-js用面向对象的形式来写,所以函数名些许不同,比如cpvadd(a, b)变成了cp.vadd(a, b)
  • 去除了函数中描述数组长度的参数,比如:
    cpMomentForPoly(mass, numVerts, *verts, offset);

变成了:

    cp.momentForPoly(mass, verts, offset); 
  • 去除了大部分getter和setter函数。

三、 HelloChipmunk案例

使用Chipmunk物理引擎进行开发的一般步骤为:
(1)创建物理空间;
(2)指定空间边界;
(3)创建空间中的物体;
(4)创建空间中的形状;
(5)连接精灵与物体(实现物体可视化);
(6)检测碰撞。

使用Chipmunk-js基本遵循以上步骤,首先创建页面结构:

<!DOCTYPE html>
<html>
<head><title>hello Chipmunk</title>
</head>
<body><canvas></canvas>
</body><style type="text/css">html {background-color: grey;}canvas {background-color: black;}</style><!-- 注意必须先引入cp.js --><script type="text/javascript" src="./cp.js"></script><script type="text/javascript" src="./hellochipmunk.js"></script>
</html>

下载cp.js存放至根目录下;
在根目录创建hellochipmunk.js文件,首先创建物理空间:

var height = 480; //界面的高度
var width = 640;//界面的宽度/*** 物理空间 ***/
function World() {//初始化空间和重力this.space = new cp.Space();//创建空间var v = cp.v;//cp.v是chipmunk中定义的二维空间矢量this.space.gravity = v(0, 100);//设置重力矢量,重力数值越大,下落加速度越大//添加空间的边界条件。需要设置边界的形状、弹性系数、摩擦系数。this.addBoundary = function() {//设置左边界。var left = this.space.addShape(new cp.SegmentShape(this.space.staticBody, v(0, 0), v(0, height), 2));//设置边界的弹性系数。0.0表示完全非弹性碰撞,1.0表示弹性碰撞。left.setElasticity(0.5);//设置摩擦系数。0.0表示无摩擦。left.setFriction(1);//设置右边界。var right = this.space.addShape(new cp.SegmentShape(this.space.staticBody, v(width, 0), v(width, height), 2));right.setElasticity(0.5);right.setFriction(1);//设置上边界。var top = this.space.addShape(new cp.SegmentShape(this.space.staticBody, v(0, 0), v(width, 0), 2));top.setElasticity(0.5);top.setFriction(1);//设置底边界。var bottom = this.space.addShape(new cp.SegmentShape(this.space.staticBody, v(0, height), v(width, height), 2));bottom.setElasticity(0.5);bottom.setFriction(1);}//添加球体。首先需要在空间中创建一个刚体,为其赋予质量、转动惯量;//然后需要指名刚体的形状,这里我们创建的是球体,所以为物体添加一个圆形的形状this.addBody = function() {var radius = 25;var mass = 1;//设置球体的转动惯量,这里使用库中的一个函数计算其惯量var moment = cp.momentForCircle(mass, 0, radius, cp.vzero);//在空间中创建球体var ballBody = new cp.Body(mass, moment);this.space.addBody(ballBody);ballBody.setPos(v(width/2, height/3));//为球体添加形状var ballShape = new cp.CircleShape(ballBody, radius, cp.vzero);this.space.addShape(ballShape);ballShape.setFriction(1);ballShape.setElasticity(0.7);}
}

然后在画布上将物理空间绘画出来:

/*** 在画布中实现可视化 ***/
function Canvas() {var _this = this;this.cns = document.getElementsByTagName('canvas')[0];//设置画布大小this.cns.height = height;this.cns.width =  width;this.ctx =  this.cns.getContext('2d');this.drawLine = function(ctx, a, b) {this.ctx.beginPath();this.ctx.moveTo(a.x, a.y);this.ctx.lineTo(b.x, b.y);this.ctx.stroke();};this.drawCircle = function(ctx, c, radius) {this.ctx.lineWidth = 3;this.ctx.beginPath();this.ctx.arc(c.x, c.y, radius, 0, 2*Math.PI, false);this.ctx.fill();this.ctx.stroke();};this.draw = function(world) {   _this.ctx.strokeStyle = 'white';_this.ctx.lineCap = 'round';_this.ctx.clearRect(0, 0, _this.cns.width, _this.cns.height);_this.ctx.font = "16px sans-serif";_this.ctx.lineCap = 'round';world.space.eachShape(function(shape) {_this.ctx.fillStyle = 'red'shape.draw(_this.ctx);})}cp.PolyShape.prototype.draw = function(ctx) {ctx.lineWidth = 2;ctx.beginPath();ctx.fillStyle = 'blue';var verts = this.tVerts;var len = verts.length;var lastPoint = new cp.Vect(verts[len - 2], verts[len - 1]);ctx.moveTo(lastPoint.x, lastPoint.y);for(var i = 0; i < len; i+=2){var p = new cp.Vect(verts[i], verts[i+1]);ctx.lineTo(p.x, p.y);}ctx.fill();ctx.stroke();};cp.SegmentShape.prototype.draw = function(ctx) {ctx.lineWidth = Math.max(1, this.r * 2);_this.drawLine(ctx, this.ta, this.tb);};cp.CircleShape.prototype.draw = function(ctx) {_this.drawCircle(ctx, this.tc, this.r);// 显示球体中的一条半径,从而可以清楚观察到球体的转动_this.drawLine(ctx,this.tc, cp.v.mult(this.body.rot, this.r).add(this.tc));};
}

最后运行空间,通过更新画布来显示动画:

var raf = window.requestAnimationFrame|| window.webkitRequestAnimationFrame|| window.mozRequestAnimationFrame|| window.oRequestAnimationFrame|| window.msRequestAnimationFrame|| function(callback) {return window.setTimeout(callback, 1000 / 60);};
var drawFrame = function() {var dt = 1/60;//每dt个时间步内更新空间。world.space.step(dt);//刷新画布图像canvas.draw.call(this, world);raf(drawFrame);
};var world = new World();//(1)创建物理空间;
world.addBoundary();//(2)指定空间边界;
world.addBody();//(3)创建空间中的物体;(4)创建空间中的形状;
var canvas = new Canvas();//(5)连接精灵与物体(实现物体可视化);
drawFrame();

使用浏览器打开后的:

四、 添加阻挡方块

我们可以在球体下落的路径上添加一个方块,模拟球体与方块的碰撞现象。在如弹一弹的小游戏中,实现原理与此类似,它们是在球体与方块碰撞后加入了回调函数,以实现加分或方块消失等事件
可以将阻挡方块看作是一种边界条件,我们在World里的addBoundary函数添加:

//添加阻挡方块
var blockBody = new cp.Body(Infinity, Infinity);//由于方块是静止的,我们设它的质量和转动惯量为无穷大
blockBody.setPos(cp.v(width/2, height*2/3));
blockBody.setAngle(0.1);//设置方块偏转角度
var block = this.space.addShape(new cp.BoxShape(blockBody, 50, 50),);
block.setElasticity(1);
block.setFriction(1);

最终效果:

引擎的具体实现细节可参考Chipmunk的文档,虽然函数名等有出入,但大致实现思路是一样的哈~

转载于:https://www.cnblogs.com/Gavin257/p/11029176.html

Chipmunk-js物理引擎学习笔记相关推荐

  1. [Unity 3D] 物理引擎学习笔记(一)

    刚体: 同是物理引擎提供的功能,碰撞检测只需要有 Collider 便可以运作,但所有与作用力相关的属性和函数却都依赖 Rigidbody. 重力: 一旦使用了 Rigidbody 组件,这个 Gam ...

  2. 【vn.py学习笔记(三)】vn.py事件引擎 学习笔记

    [vn.py学习笔记(三)]vn.py事件引擎 学习笔记 1 时间驱动 2 事件驱动 3 事件引擎工作流程 4 事件引擎结构 4.1 事件队列 4.2 事件处理线程 4.3 事件处理函数字典/通用事件 ...

  3. cocos2d - JS 物理引擎 - chipmunk

    物理引擎 - chipmunk : 生成物理世界 : 第一步 : 新建项目打开 project.json 将chipmunk模块导入 . "modules" : ["co ...

  4. 物理引擎学习06-碰撞反馈

    原本计划06章是一个碰撞检测的小demo,上手之后才发现,碰撞反馈也是一个非常复杂的话题,所以就单拎出来一章,详细说明.碰撞反馈是基于碰撞检测的结果,将发生接触的物体分离开,同时应用上物理效果,使碰撞 ...

  5. 【前端】-【node.js基础】-学习笔记

    [前端]-[node.js]-学习笔记 1 node.js介绍 1.1 node.js优点 1.2 node.js 不足之处 1.3 nodejs与java的区别 2. node中函数 3. 浏览器和 ...

  6. 物理引擎学习08-AABB树

    AABB树是由AABB包围盒结点构成的二叉树,常用来加速场景中的射线检测和碰撞检测.树的每个结点都是一个包围盒,且结点的包围盒包裹了所有子结点的包围盒.本文深入的讲解了AABB树相关的算法,以及结合物 ...

  7. JS物理引擎p2.js中文文档

    本文复制于Github p2.js项目的中文维基页面,鉴于国内访问Github网速不稳定,特粘贴到CSDN,促进知识更快传播,也希望有能力者继续完善此文档. 以下是原文,更新内容请查阅Github p ...

  8. lunar.js 基本使用学习笔记

    文章目录 lunar 基本使用学习笔记 介绍 基本使用 部分文档 API 转载 阳历相关的方法 API Solar 阳历 阳历实例化 阳历对象可以使用多种字符串输出方式: 获取年.月.日 儒略日 获取 ...

  9. 【Canvas】HTML5游戏开发的基本流程+P2.js物理引擎实战开发

    <HTML5游戏开发的基本流程> * 1. HTML5的简述 * 2. HTML5游戏开发所需的环境与工具 * 2.1. 开发环境 * 2.1.1. 浏览器 * 2.1.2. 开发语言 * ...

最新文章

  1. 什么是ObjCTypes?
  2. Jupyter Notebook 的快捷键
  3. 干货!Java 学习路线指南,看这文就够了!
  4. IOS15打包静态库
  5. Annotation 注解
  6. 753 Cracking the Safe
  7. C++是什么?怎么学?学完了能得到什么?
  8. 如何用Pygame写游戏(七)
  9. MySQL数据库优化技术概述
  10. OSPF——多区域概念及配置、ABR简介、ASBR简介、路由重分发
  11. Android4火狐,Android版火狐4正式发布
  12. 安装ssd后不识别网卡_群晖E10M20-T1:你以为它是张网卡,其实它还带俩SSD
  13. 短信接口防盗刷解决方案
  14. ROS加载PCD文件
  15. springboot如何自定义starter
  16. 数据包络分析--SBM模型(第一篇)
  17. 量化择业 银行vs券商vs公募vs私募?(行内人深度分享)
  18. 【DX12】DirectX Math库 Vector和Matrix类型 XMVECTOR、XMMATRIX
  19. 《用莫比乌斯带巧解内接矩形问题:拓扑学的用处》学习笔记
  20. android使用AlarmManager实现应用每天定时执行任务

热门文章

  1. UNI-APP,网络下载.bin二进制文件并保存到手机,在其他页面读取该.bin文件,按照协议封装后,发送给硬件设备
  2. 如何学习计算机实现攻防
  3. 【OpenCV】ChArUco标定板角点的检测Detection of ChArUco Corners
  4. c++定义虚构造_在定义的系统中发现虚构的设计
  5. 修复setup violation的方法总结
  6. IOException:Sharing Violation on Path
  7. 9G10内核时钟tick实现
  8. 华为苹果两家独霸中国高端手机市场,4000元以上份额合计近九成
  9. 一个人最顶级的才华,是会填坑
  10. acg缩写_ACG如何在Alexa上使屡获殊荣的技术播客栩栩如生,以及我们在此过程中学到的知识...