Reputation: 135
I have multiple layers on my stage. Each layer contains images surrounded with a blub ( see this question). Each blub is draggable.
Is it possible to detect collisions between the blubs while moving them? I don't want to have overlapping bubbles, but rather if they collide, they should melt.
Upvotes: 1
Views: 168
Reputation: 105015
You can determine if blobs are colliding.
There are at least 2 methods:
The bounding box method is faster.
The pixel-testing method is more precise, but slower are requires many more resources.
An example:
Here's how to calculate and test if 2 blob bounding boxes are colliding.
A Demo: http://jsfiddle.net/m1erickson/9tB7d/
Start with a Kinetic Blob
var blueBlob = new Kinetic.Line({
points: [73,140,340,23,500,109,300,170],
stroke: 'blue',
strokeWidth: 10,
fill: '#aaf',
tension: 0.8,
closed: true
});
That blob is made up of a set of Bezier curves.
Get the Bezier curves that make up the blob:
function kineticBlob2Beziers(blob){
var beziers=[];
var start=blob.getPoints();
var pts=blob.getTensionPoints();
var n=0;
var lastN=pts.length-2;
var sx=start[0];
var sy=start[1];
while(n<lastN){
bez={
s: {x:sx,y:sy},
c1:{x:pts[n++],y:pts[n++]},
c2:{x:pts[n++],y:pts[n++]},
e: {x:pts[n++],y:pts[n++]}
};
beziers.push(bez);
sx=pts[n-2];
sy=pts[n-1];
}
return(beziers);
}
Calculate the blobs bounding box using its Bezier curves:
function getBlobBB(beziers){
var minX=1000000;
var minY=1000000;
var maxX=-1000000;
var maxY=-1000000;
for(var i=0;i<beziers.length;i++){
var bez=beziers[i];
for(var t=0.00;t<=1.00;t+=.01){
var pt=getCubicBezierXYatT(bez.s,bez.c1,bez.c2,bez.e,t);
if(pt.x<minX){minX=pt.x;}
if(pt.x>maxX){maxX=pt.x;}
if(pt.y<minY){minY=pt.y;}
if(pt.y>maxY){maxY=pt.y;}
}
}
return({x:minX,y:minY,width:maxX-minX,height:maxY-minY});
}
function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
return({x:x,y:y});
}
// cubic helper formula at T distance
function CubicN(T, a,b,c,d) {
var t2 = T * T;
var t3 = t2 * T;
return a + (-a * 3 + T * (3 * a - a * T)) * T
+ (3 * b + T * (-6 * b + b * 3 * T)) * T
+ (c * 3 - c * 3 * T) * t2
+ d * t3;
}
Determines if 2 bounding boxes (rectangles) are colliding:
function Colliding(left1,top1,right1,bottom1,left2,top2,right2,bottom2){
return(!(
left1 > right2 ||
right1 < left2 ||
bottom1 < top2 ||
top1 >bottom2
));
}
Upvotes: 1