すくまりのメモ帳すくまりのメモ帳
← 記事一覧に戻る

【Egret Engine】1000個作っても大丈夫!p2.js物理ボールの生成方法

【Egret Engine】1000個作っても大丈夫!p2.js物理ボールの生成方法

はじめに

過去記事のように、何度か p2.js 物理エンジンを使用したボールの生成を行ってきました。

これらのコードをより軽く、拡張性の高いコードを作成したので公開します。

過去記事

【EgretEngine】p2.js 物理エンジンを使用した自然落下

【EgretEngine】p2.js 物理エンジンを使用して1000個の玉を描画する方法

1000個作っても大丈夫!p2.js物理ボールの生成方法

Main.ts
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
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

HTML5 Egret Engine入門講座へ戻る

HTML5 Egret Engine入門講座へ戻る