はじめに
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で動かします。
結果
結果はこんな感じ。表示されるのは43×60個です。約2500個ですね。
思ってたより中々重い感じ...。見た感じ弾が重なった時が重くなる...?(canvasの仕様かな)
ここに敵や自機を置くとなるとさらに重くなりそうですね。
閑話休題
何か参考になるものは無いかを探したところ次のサイトを見つけました。
Pixi.jsで雪を降らせてWebGLの速さを感じる
Pixi.js有能
これを見るとやはりPixi.jsは早いらしいですね。
このサイトでは実験段階で7000を超えたあたりで60fpsを下回りました。弾幕ゲームで60fpsから落ちるのは致命的です。これは開発段階であらかじめ量を決めておく必要があります。
配列操作処理
次に目についたのは配列操作処理に関するところです。確かに莫大な量の弾幕を抱えるとなると配列数も大きくなります。ここは今後重要視した方がいいですね。
WebAssembly
WebAssemblyは個人的に敷居が高く手が出しにくそうな感じがあります。でも早くなるかと思えばそうでもないようですね。このサイトではUnityで作成していましたが、ゴリゴリにコード書いて埋め込んだらもう少し早くなるのでしょうか??(それよりUnityScriptが廃止されていたことに驚き)
まとめ
webで弾幕を作ろうとするとJavaScript以外に他言語の知識を使えば何とかなる場合もありますが、できればJavaScriptだけで完結させたいところです。あとWebAssemblyは今後視野に入れていくべきだとは思っています。(個人的にはRustが触りやすそう)
素のWebGL使った方が軽いのかどうかも考えものですね。