h5 mini game making egret p2 physical engine ball drop demo

egret p2 Physical Engine Learning Record

p2(physics) download address: https://download.csdn.net/download/qq_31189489/79552684

  • Introducing a physical engine

  1. Download p2 Physical Engine Package

  2. All files in the \physics\libsrc\binphysics directory are copied to the root directory/. / p2Physics directory

  3. Modify the project root configuration file egretProperties.json

  4. The modifications are as follows

    {
          "name":"physics",
          "path":"../physics"
       
        }
    
  5. 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)]

  6. 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)]

  7. If a physics folder appears in the libs/modules/directory, the compilation is successful


  • Use physical engine

  1. 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
  2. Basic steps

    1. 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)]

    2. 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)]

    3. 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')
        }
      
    4. 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;
                  }
              }
          }
      
    5. 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

Keywords: Javascript egret

Added by krio on Mon, 07 Feb 2022 20:23:12 +0200