Implementation of the getIntersection HTML5 / kineticJS function

I study kineticjs through the tutorials presented at http://www.html5canvastutorials.com , everything is good and easy to understand, but I have a problem understanding the getIntersection function that I want to use among different objects, and dragging to detect collision / overlapping objects collision / overlapping .

As I understand the example, the getIntersection function expects a position and checks whether it intersects with any other object or not.

Although I received them, but with some problems.

I can not do it.

Below is the code I've tried so far.

 <script> var stage = new Kinetic.Stage({ container: 'container', width: 1000, height: 500, opacity: 0.5 }); var layer = new Kinetic.Layer(); var previous_position; var new_position; var collision = false; var colors = ['red', 'orange', 'yellow', 'green', 'blue', 'purple']; var yellowBox = null; for(var n = 0; n < 6; n++) { // anonymous function to induce scope (function() { var i = n; if(n < 3){ y = 50; x = i * 100 + i * 10; }else{ y = 150; x = (i - 3) * 100 + (i - 3) * 10 ; if(n == 3){ x = 0; } } var box = new Kinetic.Rect({ x: x, y: y, width: 100, height: 50, fill: colors[i], stroke: 'black', strokeWidth: 4, draggable: true, name: colors[i] }); box.on('dragstart', function() { previous_position = { x: this.attrs.x, y: this.attrs.y }; }); box.on('dragend', function() { if(collision){ //this.setPosition(previous_position); layer.draw(); collision = false; }else{ //this.setPosition(new_position); layer.draw(); } }); box.on("dragmove", function(evt) { console.log(layer.children.length); if(layer.children.length > 1){ console.log('dragging'); new_position = {x: this.attrs.x, y: this.attrs.y}; // var posBL = {x: this.attrs.x, // y: this.attrs.height + this.attrs.y}; // var posTR = {x: this.attrs.x + this.attrs.width, // y: this.attrs.y}; var posBR = {x: this.attrs.x + this.attrs.width, y: this.attrs.y + this.attrs.height }; var collisionTL = this.getStage().getIntersections(new_position); // var collisionBL = this.getStage().getIntersections(posBL); // var collisionTR = this.getStage().getIntersections(posTR); // var collisionBR = this.getStage().getIntersections(posBR); console.log(collisionTL); console.log(collisionTL.shapes); // if(collisionTL.length > 1 || collisionBL.length > 0 || collisionTR.length > 0 || collisionBR.length > 0){ if(collisionTL.length > 1){ console.log(collisionTL.shapes); collision = true; }else{ //if(collisionBR.length > 0){ collision = true; } // for(i=0; i < collision.length; i++){ // // console.log(collision[i]._id); // } } }); if(colors[i] === 'yellow') { yellowBox = box; } layer.add(box); })(); } stage.add(layer); </script> 

in the dragmove event that you see, I see the four angular positions of the drag window {comment right now}, and with that I was able to detect overlap / collision, but it has 2 problems:

1. very slow, with only three objects in my test

2. if the corner points do not intersect, it did not work in a collision (for this, the box may be larger so that it can completely cover the other)

I would greatly appreciate if anyone can help me with this ...

[A] Any dragging of an object, if by any middle one, overlaps any other object, I want it to show a collision.

[B] If possible, get getIntersection to work with a specific group of layers, depending on what is possible [C] any other workaround next to kineticjs to perform the above task

Hello

+4
source share
1 answer

Well, the KineticJS developer is working on improving the .getIntersections () function ... or at least he said it is. But until the function is improved, you must create your own collision detection function. Assuming your objects are rectangles or can be split into several points, you should go something like this:

Create a function that determines if a point is in shape (if the angle of the rectangle is inside another rectangle):

  function checkCollide(pointX, pointY, objectx, objecty, objectw, objecth) { // pointX, pointY belong to one rectangle, while the object variables belong to another rectangle var oTop = objecty; var oLeft = objectx; var oRight = objectx+objectw; var oBottom = objecty+objecth; if(pointX > oLeft && pointX < oRight){ if(pointY > oTop && pointY < oBottom ){ return 1; } } else return 0; }; 

then you can make a big loop that iterates through all the objects in the layer to check for a collision, for example:

  var children = layer.getChildren(); for( var i=0; i<children.length; i++){ // for each single shape for( var j=0; j<children.length; j++){ //check each other shape if(i != j){ //skip if shape is the same if(checkCollide(children[i].getX(), children[i].getY(), children[j].getX(), children[j].getY(), children[j].getWidth(), children[j].getHeight())) alert('top left corner collided'); } } } 

the checkCollide function that I provided only checks for a collision in the upper left corner of each figure, so you need to change the function to check all the corners, it's not a long rewrite, and there are many tutorials even here in stackoverflow that deal with collision detection of bounding rectangles

This may seem like a very heavy function, but surprisingly it is still faster than .getIntersections (). In addition, you must add additional if statements so that the function does not perform all checks all the time.

I created the game myself and used .intersects () and slowed it down a lot. I switched to this β€œsimpler” collision detection, and now my game runs about 60 feet. http://cs.neiu.edu/~tsam/physics/index.phtml (test / test) if you want to check it. You can look at the source of the page to find out how I structured collision detection to be more efficient (for example, in the checkIntersectsGoal () function.

+5
source

All Articles