本文,我们要做点有意思的效果,首先,来一个简单的边界判断,所谓边界判断:就是把物体的运动限定在一个范围内.我们先来一个简单的实例,在canvas上生成一个小球,小球的初始位置是在canvas的正中间,然后通过键盘的上下左右来移动小球的位置,如果小球碰到canvas的左边,那么不能再向左运动,其他方向同理.

要实现这个效果,只需要一个边界判断,即可。

function checkBorder() {
    if ( ball.x < ball.radius ) { //碰到左边界
        ball.x = ball.radius;
    } else if ( ball.y < ball.radius ) { //碰到上边界
        ball.y = ball.radius;
    } else if ( ball.x > width - ball.radius ) { //碰到右边界
        ball.x = width - ball.radius;
    }else if ( ball.y > height - ball.radius ){
        ball.y = height - ball.radius;
    }
}

左边界:只要判断小球的圆心x 如果小于小球的半径,那肯定是碰到了左边界,我们就让小球的中心x等于小球的半径。

右边界:只要判断小球的圆心x 如果大于canvas的宽度减去小球的半径,那肯定是碰到了右边界,我们就让小球的中心x等于canvas的宽度减去小球的半径

其他上下边界跟左右是同理。

完整的实例代码:

<head>
    <meta charset='utf-8' />
    <style>
        #canvas {
            border: 1px dashed #aaa;
        }
    </style>
    <script src="./ball.js"></script>
    <script>
        window.onload = function () {
            var oCanvas = document.querySelector("#canvas"),
                oGc = oCanvas.getContext('2d'),
                width = oCanvas.width, height = oCanvas.height,
                ball = new Ball(width / 2, height / 2);
                ball.fill( oGc );
            addEventListener("keydown", function (ev) {
                oGc.clearRect(0, 0, width, height);
                var oEvent = ev || event;
                switch (oEvent.keyCode) {
                    case 37:
                        ball.x -= 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                    case 39:
                        ball.x += 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                    case 38:
                        ball.y -= 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                    case 40:
                        ball.y += 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                }
            }, false);
            function checkBorder() {
                if ( ball.x < ball.radius ) { //碰到左边界
                    ball.x = ball.radius;
                } else if ( ball.y < ball.radius ) { //碰到上边界
                    ball.y = ball.radius;
                } else if ( ball.x > width - ball.radius ) { //碰到右边界
                    ball.x = width - ball.radius;
                }else if ( ball.y > height - ball.radius ){
                    ball.y = height - ball.radius;
                }
            }
        }
    </script>
</head>

<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>

边界穿透:

如果小球向左运动,且完全超出左边界,我们就让他从右边出来,如果小球向右运动,且完全超出右边界,我们就让他从左边出来。上下方向同理。

<head>
    <meta charset='utf-8' />
    <style>
        #canvas {
            border: 1px dashed #aaa;
        }
    </style>
    <script src="./ball.js"></script>
    <script>
        window.onload = function () {
            var oCanvas = document.querySelector("#canvas"),
                oGc = oCanvas.getContext('2d'),
                width = oCanvas.width, height = oCanvas.height,
                ball = new Ball(width / 2, height / 2);
            ball.fill(oGc);
            addEventListener("keydown", function (ev) {
                oGc.clearRect(0, 0, width, height);
                var oEvent = ev || event;
                switch (oEvent.keyCode) {
                    case 37:
                        ball.x -= 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                    case 39:
                        ball.x += 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                    case 38:
                        ball.y -= 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                    case 40:
                        ball.y += 5;
                        checkBorder();
                        ball.fill(oGc);
                        break;
                }
            }, false);
            function checkBorder() {
                if (ball.x < -ball.radius) { //完全超出左边界
                    ball.x = width + ball.radius; //让球从右边出来
                } else if (ball.y < -ball.radius) { //完全超出上边界
                    ball.y = height + ball.radius;//让球从下面出来
                } else if (ball.x > width + ball.radius) { //完全超出右边界
                    ball.x = -ball.radius;//让球从左边出来
                } else if (ball.y > height + ball.radius) {//完全超出下边界
                    ball.y = -ball.radius; //让球从上边出来
                }
            }
        }
    </script>
</head>

<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>

散弹效果:

通过canvas的中心点,不停的向四周发射小球,形成散弹的效果. 

我不知道你们有没有这样的误区:不停的向四周发射小球,那是不是的不停的创造小球?如果你这样想,程序就算写出来了,肯定会卡死

起始我们可以只创建,一定数量的小球,比如( 50, 60. ...100 ),然后当这些小球,完全超出的边界的时候,再把这些小球的圆心( x, y )设定到最开始的位置,再次随机x和y方向的速度,就可以达到目的了, 说白了就是,那个完全超出边界的小球,我们让他重新回到最初的地方,只是改变了他的颜色和速度,给人感觉就是那个发射小球的地方源源不断的在发射小球

完整的散弹效果:

