2013-03-22 96 views
0

我对CANVAS和Kineticjs都很新,但是我觉得我正在尝试的应该会容易得多,然后我才能做到这一点。基本上这是我迄今为止:拖动碰撞

我试图使用的代码是从kineticjs Stop drag to a shape when overlaps with another解决方案,但无法使其工作。

请检查现场的jsfiddle code

var isRectCollide = function(target, box) { 
    if (target.x - target.width >= box.x + box.width && 
    target.y - target.height >= box.y + box.height && 
    target.x + target.width <= box.x + box.width && 
    target.x + target.height <= box.y - box.height) 
    return false; 
    else 
    return true; 
} 

这样做的想法是粉红色的方形为可拖动而是由橙色盒子,一旦周围的橙色框和粉红色的盒子拖封锁“触动”了应该会出现蓝框并弹出。

我不确定是否使用kineticjs是最简单的方法来实现这个呢?

任何想法,提示或帮助,我将不胜感激。

回答

5

是的,由于KineticJS没有碰撞测试,您必须自己做。

这是任何2个kineticJS矩形之间的碰撞测试:

function theyAreColliding(rect1, rect2) { 
    return !(rect2.getX() > rect1.getX()+rect1.getWidth() || 
      rect2.getX()+rect2.getWidth() < rect1.getX() || 
      rect2.getY() > rect1.getY()+rect1.getHeight() || 
      rect2.getY()+rect2.getHeight() < rect1.getY()); 
} 

这里是你将如何调用框和障碍物之间的碰撞试验:

if(theyAreColliding(box,obstacle){ 
     // obstacle is blocking box 
     alert("You are being blocked!"); 
} 

这里是你如何将调用框和目标之间的碰撞测试:

if(theyAreColliding(box,target){ 
     // box touched the goal 
     alert("Goal!"); 
} 

要停止从右通过障碍拖着箱子,你必须给框自定义拖动功能是这样的:

dragBoundFunc: function(pos){ 
    if(theyAreColliding(box,obstacle){ 
     // box is touching obstacle 
     // don't let box move down 
     return({ x:pos.x, y:obstacle.getY()-1 }); 
    } else{ 
     // box is not touching obstacle 
     // let it move ahead 
     return({ x:pos.x, y:pos.y }); 
    } 
} 

你可以看到这是如何在工作中演示:http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-bounds-tutorial-with-kineticjs/

[编辑:指定每个代码去]

我把碎片放在一起成为一个工作片段下面。我确实发现了一件不幸的事情。用户可以通过拖动粉红色盒子足够快的速度穿过障碍物 - KineticJS无法快速反应以阻止非常快的拖动。

此外 - 哎呀我。我在上面的theyAreColliding函数中更正了一些缺少的括号。

dragBoundFunc作为框构造函数的附加内容(请参阅下面的代码)。

如果用户通过在框中的“dragmove”处理程序测试,这样有一个目标,你可以测试:

box.on('dragmove', function() { 
    if (theyAreColliding(box, target)) { 
     // box touched the goal 
     alert("Goal!"); 
    }  
    }); 

这里是代码和一个小提琴:http://jsfiddle.net/uCAys/

<!DOCTYPE HTML> 
<html> 
    <head> 
    <style> 
body { 
    margin: 0px; 
    padding: 20px; 
} 
canvas { 
    border: 1px solid #777; 
} 
    </style> 
    </head> 
    <body> 
    <div id="container"></div> 
    <script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.1-beta2.js"></script> 
    <script> 
     var stage = new Kinetic.Stage({ 
      container: 'container', 
      width: 300, 
      height: 300 
     }); 
     var layer = new Kinetic.Layer(); 

     //Dragable Pink box 
     var box = new Kinetic.Rect({ 
      x: 100, 
      y: 50, 
      width: 100, 
      height: 50, 
      fill: 'pink', 
      stroke: 'black', 
      strokeWidth: 2, 
      draggable: true, 
      // this causes box to be stopped if contacting obstacle 
      dragBoundFunc: function(pos){ 
       if(theyAreColliding(box,obstacle)){ 
        // box is touching obstacle 
        // don't let box move down 
        return({ 
         x: pos.x, 
         y: Math.min(obstacle.getY()-box.getHeight()-1, pos.y) 
        }); 
       } else{ 
        // box is not touching obstacle 
        // let it move ahead 
        return({ x:pos.x, y:pos.y }); 
       } 
      } 
     }); 

     box.on('dragmove', function() { 
     if (theyAreColliding(box, target)) { 
      // box touched the goal 
      box.setX(100); 
      box.setY(50); 
      alert("Goal!"); 
     }  
     }); 

     // End goal blue box 
     var target = new Kinetic.Rect({ 
      x: 100, 
      y: 200, 
      width: 100, 
      height: 50, 
      fill: 'blue', 
      stroke: 'black', 
      strokeWidth: 2 
     }); 

     // Obstacle/blocker orange box 
     var obstacle = new Kinetic.Rect({ 
      x: 125, 
      y: 145, 
      width: 50, 
      height: 30, 
      fill: 'orange', 
      stroke: 'black', 
      strokeWidth: 2 
     }); 

     function theyAreColliding(rect1, rect2) { 
      return !(rect2.getX() > rect1.getX() + rect1.getWidth() || // 
        rect2.getX() + rect2.getWidth() < rect1.getX() || // 
        rect2.getY() > rect1.getY() + rect1.getHeight() || // 
        rect2.getY() + rect2.getHeight() < rect1.getY()); // 
     } 

     layer.add(box); 
     layer.add(obstacle); 
     layer.add(target); 
     stage.add(layer); 

    </script> 
    </body> 
</html> 
+0

伟大解释以及在dragBoundFunc – SoluableNonagon 2013-03-22 13:58:14

+0

中的实现谢谢,惊人的解释,尽管我正在努力让if语句在正确的时间运行。目前他们只是自动运行刷新,然后从来没有?他们需要成为文档准备好声明还是我错过了什么?这里是我的意思是一个jsfiddle链接:[链接](http://jsfiddle.net/qHkYR/4/) 编辑:或者是因为它测试层而不是广场?因此他们总是感动? – user831496 2013-03-22 15:30:56