美文网首页
chipmunk学习笔记一

chipmunk学习笔记一

作者: babybus_break | 来源:发表于2016-07-07 16:07 被阅读633次

    初识chipmunk物理引擎

    chipmunk本是一个独立的开源项目,用纯c编写.cocos2d同时整合了chipmunk和box2d两个物理引擎.
    相比之下,chipmunk更轻量易用,但是相关的文档很少.

    • space: 发生物理模拟的空间,可容纳body, shape,joint
    • body:刚体,可被赋予shape。刚体具有质量,转动惯量,位置,线性速度,加速度,角度,角速度,角加速度等属性。刚体之间可通过joint连接
    • shape:决定刚体的碰撞外形。一个刚体上可覆盖上多个shape,同属于一个刚体的shape不会互相发生碰撞。shape同样需要加到space中。有圆,线段,凸多边形这三种shape类型。
    • joint: 用于连接刚体。有4种类型:
    • pin joint: 相当于一根棍子(质量忽略)加两个大头针(锚点),两个刚体如果用pin joint连接,他们之间的距离不会改变,他们各自可绕锚点转动(如果有力矩的话)
    • slide joint: 相当于把pin joint的棍子换成了滑槽。这个滑槽有最大和最小长度。
    • pivot joint: 即一个旋转轴。两个刚体都绕这个轴旋转
    • groove joint:相当于可滑动的pivot joint。将刚体2的旋转轴挂到处于刚体1的一段滑槽上。

    chipmunk小demo

    以下demo实例用的是cocos2d-js

    1. 初始化物理世界
      initPhysics:function(){
      var winSize = cc.director.getWinSize();
      // 创建物理空间
      this.space = new cp.Space();
      // 设置重力
      this.space.gravity = cp.v(0, -100);
      this.space.sleepTimeThreshold = 0.5; // 静止睡眠时间阀值

           var staticBody = this.space.staticBody;
           // 设置空间边界
           var walls = [ 
               new cp.SegmentShape(staticBody, cp.v(0, 0), cp.v(winSize.width, 0), 0),                             // 下
               new cp.SegmentShape(staticBody, cp.v(0, winSize.height), cp.v(winSize.width, winSize.height), 0),   // 上
               new cp.SegmentShape(staticBody, cp.v(0, 0), cp.v(0, winSize.height), 0),                            // 左
               new cp.SegmentShape(staticBody, cp.v(winSize.width, 0), cp.v(winSize.width, winSize.height), 0)     // 右
           ];
           for (var i = 0; i < walls.length; i++) {
               var shape = walls[i];
               shape.setElasticity(1);
               shape.setFriction(1);
               this.space.addStaticShape(shape);
           }
       },
      
    2. 打开调试模式

       setupDebugNode: function () {
           this._debugNode = new cc.PhysicsDebugNode(this.space);
           this._debugNode.visible = true;
           this.addChild(this._debugNode);
       },
      
    3. 刚体创建

    • 动态刚体:
      cp.Body(质量,转动惯量)
      cp.CircleShape(刚体, 半径, 重心与圆心的偏移量)

           loadDynamicBody: function (p) {
               // 刚体创建
               var body = new cp.Body(1, cp.momentForCircle(1, 0, 55, cp.vzero));
               body.setPos(p);
               this.space.addBody(body);
               // 形状创建
               var shape = new cp.CircleShape(body, 55, cp.vzero);
               shape.setElasticity(0.5);
               shape.setFriction(0.5);
               this.space.addShape(shape);
      
               //body.setAngVel(10);                           // 旋转速度
               //body.applyForce(cp.v(300,300),cp.v(0,0));     // 持续力
               //body.applyImpulse(cp.v(300,300),cp.v(0,0));   // 瞬时冲量
      
               // // 精灵绑定刚体
               // var sprite = new cc.PhysicsSprite("res/btn_refresh.png");     // 无法通过文件路径创建
               // sprite.setBody(body);
               // this.addChild(sprite);
                   return body
           },
      
    • 静态刚体:

       静态刚体创建与动态刚体基本一样,唯一的区别是静态刚体不将刚体添加到space空间,要不然会报错,具体为什么,不明。
      
       由于静态刚体的不可移动特性,space空间内只一个静态刚体就足够,其他只要创建shape,并添加到这个静态刚体this.space.staticBody上即可。
      
       如果你需要移动静态刚体最好new cp.StaticBody()创建。
      
           loadStaticBody:function(position){
               // 刚体创建
               //var body = this.space.staticBody;
               var body = new cp.StaticBody();
               body.setPos(position);
               // 形状创建
               var shape = new cp.BoxShape(body, 100, 100);
               shape.setElasticity(0.5);
               shape.setFriction(0.5);
               this.space.addShape(shape);
      
               // // 精灵
               // var sprite = new cc.PhysicsSprite("res/btn_refresh.png");    // 无法通过文件路径创建
               // sprite.setBody(body);
               // this.addChild(sprite);
               return body
           },
      
    1. 让物理世界动起来

      前面的创建还缺最关键的一步,就是激活整个物理世界

      this.scheduleUpdate() 开启调度

      并在更新函数内添加物理世界更新

       update:function(dt){
           var timeStep = 0.03;
           this.space.step(timeStep);
           // // 静态刚体位置更新(否则静态刚体创建后位置无法改变)
           // this.space.reindexStatic();
       }
      

    完整的代码

    ChipmunkLayer.js

    var DEBUG_NODE_SHOW = true;
    var ChipmunkLayer = cc.Layer.extend({
        ctor: function () {
            this._super();
            // 初始化物理世界
            this.initPhysics();
            // 开启调试模式
            this.setupDebugNode();
            // 加载动态刚体
            this.loadDynamicBody(cp.v(480,300));
            // 加载静态刚体
            this.loadStaticBody(cp.v(480,100));
            // 更新世界
            this.scheduleUpdate();
        },
        initPhysics:function(){
            var winSize = cc.director.getWinSize();
            this.space = new cp.Space();
            // 设置重力
            this.space.gravity = cp.v(0, -100);
            this.space.sleepTimeThreshold = 0.5;  // 静止睡眠时间阀值
    
            var staticBody = this.space.staticBody;
            // 设置空间边界
            var walls = [ new cp.SegmentShape(staticBody, cp.v(0, 0),
                cp.v(winSize.width, 0), 0),
               new cp.SegmentShape(staticBody, cp.v(0, winSize.height),
                   cp.v(winSize.width, winSize.height), 0),
               new cp.SegmentShape(staticBody, cp.v(0, 0),
                   cp.v(0, winSize.height), 0),
               new cp.SegmentShape(staticBody, cp.v(winSize.width, 0),
                   cp.v(winSize.width, winSize.height), 0)
            ];
            for (var i = 0; i < walls.length; i++) {
                var shape = walls[i];
                shape.setElasticity(1);
                shape.setFriction(1);
                this.space.addStaticShape(shape);
            }
        },
        setupDebugNode: function () {
            this._debugNode = new cc.PhysicsDebugNode(this.space);
            this._debugNode.visible = DEBUG_NODE_SHOW;
            this.addChild(this._debugNode);
        },
        loadStaticBody:function(position){
            // 刚体创建
            //var body = this.space.staticBody;
            var body = new cp.StaticBody();
            body.setPos(position);
            // 形状创建
            var shape = new cp.BoxShape(body, 100, 100);
            shape.setElasticity(0.5);
            shape.setFriction(0.5);
            this.space.addShape(shape);
    
            // // 精灵
            // var sprite = new cc.PhysicsSprite("res/btn_refresh.png");    // 无法通过文件路径创建
            // sprite.setBody(body);
            // this.addChild(sprite);
            return body
        },
        loadDynamicBody: function (position) {
            // 刚体创建
            var body = new cp.Body(1, cp.momentForCircle(1, 0, 55, cp.vzero));
            body.setPos(position);
            this.space.addBody(body);
            // 形状创建
            var shape = new cp.CircleShape(body, 55, cp.vzero);
            shape.setElasticity(0.5);
            shape.setFriction(0.5);
            this.space.addShape(shape);
    
            //body.setAngVel(10);                           // 旋转速度
            //body.applyForce(cp.v(300,300),cp.v(0,0));     // 持续力
            //body.applyImpulse(cp.v(300,300),cp.v(0,0));   // 瞬时冲量
    
            // // 精灵绑定刚体
            // var sprite = new cc.PhysicsSprite("res/btn_refresh.png");    // 无法通过文件路径创建
            // sprite.setBody(body);
            // this.addChild(sprite);
            return body
        },
        update:function(dt){
            var timeStep = 0.03;
            this.space.step(timeStep);
            // // 静态刚体位置更新(否则静态刚体创建后位置无法改变)
            // this.space.reindexStatic();
        }
    
    });

    相关文章

      网友评论

          本文标题:chipmunk学习笔记一

          本文链接:https://www.haomeiwen.com/subject/wlsljttx.html