Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include diagonal tiles in the surrounding tiles as an optional parameter #3973

Open
creadicted opened this issue Feb 15, 2022 · 6 comments · May be fixed by godotengine/godot#58140
Open

Include diagonal tiles in the surrounding tiles as an optional parameter #3973

creadicted opened this issue Feb 15, 2022 · 6 comments · May be fixed by godotengine/godot#58140

Comments

@creadicted
Copy link

creadicted commented Feb 15, 2022

Describe the project you are working on

I play with tilemaps, procedural generation and test out the new features of 4.0 Alpha

Describe the problem or limitation you are having in your project

On TileMaps the call get_surrounding_tiles will only return the left, top, right and bottom cells. When using with a grid I would expect also the diagonal tiles to be included in this request. I would like to introduce an optional parameter that also allows the selection of the diagonal parameters.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

It will remove the need to iterate over the tiles manually. Similar to the get_surrounding_tiles() method, which is already a wrapper over the get_neighbor_cell() method.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

draft: godotengine/godot#58140

TypedArray<Vector2i> TileMap::get_surrounding_tiles(Vector2i coords, bool p_include_diagonal_tiles) {
	if (!tile_set.is_valid()) {
		return TypedArray<Vector2i>();
	}

	TypedArray<Vector2i> around;
	TileSet::TileShape shape = tile_set->get_tile_shape();
	if (shape == TileSet::TILE_SHAPE_SQUARE) {
		around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE));
		around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE));
		around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_LEFT_SIDE));
		around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_SIDE));
        // Additional checks
        if(p_include_diagonal_tiles) {
            around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER));
            around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER));
            around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER));
            around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER));
        }
...
  • get the surrounding tiles:
    • get_surrounding_tiles(cell)
  • get the surrounding tiles including the diagonal ones:
    • get_surrounding_tiles(cell, true)

If this enhancement will not be used often, can it be worked around with a few lines of script?

Yes it can be. Similar to the current get_surrounding_tiles method which uses get_neighbor_cell internally as well.

func get_diagonal_cells(cell):
	var cells = []
	cells.append(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER))
	cells.append(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER))
	cells.append(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER))
	cells.append(get_neighbor_cell(cell, TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER))
	return cells

Is there a reason why this should be core and not an add-on in the asset library?

Because it would complete an existing method.

@groud
Copy link
Member

groud commented Feb 15, 2022

As stated on the related PR, I am not strictly again adding the feature but I'd would prefer to have it backed by a real-life use case. I mostly implemented this function as a helper to deal with the bucket fill tool, for which getting diagonals tiles are not useful.

But yeah, if someone use it for something else I am not against adding this parameter, it would make sense.

@GrindonB
Copy link

GrindonB commented Jul 6, 2023

Hello, unsure if this is the correct place, but I have a use-case in a game I'm making @groud

I'd like to get all tiles (including diagonals) around a point, which represents all valid adjacent tiles to a target in a game-word where diagonal movement is possible. Would really like this feature, thank you.

If it helps, I assumed including diagonals was the default behavior of this function before I looked into it.

@williamsokol
Copy link

I was trying to do this for an easier way to define auto tiles I should update to fix the bitmask.
Was trying to do:

var sur =  map.get_surrounding_cells(cell)
map.set_cells_terrain_connect(1,sur,0,0)

I will now have to make a nested for loop to iterate through the diagonals aswell

@henridd
Copy link

henridd commented Dec 2, 2024

I believe I have a use case for this. Or maybe I just don't know the right way of doing what I want.

In my game, you can place an action on top of a cell, such as "Mine". Once that's done, you can right-click on a unit and then right-click on the cell and order it to perform the action.

| 1 | . | . | . |
| . | 2 | 3 | . |
| . | . | . | . |

My goal is to, if the user right-clicks on the action 1 in the grid shown above, it automatically executes the actions on positions 2 and 3 in a sequence. If GetSurroundCells would return the cells on all 8 directions, this would be very easy to achieve.

@retroshark
Copy link

retroshark commented Dec 8, 2024

I also have a use case for this. I am attempting to get all the surrounding tiles (including diagonals) to update my cells using set_cells_terrain_connect().

Having an optional parameter to check for diagonals with get_surrounding_cells() would make it significantly easier in multiple areas of my project.

My current solution is the following:

func get_neighbor_cells(_position: Vector2i) -> Array:
	# Get the neighboring cell positions of cell at _x, _y 
	var neighbor_cells: Array
	
	for x in range(-1, 2):
		for y in range(-1, 2):
			if x == 0 and y == 0:
				continue
			var nx = _position.x + x
			var ny = _position.y + y
			neighbor_cells.append(Vector2i(nx, ny))
			
	return neighbor_cells

@hk0i
Copy link

hk0i commented Dec 13, 2024

I'm working on a multiplayer top-down game where I have a single spawn point at the start of the level.
I want to scan all its neighboring tiles and find the next available area for a player to spawn.

It seems like it might be possible to do this more arduously using get_neighbor_cell(coords:neighbor:), but the CellNeighbor enum has more than 9 "sides" which also seems a bit confusing and requires some sub-selections.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants