はじめに
過去記事のように、何度か p2.js 物理エンジンを使用したボールの生成を行ってきました。
これらのコードをより軽く、拡張性の高いコードを作成したので公開します。
過去記事
【EgretEngine】p2.js 物理エンジンを使用した自然落下
【EgretEngine】p2.js 物理エンジンを使用して1000個の玉を描画する方法
1000個作っても大丈夫!p2.js物理ボールの生成方法
Main.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
class Main extends egret.DisplayObjectContainer { private createPhysicsBall :CreatePhysicsBall[] = []; private world : p2.World; private BallNumber : number = 1000; public constructor() { super(); this.once(egret.Event.ADDED_TO_STAGE, this.addToStage, this); } private addToStage(event:egret.Event) { this.world = new p2.World(); this.world.sleepMode = p2.World.BODY_SLEEPING; this.world.gravity = [0, 9.8*50]; //見えない壁や地面の生成 for(let i = 0; i < 3; i++){ const planeBody: p2.Body[] = []; planeBody[i] = new p2.Body({fixedRotation:true ,type:p2.Body.STATIC}); const planeShape: p2.Plane[] = []; planeShape[i] = new p2.Plane(); switch(i){ //地面 case 0: planeBody[i].position= [0, 700]; planeBody[i].angle = Math.PI;//rad表記 break; //右の壁 case 1: planeBody[i].position= [1260, 700]; planeBody[i].angle = Math.PI/2;//rad表記 break; //左の壁 case 2: planeBody[i].position= [20, 700]; planeBody[i].angle = 3* Math.PI/2;//rad表記 break; } planeBody[i].addShape(planeShape[i]); this.world.addBody(planeBody[i]); } for(let i = 0; i < this.BallNumber; i++){ this.createPhysicsBall[i] = new CreatePhysicsBall(this.world, i , i); this.createPhysicsBall[i].drawBall(); this.addChild(this.createPhysicsBall[i]); } //ループ処理 this.addEventListener(egret.Event.ENTER_FRAME,this.worldBigin,this); } private worldBigin(dt: number): Boolean{ //bodyを自然落下 this.world.step(1/60, dt/1000, 10); //console.log(this.body.position[1]); for(let i = 0; i < this.BallNumber; i++){ this.createPhysicsBall[i].moveBall(); } return false; } } |
CreatePhysicsBall.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
class CreatePhysicsBall extends egret.DisplayObjectContainer { /** * クラスに代入されて引数の受け取り用変数 */ protected dx : number = 1; protected dy : number = 1; protected world; protected ballPositionX : number = 30; protected ballPositionY : number = 100; public constructor(world : p2.World, dx :number, dy :number) { super(); this.world = world; this.dx = dx; this.dy = dy; //this.once(egret.Event.ADDED_TO_STAGE, this.addToStage, this); } //図形の表示用オブジェクトのインスタンス化 private shape:egret.Shape; //物理挙動をもつコライダーの生成 private body : p2.Body; private bodyShape : p2.Circle; public worldBigin(dt: number): Boolean{ //bodyを自然落下 this.world.step(1/60, dt/1000, 10); //console.log(this.body.position[1]); this.moveBall(); return false; } //ボールの描画 public drawBall() { this.shape = new egret.Shape(); this.addChild(this.shape); this.body = new p2.Body({mass:1, position:[this.ballPositionX + this.dx,+ this.ballPositionY - this.dx * 10], fixedRotation:true}); this.bodyShape = new p2.Circle({ radius: 5 }); this.body.addShape(this.bodyShape); this.world.addBody(this.body); //bodyを自然落下 this.shape.x = this.body.position[0]; this.shape.y = this.body.position[1]; this.shape.graphics.beginFill(0xffd700); this.shape.graphics.drawCircle(0, 0, 5); this.shape.graphics.endFill(); } public moveBall(){ this.shape.x = this.body.position[0]; this.shape.y = this.body.position[1]; this.addChild(this.shape); } } |
GitHub
https://github.com/squmari/EgretEngine/tree/master/PhysicsBall1000