zoukankan      html  css  js  c++  java
  • 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;
        }
    }

     

     

     

     

     

     

     

  • 相关阅读:
    MyEclipse编码集设置
    Tomcat内存溢出问题解决
    避免头文件多次编译
    C++指针学习(1)
    C++头文件和实现(用复数类举例)
    从helloworld开始
    标准库string类型
    浅谈Lua的Coroutine协程的多"线程"并发模型
    关于闭包函数的概念和原理
    笔记
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/7755837.html
Copyright © 2011-2022 走看看