4

http://www.html5canvastutorials.comkineticjsで提供されているチュートリアルで学んでいます。物事はよくて理解しやすいですが、オブジェクトを検出するときにさまざまなオブジェクト間で使用したい機能を理解するのに問題があります。getIntersectiondraggingcollision / overlapping

私が例を理解している限り、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++) {
    // 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>

あなたが見ることができるイベントでdragmoveは、ドラッグボックスの4つのコーナーの位置を取得し、これでオーバーラップ/コリジョンを検出できましたが、2つの問題があります:

1.私のテストではオブジェクトが 3 つしかなく、非常に遅い

2.コーナーポイントが交差しない場合、衝突は発生しませんでした{この1つのボックスを大きくして、他のボックスを完全に覆うことができるため}

誰かが私がこのことを達成するのを手伝ってくれるなら、私は非常に感謝しています..

[A]ドラッグしているオブジェクトが他のオブジェクトとオーバーラップしている場合、衝突を表示したい。

[B]可能であれば、可能な限り特定のレイヤー グループで作業する [C]上記のタスクを達成するためgetIntersectionの他の回避策kineticJS

よろしく

4

1 に答える 1

5

わかりました、KineticJS の開発者は .getIntersections() 関数の改善に取り組んでいます... または少なくとも彼はそう言っています。ただし、機能が改善されるまでは、独自の衝突検出機能を作成する必要があります。オブジェクトが長方形であるか、一連の点に分割できると仮定すると、次のようにする必要があります。

次のように、点が形状内にあるかどうか (長方形の角が別の長方形の内側にあるかどうか) を判断する関数を作成します。

 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;
 };

次に、次のように、レイヤー内のすべてのオブジェクトを反復して衝突をチェックする大きなループを実行できます。

 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');
         }
     }
 }

私が提供した checkCollide 関数は、各シェイプの左上隅の衝突のみをチェックするため、すべてのコーナーをチェックするように関数を変更する必要があります。長い書き直しではありません。ここでも、「境界」を扱うスタックオーバーフローに関するチュートリアルがたくさんあります。長方形の衝突検出'

これは非常に重い関数のように見えるかもしれませんが、驚くことに .getIntersections() よりも高速です。また、関数が常にすべてのチェックを実行しないように、余分な if ステートメントを挿入する必要があります。

私は自分でゲームを作成し、.intersects() を使用していましたが、多くの速度が低下していました。このタイプの「より単純な」衝突検出に切り替えたところ、ゲームは約 60FPS で実行されるようになりました。http://cs.neiu.edu/~tsam/physics/index.phtml (test/test) をチェックしたい場合。ページのソースを表示して、衝突検出をより効率的に構成する方法を確認できます (checkIntersectsGoal() 関数など)。

于 2013-02-14T14:59:43.307 に答える