Trying hard to figure out an efficient way to do the following:

And so far, only coming up with something like this:

Imagine a thread of fixed length N stuck to a location on your desk. Now picture a coffee cup in the path of that thread. Now fill in only the area that the thread can reach.

I’ve tried to work it out on a whiteboard but that was only getting me so far with the subject. Now I’ve got a hunch that if I iterate (and recurse) the points within the line-of-sight from the closest to furthest points from the player that I can calculate the accessible region based on the player’s position, and how far the player can move (the length of the thread).

That brings me to Comparators. In PHP there’s a handy function called usort. It takes an array for the first argument, and the name of a function as the second argument. The function as a second argument is one usually written by you, the developer, to tell usort how to compare two elements in the array.

In Java you can accomplish usort via the Comparator interface which usually works out to something like the following:

int compare(a, b) {
if (a == b) return 0;
return (a < b) ? -1 : 1;
} |

int compare(a, b) {
if (a == b) return 0;
return (a < b) ? -1 : 1;
}

In this case I’d compare Point objects and sort them from closest to most distant locations from the player. For reference, this page was informative enough to show how to create and use your own Comparator.

One of the “features” I wanted to include in SpaceFight! is a range of mobility for the player pawns. The units of measurement for the distance is arbitrary, and the screenshot below reflects 200 “units”.

That green circle surrounding the highlighted pawn shows the player the possible area they can place that pawn. The tricky part here was limiting the “potential new location” to never exceed the radius of that circle. Perhaps there was an easier way to do this, but I solved it with a little high school trigonometry.

**Calculate distance**

a^2 + b^2 = c^2

or

square root of (a^2 + b^2) = c

In this case, **a** = x1 – x2, and **b** = y1 – y2 (using cartesian coordinates)

dist = Math.sqrt(
Math.pow((getX() - getMouseX()), 2)
+
Math.pow((getY() - getMouseY()), 2)
);

If that value **c** exceeds the pawn’s range then find the coordinate of the intersect between the circle and the line drawn between the pawn and the mouse cursor.

**Calculate angle**

Now, to force the new location to be where the lines intersect we only need two things. First, the distance which is just the pawn’s range of mobility. Second, the angle between the pawn and the mouse cursor.

angleRadian = Math.atan2(
(getMouseY() - getY()) ,
(getMouseX() - getX())
);

**Set the location**

Now that we have the angle we can calculate the new location.

pX = getX() + range * Math.cos(angleRadian);
pY = getY() + range * Math.sin(angleRadian);
setNewLocation(pX, pY);

Now if the mouse is located outside the pawn’s range then the new location will always be somewhere along the edge of the pawn’s range.

Tags: angle, coordinate, coordinates, dev, distance, game, location, new location, spacefight, technical, trigonometry

Game Dev