If you would like, I can show you how to rewrite this little bit of code to deal with hexes instead of squares. Currently it is supposed to present you with a 30x30 scrollable grid of squares that you can light up and turn off by clicking on them with a mouse. You only need the mouse and its left button to use this program. It's written in rather simplistic style, because I tried to keep it short. It has some awkward features, but I hope you won't be distracted by them. They should be easy to fix later.
Before going into the geometry of hex maps, I'd like you to explain what kind of a hex map and interface you envision your game having. The general idea in most turn-based games that display the map is the same. You either fit the whole map on screen at once, or make scrollable one like here. In the latter case, you have a camera position that tells you where you currently are on the map. This camera position is used when deciding what & where to draw on the screen and how to deal with mouse picking.
Mouse picking means choosing the object that is currently under the mouse cursor when the user interacts with the program. And the reason I used a square map is that mouse picking iwth squares is super easy. It is not much harder with hexes, either, and we can go on to that if you like.
Note that if you can fit the entire map on the screen at once, this is just really a special case where the camera position is always constant. So we can solve the more general problem and use our solution in either case.
You can post a response to this message or PM me to continue with this, assuming you want to continue. (Perhaps you found an answer elsewhere already?) We'll find a passably good interface for your game. I am sure. Just have a little patience, as I don't necessarily visit here every day.
Code: Select all
local camera = {0, 0}
local screen = {800, 600}
local squares = nil
local squaresize = 50
local maxx, maxy = 30, 30
function love.load()
-- build the map
squares = {}
for y = 1, maxy do
local row = {}
for x = 1, maxx do
local sq = {set = false}
table.insert(row, sq)
end
table.insert(squares, row)
end
screen[1] = love.graphics.getWidth()
screen[2] = love.graphics.getHeight()
end
function love.draw()
-- draw the currently visible portion of the map
-- this draws every partially visible square and relies
-- on love drawing code to clip the edges
local camx, camy = unpack(camera)
local scrx, scry = unpack(screen)
local vleft = math.floor(camx/squaresize)
local vup = math.floor(camy/squaresize)
local horc = math.ceil(scrx/squaresize) + 1
local verc = math.ceil(scry/squaresize) + 1
for y = 1, verc do
for x = 1, horc do
if squares[vup+y] and squares[vup+y][vleft+x] then
local mode = "line"
if squares[vup+y][vleft+x].set then
mode = "fill"
end
love.graphics.rectangle(mode, (vleft+x-1)*squaresize - camx,
(vup+y-1)*squaresize - camy, squaresize, squaresize)
end
end
end
end
local scrollspeed = 200
local edge = 100
function love.update(dt)
-- scroll the screen if mouse is near edges
local scrx, scry = unpack(screen)
local mx, my = love.mouse.getPosition()
if mx < edge/2 then camera[1] = camera[1] - scrollspeed * dt end
if mx > scrx - edge/2 then camera[1] = camera[1] + scrollspeed * dt end
if my < edge/2 then camera[2] = camera[2] - scrollspeed * dt end
if my > scry - edge/2 then camera[2] = camera[2] + scrollspeed * dt end
-- limit the camera position from wandering off
if camera[1] < -edge then camera[1] = -edge end
if camera[2] < -edge then camera[2] = -edge end
local xlimit, ylimit = maxx*squaresize + edge - scrx, maxy*squaresize + edge - scry
if camera[1] > xlimit then camera[1] = xlimit end
if camera[2] > ylimit then camera[2] = ylimit end
end
function love.mousepressed(x, y, button)
-- toggle the clicked square on left button click
if button ~= 'l' then return end
local wx, wy = x + camera[1], y + camera[2]
local x, y = math.floor(wx/squaresize)+1, math.floor(wy/squaresize)+1
if squares[y] and squares[y][x] then
local value = squares[y][x].set
squares[y][x].set = not value -- toggle bool flag
end
end
I tested this on the Windows version, but it should of course work everywhere. Do let me know if there are mistakes or problems I didn't find while quickly writing & testing it.