第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>