多个对象的碰撞检测不适用于所有对象

时间:2018-07-06 13:26:11

标签: javascript collision-detection

所以基本上我有一个玩家对象和一个以上的盒子。我将盒子存储在数组中作为包含“宽度,高度,x位置和y位置”的对象。当我尝试循环碰撞算法时,它不会发生碰撞,而是数组的第一盒。经过研究,我看到了很多例子。例如:Collision detection - Game development | MDN。但是循环对我不起作用。我在想什么吗?

let left,up,right,down;

let p = {
	x: '',
  y: '',
  w:	parseInt($("i").css("width")),
  h:	parseInt($("i").css("height")) 
}
let block = [
	{
  	x:	parseInt($("#block").css("left")),
    y:  parseInt($("#block").css("top")),
    w:	parseInt($("#block").css("width")),
    h:	parseInt($("#block").css("height"))
  },{
  	x:	parseInt($("#block2").css("left")),
    y:  parseInt($("#block2").css("top")),
    w:	parseInt($("#block2").css("width")),
    h:	parseInt($("#block2").css("height"))
  }];
let speed = 5;

$(document).on('keydown', function(e){
	//LEFT or RIGHT arrow pressed
	if(e.keyCode == 37) {
  	left = true;
  } else if(e.keyCode == 39) {
  	right = true;
  }
  //UP or DOWN arrow pressed
  if(e.keyCode == 38) {
  	up = true;
  } else if(e.keyCode == 40) {
  	down = true;
  }
});



//Collision detection
function collision() {
p.x = parseInt($("i").css("left"));
p.y = parseInt($("i").css("top"));

	//Left to right
for(var i in block) {
  if(right == true) {
  	if(
    p.x + p.w + speed >= block[i].x &&
    p.y + p.h > block[i].y &&
    p.y < block[i].y + block[i].h &&
    p.x + p.w <= block[i].x
    ) {
      $("i").css({"left": block[i].x - p.w});
      right = false;
    } else {
      $("i").css({"left": p.x + speed});
      right = false;
    }
  }
  
  //Right to left
  if(left == true) {
  	if(
    p.x - speed <= block[i].x + block[i].w && 
    p.y + p.h > block[i].y &&
    p.y < block[i].y + block[i].h &&
    p.x >= block[i].x + block[i].w) {
    	$("i").css({"left": block[i].x + block[i].w});
      left = false;
    } else {
    	$("i").css({"left": p.x - speed});
      left = false;
    }
  }
  
  //Down to up
  if(up == true) {
  	if(
    p.y - speed <= block[i].y + block[i].h && 
    p.x + p.w > block[i].x && 
    p.x < block[i].x + block[i].w &&
    p.y >= block[i].y + block[i].h
    ) {
    	$("i").css({"top": block[i].y + block[i].h});
      up = false;
    } else {
    	$("i").css({"top": p.y - speed});
      up = false;
    }
  }
  
  //Up to down
  if(down == true) {
  	if(
    p.y + p.h + speed >= block[i].y &&
    p.x + p.w > block[i].x &&
    p.x < block[i].x + block[i].w &&
    p.y + p.h <= block[i].y
    ) {
        	$("i").css({"top": block[i].y - p.h});
          down = false;
        } else {
        	$("i").css({"top": p.y + speed});
          down = false;
        }
  }
}
}
setInterval(collision,1);
i {
  position: absolute;
  width: 15px;
  height: 15px;
  background: red;
  border-radius: 50%;
  left: 0px;
  top: 0px;
}
#block {
  position: absolute;
  margin: 0;
  left: 65px;
  top: 120px;
  width: 20px;
  height: 50px;
  background: gray;
}
#block2 {
  position: absolute;
  margin: 0;
  left: 65px;
  top: 45px;
  width: 20px;
  height: 50px;
  background: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<i></i>
<div id="block"></div>
<div id="block2"></div>

1 个答案:

答案 0 :(得分:0)

我将碰撞算法移出了方向控制部分(右侧== true等)并解决了问题。最终状态如下。还将布尔值更改为“ dx和dy”。

