(C)WorldWideSoftware

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="utf-8">
  <title>レーザーの演出</title>
 </head>
 <body>
  <a href="http://www.wwsft.com">(C)WorldWideSoftware</a><br>
  <canvas id="bg" width="640" height="640"></canvas><br>
タップ(クリック)した所が弾の到達地点(カウントアップする数字が表示されている位置)<br>
スペースキーでも弾を発射できます<br>
  <a href="laser00src.html">ソースコードの確認</a>

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

  //キー入力
  var key = 0;
  window.onkeydown = function(event) { key = event.keyCode; }
  window.onkeyup = function(event) { key = 0; }

  //マウスとタップの判定
  var tapX = 0, tapY = 0, tapC = 0;
  cvs.addEventListener( "touchstart", touchStart );
  cvs.addEventListener( "touchmove", touchMove );
  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 touchMove(ev) {
   ev.preventDefault();
   var rect = ev.target.getBoundingClientRect();
   tapX = ev.touches[0].clientX-rect.left;
   tapY = ev.touches[0].clientY-rect.top;
  }
  function touchEnd(ev) { tapC = 0; }

  cvs.addEventListener( "mousedown", mouseDown );
  cvs.addEventListener( "mousemove", mouseMove );
  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 mouseMove(ev) {
   var rect = ev.target.getBoundingClientRect();
   tapX = ev.clientX-rect.left;
   tapY = ev.clientY-rect.top;
  }
  function mouseUp(event) { tapC = 0; }

  var endX = 160, endY = 480;//レーザーの塔到達地点

  //レーザー用の変数
  var LASER_MAX = 50;
  var laX = [], laY = [], laD = [], laP = [];
  var lasNo = 0;

  //レーザーをクリア
  function clrLaser(n) {
   laX[n] = 0;
   laY[n] = 0;
   laD[n] = 0;
   laP[n] = 0;
  }

  //レーザーをセット(シューティングで自機から撃ち出す弾をセットする処理)
  function setLaser() {
   laX[lasNo] = 320;
   laY[lasNo] = 480;
   laD[lasNo] = 270;
   laP[lasNo] =   0;
   lasNo = (lasNo+1)%LASER_MAX;
  }

  for(var i = 0; i < LASER_MAX; i++) clrLaser(i);

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

  //角度を返す関数
  function getDeg(x1, y1, x2, y2) {
   var rad = Math.atan2(y1-y2, x1-x2);
   var deg = 180*rad/Math.PI;
   return toInt((deg+360)%360);//角度は0~359度とする
  }

  //整数を返す関数
  function toInt( val ) { return parseInt(val); }

  //円を描く関数
  function fCir(x, y, r, col) {
   ctx.fillStyle = col;
   ctx.beginPath();
   ctx.arc(x, y, r, 0, Math.PI*2);
   ctx.fill();
  }

  //メイン処理
  var tmr = 0;
  function mainProc() {
   tmr ++;
   var i;
   ctx.fillStyle = "black";
   ctx.fillRect(0, 0, 640, 640);

   //レーザー到達地点(タップした位置)
   if(tapC > 0) {
    endX = tapX;
    endY = tapY;
   }

   //レーザー発射
   if(key == 32 || tapC > 0) setLaser();

   //レーザーの移動と描画
   for(i = 0; i < LASER_MAX; i++) {
    if(laX[i] == 0 && laY[i] == 0 && laD[i] == 0) continue;//発射されていない状態
    laX[i] += 32*Math.cos(Math.PI*laD[i]/180);//座標の計算
    laY[i] += 32*Math.sin(Math.PI*laD[i]/180);//
    laP[i] ++;//発射後のカウント
    r = getDeg(endX, endY, laX[i], laY[i]);//到達地点との角度差から向きを変化させる
    if(r > laD[i]) laD[i] += laP[i];//発射後のカウントが大きいほど向きが大きく変わる
    if(r < laD[i]) laD[i] -= laP[i];
    fCir(laX[i], laY[i], 40, "rgba( 64,  0,255,0.2)");
    fCir(laX[i], laY[i], 32, "rgba( 64,  0,255,0.3)");
    fCir(laX[i], laY[i], 24, "rgba(128, 64,255,0.4)");
    fCir(laX[i], laY[i], 16, "rgba(192,128,255,0.5)");
    fCir(laX[i], laY[i],  8, "rgba(255,255,255,0.6)");
    if(getDis(endX, endY, laX[i], laY[i]) < 32 || laX[i] < -160 || 800 < laX[i] || laY[i] < -160 || 800 < laY[i]) clrLaser(i);
   }

   //弾の到達地点の表示
   ctx.fillStyle = "white";
   ctx.fillText(tmr, endX, endY);
   setTimeout( mainProc, 1000/60 );//リアルタイム処理
  }

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

←動作確認に戻る