拖动碰撞 [英] Dragging collisions

查看:85
本文介绍了拖动碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于CANVAS和Kineticjs来说我都是很陌生的人,但是我觉得要尝试的要容易得多.基本上,这就是我到目前为止所拥有的:

I am pretty new to both CANVAS and Kineticjs but I feel what I am attemping should be much easier then I am making it out to be. Basically this is what I have so far:

我尝试使用的代码来自当与另一个解决方案重叠但无法使其正常工作时,停止将其拖动到某个形状.

The code I am attempting to use is from kineticjs Stop drag to a shape when overlaps with another solution but was unable to get it to work.

请检查实时jsfiddle 代码

Please check the live 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;
}

此想法是使粉红色正方形可拖动但被橙色框阻止,一旦在橙色框周围拖动并且粉红色框接触"蓝色框并应弹出.

The idea of this is for the pink square to be draggable but blocked by the orange box, once dragged around the orange box and the pink box 'touches' the blue box and pop up should occur.

我不确定使用dynamicjs是否是实现此目的的最简单方法?

I am not sure if using kineticjs is the simplest way to implement this though?

任何想法,技巧或帮助,我将不胜感激.

Any ideas, tips or help would me much appreciated.

推荐答案

是的,由于KineticJS没有碰撞测试,因此您必须自己进行碰撞测试.

Yes, since KineticJS doesn't have collision testing you must do your own.

这是任意2个dynamicJS矩形之间的碰撞测试:

Here is a collision test between any 2 kineticJS rectangles:

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

这就是在盒子和障碍物之间进行碰撞测试的方式:

And here is how you would call the collision test between the box and obstacle:

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

这是在盒子和目标之间进行碰撞测试的方式:

And here is how you would call the collision test between the box and the goal:

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

要阻止盒子向右拖动穿过障碍物,您必须为盒子提供一个自定义拖动功能,如下所示:

To stop the box from dragging right through the obstacle, you must give box a custom drag function like this:

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/

You can see how this works in a demo at: http://www.html5canvastutorials.com/kineticjs/html5-canvas-drag-and-drop-bounds-tutorial-with-kineticjs/

我将这些片段放到下面的工作片段中.我确实发现了一件不幸的事.用户有可能足够快地拖动粉红色框以穿过障碍物-KineticJS不能足够快地做出反应以停止非常快的拖动.

I put the pieces together into a working snippet below. I did find one unfortunate thing. It’s possible for the user to drag the pink box fast enough to go right through the obstacle—KineticJS can’t react fast enough to stop a very fast drag.

也-哎呀,我.我在上面的themAreColliding函数中更正了一些缺少的括号.

Also--oops on me. I corrected some missing parentheses in the theyAreColliding function above.

dragBoundFunc是box构造函数的补充(请参见下面的代码).

The dragBoundFunc goes as an addition to the box constructor (see code below).

您可以通过在框的拖动"处理程序中进行测试来测试用户是否有目标,例如:

You can test if the user has a goal by testing in the box’s "dragmove" handler, like this:

  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>

这篇关于拖动碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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