《canvas》之第15章 边界检测

130 篇文章 4 订阅
20 篇文章 6 订阅

第15章 边界检测

15.1 边界检测简介

为物体设置运动范围,碰到画布边界就反弹。

if(ball.x < ball.radius) {
	//小球碰到左边界
} else if(ball.x > cnv.width-ball.radius) {
	//小球碰到右边界
} 


if(ball.y < ball.radius) {
	//小球碰到上边界
} else if(ball.y > cnv.height-ball.radius) {
	//小球碰到下边界
} 

15.2 边界限制

通过边界检测的方法限制物体的运动范围。

if(ball.x < ball.radius) {
	//小球碰到左边界
} else if(ball.x > cnv.width-ball.radius) {
	//小球碰到右边界
} 


if(ball.y < ball.radius) {
	//小球碰到上边界
} else if(ball.y > cnv.height-ball.radius) {
	//小球碰到下边界
} 
  • 键盘事件+边界检测
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            //初始化数据
            var ball = new Ball(cnv.width / 2, cnv.height / 2);
            ball.fill(cxt);
            var key = tools.getKey();

            //添加键盘事件
            window.addEventListener("keydown", function (e) {
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                //根据key.direction的值,判断物体移动方向
                switch (key.direction) {
                    case "up":
                        ball.y -= 3;
                        break;
                    case "down":
                        ball.y += 3;
                        break;
                    case "left":
                        ball.x -= 3;
                        break;
                    case "right":
                        ball.x += 3;
                        break;
                }
                checkBorder();
                ball.fill(cxt);
            }, false);

            //定义边界检测函数
            function checkBorder() {
                //当小球碰到上边界时
                if (ball.y < ball.radius) {
                    ball.y = ball.radius;
                    //当小球碰到下边界时
                } else if (ball.y > cnv.height - ball.radius) {
                    ball.y = cnv.height - ball.radius;
                }
                //当小球碰到左边界时
                if (ball.x < ball.radius) {
                    ball.x = ball.radius;
                    //当小球碰到右边界时
                } else if (ball.x > cnv.width - ball.radius) {
                    ball.x = cnv.width - ball.radius;
                }
            }
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>

15.3 边界环绕

物体从一个边界消失后,从对面边界重新出现,形成环绕效果。

if(ball.x < -ball.radius) {
	//小球完全超出左边界
} else if(ball.x > cnv.width+ball.radius) {
	//小球完全超出右边界
} 


