Egret P2 ( 一) 掉落的小球

 

 实际效果(蛋疼这个gif制作软件,帧率太低....):

 

一 Egret和P2的坐标系

首先了解下P2和Egret的坐标系。

某人链接:http://blog.csdn.net/qilei2010/article/details/51925754

 关于p2和Egret的单位换算,我看论坛拉登的demo没写这个factor,我也就没写了,不知后面会发生什么事情呢...= =!

二 创建物理世界

啥是物理世界? p2的刚体碰撞、重力、浮力等物理运算都在这个"世界"进行。

注意这里重力是10,如果是地球上,应该是朝地面,是-10才对。为啥这里是10,后面会讲。

this.world = new p2.World();
this.world.sleepMode = p2.World.BODY_SLEEPING;  //刚体睡眠,貌似是不动的时候,不用参与物理运算??
this.world.gravity = [0,10];

 

 三 创建一个地板

Plane相当于地面,默认面向Y轴方向。

因为这个Y轴是P2的Y轴,而不是Egret的Y轴。P2和Egret的Y轴是相反的。所以将地面翻转180度。planeBody.angle = Math.PI

 

我们来看看不旋转会怎么样?

红色方块位置 =  [100,100]

棕色地面位置 = [stage.stageWidth/2,   stage.stageHeight - 100]

 

不旋转180度时的情况:

在Egret中视觉上是正常的,但是地面朝下。

在P2中,方块在地面下了,会运行不正常,方块像吃了药,飞速往下掉。

如果想P2中正常,得将地面和方块位置替换,那么在Egret中会显示地面在上,方块在下,这显然不是我们想要的。

 

 

 

旋转180度后:

Egret中视觉上和地面方向都正常了。

P2中地面朝下了,这时物理世界的重力得从-10改为10。

 

翻转后的结果就是,P2和Egret是反的,那么将地面反转,反反得正... (其实我也很晕...)

 

        var plane:p2.Plane = new p2.Plane();
        this.planeBody = new p2.Body({position:[GameConst.stage.stageWidth/2, GameConst.stage.stageHeight - 100]});
        this.planeBody.angle =  Math.PI;
        this.planeBody.addShape(plane);
        this.world.addBody(this.planeBody);
        this.plane = this.createPlane();
        this.planeBody.displays = [this.plane];

 

 四 创建一个自由落体方块

        var box:p2.Box = new p2.Box({50, height:50});    //1. 创建一个Box
        this.boxBody = new p2.Body({mass:10, angularVelocity:1, position:[100,100]});   //2. 创建一个刚体,赋予Box物理特性
        this.boxBody.addShape(box);
        this.world.addBody(this.boxBody);
        this.ball = this.createBox();
        this.boxBody.displays = [this.ball];   //3. 给Box绑一个在Egret中的显示对象
        this.addChild(this.ball);

 

 五  更新物理世界

物理世界step()不停的在进行物理运算, Egret对象就像是物理世界的影子,每帧将对象和物理世界对象同步。

    private onEnterFrame(){
        this.world.step(60/1000);  //1. 60ms/1000 = 0.06秒更新一次
        var len:number = this.world.bodies.length;
        for(var i: number = 0;i < len;i++) {                 //2. 同步物理世界对象和Egret显示对象的位置和角度
            var body: p2.Body = this.world.bodies[i];
            var display: egret.DisplayObject = body.displays[0];
            display.x = body.position[0];                     
                     display.y = body.position[1];
            display.rotation = body.angle  * 180 / Math.PI;  //弧度和角度互换
        }
    }

 

 

 六 所有代码

/**
 * 创建一个方块,自由落体
 * 
 * 1. 世界,矩形,地板的使用
 * 
 * @author chenkai
 * @since 2017/6/23
 */
class Box extends egret.Sprite{
    private world:p2.World;
    private boxBody:p2.Body;
    private planeBody:p2.Body;
    private ball:egret.Sprite;
    private plane:egret.Sprite;
    public constructor() {
        super();
        
        //创建world
        this.world = new p2.World();
        this.world.sleepMode = p2.World.BODY_SLEEPING;
        this.world.gravity = [0,10];
        //创建box
        var box:p2.Box = new p2.Box({50, height:50});
        this.boxBody = new p2.Body({mass:10, angularVelocity:1, position:[100,100]});
        this.boxBody.addShape(box);
        this.world.addBody(this.boxBody);
        this.ball = this.createBox();
        this.boxBody.displays = [this.ball];
        this.addChild(this.ball);
        //创建plane  Plane shape class. The plane is facing in the Y direction.
        var plane:p2.Plane = new p2.Plane();
        this.planeBody = new p2.Body({position:[GameConst.stage.stageWidth/2, GameConst.stage.stageHeight - 100]});  //GameConst.stage保存全局静态变量stage
        this.planeBody.angle =  Math.PI;
        this.planeBody.addShape(plane);
        this.world.addBody(this.planeBody);
        this.plane = this.createPlane();
        this.planeBody.displays = [this.plane];
        //每帧更新
        this.addEventListener(egret.Event.ENTER_FRAME, this.onEnterFrame, this);
        
    }
    private onEnterFrame(){
        //更新物理世界
        this.world.step(60/1000);
        var len:number = this.world.bodies.length;
        for(var i: number = 0;i < len;i++) {
            var body: p2.Body = this.world.bodies[i];
            var display: egret.DisplayObject = body.displays[0];
            display.x = body.position[0];                      //同步刚体和egret显示对象的位置和旋转角度
            display.y = body.position[1];
            display.rotation = body.angle  * 180 / Math.PI;
        }
    }
    private createBox(){
        var sp:egret.Sprite = new egret.Sprite();
        sp.graphics.beginFill(0xff0000);
        sp.graphics.drawRect(0,0,50,50);
        sp.graphics.endFill();
        sp.anchorOffsetX = sp.width/2;
        sp.anchorOffsetY = sp.height/2;
        return sp;
    }
    private createPlane(){
        var sp:egret.Sprite = new egret.Sprite();
        sp.graphics.lineStyle(10, 0x00ff00);
        sp.graphics.moveTo(0, 0);
        sp.graphics.lineTo(GameConst.stage.stageWidth,0);
        sp.anchorOffsetX = sp.width/2;
        sp.anchorOffsetY = sp.height/2;
        this.addChild(sp);
        return sp;
    }
}

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/gamedaybyday/p/7755837.html