LoginSignup
4
5

More than 3 years have passed since last update.

pixi.jsによる表示負荷テスト

Posted at

はじめに

webで弾幕ゲームを作成しようとした時に最初はkonva.jsをつかっていました。しかしながら重いという訳でPixi.jsを使うことになりました。
その前にcreatejsを使いましたがお察しで
東方projectのQED「495年の波紋」っぽいもので試してみようと思います。チルノ可愛いぞ

実行

以下のプログラムで実行してみた。

/*jshint esversion: 6 */
var width = window.innerWidth;
var height = window.innerHeight;
var x = width/2;
var y = height/2;
var stage = new PIXI.Container();
var renderer = PIXI.autoDetectRenderer(width, height,{
    resolution: 1,
    antialias: true,
});
document.getElementById("pixiview").appendChild(renderer.view);
window.onresize = function () {
    location.reload();
};

var time=0;
function animate(){
    requestAnimationFrame(animate);
    time++;
    if(time==3){
        addobj(obj_shot*o,obj_shot*(o+1),5,"0xff000",x,y,circle);
        for(var a=obj_shot*o;a<obj_shot*(o+1);a++){
            for(var b=0;b<circle[a].length;b++){
                stage.addChild(circle[a][b]);
            }
        }
        o++;
        time=0;
    }

    var l = 0;
    var count=0;
    for(var t=0;t<circle.length/obj_shot;t++){
        count=0;
        for(var i=0;i<360;i+=(360/obj_shot)){
            if(circle[l][0]!=""){
                var sx = circle[l][0].x;
                var sy = circle[l][0].y;
                xmove = sx+Math.cos(i*(Math.PI/180))*(5);
                ymove = sy+Math.sin(i*(Math.PI/180))*(5);
                objset(l,xmove,ymove,circle);
                if(circle[l][0].x>x*2 || circle[l][0].x<0 || circle[l][0].y>y*2 || circle[l][0].y<0){
                    circle[l][0].clear();
                    circle[l][0]="";
                    count++;
                }
            }else{count++;}
            l++;
        }
        if(count==obj_shot){
            circle.splice(0, obj_shot);
            o--;
            textobj.text--;
        }
    }
    renderer.render(stage);
}

var circle=[];
var obj_shot=60;
var o=0;
function addobj(mas,num,rad,color,x,y,obj){
    for(var i=mas;i<num+mas;i++){
        obj[i] = [];
        obj[i][0] = new PIXI.Graphics();
        obj[i][0].beginFill(color, 1);
        obj[i][0].drawCircle(0,0,rad);
        obj[i][0].globalCompositeOperation = 'destination-over';
        obj[i][0].endFill();

        obj[i][0].x=x;
        obj[i][0].y=y;
    }
    textobj.text++;
}

function objset(num,x,y,obj){
    obj[num][0].x=x;
    obj[num][0].y=y;
}

var word = "0";
var style = {fontFamily : 'Arial',fontSize : '40px', fill:'white', fontWeight : "bold"};
var textobj = new PIXI.Text(word, style);
stage.addChild(textobj);
animate();

プログラムがぐちゃぐちゃなのは許してください...
実行内容としては3frameに1回、画面中心から半径5の円が60個円状に表示され、毎フレーム5pxずつ動いていくというものです。また、全てが画面から出た時に削除されます。(それまで画面外で動いている)
PCはスペックはi7-8750H、画面サイズは479×461.5で動かします。

結果

image.png

結果はこんな感じ。表示されるのは43×60個です。約2500個ですね。
思ってたより中々重い感じ...。見た感じ弾が重なった時が重くなる...?(canvasの仕様かな)
ここに敵や自機を置くとなるとさらに重くなりそうですね。

閑話休題

何か参考になるものは無いかを探したところ次のサイトを見つけました。
Pixi.jsで雪を降らせてWebGLの速さを感じる

Pixi.js有能

これを見るとやはりPixi.jsは早いらしいですね。
このサイトでは実験段階で7000を超えたあたりで60fpsを下回りました。弾幕ゲームで60fpsから落ちるのは致命的です。これは開発段階であらかじめ量を決めておく必要があります。

配列操作処理

次に目についたのは配列操作処理に関するところです。確かに莫大な量の弾幕を抱えるとなると配列数も大きくなります。ここは今後重要視した方がいいですね。

WebAssembly

WebAssemblyは個人的に敷居が高く手が出しにくそうな感じがあります。でも早くなるかと思えばそうでもないようですね。このサイトではUnityで作成していましたが、ゴリゴリにコード書いて埋め込んだらもう少し早くなるのでしょうか??(それよりUnityScriptが廃止されていたことに驚き)

まとめ

webで弾幕を作ろうとするとJavaScript以外に他言語の知識を使えば何とかなる場合もありますが、できればJavaScriptだけで完結させたいところです。あとWebAssemblyは今後視野に入れていくべきだとは思っています。(個人的にはRustが触りやすそう)
素のWebGL使った方が軽いのかどうかも考えものですね。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5