初期角運動量を与えることで、だいぶん太陽系のような感じになってきた。
それから力のダンピングが完全に粒子間で対称になるように改良。これで超新星爆発はなくなった。動画は16倍速。
// forked from tasanokona's "太陽系の形成" http://jsdo.it/tasanokona/vJu0 // forked from tasanokona's "銀河の形成" http://jsdo.it/tasanokona/oQgm // forked from tasanokona's "2013-05-23 熊たたき" http://jsdo.it/tasanokona/ymX2 enchant(); var rand= function(n){ return (Math.random()*n); }; var BEAR = enchant.Class.create(Sprite,{ initialize: function(id,total_number){ enchant.Sprite.call(this, 1, 1); this.image = game.assets[files.icon0]; var X=Math.random(); var Y=Math.random(); // this.x = X*GameSize; // this.y= Y*GameSize; // this.x = X*GameSize/2*Math.cos(2.0*Math.PI*Y)+GameSize/2; // this.y = X*GameSize/2*Math.sin(2.0*Math.PI*Y)+GameSize/2; this.x = GameSize/5*Math.sqrt(-2.0*Math.log(X))*Math.cos(2.0*Math.PI*Y)+GameSize/2; this.y = GameSize/5*Math.sqrt(-2.0*Math.log(X))*Math.sin(2.0*Math.PI*Y)+GameSize/2; this.frame=0; X=Math.random(); Y=Math.random(); var speed=5.0; this.vx=speed*Math.sqrt(-2.0*Math.log(X))*Math.cos(2.0*Math.PI*Y);//rand(speed*2)-speed; this.vy=speed*Math.sqrt(-2.0*Math.log(X))*Math.sin(2.0*Math.PI*Y);//rand(speed*2)-speed; this.vx+=(this.y-GameSize/2)/(GameSize/2)*10.0; this.vy+=-(this.x-GameSize/2)/(GameSize/2)*10.0; this.ax=0.0; this.ay=0.0; this.ax_=0.0; this.ay_=0.0; game.rootScene.addChild(this); } }); var TIME = enchant.Class.create(Label,{ initialize: function(){ enchant.Label.call(this); this.x=0; this.y=0; this.tick=0.0; this.color="white"; this.xx=0; this.yy=0; this.addEventListener("enterframe", function(){ this.text="時間="+Math.floor(this.tick)+", x="+Math.floor(this.xx)+", y="+Math.floor(this.yy); this.tick+=dt; }); game.rootScene.addChild(this); } }); function setStars(Num){ bear = new Array(Num); for(var i=0; i<Num; i++){ bear[i] = new BEAR(i,Num); } game.rootScene.addEventListener("touchstart", function(e) { for(i=0; i<Num; i++){ bear[i].x =bear[i].x -e.x+GameSize/2; bear[i].y =bear[i].y -e.y+GameSize/2; } time.xx += e.x-GameSize/2; time.yy += e.y-GameSize/2; }); game.rootScene.addEventListener("enterframe", function() { if(Math.floor(time.tick/50)*50==Math.floor(time.tick)){ var x_=0; var y_=0; var num=0; for(i=0; i<Num; i++){ if(Math.abs(bear[i].x-GameSize/2)<GameSize&&Math.abs(bear[i].y-GameSize/2)<GameSize){ x_+=bear[i].x; y_+=bear[i].y; num++; } } x_=x_/num-GameSize/2; y_=y_/num-GameSize/2; for(i=0; i<Num; i++){ bear[i].x-=x_; bear[i].y-=y_; } time.xx += x_; time.yy += y_; } }); game.rootScene.addEventListener("enterframe", function() { var gamma=1.0/4.0/4; var a=1.05; var b=a*2; var G=10.0/2; var dx; var dy; var R; var RR; var tmp; var tmp2; var tmp3; var F; var ax; var ay; var axd; var ayd; var Nd; var aaxd=new Array(Num); var aayd=new Array(Num); for(i=0;i<Num;i++){ bear[i].ax_=0.0; bear[i].ay_=0.0; } for(i=0;i<Num;i++){ ax=0.0; ay=0.0; axd=0.0; ayd=0.0; Nd=0; for(var j=0;j<Num;j++){ if(j==i) continue; dx=(bear[j].x+bear[j].vx*hdt)-(bear[i].x+bear[i].vx*hdt); dy=(bear[j].y+bear[j].vy*hdt)-(bear[i].y+bear[i].vy*hdt); RR=dx*dx+dy*dy; R=Math.sqrt(RR); tmp=R-a; tmp2=Math.abs(tmp); if(R<4*b && tmp>0.1*a){ tmp=Math.exp(-tmp2/b)*gamma; aaxd[j]=-tmp*((bear[i].vx + bear[i].ax*hdt)-(bear[j].vx + bear[j].ax*hdt)); aayd[j]=-tmp*((bear[i].vy + bear[i].ay*hdt)-(bear[j].vy + bear[j].ay*hdt)); axd+=aaxd[j]; ayd+=aayd[j]; }else{ aaxd[j]=0; aayd[j]=0; } if(R<a) Nd++; tmp2=Math.exp(-R); tmp3=R+tmp2; tmp3*=tmp3; F=(1.0-3.0*tmp2)/tmp3; tmp=F/(R+0.001); var ax_=G*dx*tmp; var ay_=G*dy*tmp; ax += ax_; ay += ay_; bear[j].ax_-=ax_; bear[j].ay_-=ay_; } tmp3=Math.floor(Nd*Nd/25)+1; bear[i].ax_+=ax+axd/tmp3; bear[i].ay_+=ay+ayd/tmp3; for(j=0;j<Num;j++){ if(j==i) continue; bear[j].ax_-=aaxd[j]/tmp3; bear[j].ay_-=aayd[j]/tmp3; } tmp=Nd/4; if(tmp>3) tmp=3; bear[i].frame=tmp; tmp=Math.sqrt(Nd+1); if(tmp>3) tmp=3; bear[i].scaleX=(tmp); bear[i].scaleY=(tmp); } }); game.addEventListener("exitframe", function() { for(i=0; i<Num; i++){ bear[i].ax=bear[i].ax_; bear[i].ay=bear[i].ay_; bear[i].x += (bear[i].vx+bear[i].ax*hdt)*dt; bear[i].y += (bear[i].vy+bear[i].ay*hdt)*dt; bear[i].vx += bear[i].ax*dt; bear[i].vy += bear[i].ay*dt; } }); } window.onload = function(){ GameSize=620; game = new Core(GameSize, GameSize); game.fps = 100; files = { icon0: "http://jsrun.it/assets/u/R/9/j/uR9j0.png" }; game.preload(files.icon0); game.onload = function(){ game.rootScene.backgroundColor = "black"; var NumStar=1000; time=new TIME(); dt=1/20.0; hdt=dt/2.0; setStars(NumStar); }; game.start(); };