0
\$\begingroup\$

I am using this approach:

http://clintbellanger.net/articles/isometric_math/

Basically, you can calculate the iso coordinates based on the screen coordinates. What I am doing is, getting the actual world position the mouse is pointing at using get_mouse_global_position() and convert this position to isometric values.

Then I translate those coordinates back to world space coordinates to actually display the sprite.

Problem is, that when the world coordinates come from a negative position, the tiles get offset by almost an entire tile amount. Here is the relevant code.

The get_coord() function returns the actual world position of the tile used to display the Sprite

func get_coord(pos : Vector2):
    var t = Vector2()
    var e = screen_to_iso(pos)
    t = iso_to_screen(e)
    print(pos)
    print(e)
    print(t)
    return t
    pass
var buildings

func screen_to_iso(pos :Vector2):
    var flipx = 0
    var flipy = 0
    var t = Vector2()
    var x_size = size/2
    var y_size = size/4
    t.x = int((pos.x/x_size) + (pos.y/y_size))/2
    t.y = int((pos.y/y_size) - (pos.x/x_size))/2
    return t
    pass

func iso_to_screen(pos : Vector2):
    var t = Vector2()
    var x_size = size/2
    var y_size = size/4
    t = Vector2((pos.x-pos.y)*x_size, (pos.x+pos.y)*y_size)
    return t
    pass

I can't seem to figure out a way

\$\endgroup\$
1
  • \$\begingroup\$ Geometric problems are often easier to solve if you can show the error visually in a screenshot or diagram. Or even an animated Gif so we can see how the output changes as the mouse moves. \$\endgroup\$ – DMGregory Oct 15 '20 at 12:00
1
\$\begingroup\$

I'm not familiar with the language you're using (GDScript?) but the usual reason for negative sides of a grid to be off by one is that you're using an operation that rounds towards zero, where you want one that rounds down.

t.x = int((pos.x/x_size) + (pos.y/y_size))/2
t.y = int((pos.y/y_size) - (pos.x/x_size))/2

I looked for documentation and this page says

int int ( float from )

Cast a float value to an integer value, this method simply removes the number fractions, so for example int(2.7) will be equals to 2, int(.1) will be equals to 0 and int(-2.7) will be equals to -2.

That will explain your error: you want -3 and you get -2.

One solution is to use the floor function, which always rounds towards negative numbers, before converting to int.

However, I notice that you're dividing by 2 after converting to int; dividing by 2 will also round towards zero, so you can't just insert int(floor(...)) into your existing expression. I haven't studied your code enough to understand it completely, but it's possible this would work (spaces and bold inserted to highlight differences):

t.x = int(floor( ( (pos.x/x_size) + (pos.y/y_size) )/2 ))
t.y = int(floor( ( (pos.y/y_size) - (pos.x/x_size) )/2 ))
\$\endgroup\$
2
  • \$\begingroup\$ You are awesome! :) Yes, it is GDScript and I got the code from the mentioned link. \$\endgroup\$ – SPL Oct 17 '20 at 9:09
  • \$\begingroup\$ Can I upvote you more than once? :D I was struggling with this for days now! \$\endgroup\$ – SPL Oct 17 '20 at 9:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.