直线运动

今天看到一种新的直线运动方法,和我之前一直用的稍有不同,因此记录一下。


假设有两个点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 就是速度向量,换了一种方式而已

posted @ 2012-02-14 22:11  越己  阅读(319)  评论(0编辑  收藏  举报