egret p2 物理引擎 小球坠落 demo
Posted JJesson
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了egret p2 物理引擎 小球坠落 demo相关的知识,希望对你有一定的参考价值。
2022 h5小游戏制作第一天,先做个属于自己的物理引擎世界吧
egret p2物理引擎学习记录
p2(physics)下载地址:https://download.csdn.net/download/qq_31189489/79552684
引入物理引擎
下载p2 物理引擎包
\\physics\\libsrc\\bin\\physics
目录下所有文件拷贝到根目录/../p2Physics
目录下- 修改项目根目录配置文件
egretProperties.json
修改项如下
"name":"physics", "path":"../physics"
编译 打开
egret编辑器wing
找到插件
egret项目工具
编译引擎
查看是否编译成功
如果
libs/modules/
目录下出现了physics文件夹则表示编译成功
使用物理引擎
基本概念
- 世界: 设置世界内部的
重力加速度
添加元素
添加世界相关设定
等功能,比如设置材质之间的摩擦和相关系数
- 形状:绘制物体的基本形状,每一个刚体都需要添加形状,设置
形状相关属性
比如: - 刚体:设置刚体,
物理相关属性
,比如刚体类型 重量
位置
,角速度
,位置
等等 - 贴图:displays,通过贴图展示
egret
相关显示元素,绑定显示
- 世界: 设置世界内部的
- 基本步骤
创建世界
// 实例化一个world对象 this.world = new p2.World(); //设置world为睡眠状态 this.world.sleepMode = p2.World.BODY_SLEEPING; this.world.gravity = [0,9.8] console.log(\'create world success\')
创建一个地板
// 绘制地面,也是通过shape和body 两个基础对象进行合成 let stageHeight = egret.MainContext.instance.stage.stageHeight var groundShape:p2.Plane = new p2.Plane() var groundBody:p2.Body = new p2.Body( type:p2.Body.STATIC, position:[0,stageHeight -100] ) groundShape.material = this.steelMaterial groundBody.angle = Math.PI groundBody.addShape(groundShape) groundBody.displays = [] this.world.addBody(groundBody) // 由于没有绑定材质,直接绘制一条的线条 let groundLine:egret.Shape = new egret.Shape groundLine.graphics.lineStyle(2,0x00ff00) groundLine.graphics.moveTo(0,stageHeight-90) groundLine.graphics.lineTo(egret.MainContext.instance.stage.stageWidth,stageHeight-90) this.addChild(groundLine)
创建一个可视小球
private display:egret.Shape; private createBody():void var boxShape:p2.Shape = new p2.Box(width:20,height:20) var boxBody:p2.Body = new p2.Body( mass: 2, position: [200, 200],velocity:[30,5]) boxShape.material = this.iceMaterial this.display = new egret.Shape() this.display.x = 100 this.display.graphics.beginFill(0xff0000,1) this.display.graphics.drawCircle(0,0,(<p2.Box>boxShape).width) this.display.graphics.endFill() // this.display.width = (<p2.Box>bfoxShape).width // this.display.height = (<p2.Box>boxShape).height boxBody.displays = [this.display] boxBody.addShape(boxShape) this.world.addBody(boxBody) this.addChild(this.display) // var boxShape:p2.Shape = new p2.Shape() // var boxBody:p2.Body = new p2.Body( mass: 1, position: [200, 180],angularVelocity:1 ) // boxBody.addShape(boxShape) // this.world.addBody(boxBody) console.log(\'create body success\')
更新视图
world
创建出来,并不会自动执行运动逻辑,需要通过world.step()
进行步进运动
this.world.step(1); var l = this.world.bodies.length; for (var i:number = 0; i < l; i++) var boxBody:p2.Body = this.world.bodies[i]; var box:egret.DisplayObject = boxBody.displays[0]; if (box) //将刚体的坐标和角度赋值给显示对象 box.x = boxBody.position[0]; box.y = boxBody.position[1]; //如果刚体当前状态为睡眠状态,将图片alpha设为0.5,否则为1 if (boxBody.sleepState == p2.Body.SLEEPING) box.alpha = 0.5; else box.alpha = 1;
在主程序中执行所有方法,并且通过时钟函数不断调用update函数,最终代码如下
main.ts
class HelloWorld extends eui.UILayer // 定义一个world变量 private world:p2.World // 定义一个调试画布 private debugDraw:any // 定义两种材质 private iceMaterial = new p2.Material(1); private steelMaterial = new p2.Material(2); private async runGame() console.log(\'加载资源\') // 入口方法 await this.loadResource() // console.log(\'创建背景\') // this.createBg() console.log(\'创建灰色遮罩\') this.createMask() // console.log(\'绘制movieClips\') // this.createClips() this.createWorld() this.createGround() this.createBody() this.addEventListener(egret.Event.ENTER_FRAME,this.update,this); private createClips() let data = RES.getRes("chara_json") let textr = RES.getRes(\'chara_png\') let factorys:egret.MovieClipDataFactory = new egret.MovieClipDataFactory(data,textr) let paimeng:egret.MovieClip = new egret.MovieClip(factorys.generateMovieClipData(\'paimeng\')) this.addChild(paimeng) paimeng.gotoAndPlay("main",-1) // 入口函数 protected createChildren(): void super.createChildren() this.runGame() // 创建背景图片 private createBg() let bg = new Util().createBitMap(\'bg_jpg\') console.log(bg) this.addChild(bg) bg.width = this.stage.stageWidth bg.height = this.stage.stageHeight // 加载资源 private async loadResource() try const loadingView = new LoadingUI(); this.stage.addChild(loadingView); // 暂时注释预加载资源 // await RES.loadConfig("resource/default.res.json", "resource/"); // await RES.loadGroup("preload", 0, loadingView); this.stage.removeChild(loadingView); catch (e) console.error(e); // 创建遮罩 private createMask() let mask = new egret.Shape() mask.graphics.beginFill(0xffffff,1) mask.graphics.drawRect(0,0,this.stage.stageWidth,this.stage.stageHeight) mask.graphics.endFill() mask.y = 0 this.addChild(mask) // 创建刚体 private createWorld():void // 实例化一个world对象 this.world = new p2.World(); //设置world为睡眠状态 this.world.sleepMode = p2.World.BODY_SLEEPING; this.world.gravity = [0,9.8] console.log(\'create world success\') //生成地板Plane private planeBody:p2.Body; private createGround():void // 绘制地面,也是通过shape和body 两个基础对象进行合成 let stageHeight = egret.MainContext.instance.stage.stageHeight var groundShape:p2.Plane = new p2.Plane() var groundBody:p2.Body = new p2.Body( type:p2.Body.STATIC, position:[0,stageHeight -100] ) groundShape.material = this.steelMaterial groundBody.angle = Math.PI groundBody.addShape(groundShape) groundBody.displays = [] this.world.addBody(groundBody) // 由于没有绑定材质,直接绘制一条的线条 let groundLine:egret.Shape = new egret.Shape groundLine.graphics.lineStyle(2,0x00ff00) groundLine.graphics.moveTo(0,stageHeight-90) groundLine.graphics.lineTo(egret.MainContext.instance.stage.stageWidth,stageHeight-90) this.addChild(groundLine) // //建立一个shape形状 // let planeShape:p2.Plane = new p2.Plane(); // //建立body刚体 // this.planeBody= new p2.Body( // //刚体类型 // type:p2.Body.STATIC, // //刚体的位置 // position:[0,this.stage.stageHeight] // ); // this.planeBody.angle = Math.PI; // this.planeBody.displays = []; // this.planeBody.addShape(planeShape); // this.world.addBody(this.planeBody); console.log(\' create ground success\') private display:egret.Shape; private createBody():void var boxShape:p2.Shape = new p2.Box(width:20,height:20) var boxBody:p2.Body = new p2.Body( mass: 2, position: [200, 200],velocity:[30,5]) boxShape.material = this.iceMaterial this.display = new egret.Shape() this.display.x = 100 this.display.graphics.beginFill(0xff0000,1) this.display.graphics.drawCircle(0,0,(<p2.Box>boxShape).width) this.display.graphics.endFill() // this.display.width = (<p2.Box>bfoxShape).width // this.display.height = (<p2.Box>boxShape).height boxBody.displays = [this.display] boxBody.addShape(boxShape) this.world.addBody(boxBody) this.addChild(this.display) // var boxShape:p2.Shape = new p2.Shape() // var boxBody:p2.Body = new p2.Body( mass: 1, position: [200, 180],angularVelocity:1 ) // boxBody.addShape(boxShape) // this.world.addBody(boxBody) console.log(\'create body success\') //帧事件,步函数 private update() this.world.step(1); var l = this.world.bodies.length; for (var i:number = 0; i < l; i++) var boxBody:p2.Body = this.world.bodies[i]; var box:egret.DisplayObject = boxBody.displays[0]; if (box) //将刚体的坐标和角度赋值给显示对象 box.x = boxBody.position[0]; box.y = boxBody.position[1]; //如果刚体当前状态为睡眠状态,将图片alpha设为0.5,否则为1 if (boxBody.sleepState == p2.Body.SLEEPING) box.alpha = 0.5; else box.alpha = 1; // private createDebug():void // // private createTestPhysic():void // console.log(\'create begin\') // const body = new p2.Body() // //创建宽4单位、高2单位的矩形形状 // const shpRect: p2.Shape = new p2.Shape(angle:1,position: [200, 180]); // //创建平面形状 // const shpPlane: p2.Plane = new p2.Plane(); //
遇到的坑:详见这个博客:https://www.cnblogs.com/zm-blogs/p/15869701.html
以上是关于egret p2 物理引擎 小球坠落 demo的主要内容,如果未能解决你的问题,请参考以下文章