旋转时两个元素之间的碰撞

Wil*_*spe 2 javascript onmouseover overlap hover collision

var keys = new Array();
	var direction;
	var direction;
	var iNr = 0;
	
	$(document).ready(function(){
		looper();
		$("#demo1").css("margin-top", 400 + "px");
		$("#demo2").css("margin-left", 380 + "px");
		myFunction();
	});
	
	function myFunction()
	{
		iNr = iNr + 0.5;
		$("#main").css("transition","all 0.1s");
		$("#main").css("transform","rotate(" + iNr + "deg)");
		
		
		setTimeout(function()
		{
			myFunction();
		}, 50);
	
	}
	
	function looper()
	{	
		var p =$("#circle");
		var offset = p.offset();
		var t =$(".red");
		var roffset = t.offset();
		
		var rect1 = {x: offset.left, y: offset.top, width: p.width(), height: p.height()}
		var rect2 = {x: roffset.left, y: roffset.top, width: t.width(), height: t.height()}

		if (rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x && rect1.y < rect2.y + rect2.height && rect1.height + rect1.y > rect2.y) {
			
			console.log("now");
		}
		
		if(direction == "left")
		{
			if(offset.left - 50 > 0)
			{
				$("#circle").css("left", ($("#circle").position().left - 2) + "px");
			}
		}
		if(direction == "up")
		{
			if(offset.top - 50 > 0)
			{
				$("#circle").css("top", ($("#circle").position().top - 2) + "px");
			}
		}
		if(direction == "right")
		{
			if((offset.left + 50) < $(window).width())
			{
				$("#circle").css("left", ($("#circle").position().left + 2) + "px");
			}
		}
		if(direction == "down")
		{
			if((offset.top + 50) < $(window).height())
			{
				$("#circle").css("top", ($("#circle").position().top + 2) + "px");
			}
		}
		
		
		
		ID=window.setTimeout("looper();", 1);
	}

	
	$(document).keyup(function(event) {
		
		if (event.keyCode == 37)
		{
			var index = keys.indexOf("37");
			keys.splice(index, 1);
			direction = "";
		}
		if (event.keyCode == 38)
		{
			var index = keys.indexOf("38");
			keys.splice(index, 1);
			direction = "";
		}
		if (event.keyCode == 39)
		{
			var index = keys.indexOf("39");
			keys.splice(index, 1);
			direction = "";
		}
		if (event.keyCode == 40)
		{
			var index = keys.indexOf("40");
			keys.splice(index, 1);
			direction = "";
		}
	});
	
	$(document).keydown(function(event) {
		
		if (event.keyCode == 37)
		{
			keys.push("37");
			direction = "left";
		}
		if (event.keyCode == 38)
		{
			keys.push("38");
			direction = "up";
		}
		if (event.keyCode == 39)
		{
			keys.push("39");
			direction = "right";
		}
		if (event.keyCode == 40)
		{
			keys.push("40");
			direction = "down";
		}
	});
Run Code Online (Sandbox Code Playgroud)
<!doctype html>
<html lang="en">

	<head>
		<meta charset="utf-8">
		<title>test</title>

		<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
		
	</head>
	
	
	<body style="background-color:black; overflow-y:scroll;">
	
		<div style="width:400px; margin-left:500px; height:400px;" id="main">
			<div id="demo1" style="width:400px; height:20px; background-color:red; position:absolute;" class="red test all"></div>
			<div id="demo2" style="width:20px; height:400px; background-color:yellow; position:absolute;" class="test all"></div>
			<div id="demo3" style="width:400px; height:20px; background-color:blue; position:absolute;" class="test all"></div>
			<div id="demo4" style="width:20px; height:400px; background-color:green; position:absolute;" class="test all"></div>
		</div>
		
		<div style="width:25px; height:25px; background-color:white; position:absolute; border-radius:50%;" id="circle"></div>
	
	</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我已经编写了一个游戏。在这个游戏中,我的函数检查div1div2之间是否存在冲突。或者,如果它们重叠或如此……您想如何拼写。没有旋转,一切都很好。

但是现在我有一个问题。我想旋转DIV2transform:rotate(Xdeg);

但是如果我这样做,碰撞的计算将无法正常进行。

我用这个:

