以前一直以为玄之又玄的碰撞检测算法,其实也不过是一些加减法。看来还是写的太少,大多时候只是停留在望而止步的层次。
矩形的碰撞检测原理就是两个矩形的x值+宽度和y值+高度的各种比较。
function(c1,c2{ return !{ b1.x + b1.w < b2.x || b1.y + b1.h < b2.y || b2.x + b2.w < b1.x || b2.y + b2.h < b1.y }
意思就是矩形1的x加上矩形1的宽度是否小于矩形2的x,这样就能检测到当矩形1在矩形2的左边的时候,两个矩形在水平方向上是否有重叠;垂直方向同理,把x改为y,宽度改为高度即可。
碰撞检测的原理搞清楚了之后其他的就是小意思了,利用动画帧即可做出方块下落的动画。
完整代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>碰撞检测</title> <style type="text/css"> canvas{ border: 1px solid #ccc; } </style> </head> <body> <canvas id="cav" width="300" height="300"></canvas> <script> /*通过调整方块的y轴位置而不断下落,如果到了画布的底部或者碰撞到了其他方块则停止下落,这是矩形的碰撞检测*/ var cav = document.getElementById("cav"), ctx = cav.getContext('2d'); var rects = [],//把方块存储起来 speed = 2;//下落速度 //方块的初始化 function rectInit(x, y, width, height) { this.x = x; this.y = y; this.w = width; this.h = height; } //创建方块 function createRect() { var x = cav.width * Math.random(), y = 0; var rect = new rectInit(x, y, 30, 30); rects.push(rect); return rect; } //一开始先创建一个方块 var oRect = new rectInit(cav.width / 2, 0, 30, 30); rects.push(oRect); //方块下落动画 function animate() { ctx.clearRect(0, 0, cav.width, cav.height); //如果没有到底部 if(oRect.y < cav.height-oRect.h){ oRect.y += speed; } else{//到了底部后停止下落 oRect.y = cav.height-oRect.h; oRect = createRect();//再度创建一个方块 } ctx.fillStyle = '#f00'; //循环数组里存储的方块 rects.forEach(function(r,i){ if(oRect !== r && collision(oRect,r)){ // console.log('碰撞成功'); oRect.y = r.y - oRect.h; oRect = createRect(); } ctx.fillRect(r.x,r.y,r.w,r.h); }); requestAnimationFrame(animate); } animate(); //矩形的碰撞检测 function collision(c1, c2) { return !(c1.x + c1.w < c2.x || c1.y + c1.h < c2.y || c2.x + c2.w < c1.x || c2.y + c2.h < c1.y ); } </script> </body> </html>