Page 1 of 2
snap object to grid
Posted: Sun Sep 29, 2013 6:55 am
by mangadrive
I have a selector that goes over a tilemap that is 64x64. I have it snapping to tiles if an enemy is present, but for the life of my can't seem to create a free targeting option that would just allow me to select the blank tile with a mouse and snap the selector to that tile.
Code: Select all
function ents.TargetLockSelected() -- Enemy Selection with Mouse locked to enemies
for i, ent in pairs(ents.enemies) do
local x = love.mouse.getX()
local y = love.mouse.getY()
if x >= 272 and x <= 528 and y >= 32 and y <= 288 and x > ent.x and y > ent.y then
selector.x = ent.x
selector.y = ent.y
end
end
end
I just need a solution that will point to a tile within that same range and not worry about enemies but still snap to the 64/64 grid... and I know it's easier than my mind is letting it be right now.
Re: snap object to grid
Posted: Sun Sep 29, 2013 8:39 am
by Plu
You have to round the selection ring's coodinates to something that aligns with the grid. I don't know your full code, but the basic idea is like this:
Code: Select all
x = math.floor( mouse.x / 64 ) * 64
That would snap your x to always be a multiple of 64. Depending on whether you have your x in the center or a corner of the tile, and on whether you start counting at 0 or 1, you might have to add another 32 or 64 to the total.
Re: snap object to grid
Posted: Sun Sep 29, 2013 7:51 pm
by mangadrive
I knew it was something simple like this and I didn't have math.floor considered.
Thank you very much.
Re: snap object to grid
Posted: Mon Sep 30, 2013 2:47 am
by mangadrive
So just a note for anyone that may search this:
I ended up actually hard coding all the values like a GUI element for the selection pointer because while math.floor and the tile considerations do work, it's problematic on a tile map or grid that's not centered on 0. You can offset it by adding/subtracting portions of the tile width/height as suggested, but you'll get weird things like the selection jumping to the left/right/up/down if you click on the left/right/up/down half of the tile.
So in the end I wrote a bunch of if statements that considered x/y instead and would just shift the selector to the tile somewhat manually like so in this example:
Code: Select all
local x = love.mouse.getX()
if x >= 272 and x <= 336 then
selector.x = 272
end
More code, but more accurate for needed purposes.
Moral of the story: Over thinking is dangerous and you aren't going to kill your whole project and I could have fixed this myself long ago had I not been stubborn into thinking I needed to do it the "short" way v/s the more code way that actually fixed the problem.
Re: snap object to grid
Posted: Mon Sep 30, 2013 9:05 am
by Germanunkol
I know they say to never change a running system, but:
I think you should look into this further. Hard-Coding is the easiest way, but changing anything later on will be a pain.*
How are you offsetting the map? Are you using translate?
You should look into vrdl's "HUMP" library, it offers a camera that is really useful here. If you use this, there's a function that converts mouse coordinates to world-coordinates, which is probably the problem that you're having.
Although it's really weird that hard coding it fixes it. Maybe you could post a .love showing the problem?
I've got a working example of snap-to-grid in the attached demo.
- Bezier.love
- (Fixed version) Usage: Draw a shape using CTRL+click multiple times. Then click outside the shape and drag it. Both creating of points and dragging the shape snap to grid.
- (28.13 KiB) Downloaded 228 times
The code for smapping to grid is in Scripts/shapeControl.lua, in function ShapeControl:update( mX, mY, dt ).
mX and mY are the mouse coordinates, transformed into world coordinates, after moving and scaling the camera.
Then, you can simply do:
Code: Select all
if self.snapToGrid then
mX = math.floor((mX+self.gridSize/2)/self.gridSize)*self.gridSize
mY = math.floor((mY+self.gridSize/2)/self.gridSize)*self.gridSize
end
"+self.gridSize/2" is there in ordeer to round up if mX or mY are more than half way to the next grid line.
* If you really need to hard-code it, at least do it using a while or for loop, something like:
Code: Select all
tileSize = 50
curX = 0
while curX < x do
if curX + tileSize >= x then
x = curX
break
end
curX = curX + tileSize
end
(untested)
[]
Posted: Mon Sep 30, 2013 10:43 am
by bekey
-snip-
Re: snap object to grid
Posted: Mon Sep 30, 2013 11:51 am
by Germanunkol
Very sorry about that, I had some linux-specific code in there (os.executed("sleep 0.1")) for debugging purposes which I forgot to replace with the correct platform-independent version (love.timer.sleep(0.1)). Thanks for pointing that out!
Updated the post above, added new version.
Could you try again and see if I fixed it?
Making a mental not to self never to use os.execute again, unless needed.
[]
Posted: Mon Sep 30, 2013 11:52 am
by bekey
-snip-
Re: snap object to grid
Posted: Mon Sep 30, 2013 11:57 am
by Germanunkol
Updated again (see post above). I've never seen that error you're posting, but I suspect it has to do with giving values of 1f instead of 1.0 in a shader?
Weird that it works for me, though...
WIll boot up Windows and try it myself.
Edit: Tested the new version, works for me on Linux and on Win7, 64bit.
[]
Posted: Mon Sep 30, 2013 12:00 pm
by bekey
-snip-