Cocos2d-js Chipmunk的使用,实现一根绳子

最近笔者在学习cocos2d-js,打算和朋友合作完成一款游戏,但是在制作过程中发现现在网上cocos2d-js的资料少的可怜,特别是物理引擎这一块,熟悉Chipmunk和Box2d的朋友们都知道,这两个引擎的C++的资料是非常丰富的,但关于JS的少之又少,所以笔者想借此机会分享一点Chipmunk js的用法。笔者能力有限,不喜勿喷。


首先先来介绍一下Chipmunk这款物理引擎。Chipmunk物理引擎,由Howling Moon Software的Scott Lebcke开发,用纯C编写。

Chipmunk的核心概念:空间(space):类似于场景,所有的物理事件发生的地方。

刚体(body):接触过物理引擎的朋友都知道,用来模拟物理形态的物体。

形状(shape):物体的形状。

节点,关节(joint):链接刚体的节点。


cocos2d-js中封装好了Chipmunk引擎,所以只需要按以下步骤就可以完成物理引擎的使用:

1.创建物理空间:create space

2.确认物理空间边界:create wall

3.建立空间中的物体:create body

4.给物体指定形状:bind shape

5.给刚体绑定精灵:bind sprite


通过以上五步基本就可以实现简单的物理引擎的使用,下面,我们用Chipmunk实现一根摇摆的绳子。

先看一下效果图:

看过图相信读者也基本明白如何实现绳子了,对,就是把一连串的刚体串在一起,就能实现绳子的物理特性,废话不多说,咱们直接上代码。

RodeTestScene.js:

首先建立Scene,把Layer加到Scene上

var RopeTestScene=cc.Scene.extend({
    onEnter: function () {
        this._super();
        var layer=new RopeTestLayer();
        this.addChild(layer);
    }
});


下面看看我们Layer的构造函数里面使用的方法

var DEBUG_NODE_SHOW = true;  //<span style="color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 26px; orphans: auto; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px; display: inline !important; float: none; background-color: rgb(255, 255, 255);">是否绘制调试遮罩开关常量</span>
var RADIUS=10;   //半径

var RopeTestLayer=cc.Layer.extend({
    space:null,
    ctor:function(){
        this._super();

        var size=cc.winSize;

        this.initPhysics();  //初始化物理空间

        this.scheduleUpdate();
        
        //绳子
        this.createRope();

        return true;
    },

下面我们来写一个物理空间调试测试的Node对象函数:
setupDebugNode: function () {
        this._debugNode = new cc.PhysicsDebugNode(this.space);

        this._debugNode.visible = DEBUG_NODE_SHOW;

        this.addChild(this._debugNode);
    },

接下来就是重点了,我们要初始化物理空间并建立物理空间界限(wall),看代码:
  initPhysics:function(){
        var winSize=cc.director.getWinSize();

        this.space=new cp.Space();
        this.setupDebugNode();

        this.space.gravity=cp.v(0,-100);
        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)
        ];
       //把四面墙添加到space,这里要注意,墙是静态shape,这点很重要
        for(var i=0;i<walls.length;i++){
            var shape=walls[i];
            shape.setElasticity(1);
            shape.setFriction(1);
            this.space.addStaticShape(shape);
        }
    },

我们的环境建立好了,下面就是我们要做的绳子,先上代码,然后慢慢分析:
 createRope:function(){
        var size=cc.winSize;

        this.List=[];  //建立一个容器,用来储存咱们的20个刚体
        for(var i=0;i<20;i++){
            var body=new cp.Body(1,cp.momentForCircle(1,0,RADIUS,cp.v(0,0)));  //圆形刚体
            body.setPos(cc.p(size.width/2-i*10,size.height*0.9-i*50));    //为了能让绳子摆动,坐标稍微偏移一点
            this.space.addBody(body); //将刚体添加到空间里

            var shape=new cp.CircleShape(body,RADIUS,cp.v(0,0));  //圆型形状
            shape.setElasticity(0.5);
            shape.setFriction(0.5);
            this.space.addShape(shape);   //将形状添加到空间里

            var sprite=new cc.PhysicsSprite(res.Point_png);  //创建精灵
            sprite.setBody(body);              //绑定刚体
            sprite.setScale(0.2);
            sprite.setPosition(cc.p(size.width/2-i*10,size.height*0.9-i*50));
            this.addChild(sprite);           //添加精灵到场景
            this.List.push(body);             //将刚体压入容器

        }

        for(var i=1;i<this.List.length;i++){     //注意我们从第二个刚体开始循环
            var body1=this.List[i-1];             //前一个刚体
            var body2=this.List[i];              //当前刚体
            var joint_j=new cp.SlideJoint(body1,body2,cc.p(0,0),cc.p(0,0),30,50);   //将当前刚体和前一个刚体相连
            this.space.addConstraint(joint_j);   //将节点添加到空间
        }

        //静态刚体,作为绳子的顶端
        var body_up=new cp.StaticBody(1,cp.momentForCircle(1,0,RADIUS,cp.v(0,0)));  //注意,这是一个静态刚体
        body_up.setPos(cc.p(size.width/2,size.height));   

        var shape_up=new cp.CircleShape(body_up,Radius,cp.v(0,0));
        shape_up.setElasticity(0.5);
        shape_up.setFriction(0.5);
        this.space.addStaticShape(shape_up);   //静态形态

        var joint_up=new cp.SlideJoint(body_up,this.List[0],cc.p(0,0),cc.p(0,0),30,50);
        this.space.addConstraint(joint_up);

    }

接下来最后一步,不要忘了添加:
 update:function(dt){
        var timeStep=0.03;
        this.space.step(timeStep);
    },

    onExit:function(){
        this._super();
        cc.log("onExit");
    }

下面运行我们的程序,就能看到绳子了,怎么样,是不是很简单。


最后声明一点,本篇借鉴了关东升的博客。




展开阅读全文

没有更多推荐了,返回首页