var rect1 = {x: 5, y: 5, width: 50, height: 50}
var rect2 = {x: 20, y: 10, width: 10, height: 10}

if (rect1.x < rect2.x + rect2.width && rect1.x + rect1.width > rect2.x && rect1.y < rect2.y + rect2.height && rect1.height + rect1.y > rect2.y) {
    // collision detected!
}
Run Code Online (Sandbox Code Playgroud)

您有解决这个问题的想法吗?

感谢您的帮助:-)

Bla*_*ley 5

有几种方法可以做到这一点。本示例仅指导您如何使用矩形完成此操作。

这些是在这里完成的步骤:

  • 您必须计算要检查它们是否发生碰撞的所有矩形的所有旋转角的位置。要获得这些旋转的角,可以使用几种方法。在此示例中,使用2d向量和2d旋转矩阵:

    • 一个向量,其原点位于矩形的中心,并指向矩形的左上角(x,y):

      var center = {
          x: x + width / 2,
          y: y + height / 2
      };
      
      var vector = {
          x: (x - center.x),
          y: (y - center.y)
      };
      
      Run Code Online (Sandbox Code Playgroud)
    • 将此矢量与旋转矩阵相乘以旋转此矢量:

      // modified sin function to calulcate sin in the unit degrees instead of radians
      function sin(x) {
         return Math.sin(x / 180 * Math.PI);
      }
      
      // modified cos function 
      function cos(x) {
         return Math.cos(x / 180 * Math.PI);
      }
      
      var rotationMatrix = [[cos(angle), -sin(angle)],[sin(angle), cos(angle)]];
      
      var rotatedVector = {
          x: vector.x * rotationMatrix[0][0] + vector.y * rotationMatrix[0][1],
          y: vector.x * rotationMatrix[1][0] + vector.y * rotationMatrix[1][1]
      };
      
      Run Code Online (Sandbox Code Playgroud)
    • 最后得到旋转的左上角,您可以从矩形的中心开始,然后转到旋转的矢量所指向的位置。这是旋转后位于左上角的位置:

      {
          x: (center.x + rotatedVector.x),
          y: (center.y + rotatedVector.y)
      }
      
      Run Code Online (Sandbox Code Playgroud)
    • 上述所有步骤均由getRotatedTopLeftCornerOfRect完成,并且还必须与所有其他角落一起完成。在计算下一个角(右上角)的位置之前,必须计算指向该角的下一个矢量。为了获得指向右上角的下一个矢量,需要计算第一个矢量(左上)和第二个矢量(右上)之间的角度。当第三矢量的角度增加第一角度和第二角度时,第三矢量指向右下角,并且第四矢量旋转一个将第一角度,第二角度和第三角度相加的角度。所有这些都是在setCorners -method中完成的,此图像部分显示了此过程:

在此处输入图片说明


  • 为了检测碰撞,有很多算法。在此示例中,“多边形中点”算法用于检查矩形的每个旋转角是否具有边界或与另一个矩形相同,如果是,则方法isCollided返回true。PointInPoly中使用了Point in Polygon算法,也可以在此处找到。

组合上述所有步骤都很棘手,但是它可以与所有大小的所有矩形一起使用,并且最好的方法是在没有库的情况下通过单击“运行代码段”在此处进行测试。

经过测试的浏览器:FF 50.1.0,IE:10-EDGE,Chrome:55.0.2883.87 m):

var center = {
    x: x + width / 2,
    y: y + height / 2
};

var vector = {
    x: (x - center.x),
    y: (y - center.y)
};
Run Code Online (Sandbox Code Playgroud)
// modified sin function to calulcate sin in the unit degrees instead of radians
function sin(x) {
   return Math.sin(x / 180 * Math.PI);
}

// modified cos function 
function cos(x) {
   return Math.cos(x / 180 * Math.PI);
}

var rotationMatrix = [[cos(angle), -sin(angle)],[sin(angle), cos(angle)]];

var rotatedVector = {
    x: vector.x * rotationMatrix[0][0] + vector.y * rotationMatrix[0][1],
    y: vector.x * rotationMatrix[1][0] + vector.y * rotationMatrix[1][1]
};
Run Code Online (Sandbox Code Playgroud)
{
    x: (center.x + rotatedVector.x),
    y: (center.y + rotatedVector.y)
}
Run Code Online (Sandbox Code Playgroud)