0 votes

I have a game I am working on where there are tiles in rows and columns. Players can swap the tiles by dragging them around with the mouse and I want to check what order they are in after each move.

I've tried a couple of iterations of what I thought would work by using an Area2D node that moves to each tile position and adds the tiles to lists after releasing the mouse button. Instead, the Area2D moves, but only adds the first tile it was on to the list (or in the case of using a signal, doesn't even add anything after the first input).

I've tried using bodyentered and getoverlapping_bodies. I've also tried switching between _input and _process. Here is the relevant code trying to get just the top row:

func _process(_delta):
if Input.is_action_just_released("mouse_left"):
    checkTiles()

func checkTiles():
for column in columns:
    $PosChecker.position.x = firstColumnX + columnSpacingX*column
    $PosChecker/CollisionShape2D.position.x = firstColumnX + columnSpacingX*column
    print($PosChecker.position.x)
    rowList += $PosChecker.get_overlapping_bodies()
    for name in rowList:
        print(name.tempText)
$PosChecker.position.x = firstColumnX
$PosChecker.position.y = firstRowY
rowList.clear()

I'm assuming this has something to do with sequencing and/or collisions all processing at once (as in the case of getoverlappingbodies). But I've spent way too much time banging my head against the walling trying to figure this out and I obviously have no idea what I am doing.

Am I missing something or going about it wrong? Is there an elegant solution to this or should I maybe place Area2Ds at each tile position?

Godot version 3.2.3
in Engine by (15 points)

2 Answers

+1 vote
Best answer

You've managed to complicate a simple problem
Add all related nodes to an array then use a custom sorting function
even easier if they're part of a group

func compare_positions(a, b):
    return a.rect_position < b.rect_position

func checkTiles():
    var tiles = get_tree().get_nodes_in_group("Tiles")
    tiles.sort_custom(self, "compare_positions")
    print(tiles)

func _process(_delta):
    if Input.is_action_just_released("mouse_left"):
        checkTiles():

Can't really remember how xy sorting works but you can always use use two comparisons in that case to get the desired results

For rows

func compare_rows(a, b):
    return a.rect_position.x < b.rect_position.x

for columbs

func compare_columbs(a, b):
    return a.rect_position.y < b.rect_position.y
by (3,290 points)
selected by

Thanks! It works perfectly! I really was overdoing it.

+1 vote

Are You using TIleMap ?

If Yes, than You can iterate through tiles with Tilemap methods. Get-used-rect() for whole cells area, or manually like :

for x in yourtotalcellshorizontally:
     for y in your totalcellvertically:
            get-cell(x,y) or getcellv(x,y) 

If You want to only check column and row where cursor is, than just transofrm mouse position into world-to-map() and check it in similar way

by (1,121 points)

I am not, but I think there might be some confusion given that I was calling the nodes players drag around "tiles" in my post. They are KinematicBody2Ds.

Wakatta below was able to solve my issue, but I'm wondering now if using a TileMap is actually possible for my situation. Are you able to do a sort of drag and drop system such as an inventory system with TileMap?

For project like inventory even TileMap seems to overkill :). There are control nodes like Itemlist or gridcontainer useful for that. However they may lack some graphical shenanigans. All in all it is possible to easily make functional inventory with TileMap, as long as items are all one size :).

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 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 webmaster@godotengine.org with your username.