One for the mathematicians: mapping screen click to iso grid

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
togFox
Party member
Posts: 828
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

One for the mathematicians: mapping screen click to iso grid

Post by togFox »

Never done iso maps before so never realised how hard this is. I have an isometric tiled map where 1,1 is in the top corner and 1,col is in the right corner of the screen (orientation matters). When there is a mouse-click on a tile, I need to work out which tile was clicked. I watched this very good tutorial where the first 10 minutes explains the maths but then he jumps to C# or C++ or to a language I can't even identify :(

https://www.youtube.com/watch?v=ukkbNKTgf5U

None the less - I pick through the demo code he provides here:
https://github.com/OneLoneCoder/olcPix ... cTiles.cpp

and I think I've done okay translating the C into LUA:

Code: Select all

function ConvertGraphicsToGridXY(x,y)
-- Converts a screen co-ordinate (origin top-left corner) into an isometric grid co-ordinate
	local tilewidth = 32
	local tileheight = 21

	-- Work out active cell. This means the 'normal' left/right aligned grid
	local cellx = x / tilewidth
	local celly = y / tileheight
	
	-- Work out mouse offset into cell. Will be used later to determine if x,y is in one of the corners of the cell
	local offsetx = x / tilewidth
	local offsety = y / tileheight
	
	isox = cf.round(celly + (cellx),1)		-- cf.round is just a rounding function from one of my personal libraries
	isoy = cf.round(celly - cellx,1)
	
	return isox,isoy

end
The approach is to 'overlay' an invisible left/right,up/down grid over the isometric grid, determine which cell was clicked, then determine which corner of the cell was clicked, and then map that to the iso grid.

I have two problems:
a) is my code conversion actually correct (I think it is)
b) in the tutorial, he uses some sort of colour mask thingy to detect corner clicks. Anyone familiar with the subject might have seen this before:
Image

Other languages can check which colour was clicked and thereby know what corner was clicked. Is there a similar way in lua/love2d?

Here is my tiled map for reference:

Image

Finally, I'm happy to use some module or engine or something with this but things like STI and tileclick either don't do isometric or don't do forever expanding random maps (i.e you have to handcraft each map).

This is just day 2 on this project and I'm pretty chuffed with the progress already. With so many isometric dungeon-crawlers out there I'm hoping this is an easy problem to fix. Thanks.
Last project:
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/idle-gridiron
User avatar
togFox
Party member
Posts: 828
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: One for the mathematicians: mapping screen click to iso grid

Post by togFox »

I've just found this function in LUAPill github that is probably helpful:

Code: Select all

function luapill:screenToMap(screen)
   local map = {}
   screen.x = (screen.x - CAMERA.x) / TILESCALE
   screen.y = (screen.y - CAMERA.y) / TILESCALE
   map.x = math.floor(math.floor(screen.x / TILE_WIDTH_HALF + screen.y / TILE_HEIGHT_HALF) / 2)
   map.y = math.floor(math.floor(screen.y / TILE_HEIGHT_HALF -(screen.x / TILE_WIDTH_HALF)) / 2) + 1
   return map
end
I don't need tilescale (camera zooming) and camera.x/y is probably relevant (panning the map). I'm sure a solution is close!
Last project:
https://togfox.itch.io/hwarang
A card game that brings sword fighting to life.
Current project:
Idle gridiron. Set team orders then idle and watch: https://togfox.itch.io/idle-gridiron
User avatar
ivan
Party member
Posts: 1915
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: One for the mathematicians: mapping screen click to iso grid

Post by ivan »

It's possible to do this using just math (without a bitmap mask), but it depends on the tilt of the tile.
A while ago I wrote a short tutorial on:
https://2dengine.com/?p=isometric#Mouse ... tile_index
sisyphu2
Prole
Posts: 17
Joined: Mon Sep 28, 2020 3:15 pm

Re: One for the mathematicians: mapping screen click to iso grid

Post by sisyphu2 »

togFox wrote: Sun May 02, 2021 12:55 am Never done iso maps before so never realised how hard this is. I have an isometric tiled map where 1,1 is in the top corner and 1,col is in the right corner of the screen (orientation matters). When there is a mouse-click on a tile, I need to work out which tile was clicked. I watched this very good tutorial where the first 10 minutes explains the maths but then he jumps to C# or C++ or to a language I can't even identify :(

https://www.youtube.com/watch?v=ukkbNKTgf5U

None the less - I pick through the demo code he provides here:
https://github.com/OneLoneCoder/olcPix ... cTiles.cpp

and I think I've done okay translating the C into LUA:

Code: Select all

function ConvertGraphicsToGridXY(x,y)
-- Converts a screen co-ordinate (origin top-left corner) into an isometric grid co-ordinate
	local tilewidth = 32
	local tileheight = 21

	-- Work out active cell. This means the 'normal' left/right aligned grid
	local cellx = x / tilewidth
	local celly = y / tileheight
	
	-- Work out mouse offset into cell. Will be used later to determine if x,y is in one of the corners of the cell
	local offsetx = x / tilewidth
	local offsety = y / tileheight
	
	isox = cf.round(celly + (cellx),1)		-- cf.round is just a rounding function from one of my personal libraries
	isoy = cf.round(celly - cellx,1)
	
	return isox,isoy

end
The approach is to 'overlay' an invisible left/right,up/down grid over the isometric grid, determine which cell was clicked, then determine which corner of the cell was clicked, and then map that to the iso grid.

I have two problems:
a) is my code conversion actually correct (I think it is)
b) in the tutorial, he uses some sort of colour mask thingy to detect corner clicks. Anyone familiar with the subject might have seen this before:
Image

Other languages can check which colour was clicked and thereby know what corner was clicked. Is there a similar way in lua/love2d?

Here is my tiled map for reference:

Image

Finally, I'm happy to use some module or engine or something with this but things like STI and tileclick either don't do isometric or don't do forever expanding random maps (i.e you have to handcraft each map).

This is just day 2 on this project and I'm pretty chuffed with the progress already. With so many isometric dungeon-crawlers out there I'm hoping this is an easy problem to fix. Thanks.
I encountered the same challenge when starting my own isometric game.
This article was the most useful for me when starting out:
http://clintbellanger.net/articles/isometric_math/
As the poster above says, I would also endorse a simple mathematical approach.
RNavega
Party member
Posts: 385
Joined: Sun Aug 16, 2020 1:28 pm

Re: One for the mathematicians: mapping screen click to iso grid

Post by RNavega »

sisyphu2 wrote: Thu May 06, 2021 10:02 pm This article was the most useful for me when starting out:
http://clintbellanger.net/articles/isometric_math/
Nice tutorial, thanks. I like how it's framed as an affine transformation of spaces -- to travel on the horizontal axis you need a 2D vector, as well as another 2D vector to travel on the vertical axis. So it's not just (x,y), but (x,y),(u,v).

What I didn't understand was this part:

EDIT: whoops, nevermind, I was making an arithmetic error.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 14 guests