(C)WorldWideSoftware

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="utf-8">
  <title>弾の軌跡3簡易版</title>
 </head>
 <body>
  <a href="http://www.wwsft.com">(C)WorldWideSoftware</a><br>
  <canvas id="bg" width="640" height="640"></canvas><br>
画面クリック(タップ)した位置からレーザー発射<br>
弾の軌跡を描く演出用の描画面を用意できる環境を想定した簡易版です<br>
レーザーの軌跡(座標)は保持せず、描画面を毎フレーム薄い黒で塗ることで、軌跡の表示を実現しています<br>
  <a href="laser02_2src.html">ソースコードの確認</a>

  <script>
  //描画面(キャンバス)の準備
  var cvs = document.getElementById("bg");
  var ctx = cvs.getContext("2d");

  //マウスとタップの判定
  var tapX = 320, tapY = 320, tapC = 0;
  cvs.addEventListener("touchstart", touchStart);
  cvs.addEventListener("touchend", touchEnd);
  function touchStart(ev) {
   ev.preventDefault();
   var rect = ev.target.getBoundingClientRect();
   tapX = ev.touches[0].clientX-rect.left;
   tapY = ev.touches[0].clientY-rect.top;
   tapC = 1;
  }
  function touchEnd(ev) { tapC = 0; }

  cvs.addEventListener("mousedown", mouseDown);
  cvs.addEventListener("mouseup", mouseUp);
  function mouseDown(ev) {
   var rect = ev.target.getBoundingClientRect();
   tapX = ev.clientX-rect.left;
   tapY = ev.clientY-rect.top;
   tapC = 1;
  }
  function mouseUp(ev) { tapC = 0; }

  //レーザー到達地点
  var targetX = 0;
  var targetY = 80;

  //レーザー用の変数 今回は5本セットで処理しています
  var LASER_NUM = 5;
  var LASER_MAX = 100;//レーザーの軌跡を管理

  var laserP = 0;//発射用のフラグ

  var laX = [0,0,0,0,0], laY = [0,0,0,0,0];//座標
  var laXP = [0,0,0,0,0], laYP = [0,0,0,0,0];//方向(移動量)

  //レーザーをセット(自機から撃ち出す処理)
  function setLaser() {
   for(var n=0; n<LASER_NUM; n++) {
    laX[n] = tapX;
    laY[n] = tapY;
    laXP[n] = (n-(LASER_NUM-1)/2)*(160/LASER_NUM);
    laYP[n] = 24;//←↑レーザーの方向、初期値は後方左右に広げて撃ち出す
   }
   laserP = 90;//次のレーザーが撃てるまでのフレーム数
  }

  //線を引く関数
  ctx.lineCap = "round";
  function line(x1, y1, x2, y2, wid, col) {
   ctx.lineWidth = wid;
   ctx.strokeStyle = col;
   ctx.beginPath();
   ctx.moveTo(x1, y1);
   ctx.lineTo(x2, y2);
   ctx.stroke();
  }

  //距離を求める関数
  function getDis(x1, y1, x2, y2) {
   return( Math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) ) );
  }

  //メイン処理
  function mainProc() {
   var c, m, n, dis, dx, dy;

   ctx.fillStyle = "rgba(0,0,0,0.05)";
   ctx.fillRect(0, 0, 640, 640);

   //ターゲットの位置
   targetX++; if(targetX > 640) targetX = 0;
   line(targetX-20,targetY,targetX+20,targetY,12,"#80c000");
   line(targetX,targetY-20,targetX,targetY+20,12,"#80c000");

   //レーザー発射?
   if(laserP == 0) {
    if(tapC > 0) setLaser();
   }
   else {
    laserP--;
   }

   //レーザーの移動と描画
   for(n=0; n<LASER_NUM; n++) {
    if(laX[n]!=0 || laY[n]!=0) {//発射されている

     //レーザーが向かう方向(座標の変化量)を計算
     dis = getDis(targetX, targetY, laX[n], laY[n]);//ターゲットとの距離
     if(dis < 1) dis = 1;
     dx = 20*(targetX-laX[n])/dis;//ターゲットに向かうX方向ベクトル n倍してX方向最大速度
     dy = 20*(targetY-laY[n])/dis;//ターゲットに向かうY方向ベクトル n倍してY方向最大速度
     laXP[n] = (laXP[n]*8+dx*2)/10;
     laYP[n] = (laYP[n]*8+dy*2)/10;

     laX[n] += laXP[n];//座標の計算
     laY[n] += laYP[n];
 
     //レーザーの軌跡を描く
     for(c=0; c<4; c++) {//4色重ねてレーザーっぽく
      line(laX[n]-laXP[n], laY[n]-laYP[n], laX[n], laY[n], 16-c*4, "rgb("+(c*40)+","+(c*80)+","+(255)+")");
     }

     if(getDis(targetX, targetY, laX[n], laY[n]) < 20) { laX[n]=0; laY[n]=0; };//ターゲットに到達
     if(laserP == 0) { laX[n]=0; laY[n]=0; };//あるいは一定時間経過したらレーザーを消滅させる
    }
   }

   //タップ位置の表示
   ctx.fillStyle = "white";
   ctx.fillText(laserP, tapX, tapY);

   setTimeout(mainProc, 1000/60);//リアルタイム処理
  }

  mainProc();//処理スタート
  </script>
 </body>
</html>

←動作確認に戻る