前回のコードに跳ね返る処理を入れるにも三角関数は必須だ。
ということで、とりあえずどの方向にも等速にボールを移動させる手段を探す。
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>
上下左右どのように引っ張っても本当にコレだけでイケた。
少しブレるかもと思ったけど一定速でスムースに動いてくれる。
目的どおりのものが少しずづできあがっていくのって楽しい!