好的,所以我有一个512x512
的比赛场地,-32
和512
的x
都变成了y
。
现在,我需要计算两个实体之间的角度,我将以下代码作为一种变通办法,它在大多数情况下都有效,但有时仍然会失败:
Shooter.getAngle = function(a, b) {
var ax = a.x;
var bx = b.x;
if (a.x < this.width / 4 && b.x > this.width - this.width / 4) {
ax += this.width;
} else if (a.x > this.width - this.width / 4 && b.x < this.width / 4) {
bx += this.width;
}
var ay = a.y;
var by = b.y;
if (a.y < this.height / 4 && b.x > this.height - this.height / 4) {
ay += this.height;
} else if (a.y > this.height - this.height / 4 && b.y < this.height / 4) {
by += this.height;
}
return this.wrapAngle(Math.atan2(ax - bx, ay - by) + Math.PI);
};
我只是不知道如何将
a
投影到b
上,以便正确地考虑包装。如果有人能帮上忙,那将是很棒的,因为从目标飞出的寻的导弹并不是那么有趣。
为了澄清起见,如果玩家向右移动,则导弹应像其他玩家一样,沿战场边缘向左跟随他。
编辑:
这是一个测试版本,示例显示它可以正确包装,但在某些情况下不必包装它会中断:
function getAngle(a, b) {
var tx = a.x - b.x;
var ty = a.y - b.y;
// actual area goes from -16 to 512 due to the border space that's out of screen
tx = ((tx + 16) % (480 + 32)) - 16;
ty = ((ty + 16) % (480 + 32)) - 16;
var r = Math.atan2(ty, tx) * (180 / Math.PI);
// example
// |> b a >|
// a.x = 460
// b.x = 60
// missile should go over the right border
// tx = 400
// r = 0
// missile goes right, OK
// example2
// |< a b <|
// a.x = 60
// b.x = 460
// missile should go over the left border
// tx = -400
// r = 180
// missile goes left, OK
// example3
// | a >>>> b |
// a.x = 60
// b.x = 280
// missile should go right
// tx = -220
// r = 180
// missile goes left, WRONG
// example4
// | b <<<< a |
// a.x = 280
// b.x = 60
// missile should go left
// tx = 220
// r = 0
// missile goes right, WRONG
console.log(ty, tx);
console.log(r);
}
function Point(x, y) {
this.x = x;
this.y = y;
}
getAngle(new Point(460, 240), new Point(60, 240));
getAngle(new Point(60, 240), new Point(460, 240));
getAngle(new Point(60, 240), new Point(280, 240));
getAngle(new Point(280, 240), new Point(60, 240));
看来唯一可行的方法是检查
a.x < width * 0.25
和b.x > width * 0.75
等情况,但这是有问题的,至少在我上面发布的版本中这样:/ 最佳答案
我将使用这种方法:将目标用作坐标系的中心(并正确包装导弹的坐标),然后计算角度。因此,伪代码应该是这样的(EDIT2:更正的代码,类似的问题也导致了测试中的问题):
// missile.x/y = missile's coordinates
// target.x/y = target's coordinates
temp.x = missile.x - target.x;
temp.y = missile.y - target.y;
// The wrapping code - feel free to adjust,
// from the comments it seems you handle this
// a bit differently
while (temp.x < -240)
temp.x += 480
while (temp.y < -240)
temp.y += 480
while (temp.x > 240)
temp.x -= 480
while (temp.y > 240)
temp.y -= 480
// Now you can calculate the angle your missile must go,
// it has to fly across the line from temp.x/y to (0,0)
编辑:我看过视频,我认为您的代码中有一些错误,但是我不确定在哪里。使用数学函数和角度可能会有些棘手,因为通常数学坐标的Y轴朝上,屏幕坐标的Y轴朝下。
现在最好的方法可能是开始一些单元测试,如下所示:
// Create a function that returns the angle a missile must
// fly and cares about all the dirty details with wrapping etc.
MissileAngle(missile.x, missile.y, target.x, target.y)
// Now create some tests for it, f.e.:
MissileAngle(missile top left corner, target bottom right corner)
Expected Result: Northwest
MissileAngle(missile bottom right corner, target top left corner)
Expected Result: Southeast
请注意,我在这里没有使用坐标,因为它在很大程度上取决于您使用的坐标系,这实际上可以帮助您更好地了解问题(当然,希望至少可以帮助您解决错误)这是一种无需查看实际游戏即可快速检查其是否正常运行的方法,这比较耗时。