1
votes

This seems like a really simple question but I've been at this for a couple of hours and need an outsiders perspective.

I'm migrating a start of a game to Godot from Unity.

I'm selecting an area of tiles (startDragPosition, endDragPosition, both Vector2 objects) from a TileMap and setting them to a certain tile. Currently the dragging only works if the direction is top->bottom and left->right, so if the ending x and y are larger than the starting x and y In Unity(C#) I had a few simple lines to flip the rectangle values if it was dragged in reverse.

if (end_x < start_x) {
        int tmp = end_x;
        end_x = start_x;
        start_x = tmp;
    }
    if (end_y < start_y) {
        int tmp = end_y;
        end_y = start_y;
        start_y = tmp;
    }

However in when I try a similar approach in Godot it is not working for some reason. I'm thinking that I'm messing up somewhere earlier and any help would be appreciated. If there is an easier way of doing this please tell me I'm fairly new to Godot itself.

Here is the function responsible for dragging in my Godot script(GD)

func Drag():
if(Input.is_action_just_pressed("click")):
    startDragPosition=get_global_mouse_position()
if(Input.is_action_pressed("click")):
    endDragPosition=get_global_mouse_position()
    
    print("01 START: "+String(stepify(startDragPosition.x-8,16)/16)+"_"+String(stepify(startDragPosition.y-8,16)/16))
    print("01 END: "+String(stepify(endDragPosition.x-8,16)/16)+"_"+String(stepify(endDragPosition.y-8,16)/16))
    if(endDragPosition.x<startDragPosition.x):
        var temp = endDragPosition.x
        endDragPosition.x=startDragPosition.x
        startDragPosition.x=temp
        
    if(endDragPosition.y<startDragPosition.y):
        var temp = endDragPosition.y
        endDragPosition.y=startDragPosition.y
        startDragPosition.y=temp
    
    for x in range(startDragPosition.x,endDragPosition.x):
        for y in range(startDragPosition.y,endDragPosition.y):
            get_node("../DragPreview").set_cell((stepify(x-8,16))/16,(stepify(y-8,16))/16,0)
            #get_node("../DragPreview").update_bitmask_area(Vector2((stepify(x-8,16))/16,(stepify(y-8,16))/16))
            
if(Input.is_action_just_released("click")):
    print("START: "+String(stepify(startDragPosition.x-8,16)/16)+"_"+String(stepify(startDragPosition.y-8,16)/16))
    print("END: "+String(stepify(endDragPosition.x-8,16)/16)+"_"+String(stepify(endDragPosition.y-8,16)/16))
    startDragPosition=null
    endDragPosition=null
1
Note: you can use world_to_map to get the tile coordinates from a position. I believe that is what you are doing with stepify and division. You may also be interested in make_local_input. - Theraot
See also Wrong TileMap coordinates on zoom with InputEventScreenTouch and (Godot Engine) Fill an 2D Polygon with Tilemap tiles. I do not expect this to solve the problem, which is why I'm not writing it in an answer. - Theraot

1 Answers

1
votes

When you drag, you always write to endDragPosition.

When you drag to the left or drag up, and you update endDragPosition, it will have smaller coordinates than it had before. Because of that you swap the coordinates with startDragPosition… And then you keep dragging left or up, and that updates endDragPosition again. The original startDragPosition is lost.


Either you work with a copy when you are deciding the start and end:

var start = startDragPosition
var end = endDragPosition
if(end.x<start.x):
    var temp = end.x
    end.x=start.x
    start.x=temp

if(end.y<start.y):
    var temp = end.y
    end.y=start.y
    start.y=temp

for x in range(start.x,end.x):
    for y in range(start.y,end.y):
        # whatever
        pass

Or you forget this swapping shenanigans, and give the loops a step:

var start = startDragPosition
var end = endDragPosition
for x in range(start.x,end.x,sign(end.x-start.x)):
    for y in range(start.y,end.y,sign(end.y-start.y)):
        # whatever
        pass