pirika logo

ホームページ Pirikaで化学 ブログ 業務リスト お問い合わせ
情報化学+教育トップ 情報化学 MAGICIAN MOOC プログラミング
高校生レベルのプログラミングはMAGICIAN-Jrへどうぞ。
フィードバックはお問い合わせフォームからお願いします。

プログラミング・トップ > 化学,薬学系の親子で楽しみながらプログラミング >第5時限:理科:ワープ理論構築

2022.3.4

Pirika.comでプログラミング
山本博志

元のプログラムはこちらから

5-1-1:理論のさらなる改良

完成形プログラム(▶︎をクリックして開く)

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title></title>
  </head>
  <body>
  <h1></h1>
<div style="cursor:url(./images/Enterprize80.png), pointer"> 

<canvas width="600" height="350"></canvas>
  
</div>

<input type="button" id="btnStart" value="Start" onclick="StartSimu()">
 
<script type="text/javascript">

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const width = canvas.width ;
const height = canvas.height ;

let MySimu = false;      // シミュレーション・フラグ

    var center={};

    var dots = [];
    var density = 40;  //パーティクルの数
    var colors = ['#ee0000', '#eeee00', '#0000db'];
    var baseSize = 5;
    var baseSpeed = 3;

    
    //マウスの位置を読み込む。
   var mousePos;
    
    canvas.addEventListener('mousemove', function (evt) {//マウスが動いていたら
          mousePos = getMousePosition(canvas, evt);//マウスの位置を読み取る。

          center.x = mousePos.x;//前のバージョンは画面の中央からドットが出てきた。
          center.y = mousePos.y;//centerにマウスの位置を入れるとマウスのところから

        }, false);
        
    function getMousePosition(canvas, evt) {//マウスの位置を読み取る。
        var rect = canvas.getBoundingClientRect();//キャンバスの位置の補正
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
      }
    
    var Dot = function () {
        this.size = Math.floor( Math.random() * 6 ) + baseSize; //大きさ
        this.color = colors[~~(Math.random() * 3)]; //色
        this.speed = this.size / baseSpeed; // 大きさによって速度変更
        //mousePos = getMousePosition(canvas, evt);
        this.pos = {   // 位置
            x: canvas.width / 2,
            y: canvas.height / 2
        };

        var rot = Math.random() * 360;  // ランダムな角度
        var angle = rot * Math.PI / 180;

        this.vec = {    // 移動方向
            x: Math.cos(angle) * this.speed,
            y: Math.sin(angle) * this.speed
        };

        // ランダムに配置
        var startRandom = Math.random();
        this.pos.x += this.vec.x * (startRandom * center.x);
        this.pos.y += this.vec.y * (startRandom * center.y);

    };


    Dot.prototype = {
        update: function() {
            this.pos.x += this.vec.x;
            this.pos.y += this.vec.y;
            

            if(this.pos.x > canvas.width + baseSize
                  || this.pos.x < 0 - baseSize
                  || this.pos.y > canvas.height + baseSize
                  || this.pos.y < 0 - baseSize) {
                this.pos.x = center.x;
                this.pos.y = center.y;
            }
        },

        draw: function() {
            var MyColor=this.color;
            var MyX=this.pos.x;
            var MyY=this.pos.y;
            var MyRad=this.size;
            var InitCx=MyX+MyRad*(204-175)/100;
            var InitCy=MyY+MyRad*(50-100)/100;
            var InitCr=0.1*MyRad;
            var EndCx=MyX+0.25*MyRad;
            var EndCy=MyY-0.25*MyRad;
            var EndCr=0.75*MyRad;
            ctx.beginPath(); 
            
            
            
            ctx.arc(MyX, MyY, MyRad, 0, Math.PI*2, true);
            var gradient2=ctx.createRadialGradient(InitCx,InitCy,InitCr,EndCx,EndCy,EndCr);
            gradient2.addColorStop(0.0,"#EEEEEE");
            gradient2.addColorStop(1.0,MyColor);
            ctx.fillStyle = gradient2; 
            ctx.fill();

        }

        
    };
    
    
function EraseCenter() {//中心から半径100を黒く塗る。星は見えない。
            ctx.arc(mousePos.x, mousePos.y, 100, 0, Math.PI*2, true);
            
            ctx.fillStyle = 'rgba(0,0,0,0.9)';
            ctx.fill();
        
        }
  
function loop() {//アニメーションループ
    if(MySimu){
        ctx.fillStyle = 'rgba(0,0, 0, 0.15)';//黒をセットして、0.15分残像を残す。
        ctx.fillRect(0, 0,  width, height);//キャンバスを埋める

            for (var i = 0; i < density; i++) {
                    dots[i].update();
                    dots[i].draw();
                    
            }
            EraseCenter();
     

    requestAnimationFrame(loop);
   }
}


// 開始ボタンが押されたとき
function StartSimu() {
  if (MySimu) {
    MySimu = false;
    document.getElementById('btnStart').value = 'シミュレーション開始';
  } else {
    MySimu = true;
    document.getElementById('btnStart').value = 'シミュレーション停止';
    center.x = canvas.width / 2;//初期値、キャンバスの中央
    center.y = canvas.height / 2;

        for (var i = 0; i < density; i++) {
            dots.push(new Dot());//Dotを作って、dots配列に入れていく。
        }
    loop();
  }
}

</script>
  </body>
</html>

まず、宇宙は真っ暗だ。(背景を黒くする。)
ワープは光よりも早いのだから、残像をつけよう。(これは5-4のプログラムにある。)

ctx.fillStyle = 'rgba(0,0, 0, 0.15)';//黒をセットして、0.15分残像を残す。

新しい球が一点から出るのは変だ、トンネルの枠から出るようにしよう。

function EraseCenter() {//中心から半径100を黒く塗る。星は見えない。
     ctx.arc(mousePos.x, mousePos.y, 100, 0, Math.PI*2, true);
            
    ctx.fillStyle = 'rgba(0,0,0,0.9)';
    ctx.fill();
        
}


少しは良く見えるだろうか?


Copyright pirika.com since 1999-
Mail: yamahiroXpirika.com (Xを@に置き換えてください) メールの件名は[pirika]で始めてください。