当权利等于true时,我先移动对象,然后将right设置为true,这会导致循环运行一次,因此它不会计算其他对象。

干杯。

let speed = 5;
let dx = 0;
let dy = 0;

let p = {
	x: '',
  y: '',
  w:	parseInt($("i").css("width")),
  h:	parseInt($("i").css("height")) 
}
var block = [
	{
  	x:	parseInt($("#block").css("left")),
    y:  parseInt($("#block").css("top")),
    w:	parseInt($("#block").css("width")),
    h:	parseInt($("#block").css("height"))
  },{
  	x:	parseInt($("#block2").css("left")),
    y:  parseInt($("#block2").css("top")),
    w:	parseInt($("#block2").css("width")),
    h:	parseInt($("#block2").css("height"))
  }];

$(document).on('keydown', function(e){
	//LEFT or RIGHT arrow pressed
	if(e.keyCode == 37) {
  	dx = -speed;
  } else if(e.keyCode == 39) {
  	dx = speed;
  }
  //UP or DOWN arrow pressed
  if(e.keyCode == 38) {
  	dy = -speed;
  } else if(e.keyCode == 40) {
  	dy = speed;
  }
});



//Collision detection
function collision() {
//Left to right
for(let i in block) {
p.x = parseInt($("i").css("left"));
p.y = parseInt($("i").css("top"));
	if(
    p.x + p.w + dx > block[i].x &&
    p.y + p.h > block[i].y &&
    p.y < block[i].y + block[i].h &&
    p.x + p.w < block[i].x + block[i].w
    ) 
  {
    $("i").css({"left": block[i].x - p.w});
    dx = 0;
  }
    
  if(dx > 0) {
      $("i").css({"left": p.x + dx});
      dx = 0;
  }
}
  //Right to left
for(let i in block) {
p.x = parseInt($("i").css("left"));
p.y = parseInt($("i").css("top"));
  if(
    p.x + dx < block[i].x + block[i].w && 
    p.y + p.h > block[i].y &&
    p.y < block[i].y + block[i].h &&
    p.x > block[i].x
    )
    {
    	let z = $("i").css({"left": block[i].x + block[i].w});
      dx = 0;
    }
    
  if(dx < 0) {
    	$("i").css({"left": p.x + dx});
      dx = 0;
  }
}  
  //Down to up
for(let i in block) {
p.x = parseInt($("i").css("left"));
p.y = parseInt($("i").css("top"));
  if(
    p.y + dy < block[i].y + block[i].h &&
    p.x + p.w > block[i].x && 
    p.x < block[i].x + block[i].w && 
    p.y > block[i].y
    ) 
    {
    	$("i").css({"top": block[i].y + block[i].h});
      dy = 0;
    }
    
  if(dy < 0) {
    	$("i").css({"top": p.y + dy});
      dy = 0;
  }
}  
  //Up to down
for(let i in block) {
p.x = parseInt($("i").css("left"));
p.y = parseInt($("i").css("top"));
  if(
    p.y + p.h + dy > block[i].y &&
    p.x + p.w > block[i].x &&
    p.x < block[i].x + block[i].w && 
    p.y + p.h < block[i].y + block[i].h
    ) 
    {
    	$("i").css({"top": block[i].y - p.h});
    	dy = 0;
    }
        
  if(dy > 0) {
  	$("i").css({"top": p.y + dy});
  	dy = 0;
  }
}
}
setInterval(collision,1);
i {
  position: absolute;
  width: 15px;
  height: 15px;
  background: red;
  border-radius: 50%;
  left: 0px;
  top: 0px;
}
#block {
  position: absolute;
  margin: 0;
  left: 65px;
  top: 120px;
  width: 20px;
  height: 50px;
  background: gray;
}
#block2 {
  position: absolute;
  margin: 0;
  left: 345px;
  top: 60px;
  width: 20px;
  height: 50px;
  background: gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<i></i>
<div id="block"></div>
<div id="block2"></div>