OK, so I have a play field of 512x512
which wraps around, -32
becomes 512
for both x
and y
.
Now I need to calculate the angle between two entities, I have the following code as a kind of workaround, it works most of the time, but sometimes it still fails:
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);
};
I just can't figure out how to project a
onto b
so that the wrapping is accounted for correctly.
If anyone could help, it would be great, since homing missiles that fly away from their target aren't that fun.
For clarification, if the player is moving right, the missile should follow him over the edge of the field to the left side, just as another player would do.
EDIT:
Here's a test version, the examples show that it wraps correctly but in cases were it doesn't have to wrap it breaks:
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));
It seems the only way to getting it work is by checking for cases when a.x < width * 0.25
and b.x > width * 0.75
etc. but that's buggy, at least in the version I posted above :/