HTML5 / kineticJS getIntersection函数的实现 [英] HTML5 / kineticJS getIntersection function implementation

查看:152
本文介绍了HTML5 / kineticJS getIntersection函数的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过在 http:// www提供的教程学习 kineticjs .html5canvastutorials.com ,事情很好,很容易理解,但是,在理解 getIntersection 函数时,我想要在不同对象中使用拖动以检测碰撞/重叠对象。



目前为止因为我已经理解了这个例子,所以 getIntersection 函数需要一个位置并检查它是否与任何其他对象相交。



虽然我得到了他们,但有一些问题。



我无法完成此操作。



下面是我已经试过的代码。

 < 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 ++){
//引发作用域的匿名函数
(function(){
var i = n;
if 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();
}
} );

ox.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 ();
var collisionTL = this.getStage $ b // 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>

您可以看到 dragmove 事件我得到了拖动框的四个角位{现在评论},并且我能够检测到重叠/碰撞,但它有两个问题:

1。在我的测试中只有3个物体非常慢



2。如果没有角点相交它没有' t发射碰撞的东西{因为这个盒子可以更大,所以它可以完全覆盖另一个盒子}



如果有人能帮我完成这件事,我会高度赞赏。 。



[A] 任何对象的拖拽都会重叠其他对象,我希望它显示碰撞。
$ b

[B] 如果可能,使 getIntersection 在特定的图层组上工作
[C]除 kineticJS 之外的任何其他解决方法来完成上述任务


问候

解决方案

好的,KineticJS的开发人员正在努力改进.getIntersections()函数......或者至少他说他是。但是在功能得到改进之前,您必须制作自己的碰撞检测功能。假设你的对象是矩形或可以分解成一系列点,你应该像这样:



创建一个函数来确定一个点是否在一个形状中(如果矩形的角落在另一个矩形内)如下所示:

 函数checkCollide(pointX,pointY,objectx,objecty, objectw,objecth){// pointX,pointY属于一个矩形,而对象变量属于另一个矩形
var oTop = objecty;
var oLeft = objectx;
var oRight = objectx + objectw;
var oBottom = objecty + objecth; (pointX> oLeft&& pointX< oRight){
if(pointY> otop&& pointY< oBottom){
return 1(

) ;
}
}
其他
返回0;
};

然后你可以做一个大循环,遍历层中的所有对象来检查碰撞,就像这样:

  var children = layer.getChildren(); 
for(var i = 0; i< children.length; i ++){//对于每个单一形状
for(var j = 0; j< children.length; j ++){//检查每个其他形状
if(i!= j){//如果形状相同则跳过
if(checkCollide(children [i] .getX(),children [i] .getY(),children [ j).getX(),children [j] .getY(),children [j] .getWidth(),children [j] .getHeight()))
alert('left left corner collided');



code
$ b我只提供checkCollide函数检查每个形状左上角的碰撞,所以你必须修改函数来检查所有的角落,这不是一个长时间的重写,甚至在这里有很多教程,在处理'边界矩形碰撞检测' p>

这可能看起来像是一个非常繁重的函数,但令人惊讶的是它仍然比.getIntersections()更快。此外,您应该添加额外的if语句,以便该函数不会一直运行所有检查。



我自己创建了一个游戏,并使用.intersects ()并且有很多放缓。我转向了这种'更简单'的碰撞检测,现在我的游戏运行速度大约为60FPS。 http://cs.neiu.edu/~tsam/physics/index.phtml(测试/测试),如果你想检查出来。您可以查看页面源代码,以了解如何将碰撞检测结构化为更高效(例如,在checkIntersectsGoal()函数中。


I am learning kineticjs through tutorials provided at http://www.html5canvastutorials.com, things are good and easy to understand but, I am having issue in understanding the getIntersection function that i want to use among different objects while dragging to detect collision / overlapping objects.

As far as I have understood the example the getIntersection function expects a position and checks if its intersecting with any other object or not..

Though I got them but with some issues.

I am unable to accomplish this..

Below is the code that I have tried up to now..

<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 you guyz can see I get the four corner positions of the dragging box {commented right now} and with this I was able to detect the overlap / collision but it has 2 issues:

1. very slow with only 3 objects in my test

2. if non of the corner points intersect it didn't fire the collision stuff {for this one box can be bigger so it can cover the other entirely}

I would highly apreciate if anyone can please help me accomplish this stuff..

[A] Any object dragging if by any mean overlaps any other object I want it to show collision.

[B] If possible make getIntersection to work on a particular layer group whichever is possible [C] any other workaround beside kineticJS to accomplish the above task

Regards

解决方案

Ok, the developer of KineticJS is working on improving the .getIntersections() function... or at least he said he is. But until the function is improved you have to make your own collision detection function. Assuming that your objects are rectangles or can be broken into a series of points you should go with something like this:

Create a function which determines if a point is in a shape (if the corner of a rectangle is inside another rectangle) like so:

 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 do a big loop which iterates through all objects in a layer to check collision, like so:

 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 I provided only checks the collision for the top left corner on each shape, so you have to modify the function to check all corners, it's not a long rewrite, and there are plenty tutorials even here on stackoverflow which deal with 'bounding rectangles collision detection'

This may seem like it is a very heavy function, but surprisingly it is still faster than .getIntersections(). Also, you should throw in extra if statements so that the function doesn't run through all the checks all the time.

I created a game myself and was using .intersects() and was having a lot of slow down. I switched over to this type of 'simpler' collision detection and now my game runs around 60FPS. http://cs.neiu.edu/~tsam/physics/index.phtml (test/test) if you want to check it out. You can view page source to see how I structured the collision detection to be more efficient (such as in checkIntersectsGoal() function.

这篇关于HTML5 / kineticJS getIntersection函数的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