if(ball.y < -ball.radius) {
	//小球完全超出上边界
} else if(ball.y > cnv.height+ball.radius) {
	//小球完全超出下边界
} 
  • 边界环绕
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            //初始化数据
            var ball = new Ball(0, cnv.height/2);
			var ball2 = new Ball(cnv.width, cnv.height/2);
			
            var vx = 0.2;

            (function frame() {
                window.requestAnimationFrame(frame);
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                ball.x += vx;
                ball2.x += vx;
                //当小球“完全超出”右边界时
                if(ball.x > cnv.width + ball.radius) {
					ball.x = ball2.x - cnv.width;
                } else if(ball2.x > cnv.width + ball2.radius) {
					ball2.x = ball.x - cnv.width;
                }

                ball.fill(cxt);
                ball2.fill(cxt);
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>
  • 键盘控制
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            var ball = new Ball(cnv.width/2, cnv.height/2);
            ball.fill(cxt);
			
            var key = tools.getKey();
            //添加键盘事件
            window.addEventListener("keydown", function (e) {
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                //根据key.direction的值,判断小球移动方向
                switch (key.direction) {
                    case "up":
                        ball.y -= 3;
                        break;
                    case "down":
                        ball.y += 3;
                        break;
                    case "left":
                        ball.x -= 3;
                        break;
                    case "right":
                        ball.x += 3;
                        break;
                }
                if (ball.y < -ball.radius) {//检测上边界
                    ball.y = cnv.height + ball.radius;
                } else if (ball.y > cnv.height + ball.radius) {//检测下边界
                    ball.y = -ball.radius;
                }
                if (ball.x < -ball.radius) {//检测左边界
                    ball.x = cnv.width + ball.radius;
                } else if (ball.x > cnv.width + ball.radius) {//检测右边界
                    ball.x = -ball.radius;
                }
                ball.fill(cxt);
				
            }, false);
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>
  • 键盘控制2
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            var ball = new Ball(cnv.width/2, cnv.height/2);
            ball.fill(cxt);
			
            var key = tools.getKey();
            //添加键盘事件
            window.addEventListener("keydown", function (e) {
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                //根据key.direction的值,判断小球移动方向
                switch (key.direction) {
                    case "up":
                        ball.y -= 3;
                        break;
                    case "down":
                        ball.y += 3;
                        break;
                    case "left":
                        ball.x -= 3;
                        break;
                    case "right":
                        ball.x += 3;
                        break;
                }
				
				if (ball.y < -ball.radius) {//检测上边界
					ball.y = cnv.height - ball.radius;
				} else if (ball.y > cnv.height + ball.radius) {//检测下边界
					ball.y = -ball.radius;
				}
				if (ball.x < -ball.radius) {//检测左边界
					ball.x = cnv.width - ball.radius;
				} else if (ball.x > cnv.width + ball.radius) {//检测右边界
					ball.x = -ball.radius;
				}
                ball.fill(cxt);
				
				var up_flag = ball.y>=-ball.radius && ball.y<=ball.radius;
				var down_flag = ball.y>=cnv.height - ball.radius && ball.y<=cnv.height + ball.radius;
				var left_flag = ball.x>=-ball.radius && ball.x<=ball.radius;
				var right_flag = ball.x>=cnv.width - ball.radius && ball.x<=cnv.width + ball.radius;
				if(up_flag || down_flag || left_flag || right_flag) {
					var ball2 = new Ball(ball.x, ball.y);
					if(up_flag) {
						ball2.y += cnv.height;
					} else if(down_flag) {
						ball2.y -= cnv.height;
					}
					if(left_flag) {
						ball2.x += cnv.width;
					} else if(right_flag) {
						ball2.x -= cnv.width;
					}
					ball2.fill(cxt);
				} 
				
				
            }, false);
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>

15.4 边界生成

物体完全超出边界后,在最开始位置重新生成,可以创建喷泉效果及各种粒子特效。

if (ball.x < -ball.radius ||
	ball.x > cnv.width + ball.radius ||
	ball.y < -ball.radius ||
	ball.y > cnv.height + ball.radius) {

}
  • 获取随机颜色
//获取随机颜色值
window.tools.getRandomColor = function() {
    return '#' +
    (function (color) {
        return (color += '0123456789abcdef'[Math.floor(Math.random() * 16)])
        && (color.length == 6) ? color : arguments.callee(color);
    })('');
}
  • 随机小球
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            //定义一个用来存放小球的数组balls
            var balls = [];
            //n表示小球数量
            var n = 50;

            //生成n个小球,其中小球的color、vx、vy都是随机值
            for (var i = 0; i < n; i++) {
                //球心坐标为Canvas中心,color为随机颜色值
                var ball = new Ball(cnv.width / 2, cnv.height / 2, 5, tools.getRandomColor());
                //ball.vx和ball.vy取值都是:-1~1之间的任意数
                ball.vx = Math.random() * 2 - 1;
                ball.vy = Math.random() * 2 - 1;
                //添加到数组balls中
                balls.push(ball);
            }

            (function frame() {
                window.requestAnimationFrame(frame);
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                //使用forEach()函数遍历数组balls
                balls.forEach(function (ball) {
                    //边界检测,使得小球完全移出画布后会在中心位置重新生成
                    if (ball.x < -ball.radius ||
                      ball.x > cnv.width + ball.radius ||
                      ball.y < -ball.radius ||
                      ball.y > cnv.height + ball.radius) {
                        ball.x = cnv.width / 2;
                        ball.y = cnv.height / 2;
                        ball.vx = Math.random() * 2 - 1;
                        ball.vy = Math.random() * 2 - 1;
                    }
                    ball.fill(cxt);

                    ball.x += ball.vx;
                    ball.y += ball.vy;
                })
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>
  • 重力影响
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            //balls表示用来存放小球的数组
            var balls = [];
            //n表示小球数量
            var n = 50;
            var gravity = 0.15;

            //生成n个小球,其中小球的color、vx、vy取的都是随机值
            for (var i = 0; i < n; i++) {
                var ball = new Ball(cnv.width / 2, cnv.height / 2, 5, tools.getRandomColor());
                //随机生成-3~3之间的数
                ball.vx = (Math.random() * 2 - 1) * 3;
                ball.vy = (Math.random() * 2 - 1) * 3;
                balls.push(ball);
            }

            (function frame() {
                window.requestAnimationFrame(frame);
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                //使用forEach()函数遍历数组balls
                balls.forEach(function (ball) {
                    //边界检测,使得小球完全移出画布后会在中心位置重新生成
                    if (ball.x < -ball.radius ||
                      ball.x > cnv.width + ball.radius ||
                      ball.y < -ball.radius ||
                      ball.y > cnv.height + ball.radius) {
                        ball.x = cnv.width / 2;
                        ball.y = cnv.height / 2;
                        ball.vx = (Math.random() * 2 - 1) * 3;
                        ball.vy = (Math.random() * 2 - 1) * 3;
                    }
                    ball.fill(cxt);

                    ball.x += ball.vx;
                    ball.y += ball.vy;
                    ball.vy += gravity;
                })
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>
  • 散弹效果
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            //balls表示用来存放小球的数组
            var balls = [];
            //n表示小球数量
            var n = 50;

            //生成n个小球,其中小球的color、vx、vy取的都是随机值
            for (var i = 0; i < n; i++) {
                var ball = new Ball(cnv.width / 2, cnv.height / 2, 5, tools.getRandomColor());
                ball.vx = 3;
                ball.vy = (Math.random() * 2 - 1) * 3;
                balls.push(ball);
            }

            (function frame() {
                window.requestAnimationFrame(frame);
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                //使用forEach()函数遍历数组balls
                balls.forEach(function (ball) {
                    //当小球移出画布时,会在中心位置重新生成
                    if (ball.x < -ball.radius ||
                      ball.x > cnv.width + ball.radius ||
                      ball.y < -ball.radius ||
                      ball.y > cnv.height + ball.radius) {
                        ball.x = cnv.width / 2;
                        ball.y = cnv.height / 2;
                        //随机产生3~4之间的任意数
                        ball.vx = Math.random() + 3;
                        //随机产生-3~3之间的任意数
                        ball.vy = (Math.random() * 2 - 1) * 3;
                    }
                    ball.fill(cxt);

                    ball.x += ball.vx;
                    ball.y += ball.vy;
                })
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>

15.5 边界反弹

物体碰到边界之后会反弹回来。

if (ball.x < ball.radius) {//碰到左边界
    ball.x = ball.radius;
    vx = -vx;   
} else if (ball.x > canvas.width - ball.radius) {//碰到右边界
    ball.x = canvas.width - ball.radius;
    vx = -vx;
}

if (ball.y < ball.radius) {//碰到上边界
    ball.y = ball.radius;
    vy = -vy;
} else if (ball.y > canvas.height - ball.radius) {//碰到下边界
    ball.y = canvas.height - ball.radius;
    vy = -vy;
}
  • 单球反弹
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            var ball = new Ball(cnv.width / 2, cnv.height / 2);
            //随机产生-3~3之间的任意数,作为vx、vy的值
            var vx = (Math.random() * 2 - 1) * 3;
            var vy = (Math.random() * 2 - 1) * 3;

            (function drawFrame() {
                window.requestAnimationFrame(drawFrame);
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                ball.x += vx;
                ball.y += vy;

                //边界检测
                //碰到左边界
                if (ball.x < ball.radius) {
                    ball.x = ball.radius;
                    vx = -vx;
                    //碰到右边界
                } else if (ball.x > canvas.width - ball.radius) {
                    ball.x = canvas.width - ball.radius;
                    vx = -vx;
                }
                //碰到上边界
                if (ball.y < ball.radius) {
                    ball.y = ball.radius;
                    vy = -vy;
                    //碰到下边界
                } else if (ball.y > canvas.height - ball.radius) {
                    ball.y = canvas.height - ball.radius;
                    vy = -vy;
                }

                ball.fill(cxt);
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>
  • 多球反弹
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <meta charset="utf-8" />
    <script src="js/tools.js"></script>
    <script src="js/ball.js"></script>
    <script type="text/javascript">
        function $$(id) {
            return document.getElementById(id);
        }
        window.onload = function () {
            var cnv = $$("canvas");
            var cxt = cnv.getContext("2d");

            //定义一个用来存放小球的数组balls
            var balls = [];
            //n表示小球数量
            var n = 10;

            //生成n个小球,其中小球的color、vx、vy都是随机的
            for (var i = 0; i < n; i++) {
                var ball = new Ball(cnv.width / 2, cnv.height / 2, 8, tools.getRandomColor());
                //随机产生-3~3之间的任意数,作为vx、vy的值
                ball.vx = (Math.random() * 2 - 1) * 3;
                ball.vy = (Math.random() * 2 - 1) * 3;
                //添加到数组balls中
                balls.push(ball);
            }

            (function frame() {
                window.requestAnimationFrame(frame);
                cxt.clearRect(0, 0, cnv.width, cnv.height);

                //使用forEach()函数遍历数组balls
                balls.forEach(function (ball) {
                    ball.x += ball.vx;
                    ball.y += ball.vy;

                    //边界检测
                    //碰到左边界
                    if (ball.x < ball.radius) {
                        ball.x = ball.radius;
                        ball.vx = -ball.vx;
                        //碰到右边界
                    } else if (ball.x > canvas.width - ball.radius) {
                        ball.x = canvas.width - ball.radius;
                        ball.vx = -ball.vx;
                    }
                    //碰到上边界
                    if (ball.y < ball.radius) {
                        ball.y = ball.radius;
                        ball.vy = -ball.vy;
                        //碰到下边界
                    } else if (ball.y > canvas.height - ball.radius) {
                        ball.y = canvas.height - ball.radius;
                        ball.vy = -ball.vy;
                    }

                    ball.fill(cxt);
                })
            })();
        }
    </script>
</head>
<body>
    <canvas id="canvas" width="200" height="150" style="border:1px solid silver;"></canvas>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值