-1

我希望这个 div 从 A 点到 B 点,反之亦然。问题是dist变量(距离)永远不会达到 0,它通常是 1 或 -1(或其他一些值范围),这会导致 div 卡住并且不会去任何地方。在我的完整代码中,每次打开页面时,A 点和 B 点的位置都是随机的。

下面的示例正在重现该问题。看到它按预期工作 #pointA { top: 5px; left: 5px; }|#pointB { top: 5px; left: 105px; }

var score = 0, points = 0, boxMode = 0, speed, speedX, speedY, angleRadians,
distX, distY, dist;

var destinationX = $("#pointB").position().left;
var destinationY = $("#pointB").position().top;

var pointAPos = $("#pointA").position();
var pointAx = pointAPos.left;
var pointAy = pointAPos.top;

var pointBPos = $("#pointB").position();
var pointBx = pointBPos.left;
var pointBy = pointBPos.top;

var boxPos = $('#box').position();
var boxX = pointAx;
var boxY = pointAy;
	
function calculateDistance(x, y) {
  distX = boxX - x;
  distY = boxY - y;
  dist = Math.sqrt((distX*distX)+(distY*distY));
}

function boxMove() {
  angleRadians = Math.atan2(-distX, -distY);
  speed = 2;
  speedX = speed * Math.sin(angleRadians);
  speedY = speed * Math.cos(angleRadians);
	
  document.getElementById("box").style.left = boxX + "px";
  document.getElementById("box").style.top = boxY + "px";
	
  boxX += speedX;
  boxY += speedY;
}

function boxAI() {
  calculateDistance(destinationX, destinationY);
  if (!dist == 0) {
    boxMove();
  } else {
    if (boxMode == 0) {
	  points += 1;
	  if (points == 50) {
	    // change destination to point A
		destinationX = pointAx;
		destinationY = pointAy;
		boxMode = 1;
	  }
	} else {
	  // change destination to point B
	  destinationX = pointBx;
	  destinationY = pointBy;
      score += points;
      points = 0;
	  boxMode = 0;
	}
  }
}
function mainLoop() {
  boxAI();
  $("#debug").html(points + " " + score + " " + boxMode);
  requestAnimationFrame(mainLoop);
}

requestAnimationFrame(mainLoop);
#levelWrapper {
  position: relative;
  width: 400px;
  height: 150px;
  top: 2px;
  margin: auto;
  border: 1px solid red;
}
			
#pointA {
  position: absolute;
  background: beige;
  width: 45px;
  height: 45px;
  top: 3px;
  left: 50px;
  margin: auto;
}
			
#pointB {
  position: absolute;
  background: beige;
  width: 45px;
  height: 45px;
  top: 45px;
  left: 195px;
  margin: auto;
}
			
#box {
  position: absolute;
  background: black;
  height: 5px;
  width: 5px;
}

#debug {
  position: relative;
  background: white;
  width: 250px;
  height: 120px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="debug"></div>

<div id="levelWrapper">
<div id="pointA">A</div>
<div id="pointB">B</div>
<div id="box"></div>
</div>
		
<script src="jquery-3.2.1.js"></script>
<script type="text/javascript" src="woods_2.js"></script>
		
</body>

4

1 回答 1

5

在 JavaScript 中,!运算符优先于==,因此if (dist != 0)已经是一种改进。

但是当您使用一个speed变量来确定距离的两次连续测量之间的差异时,您应该相应地进行测试,并查看距离是否从零移走了一步:

if (dist >= speed)

这是您的代码,有一些更改:

var score = 0, points = 0, boxMode = 0, speed, speedX, speedY, angleRadians,
distX, distY, dist;

var destinationX = $("#pointB").position().left;
var destinationY = $("#pointB").position().top;

var pointAPos = $("#pointA").position();
var pointAx = pointAPos.left;
var pointAy = pointAPos.top;

var pointBPos = $("#pointB").position();
var pointBx = pointBPos.left;
var pointBy = pointBPos.top;

var boxPos = $('#box').position();
var boxX = pointAx;
var boxY = pointAy;
var speed = 2; // make speed visible to other functions

function calculateDistance(x, y) {
    distX = boxX - x;
    distY = boxY - y;
    dist = Math.sqrt((distX*distX)+(distY*distY));
}

function boxMove() {
    angleRadians = Math.atan2(-distX, -distY);
    speedX = speed * Math.sin(angleRadians);
    speedY = speed * Math.cos(angleRadians);

    document.getElementById("box").style.left = boxX + "px";
    document.getElementById("box").style.top = boxY + "px";

    boxX += speedX;
    boxY += speedY;
}

function boxAI() {
    calculateDistance(destinationX, destinationY);
    // As the distance makes jumps of <speed> units,
    // check whether it is within one step of the target
    if (dist >= speed) {
        boxMove();
    } else {
        score++; // Not sure what score should be measuring
        if (boxMode == 0) {
            // Change destination to point A
            destinationX = pointAx;
            destinationY = pointAy;
            boxMode = 1;
        } else {
            // Change destination to point B
            destinationX = pointBx;
            destinationY = pointBy;
            boxMode = 0;
        }
    }
}

function mainLoop() {
    boxAI();
    $("#debug").html(points + " " + score + " " + boxMode);
    requestAnimationFrame(mainLoop);
}

requestAnimationFrame(mainLoop);
#levelWrapper {
  position: relative;
  width: 400px;
  height: 150px;
  top: 2px;
  margin: auto;
  border: 1px solid red;
}
            
#pointA {
  position: absolute;
  background: beige;
  width: 45px;
  height: 45px;
  top: 3px;
  left: 50px;
  margin: auto;
}
            
#pointB {
  position: absolute;
  background: beige;
  width: 45px;
  height: 45px;
  top: 45px;
  left: 195px;
  margin: auto;
}
            
#box {
  position: absolute;
  background: black;
  height: 5px;
  width: 5px;
}

#debug {
  position: relative;
  background: white;
  width: 250px;
  height: 120px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="debug"></div>

<div id="levelWrapper">
<div id="pointA">A</div>
<div id="pointB">B</div>
<div id="box"></div>
</div>

我不明白你想对scorepoints做什么,所以你需要在这方面修改代码。现在我删除了对points变量的更改,并且每次反弹只会增加分数。

于 2017-10-08T18:45:58.347 回答