ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Egret之P2物理引擎(测试)

2021-05-23 14:51:39  阅读:221  来源: 互联网

标签:Egret P2 egret private p2 引擎 texture factor world


一 : 前景

    前几个月,公司做了下"合成大西瓜" . 现在整理一下 P2的参数传递 , 碰撞检测 和 坐标转换

二, API

        Ⅰ, 传递参数

             在p2.Body实例对象上,加一个自定义的field,如: UserData. 如下

B01.png

        Ⅱ, 碰撞检测

            B02.png

        Ⅲ, 坐标转换  p2.Body的实例对象 toWorldFrame( out Array

            B03.png

三, 核心代码
import {GameUtils} from "../cn/GameUtils";

/**
 * 小型的P2物理演示
 * @author Aonaufly
 */
export class DemoP2 extends egret.DisplayObjectContainer{
    private world: p2.World;
    private body: p2.Body;
    private planeBox: p2.Body;//地板刚体
    private factor: number = 30;
    private debugDraw: p2DebugDraw;
    private display: egret.Bitmap;//用于刚体显示
    private targetMap: egret.Bitmap;
    public constructor() {
        super();
    }

    public start(): void{
        //创建p2物理世界world
        this.world = new p2.World();
        this.world.gravity = [0,10];

        //添加一个地板
        this.createPlane();

        //创建矩形形状shape
        let shape: p2.Box = new p2.Box({
            width: 275/this.factor,
            height: 100/this.factor
        });



        //创建刚体
        this.body = new p2.Body({ mass: 1} );//给出刚体的质量为1
        this.body["userData"] = "hello p2";//需要传递的参数
        this.body.position = [275/this.factor,100/this.factor];

        //#region 添加贴图
        this.body.displays = [ this.getDisplay(`b1`) ];
        if( !this.display.parent ){
            this.addChild( this.display );
        }
        //#endregion


        this.body.addShape( shape );//加入形状
        this.world.addBody( this.body );//加入刚体

        //添加p2调试试图
        let sprite: egret.Sprite = new egret.Sprite();
        this.addChild( sprite );
        this.debugDraw = new p2DebugDraw( this.world,sprite );//调试初始化

        this.addEvent();
        //体检游戏帧事件
        this.addEventListener( egret.Event.ENTER_FRAME , this.loop, this );
    }

    private getDisplay( key: string): egret.Bitmap{
        let texture: egret.Texture = RES.getRes(`${key}_png`);
        if( !this.display ){
            this.display = new egret.Bitmap( texture );
            this.display.anchorOffsetX = texture.textureWidth >>1;
            this.display.anchorOffsetY = texture.textureHeight >>1;
        }else{
            if( this.display.texture != texture ) this.display.texture = texture;
        }
        return this.display;
    }

    //生成挡板
    private createPlane(): void{
        //创建1个形状
        let planeShape: p2.Box = new p2.Box( {
            width: GameUtils.instance.stage.stageWidth/this.factor,
            height: 100/this.factor
        } );
        //创建刚体
        this.planeBox = new p2.Body({
            //刚体的类型
            type: p2.Body.STATIC,
            //刚体的位置
            position: [GameUtils.instance.stage.stageWidth/this.factor/2,(GameUtils.instance.stage.stageHeight - 100/2)/this.factor]
        });
        // this.planeBox.angle = 0.1;
        this.planeBox.displays = [];
        this.planeBox.addShape( planeShape );
        this.world.addBody( this.planeBox );
    }
    //#region 碰撞事件处理
    private addEvent(): void{
        this.world.on( "postBroadPhaseEvent" , this.onPostBroadPhaseEvent , this);//当2个刚体的AABB发生重叠时,不断地派发postBroadPhase事件
        this.world.on( "preSolveEvent" , this.onPreSolveEvent , this);//当2个刚体的形状发生重叠时
        this.world.on( "beginContact" , this.onBeginContact , this);//当2个刚体形状发生重叠时会派发beinContact事件
        this.world.on( "endContact" , this.onEndContact , this);//当2个刚体分离不再重叠时派发endContract
    }
    private removeEvent(  ): void{
        this.world.off( "postBroadPhaseEvent" , this.onPostBroadPhaseEvent );//当2个刚体的AABB发生重叠时,不断地派发postBroadPhase事件
        this.world.off( "preSolveEvent" , this.onPreSolveEvent );//当2个刚体的形状发生重叠时
        this.world.off( "beginContact" , this.onBeginContact );//当2个刚体形状发生重叠时会派发beinContact事件
        this.world.off( "endContact" , this.onEndContact );//当2个刚体分离不再重叠时派发endContract
    }

    private onPostBroadPhaseEvent( e: any ): void{
        console.log( e );
    }
    private onPreSolveEvent( e:any ): void{
        console.log( e );
    }
    private onBeginContact( e:any ): void{
        console.log( e );
        let worldPo: Array = [];
        e.bodyB.toWorldFrame( worldPo, [ 0,0] );
        this.showTarget( { x: worldPo[0] , y: worldPo[1] } );

    }
    private onEndContact( e: any ): void{
        console.log( e );
    }
    //#endregion

    private showTarget : ( po: {x: number,y:number} ) => void = ( po ) => {
        if( !this.targetMap ){
            let texture: egret.Texture = RES.getRes( `target` );
            this.targetMap = new egret.Bitmap( texture);
            this.targetMap.anchorOffsetX = texture.textureWidth >>1;
            this.targetMap.anchorOffsetY = texture.textureHeight >>1;
            this.targetMap.scaleX = this.targetMap.scaleY = 0.2;
            this.addChild( this.targetMap );
        }
        console.log( `type x: ${po.x} y: ${po.y}` );
        this.targetMap.x = po.x * this.factor;
        this.targetMap.y = po.y * this.factor;
    }


    private loop( e: egret.Event ): void{
        this.world.step( 1/60,0,10 );
        // this.display.x = this.body.position[0] * this.factor;                      //同步刚体和egret显示对象的位置和旋转角度
        // this.display.y = this.body.position[1] * this.factor;
        // this.display.rotation = this.body.angle  * 180 / Math.PI;

        let texture: egret.DisplayObject;
        if( this.world.bodies !=null && this.world.bodies.length > 0 ){
            this.world.bodies.forEach( ( itemBody ) => {
                if( itemBody.type != p2.Body.STATIC){
                    if( itemBody.displays && itemBody.displays.length > 0 ){
                        texture = itemBody.displays[0];
                        texture.x = itemBody.position[0] * this.factor;
                        texture.y = itemBody.position[1] * this.factor;
                        texture.rotation = itemBody.angle  * 180 / Math.PI;
                    }
                    console.log( `参数 : ${ itemBody["userData"] }` );
                }else{
                    console.log("static body");
                }
            } );
        }

        this.debugDraw.drawDebug();//绘制调试区域
    }
}
四, 代码

B04.png


标签:Egret,P2,egret,private,p2,引擎,texture,factor,world
来源: https://blog.51cto.com/aonaufly/2804522

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有