首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >拖拽碰撞

拖拽碰撞
EN

Stack Overflow用户
提问于 2013-03-22 13:40:45
回答 1查看 2.5K关注 0票数 0

我对CANVAS和Kineticjs都是新手,但我觉得我尝试的东西应该比我想要的要容易得多。基本上,这就是我到目前为止所得到的:

我尝试使用的代码来自kineticjs Stop drag to a shape when overlaps with another解决方案,但无法使其正常工作。

请查看实时jsfiddle code

代码语言:javascript
复制
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是不是实现这一点的最简单方法?

任何想法,提示或帮助,我将非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-22 14:57:53

是的,因为KineticJS没有碰撞测试,所以你必须自己做。

下面是任意两个kineticJS矩形之间的碰撞测试:

代码语言:javascript
复制
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());
}

下面是你如何调用盒子和障碍物之间的碰撞测试:

代码语言:javascript
复制
if( theyAreColliding(box,obstacle){
      // obstacle is blocking box
      alert("You are being blocked!");
}

下面是如何调用长方体和目标之间的碰撞测试:

代码语言:javascript
复制
if( theyAreColliding(box,target){
      // box touched the goal
      alert("Goal!");
}

要阻止长方体拖动通过障碍物,必须为长方体提供一个自定义拖动函数,如下所示:

代码语言:javascript
复制
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”处理程序中进行测试来测试用户是否有目标,如下所示:

代码语言:javascript
复制
  box.on('dragmove', function() {
    if (theyAreColliding(box, target)) {
        // box touched the goal
        alert("Goal!");
    }      
  });

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

代码语言:javascript
复制
<!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>
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15563481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档