之前我们学习js的时候都写过碰撞反弹,canvas里的碰撞反弹也可以用同样的条件判断,现在我们回顾一下之前的判断
外接矩形碰撞
我们根据上面的判断来写一下效果
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
运动方块的构造函数
function Rect(x,y,w,h,color,speedx,speedy){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.color = color;
this.speedx = speedx;
this.speedy = speedy;
}
Rect.prototype.draw=function(){
context.beginPath();
context.fillStyle = this.color;
context.fillRect(this.x,this.y,this.w,this.h);
}
Rect.prototype.move=function(){
this.x +=this.speedx;
this.y +=this.speedy;
//碰壁检测
if(this.x<0||this.x>canvas.width-this.w){
this.speedx *=-1;
}
if(this.y<0||this.y>canvas.height-this.h){
this.speedy *=-1;
}
}
实例化方块,运动的函数
方式一:通过判断方块位置
var rect1 = new Rect(0,0,50,50,"green",1,3)
var rect2 = new Rect(450,0,50,50,"red",2,4)
function act1(){
context.clearRect(0,0,canvas.width,canvas.height);
rect1.draw();
rect1.move();
rect2.draw();
rect2.move();
//碰撞检测
if((rect1.x+rect1.w)>rect2.x&&rect1.x<(rect2.x+rect2.w) && (rect1.y+rect1.h)>rect2.y&&rect1.y<(rect2.y+rect2.h)){
console.log(11111111111)
rect1.speedx *=-1;
rect1.speedy *=-1;
rect2.speedx *=-1;
rect2.speedy *=-1;
}
window.requestAnimationFrame(act1);
}
act1()
通过判断方块是否重叠
var rect1 = new Rect(0,0,50,50,"green",1,3)
var rect2 = new Rect(450,0,50,50,"red",2,4)
function act1(){
context.clearRect(0,0,canvas.width,canvas.height);
rect1.draw();
rect1.move();
rect2.draw();
rect2.move();
//像素碰撞
if(isCrash(rect1,rect2)){
console.log(22222222)
rect1.speedx *=-1;
rect1.speedy *=-1;
rect2.speedx *=-1;
rect2.speedy *=-1;
};
window.requestAnimationFrame(act1);
}
act1()
function isCrash(rect1,rect2){
var min1x = rect1.x;
var max1x = rect1.x+rect1.w;
var min2x = rect2.x;
var max2x = rect2.x+rect2.w;
var min1y = rect1.y;
var max1y = rect1.y+rect1.h;
var min2y = rect2.y;
var max2y = rect2.y+rect2.h;
//假设碰撞出新的方块
var nminx = Math.max(min1x,min2x);
var nmaxx = Math.min(max1x,max2x);
var nminy = Math.max(min1y,min2y);
var nmaxy = Math.min(max1y,max2y);
if(nmaxx >nminx && nmaxy>nminy){
return true;
}
}
外接圆碰撞
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
function Ball(x,y,r,color,speedx,speedy){
this.x = x;
this.y = y;
this.r = r;
this.color = color;
this.speedx = speedx;
this.speedy = speedy;
}
Ball.prototype.draw=function(){
context.beginPath();
context.fillStyle = this.color;
context.arc(this.x,this.y,this.r,0,Math.PI*2);
context.fill();
}
Ball.prototype.move=function(){
this.x +=this.speedx;
this.y +=this.speedy;
//碰壁检测
if(this.x<this.r||this.x>canvas.width-this.r){
this.speedx *=-1;
}
if(this.y<this.r||this.y>canvas.height-this.r){
this.speedy *=-1;
}
}
var Ball1 = new Ball(50,50,25,"green",1,3)
var Ball2 = new Ball(450,50,20,"red",2,4)
function act1(){
context.clearRect(0,0,canvas.width,canvas.height);
Ball1.draw();
Ball1.move();
Ball2.draw();
Ball2.move();
//碰撞检测
if(Math.pow(Ball1.x-Ball2.x,2)+Math.pow(Ball1.y-Ball2.y,2)<Math.pow(Ball1.r+Ball2.r,2)){
Ball1.speedx *=-1;
Ball1.speedy *=-1;
Ball2.speedx *=-1;
Ball2.speedy *=-1;
}
window.requestAnimationFrame(act1);
}
act1()
最后显示:
像素碰撞
还存在一种碰撞叫做像素的碰撞,虽然图像所在矩形碰撞,但是不代表图像之间发生碰撞;
我们需要检测图像所在矩形是否相较,同时检测两图在相交矩形内的像素,存在一点在两个图上的 alpha 值不为 0,则发生碰撞。
我们利用上面矩形碰撞的方式二来写像素碰撞,方式一我们不能得到重叠的矩形
var canvas = document.getElementById("mycanvas");
var context = canvas.getContext("2d");
var img = new Image();
img.src = "Chat.png";
var play = new Image();
play.src = "Play.png";
img.onload = function(){
context.beginPath();
context.drawImage(img,100,100);
var rect1 = new Rect(100,100,img.width,img.height);
canvas.onmousedown = function(){
canvas.onmousemove = function(e){
var ev = e||window.event;
var x = ev.clientX-canvas.offsetLeft;
var y = ev.clientY-canvas.offsetTop;
context.clearRect(0,0,canvas.width,canvas.height);
context.drawImage(play,x,y)
// context.drawImage(play,x-play.width/2,y-(play.height/2))
var rect2 = new Rect(x,y,play.width,play.height);
//实例化
context.drawImage(img,100,100);
var res = isCrash(rect1,rect2)
if(res.judge){
var newRect = res.rect;
//分别遍历碰撞区域的像素点
//清除某一区域的画布
context.clearRect(0,0,canvas.width,canvas.height)
//画蓝色图
context.drawImage(img,100,100);
//获取蓝图的像素点
var imgData1 = context.getImageData(res.rect.x,res.rect.y,res.rect.w,res.rect.h);
context.clearRect(0,0,canvas.width,canvas.height)
//画绿色图
context.drawImage(play,x,y);
//获取绿色图的像素点
var imgData2 = context.getImageData(res.rect.x,res.rect.y,res.rect.w,res.rect.h);
context.drawImage(img,100,100);
for(var i=0;i<imgData1.data.length;i+=4){
if(imgData1.data[i+3]>0 && imgData2.data[i+3]>0){
console.log("像素碰撞了")
break;
}
}
};
}
}
}
canvas.onmouseup =function (){
canvas.onmousemove = null;
}
function Rect(x,y,w,h){
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
function isCrash(rect1,rect2){
var min1x = rect1.x;
var max1x = rect1.x+rect1.w;
var min2x = rect2.x;
var max2x = rect2.x+rect2.w;
var min1y = rect1.y;
var max1y = rect1.y+rect1.h;
var min2y = rect2.y;
var max2y = rect2.y+rect2.h;
//假设碰撞出新的方块
var nminx = Math.max(min1x,min2x);
var nmaxx = Math.min(max1x,max2x);
var nminy = Math.max(min1y,min2y);
var nmaxy = Math.min(max1y,max2y);
var obj = new Rect(nminx,nminy,(nmaxx-nminx),(nmaxy-nminy));
if(nmaxx >nminx && nmaxy>nminy){
return {
judge:true,
rect:obj
};
}else{
return {
judge:false
};
}
}