乗車日記

自転車ときのこ

太陽系の形成-高速化-

昨晩、梅雨入りというニュースを聞く。今朝は雨が降るとみて起きず。実際どの程度降っていたかは不明。

夜、太陽系の形成プログラムを高速化。重力の計算を個々のスプライトのイベントではなく、coreのほうでまとめて行うことにした。
それから、クリックした場所を表示の中心にする機能、中心の空間座標の表示、10単位時間ごとにh表示の中心を重心位置にする機能を追加。最後のやつがないと、長い時間が経過すると星が流れていってどこに行ったか分からなくなってしまう。
だいたい分かってきたので、そろそろ3次元化したい。
http://jsdo.it/tasanokona/vJu0/fullscreen

enchant();
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();
};

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=7.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.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/10)*10==Math.floor(time.tick)){
           var x_=0;
           var y_=0;
           for(i=0; i<Num; i++){
             x_+=bear[i].x;
             y_+=bear[i].y;
            }
           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/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;
           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=Math.exp(-R/b)*gamma;
                            axd-=tmp*((bear[i].vx + bear[i].ax*hdt)-(bear[j].vx + bear[j].ax*hdt));
                            ayd-=tmp*((bear[i].vy + bear[i].ay*hdt)-(bear[j].vy + bear[j].ay*hdt));
                        }
                        if(R < b){
                            Nd++;
                        }
                        tmp2=Math.exp(-R);
                        tmp3=R+tmp2;
                        tmp3*=tmp3;
                        F=(1.0-3.0*tmp2)/tmp3;
                 //    if(F<-2.0) console.log(F);
                      tmp=F/(R+0.01);
                        ax += G*dx*tmp;
                        ay += G*dy*tmp;
                    }
                bear[i].ax_=ax+axd;
                bear[i].ay_=ay+ayd;
                bear[i].frame=Nd/4;
                bear[i].scale=(Nd+1);
           }
        });
        
        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;
            }
        });
}