How to remember a custom position on a sprite

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Elis

Hi,

I have a lot of sprites, and I want to set some sort of custom anchor on each of them, so that I can spawn other sprites at this position. I don’t know what is the best way to do this.
I was thinking about creating custom nodes as children for each of them, or having a script sheet for each of them with a var containing these coordinates, but as I’m very new to godot I don’t really know what will or won’t be efficient, or convenient (putting the coordinates in the script sheet is very difficult, as I can’t visualize directly what I’m doing).

Visual explanation

:bust_in_silhouette: Reply From: RenenerG

Hello Ells,

Basically every node, which inherits from Node2D could do that. I guess you want to archieve this with the help of the nodes property position or global_position.

For a better overview, you could use Position2D nodes. They are basically just Node2D nodes, but visually displayed as crosses in the scene, so you could use them as “ancor” and store or manipulate the position or global_position in your script.


For example you could create a new simple scene for the red shape, something like this:

RedShape(Sprite)
    - PosA(Position2D)
    - PosD(Position2D)  

Then, you just need to drag the Position2D nodes in the editors 2D-view on the holes of your sprite. Then you can just access the positions of the Position2D nodes with something like this:

# This script is attached to 'RedShape'.
extends Sprite

# Store references to the position nodes.
onready var posA = $PosA
onready var posD = $PosD

# Or every other function...
func _ready():
    # Get the position relative to its parent (RedShape in this case).
    var position = posA.position
    # Just print the x and y coordinates. 
    print("A: Vector2(" + str(position.x) + ", " + str(position.y) + ")")

And if you want to spawn other sprites at this position, you could do something like this in the same script:

# Will shown up, in the inspector-tab of the node.
# Just drag for example an PNG file in there.. 
export(String, FILE, "*.png") var texture_path

# If you youse Godot 3.1 you can do it easier without calling 'load':
export var another_texture : Texture

func add_a_sprite_the_old_way( ):
    var my_texture = load(texture_path)
    var sprite = Sprite.new( )
    sprite.set_texture(my_texture )
    add_child(sprite)
    # set the position of the sprite
    sprite.position = posA.position

func add_a_sprite_the_new_way( ):
    var sprite = Sprite.new( )
    sprite.set_texture(another_texture)
    add_child(sprite)
    # also set the position....

If you are using Godot 3.1 and you really know the positions on each of your shapes. Then you could do it more dynamically and instanciate these Position2D nodes inside your Sprite via code:

extends Sprite

# With this you can initialize an array from the inspector with Vector2 coordinates.
export var positions: = [ ]

func _ready():
    for i in range(position.size()):
        var position2D = Position2D.new()
        position2D.position = positions[i]
        add_child(position2D)
    

See basic GD scripting and Arrays for more information.


The only problem I see is, when you have multiple of these scenes.
How do the other scenes know, how to attach them?

I would probably go for the first thing that comes to mind:

You could do something like naming/labeling them. A to A, B to B, like you mentioned.

Then if you try to connect two shapes, like you shown in your picture. You could iterate over the childs (which are nothing more than Position2D nodes) of one of the Sprite and pick the positions you want to connect.

Then set the position of the sprite, not the position2D.
But you will end up, that you put the origin of the Sprite at the position of the Position2D. Therefore you need to calculate an offset (the direction/distance from the Position2Dnode to the center (origin) of the Sprite), which needs to be added to the sprite’s position.

Good Luck!

Thank you very much for your more than complete answer! It really helped me =)

Elis | 2019-02-22 20:57