(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>
←動作確認に戻る