egret p2 Physical Engine Learning Record
p2(physics) download address: https://download.csdn.net/download/qq_31189489/79552684
-
Introducing a physical engine
-
Download p2 Physical Engine Package
-
All files in the \physics\libsrc\binphysics directory are copied to the root directory/. / p2Physics directory
-
Modify the project root configuration file egretProperties.json
-
The modifications are as follows
{ "name":"physics", "path":"../physics" }
-
Compile Open egret Editor wing Find Plugin egret Project Tool Compile Engine
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-CiUikRO8-1644246147802) (attachment:9e3c157f630e22e7e43976151e41)]
-
Check to see if compilation was successful
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-W7h4V40K-1644246147805) (attachment: 5bbf974a7f99351d79a4eff93377c4)]
-
If a physics folder appears in the libs/modules/directory, the compilation is successful
-
Use physical engine
-
Basic concepts
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-H2CHqr3s-1644246147806) (attachment: 9cd3b0d8e3d4fc61b6cffd30e5d3)]
- World: Set the acceleration of gravity within the world Add elements to add world-related settings, such as setting friction and correlation coefficients between materials
- Shape: Draw the basic shape of an object, each rigid body needs to add a shape, set shape-related properties such as:
- Rigid body: Set rigid body, physical related properties, such as weight position, angular velocity, position of rigid body type, etc.
- Map: displays, showing egret related display elements by map, binding display
-
Basic steps
-
Create the World
// Instantiate a world object this.world = new p2.World(); //Set world to sleep this.world.sleepMode = p2.World.BODY_SLEEPING; this.world.gravity = [0,9.8] console.log('create world success')
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-JnhP0XUJ-1644246147808) (attachment: fc678f9c7d342956195ddad8872e9e)]
-
Create a floor
// Drawing the ground is also a synthesis of shape s and bodies 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) // Draw a line directly because there is no material bound 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)
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-Pc6II9Ww-1644246147809) (attachment: f9d659f069f5597e34d72f82562a75)]
-
Create a visual ball
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-dr1kU5GJ-1644246147811)(attachment:d4015ba6d3120dfae802b32b9dad9226)]
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') }
-
Updating the view world is created and does not automatically execute the motion logic; it needs to go through the world.step() to step
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-YgTZ2BvM-1644246147813)(attachment:68eb0e172825c999a5b375c373f38e3a)]
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) { //Assigning coordinates and angles of rigid bodies to display objects box.x = boxBody.position[0]; box.y = boxBody.position[1]; //If the current state of the rigid body is sleep, set the picture alpha to 0.5, otherwise 1 if (boxBody.sleepState == p2.Body.SLEEPING) { box.alpha = 0.5; } else { box.alpha = 1; } } }
-
All methods are executed in the main program, and the update function is called continuously through the clock function, with the final code as main.ts
[External chain picture transfer failed, source station may have anti-theft chain mechanism, it is recommended to save the picture and upload it directly (img-kk6yiRPA-1644246147815)(attachment:7244415b79b4ba4c1e1a6f77c4df0d1b)]
class HelloWorld extends eui.UILayer{ // Define a world variable private world:p2.World // Define a debug canvas private debugDraw:any // Define two materials private iceMaterial = new p2.Material(1); private steelMaterial = new p2.Material(2); private async runGame(){ console.log('load resources') // Entry Method await this.loadResource() // console.log('Create Background') // this.createBg() console.log('Create Gray Mask') this.createMask() // console.log('Draw 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) } // Entry function protected createChildren(): void { super.createChildren() this.runGame() } // Create Background Picture 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 } // load resources private async loadResource() { try { const loadingView = new LoadingUI(); this.stage.addChild(loadingView); // Temporary Comments Preload Resources // await RES.loadConfig("resource/default.res.json", "resource/"); // await RES.loadGroup("preload", 0, loadingView); this.stage.removeChild(loadingView); } catch (e) { console.error(e); } } // Create Mask 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) } // rigid body private createWorld():void{ // Instantiate a world object this.world = new p2.World(); //Set world to sleep this.world.sleepMode = p2.World.BODY_SLEEPING; this.world.gravity = [0,9.8] console.log('create world success') } //Generate Floor Plane private planeBody:p2.Body; private createGround():void{ // Drawing the ground is also a synthesis of shape s and bodies 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) // Draw a line directly because there is no material bound 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) // //Create a shape shape // let planeShape:p2.Plane = new p2.Plane(); // //Build body rigid body // this.planeBody= new p2.Body({ // //Rigid body type // type:p2.Body.STATIC, // //Position of the rigid body // 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') } //Frame Events, Step Functions 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) { //Assigning coordinates and angles of rigid bodies to display objects box.x = boxBody.position[0]; box.y = boxBody.position[1]; //If the current state of the rigid body is sleep, set the picture alpha to 0.5, otherwise 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() // //Create a rectangle with a width of 4 units and a height of 2 units // const shpRect: p2.Shape = new p2.Shape({angle:1,position: [200, 180]}); // //Create a flat shape // const shpPlane: p2.Plane = new p2.Plane(); // } }
-
Encountered pits can be referred to in this article: https://editor.csdn.net/md/?articleId=122815983