0 votes

I'm working on an hexagonal map in a 3D world, but I don't think that's important. I created a function that returns the distance between two tiles in someway similar to Manhattan distance, but in an hexagonal grid. I checked it for thousands of tiles and works. Now the error cames.

The position of the tile is Vector2(1,1) in offset coordinates (https://www.redblobgames.com/grids/hexagons/). When I call a method inside the tile script, I get a weird result. To see what is happening, I made something like print(tilePosition, Vector2(1,1)) and I get (1,1)(1,1), that's ok. But the method still gives me a bad result, so I wrote if tilePosition == Vector2(1,1): print something, this if statement is never passed. I make sure that the tilePosition is a Vector2 using typeof, and that the method is inside _ready to make sure that the method is called after the position of the tile is set to the desired one. I don't know what is happening. Any help? Some pieces of code are bellow:

The ''game manager'' that adds the tile:

extends Spatial

var R : int = 2
var rng : RandomNumberGenerator = RandomNumberGenerator.new()
var tilesVpositions : PoolVector2Array
var tilesIds : PoolIntArray = PoolIntArray([])

func _ready():

    tilesVpositions = PoolVector2Array([Vector2(1,1)])

    var tile : Spatial

    for i in range(tilesVpositions.size()):
        tile = GLOBALS.Tile.instance()
        tile.name = tile.ttranslation
        add_child(tile, true)
        #tile.id = i

GLOBALS is a singleton used by every node, contains the information about the hexagonal grid and many methods (''vdisplacement'' is the function that makes a displacement in offset coordinates). The other script where the if statement is done:

extends Spatial

onready var mesh : MeshInstance = $Mesh

var vtranslation : Vector2 = Vector2.ZERO
var ttranslation : String = '0,0'
var id : int # identification in the world

func _init():
    vtranslation = GLOBALS.b_to_v(translation)
    ttranslation = GLOBALS.v_to_t(vtranslation)

func _ready():
    id = _get_id()

func _get_id() -> int:
    var H : int = GLOBALS.hex_dist(Vector2.ZERO, vtranslation)
    if vtranslation == Vector2(1,1):
        print(vtranslation, GLOBALS.hex_dist(Vector2.ZERO, Vector2(1,1))) # this is never printed

GLOBALS.b_to_v and similars takes, in this case, translation (the default Godot Spatial.translation) and transforms it into offset coordinates.

If I make print(vtranslation.x) I get 1, the same for print(vtranslation.y)

See comments bellow in @Thomas Karcher answer.

Godot version 3.2.3
in Engine by (249 points)
edited by

2 Answers

0 votes
Best answer

It works changing vtranslation to self.translation in _get_id()

by (249 points)
0 votes

You are likely running into float precision error. It is not good practice to compare vectors this way. Print might be rounding that out so it's hard to see, but it's there. Your Vectors are probably something like Vector2(1, 0.99999999) or Vector2(1, 1.0000001).
A better check would then be the following:

by (1,758 points)

I understand what you are saying. I use some sqrt(3) and /2, so I'm converting int into float and viceversa, but I made the code in that way that I only get int at the end (making things like func f()->int: or int(something)). I tried your advice and it doesn't work.

I was trying things and I found something that I don't understand and it may be the problem. When I write in the "game manager" :

    tile.id = jj_get_id(tile.vtranslation) # this functions returns 12
    print(tile.id)  # but when I print this is 7

jj_get_id is the same function which one I has problems, but written in the "game manager" code and not in the "tile" code.

Can you help me?

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.