<head>
    <meta charset='utf-8' />
    <style>
        #canvas {
            border: 1px dashed #aaa;
        }
    </style>
    <script src="./ball.js"></script>
    <script>
        window.onload = function () {
            var oCanvas = document.querySelector("#canvas"),
                oGc = oCanvas.getContext('2d'),
                width = oCanvas.width, height = oCanvas.height,
                balls = [], n = 50;
            function getRandColor() {
                return '#' + ( function( color ){
                    return ( color += '0123456789abcdef' [Math.floor( Math.random() * 16 )] ) && ( color.length == 6 ) ? color : arguments.callee( color );
                } )( '' );
            }
            for( var i = 0; i < n; i++ ) {
                var ball = new Ball( width / 2, height / 2, 20, getRandColor() );
                ball.vx = ( Math.random() * 2 - 1 ) * 5;
                ball.vy = ( Math.random() * 2 - 1 ) * 5;
                balls.push( ball );
            }
            (function move(){
                oGc.clearRect( 0, 0, width, height );
                balls.forEach( function( ball ){
                    if ( ball.x < -ball.radius
                        || ball.x > width + ball.radius
                        || ball.y < -ball.radius
                        || ball.y > height + ball.radius ) {
                            ball.x = width / 2;
                            ball.y = height / 2;
                            ball.vx = ( Math.random() * 2 - 1 ) * 5;
                            ball.vy = ( Math.random() * 2 - 1 ) * 5;
                    }
                    ball.x += ball.vx;
                    ball.y += ball.vy;
                    ball.fill( oGc );
                } );
                requestAnimationFrame( move );
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>

我们可以在之前的基础上,加上重力的影响,实现喷泉的效果:

<head>
    <meta charset='utf-8' />
    <style>
        #canvas {
            border: 1px dashed #aaa;
        }
    </style>
    <script src="./ball.js"></script>
    <script>
        window.onload = function () {
            var oCanvas = document.querySelector("#canvas"),
                oGc = oCanvas.getContext('2d'),
                width = oCanvas.width, height = oCanvas.height,
                balls = [], n = 50, gravity = 0.2;
            function getRandColor() {
                return '#' + (function (color) {
                    return (color += '0123456789abcdef'[Math.floor(Math.random() * 16)]) && (color.length == 6) ? color : arguments.callee(color);
                })('');
            }
            for (var i = 0; i < n; i++) {
                var ball = new Ball(width / 2, height / 2, 20, getRandColor());
                ball.vx = (Math.random() * 2 - 1) * 5;
                ball.vy = (Math.random() * 2 - 1) * 10;
                balls.push(ball);
            }
            (function move() {
                oGc.clearRect(0, 0, width, height);
                balls.forEach(function (ball) {
                    if (ball.x < -ball.radius
                        || ball.x > width + ball.radius
                        || ball.y < -ball.radius
                        || ball.y > height + ball.radius) {
                        ball.x = width / 2;
                        ball.y = height / 2;
                        ball.vx = (Math.random() * 2 - 1) * 5;
                        ball.vy = (Math.random() * 2 - 1) * 10;
                    }
                    ball.x += ball.vx;
                    ball.y += ball.vy;
                    ball.vy += gravity;
                    ball.fill(oGc);
                });
                requestAnimationFrame(move);
            })();
        }
    </script>
</head>

<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>

还可以通过控制小球的vx, vy,就是x方向和y方向的速度,来限制小球朝某一个方向发射,下面的例子,我们只让小球朝着x轴的右边发射。

<head>
    <meta charset='utf-8' />
    <style>
        #canvas {
            border: 1px dashed #aaa;
        }
    </style>
    <script src="./ball.js"></script>
    <script>
        window.onload = function () {
            var oCanvas = document.querySelector("#canvas"),
                oGc = oCanvas.getContext('2d'),
                width = oCanvas.width, height = oCanvas.height,
                balls = [], n = 50;
            function getRandColor() {
                return '#' + ( function( color ){
                    return ( color += '0123456789abcdef' [Math.floor( Math.random() * 16 )] ) && ( color.length == 6 ) ? color : arguments.callee( color );
                } )( '' );
            }
            for( var i = 0; i < n; i++ ) {
                var ball = new Ball( width / 2, height / 2, 20, getRandColor() );
                ball.vx = Math.abs( ( Math.random() * 2 - 1 ) * 5 );
                ball.vy = ( Math.random() * 2 - 1 ) * 5;
                balls.push( ball );
            }
            (function move(){
                oGc.clearRect( 0, 0, width, height );
                balls.forEach( function( ball ){
                    if ( ball.x < -ball.radius
                        || ball.x > width + ball.radius
                        || ball.y < -ball.radius
                        || ball.y > height + ball.radius ) {
                            ball.x = width / 2;
                            ball.y = height / 2;
                            ball.vx = Math.abs( ( Math.random() * 2 - 1 ) * 5 );
                            ball.vy = ( Math.random() * 2 - 1 ) * 5;
                    }
                    ball.x += ball.vx;
                    ball.y += ball.vy;
                    ball.fill( oGc );
                } );
                requestAnimationFrame( move );
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="1200" height="600"></canvas>
</body>

我学院网