0
\$\begingroup\$

What I'm essentially trying to do is what a lot of FPS's nowadays do in regards to their HUD. When an objective is off-screen, a small icon / symbol is shown on the perimeter of the screen, basically pointing towards the objective.

I'm working in 2D and I'm trying to get offscreen enemies (top-down) to show their positions via small points around the perimeter of the screen (a rectangle view, pretty standard).

Simply put, I'm trying to find the value of the red point when everything else is known:

Here's my code, and while it seems to be half functioning, sometimes it'll do funny things.

// Scan through enemiesRef list, and update dots to draw.
// ------------------------------------------------------
Enemy enemyRef;
float a, b, x, y;
float screenRatio = frustumWidth / frustumHeight;
float minX = topLeft.x;
float maxX = topLeft.x + frustumWidth;
float minY = topLeft.y;
float maxY = topLeft.y + frustumHeight;

// Loop through each enemy.
// ------------------------
for (int i = enemiesRef.size() - 1; i >= 0; --i)
{
    enemyRef = enemiesRef.get(i);

    // Get x and y distance to the enemy.
    // ----------------------------------
    x = enemyRef.position.x - center.x;
    y = enemyRef.position.y - center.y;

    // Check if the enemy is on-screen and skip.
    // -----------------------------------------
    if (Math.abs(x) < halfFrustumWidth && Math.abs(y) < halfFrustumHeight)
        continue;

    // Determine the known variable and derive the unknown.
    // ----------------------------------------------------
    float ratio = Math.abs(x) / Math.abs(y);
    if (ratio >= screenRatio)
    {
        // The a is known, the dot is on either the left or right.
        // -------------------------------------------------------
        if (enemyRef.position.x < center.x)
            a = minX;
        else
            a = maxX;

        // Calculate b.
        // ------------
        b = a * (enemyRef.position.y / enemyRef.position.x);
    }
    else
    {
        // The b is known, the dot is either on the top or bottom.
        // -------------------------------------------------------
        if (enemyRef.position.y < center.y)
            b = minY;
        else
            b = maxY;

        // Calculate a.
        // ------------
        a = b / (enemyRef.position.y / enemyRef.position.x);
    }
}

It seems the code accurately detects whether the point should be on the top / left / bottom / right, but if the object is far enough off screen (as in, it's both past the upper boundary of the view and the left boundary view at the same time, for example), the dot on the map just flies off the screen (for example, to the left, it's x coordinates going into negatives).

I believe the error lies somewhere in calculating a or b:

a = b / (enemyRef.position.y / enemyRef.position.x);
b = a * (enemyRef.position.y / enemyRef.position.x);

Whether it be with the signs of the values, or if the values I'm calculating are just wrong, etc, I don't know.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Nevermind, I got it working by using the equation of a line rather than this pseudo-trig stuff. Thanks anyway.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .