直线运动
今天看到一种新的直线运动方法,和我之前一直用的稍有不同,因此记录一下。
假设有两个点p1和p2,如下:
var p1 = {x: 10, y: 10}, p2 = {x: 100, y: 100};
现在要从p1运动到p2,这种程序一般需要定义一个运动速度:
var speed = 1;
假设运动的物体是个小球,那么这个小球就以每帧1px的速度从p1运动到p2。
var ball = {x: 10, y: 10};
按照OO的思想,speed应该是ball这个对象的属性,好了,现在小球有 x, y, speed 这三个属性,但是这也不能确定小球的运动,因为还差运动方向呢!
这里介绍“速度向量”的概念,想必大家对向量比较熟悉,即长度和方向,那么所谓的速度向量,就是速度和方向。速度向量通常以 vx 和 vy 作为变量名,可见是 x方向 和 y方向的速度。接着说刚才的问题:方向怎么得到呢?
方向其实就是角度,知道 起始点(p1) 和 结束点(p2),角度很容易得到:
var a = Math.atan2(p2.y - p1.y, p2.x - p1.x);
有了方向,于是可得到速度向量:
var vx = Math.cos(a) * speed, vy = Math.sin(a) * speed;
因此小球应该有的属性是 x, y, vx, vy。这里我给出一个例子:
<!doctype html> <html> <head> <meta charset="utf-8"/> <script> window.onload = function() { canvasApp(); } function canvasApp() { var p1 = {x: 10, y: 10}, p2 = {x: 100, y: 100}, speed = 1; var a = Math.atan2(p2.y - p1.y, p2.x - p1.x), vx = Math.cos(a) * speed, vy = Math.sin(a) * speed; var ball = {x: p1.x, y: p1.y, vx: vx, vy: vy}; // 开始一个帧率为24的动画 setInterval(render, 1000 / 24); var canvas = $('canvas'), c = canvas.getContext('2d'); function render() { c.fillStyle = 'lightblue'; c.fillRect(0, 0, canvas.width, canvas.height); c.fillStyle = 'red'; c.beginPath(); c.arc(ball.x, ball.y, 5, 0, Math.PI * 2); c.closePath(); c.fill(); ball.x += ball.vx; ball.y += ball.vy; } } function $(id) { return document.getElementById(id); } function p(a) { console.log(a) } </script> <style> body { text-align: center; } canvas { margin: 0 auto; } </style> </head> <body> <canvas id="canvas" width="1200" height="500"> 您的浏览器不支持canvas! </canvas> </body> </html>
说到这里,只是介绍了我以前常用的一种方式,今天看到一种大同小异的,细节部分稍有不同。
首先计算两点之间的距离:
var dx = p2.x - p1.x, dy = p2.y - p1.y, distance = Math.sqrt(dx * dx + dy * dy);
接着计算以speed的速度需要运动几次:
var moves = distance / speed;
moves不用取整,接着计算每次运动分摊到 X方向 和 Y方向 的速度是多少:
var xUnit = (p2.x - p1.x) / moves, yUnit = (p2.y - p1.y) / moves;
其实xUnit 和 yUnit 就是速度向量,换了一种方式而已