可拖动图形与随机静态图形碰撞

Draggable figure collision with random static figures

本文关键字:图形 静态 碰撞 随机 拖动      更新时间:2023-09-26

我在画布上随机放置了许多静态正方形。当另一个draggable图形在它们之间碰撞并打印rect的"名称"属性时,这些正方形有什么方法可以检测到吗?

这是代码(也可在JSFiddle中获得)

var arrowMode = true;
var stage = new Kinetic.Stage({
    container: 'container',
    height: 400,
    width: 800
});
var arrowsLayer = new Kinetic.Layer();
stage.add(arrowsLayer);
$(stage.getContainer()).on('click',function(e){
    if(arrowMode){
        arrowMode=false;
        var x = stage.getMousePosition().x;
        var y = stage.getMousePosition().y;
        for(var i=0;i<6;i++){
            //Rects will be collide for a circle
            var rect = new Kinetic.Rect({
                name:'rect'+(i+1),
                x: i<3? x + (i)*60:x + (i-3)*60,
                y: i<3? y : y +60,
                width: 50,
                height: 50,
                fill:'black'
            });
            arrowsLayer.add(rect);
        }
        var circle = new Kinetic.Circle({
            draggable: true,
            stroke: "black",
            fill: "#0FF30F",
            strokeWidth: 2,
            radius: 10,
            x:x+400,
            y:y+100
        });
    arrowsLayer.add(circle);  
    stage.add(arrowsLayer);
    }
});

一个非常有趣的问题。

让我们站在巨人的肩膀上,使用这个SO问题:KineticJS-用新的鼠标位置更新文本层,以及这个SO问题,如何在KineticJS中分别使用拖动和点击?

现在我们唯一要做的就是获取正方形的坐标,鼠标的坐标,然后制作一个简单的switch语句,根据需要输出文本。

守则

为了得到正方形的坐标(软编码),我使用了一个二维数组:

var poss = new Array(6);
  for (var i = 0; i < 6; i++) {
    poss[i] = new Array(2);
}

现在,当用户第一次点击画布并生成正方形时,我将它们的坐标附加到数组中:

for(var i=0;i<6;i++){
      var posX = i<3? x + (i)*60:x + (i-3)*60;
      var posY = i<3? y : y +60;
      poss[i][0] = posX;
      poss[i][1] = posY;
      var rect = new Kinetic.Rect({
      name:'rect'+(i+1),
      x: posX,
      y: posY,
      width: 50,
      height: 50,
      fill:'black'
   });

现在我需要检测绿点何时被拖动,然后启动一个检查碰撞的功能。

为了检测绿点是否被拖动,我使用dragstartdragend:

circle.on('dragstart', function(e){
    indrag = true;
});
circle.on('dragend', function(e){
    indrag = false;
});

$(stage.getContent()).on('mousemove', function (e) {
   if (indrag)
   {            
     checkCollision(e);
   }
});

现在我所需要做的就是定义函数checkCollision(e),它迭代所有正方形的坐标(保存在数组中)以检查冲突:

function checkCollision(event) {
  var pos = stage.getMousePosition();
  var mouseX = parseInt(pos.x);
  var mouseY = parseInt(pos.y);
  $("#coordinates").replaceWith("<div id='coordinates'>X-axis: "+mouseX+"<br />Y-axis: "+mouseY+"</div>");
  $("#inSquare").replaceWith("<div id='inSquare'>Nothing is happening</div>");
  //check if collision with squares
  for (var k = 0; k < 6; k++)
  {
     if (mouseX >= poss[k][0] && mouseX <= (poss[k][0]+50) && mouseY >= poss[k][1] && mouseY <= (poss[k][1]+50))
     {   
         $("#inSquare").replaceWith("<div id='inSquare'>You have just dragged the green dot in square number " +(k+1)+"</div>");
     }
  }
}

Demo

您可以在此处找到此实现的工作示例。

限制

注意两件重要的事情:

  • 我使用鼠标坐标来检查碰撞;而不是圆的宽度。如果要使用圆的宽度,可以使用圆的半径(例如,使用(mouseX + widthCircle)代替mouseX,在某些变量中定义widthCircle)。

  • 我的一些代码是多余的(我定义了两次变量)。因此,如果你愿意,你仍然可以缩短我的代码。

我希望这能回答你的问题。祝你好运

更新

要显示指定的名称属性,我建议保持代码的整洁,并使用switch语句,如下所示:

var name;
switch (k)
{
   case 0: name = "I'm in the upper left";                   break;
   case 1: name = "I'm more awesome than the other squares"; break;
   case 2: name = "I'm a black square";                      break;
   case 3: name = "I'm in the bottom left";                  break;
   case 4: name = "I like coffee";                           break;
   case 5: name = "Nanos gigantum humeris insidentes";       break;
}
$("#inSquare").replaceWith("<div id='inSquare'>"+name+"</div>");

你可以在这里找到该代码的实现。