How to Detect Mouse Input on a Tile and Change that Tile

Hi all, I’m wanting to detect mouse input on a tile that’s placed on a level using the tile map and then change that tile to another one. I have collisions setup on my tiles but when I click anywhere on the level the mouse input is detected everywhere (tile or not).

So something like if tile 1 is clicked on from this tile source draw tile 2 where I clicked my mouse.

Apologies if this doesn’t make sense… trying to wrap my head around what can and can’t be done with using tile sources / tile maps.

Thank you for taking the time to help me.

P.S. - my script is attached to my level game object which has the tile map as a component… not sure if that matters or is the wrong way to go about this.

Use action.x and action.y
Some thing like this will work :slight_smile:

local TILE_SIZE = 16       --your tile size
local TILE = {
   x = 5,
   y = 5
} -- x and y of tile

--in the on_input function
if action_id == hash("touch") then
   local x = math.floor(action.x)  --covert action.x to closest int
		local y = math.floor(action.y)  --covert action.y to closest int

		local tile_x = TILE.x * TILE_SIZE
		local tile_y = TILE.y * TILE_SIZE

		local next_x = (TILE.x + 1) * TILE_SIZE
		local next_y = (TILE.y + 1) * TILE_SIZE

		local touches_x = (action.x > tile_x) and (action.x < next_x)
		local touches_y = (action.y > tile_y) and (action.y < next_y)

		if touches_x and touches_y then  --if the tile is the required tile
			tilemap.set_tile("#my_tilemap", hash("layer1"), TILE.x+ 1, TILE.y +1 , 229) --set the current tile to some other tile
		end
end

It won’t affect anything :slight_smile:, as long as you don’t put a ‘/’ instead of ‘#’ in above example.

2 Likes

Awesome! I’ll try this out! Thank you so much for taking the time to reply.

1 Like

What if I have hundreds of tiles on the tile map? Do I do a loop and put them all in a table? Is there a way to get the tile if something else is colliding with it? What if I don’t know the tiles exact coordinates on the tile map? Because that’s what info the script is wanting right? Sorry for all the tile related questions. If anybody is willing to answer I’m really trying to soak this all in and figure out if a tile map is the way to go or if I should use a bunch of actors.

1 Like

What kind of game are you trying to create? You mention clicking on tiles and you mention things colliding with tiles. If you want a tilemap to act as a background for a level with passable areas and areas that actors can’t pass then use a tilemap for the level with some tiles in the tilesource assigned a collision group. And use game objects for the actors that are moving on the tilemap and that you can click on.

1 Like

It’s mainly a 2D turn based top down strategy game with mostly ASCII graphics.

I want there to be terrain that can be terraformed so for example tiles that represent higher spots on the map would need to be able to be lowered and changed at runtime.

For example a terraformer would have a radius around it that it could terraform and then those tiles would go from higher terrain to lower terrain. The terrain would not be complicated with about four or five tiles representing each elevation and only about four different height layers (maybe that is complicated, I’m not sure).

Thinking this through maybe it’d be best to have one game object for each elevation and then I could change out the sprite for different variations.

Either way there will still be either lots of tiles or lots of game objects. They would be repeated often so I don’t know how that would affect memory usage, etc…

It’s almost sounding like using game objects is the way to go.

What do you think? I hope so of that makes sense.

The tiles are 20px x 20px.

Thank you for the help!

I would use a tilemap for the actual terrain, probably with a parallel Lua based data structure (grid made up of Lua tables) to represent the data about the tiles. The terraformers would be game objects so that they are easier to interact with.

2 Likes

I’m a bit confused. If tile size is 16x16, how can you match tilemap location if you don’t do:

local x = math.ceil(action.x/TILE_SIZE)
local y = math.ceil(action.y/TILE_SIZE)

?
Also from my tests screen scale ratio comes into play on action.x & action.y.
Making it conversion like this:

local x = math.ceil(action.x/SCREEN_SCALE/TILE_SIZE)
local y = math.ceil(action.y/SCREEN_SCALE/TILE_SIZE)
1 Like

All of this seems complicated but I’ll give it a shot. Are there any learning resources for this topic specifically with examples? Even an extremely scaled down version of like a 5x5 grid? Thank you.

Oh !! My baad!!. @mannequinraces. I’ve updated the script. It will now work :smile:
[Sometimes I’m way too stupid :wink: ]

1 Like

No worries! Thanks. I’ll try out any and all suggestions.

In my opinion, the easiest way is to have 2x layers in tilemap from which one is hidden and have tiles that represent your needed information. Using previous examples you can convert world position into tilemap position and receive tile ID from the needed layer (one that’s visual for players and second hidden using specific tiles). You can read the ID of hidden layer and if you need to change height change visual tile and change in the hidden layer to one that represents needed height.
I’ve talked about this approach in my video -

5 Likes

Sounds interesting! I’ll check this out. Thanks for sharing.

2 Likes