前回のコードに跳ね返る処理を入れるにも三角関数は必須だ。
ということで、とりあえずどの方向にも等速にボールを移動させる手段を探す。
Flashゲーム講座&ASサンプル集【三角関数を使った計算について】
‘どの方向にも一定の速度で移動するキャラクター’
というそのものズバリな解説を見つけた、よしコレでいこう。
ActionScript だけど基本計算は JavaScript と同一なはず。
endo blog: Javascript Math.atan2() X軸からポイントまでの角度を取得
って JavaScript には Math.atan2 という便利すぎ関数があるじゃないの。
HTML 中を引っ張った逆方向に移動するのだから
// 角度をラジアンで取得 ラジアン = Math.atan2(Y座標, X座標) // 移動先の算出 X座標 -= Math.cos(ラジアン) * 移動ピクセル数 Y座標 -= Math.sin(ラジアン) * 移動ピクセル数
あれ、こんな冗談みたいに単純で本当にいいのかな?
試しに前回のを 20/1000 秒毎に 10px 移動する感じに書き換えてみる。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>一定速で移動させる</title> <!-- for Smart Phone --> <meta name="viewport" content=" width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <style> body { margin: 0; overflow: hidden; -webkit-text-size-adjust: 100%; } #ID_CANVAS { background-color: #FFEE00; } </style> <script type="text/javascript"><!-- var canvas = null; var context = null; var ball = null; var offset = 24; // struct var ballData = function() { this.timer_id = -1; this.timer_count = 0; this.x = 0; this.y = 0; //this.move_x = 0; //this.move_y = 0; this.rotation = 0; } var BallData = new ballData(); // Event Handler var onBallTouchStart = function(e) { e.preventDefault(); } var onBallTouchMove = function(e) { if (BallData.timer_id == -1) { context.clearRect(0, 0, canvas.width, canvas.height); BallData.x = e.touches[0].pageX; BallData.y = e.touches[0].pageY; context.beginPath(); context.moveTo(160, 160); context.lineTo(BallData.x, BallData.y); context.stroke(); moveBall(BallData.x, BallData.y); } } var onBallTouchEnd = function(e) { if (BallData.timer_id == -1) { //BallData.move_x = (BallData.x - 160) / 5; //BallData.move_y = (BallData.y - 160) / 5; BallData.rotation = Math.atan2(BallData.y - 160, BallData.x - 160) BallData.timer_count = 20; BallData.timer_id = setInterval(onTimer, 20); } } // Timer Handler var onTimer = function() { if (BallData.timer_count > 0) { //BallData.x -= BallData.move_x; //BallData.y -= BallData.move_y; BallData.x -= Math.cos(BallData.rotation) * 10; BallData.y -= Math.sin(BallData.rotation) * 10; moveBall(BallData.x, BallData.y); BallData.timer_count--; } else { clearInterval(BallData.timer_id); BallData.timer_id = -1; context.clearRect(0, 0, canvas.width, canvas.height); moveBall(160, 160); } } // Func var moveBall = function(x, y) { ball.style.left = x - offset + "px"; ball.style.top = y - offset + "px"; } // Connect var init = function() { if (window.TouchEvent) { canvas = document.getElementById("ID_CANVAS"); canvas.width = window.innerWidth; canvas.height = window.innerHeight;// - 100; context = canvas.getContext("2d"); ball = document.getElementById("ID_BALL"); ball.addEventListener("touchstart",onBallTouchStart); ball.addEventListener("touchmove",onBallTouchMove); ball.addEventListener("touchend",onBallTouchEnd); moveBall(160, 160); var back = document.getElementById("ID_BACK"); back.style.top = canvas.height - 30 + "px"; back.addEventListener("touchstart", function() { document.location = "."; }); } } //--> </script> </head> <body onLoad="init()"> <canvas id="ID_CANVAS"></canvas> <img id="ID_BALL" src="ball.png" style="position:absolute"> <img id="ID_BACK" src="back.png" style="position:absolute"> <!--<a id="ID_BACK" style="position:absolute" href=".">Back</a>--> </body> </html>
上下左右どのように引っ張っても本当にコレだけでイケた。
少しブレるかもと思ったけど一定速でスムースに動いてくれる。
目的どおりのものが少しずづできあがっていくのって楽しい!