Assigning element creation order for grid objects

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
Rishavs
Party member
Posts: 103
Joined: Sat Oct 17, 2009 5:29 am
Contact:

Assigning element creation order for grid objects

Post by Rishavs »

Hi

[Sorry for the shitty title. Couldn't think of any title.]

I am trying to create a simple hex grid using Kenny's hex tiles.

For the grid, I need all the tiles to be rendered in proper order:
left to right
and then the next row.

Unfortunately, i am using a hex grid obj insetad of nested for loops (which were originaly used for creating the grid)

Code: Select all

    for id, hex in pairs(hex_grid_obj) do
        local hexX, hexY = cam:cameraCoords(hex.center.x, hex.center.y)
        
        -- only render if hexes are within the screen
        if 0 < hexX and hexX < scrWidth 
            and 0 < hexY and hexY < scrHeight then        

            love.graphics.draw( img_ocean,hex.center.x - (math.sqrt(3) * hex_size /2) , hex.center.y- hex_size)

        end
    end
As expected, the tiles are arranged in strange order. The obj doesnt have the hexes in the order of their creation.
randTiles.png
randTiles.png (104.54 KiB) Viewed 3991 times
This is a sample hex in the grid:

Code: Select all

"38q50r-88s" = {
  biome = "ocean",
  center = {
    x = 549.92613140312,
    y = 380
  },
  coord = {
    q = 38,
    r = 50,
    s = -88
  },
  elevation = 0,
  isOnEdge = false,
  lum = 237,
  moisture = 0,
  tempColor = { 20, 120, 200 },
  vertices = { 554.25625842204, 382.5, 549.92613140312, 385, 545.5960043842, 382.5, 545.5960043842, 377.5, 549.92613140312, 375, 554.25625842204, 377.5 }
}
the hexes were added to the obj using set notation:

Code: Select all

hex_grid_obj[temp_hex_id] = temp_hex
Some ways, i can think of fixing this is :
Add a counter to the nested for loops used in creating grid. then assign the count as a attribute to each hex, putting a serial number against each. When the grid is done, sort the hexes in the obj using this serial number. except i dont know how to sort the elements of any object based on its attribute.

Add the hex to the set in a way that order is maintained. Again no idea how to do that.

I am sure many of you have conquered this issue. Can you give me some pointers on how to tackle it?
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Assigning element creation order for grid objects

Post by raidho36 »

Or you can just put the entities in a table using the count as index.
User avatar
Rishavs
Party member
Posts: 103
Joined: Sat Oct 17, 2009 5:29 am
Contact:

Re: Assigning element creation order for grid objects

Post by Rishavs »

hmmm....

I wanted to keep all my hex attributes in a single object.

But from a rendering POV your solutions seems the simplest and fastest. Will try it rightaway.
Are there other alternative methods?
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Assigning element creation order for grid objects

Post by raidho36 »

Why considering them if you already got the one that's better? You could encode some data into key but generating strings will absolutely tank performance, and you will still need them in an indexed array in order for them to be sorted, for other types of keys order is not defined and is typically random.
User avatar
Rishavs
Party member
Posts: 103
Joined: Sat Oct 17, 2009 5:29 am
Contact:

Re: Assigning element creation order for grid objects

Post by Rishavs »

Ok. this is much faster, for sure, than iterating through my heavy hexgrid object. :D

but i am still not able to get a proper image rendering order in grids. I started adding the hex ids to a simple list and used ipairs to run through it. But my output is still skewed.
randTiles.png
randTiles.png (49.31 KiB) Viewed 3970 times

i did what you suggested and am putting the hex ids in a "hex_grid_ordered_table" list.

Code: Select all

1        0q0r0s
2        0q1r-1s
3       -1q2r-1s
4       -1q3r-2s
5       -2q4r-2s
...
...
I am creating grid as thus:

Code: Select all

function create_hex_grid()
    
    local temp_hex = {}
    local temp_hex_points = {}
    local temp_hex_id = 0
    
    local hex_height = hex_size * 2
    local hex_width = math.sqrt(3) * hex_size
    
    local starting_hex_X = hex_width/2
    local starting_hex_Y = hex_height/2
    
    -- first create a staggered points grid
    for w=0, lvl_width_hex_count - 1 do
        for h = 0, lvl_height_hex_count - 1 do
            hexX = starting_hex_X + (w * hex_width) + ((hex_width/2) * (h % 2))
            hexY = starting_hex_Y + (h * hex_height * 3/4) 
            
            -- calculate and save the axial coordinates
            local cQ = w - (h - (h % 2)) / 2
            local cR = h
            local cS = - cQ - cR
            
            if cQ == -0 then cQ = 0 end
            if cR == -0 then cR = 0 end
            if cS == -0 then cS = 0 end
     
            temp_hex_id = cQ .. "q" .. cR .. "r" .. cS .. "s"
            temp_hex_points = create_hex(hexX, hexY, hex_size - hex_grid_gap/2)
            temp_hex  = {
                center = {x = hexX, y = hexY},
                coord = {q = cQ, r = cR, s = cS},
                biome = "empty",
                isOnEdge = false,
                vertices = temp_hex_points
            }

            hex_grid_obj[temp_hex_id] = temp_hex
            
            table.insert(hex_grid_ordered_table, temp_hex_id)
        
        end
    end
    
end

function create_hex (hX, hY, hSize)
    local fn_hex_points = {}
    
    for i=0,5 do
        local vertAngle = 2 * math.pi / 6 * (i + 0.5)
        local vertX = hX + hSize * math.cos(vertAngle)
        local vertY = hY + hSize * math.sin(vertAngle)
        
        table.insert(fn_hex_points, vertX)
        table.insert(fn_hex_points, vertY)
    end
    
    return fn_hex_points
end

and my draw function is:

Code: Select all

function love.draw(dt)
    for _, h_id in ipairs(hex_grid_ordered_table) do
        
        local hex = hex_grid_obj[h_id]
        local hexX, hexY = hex.center.x, hex.center.y
        
        -- only render if hexes are within the screen
        if 0 < hexX and hexX < scrWidth 
            and 0 < hexY and hexY < scrHeight then
            love.graphics.draw( img_ocean, hex.center.x - (math.sqrt(3) * hex_size /2) , hex.center.y- hex_size)
        end
    end

    love.graphics.setColor(255, 255, 255)
    love.graphics.print("FPS: "..tostring(love.timer.getFPS( )), 10, 10)    
    love.graphics.print("Hexes: ".. render_count, 10, 30)
end
User avatar
raidho36
Party member
Posts: 2063
Joined: Mon Jun 17, 2013 12:00 pm

Re: Assigning element creation order for grid objects

Post by raidho36 »

I think it's because you first push in there even rows then odd rows, so any odd row is on top of any even row.
User avatar
Rishavs
Party member
Posts: 103
Joined: Sat Oct 17, 2009 5:29 am
Contact:

Re: Assigning element creation order for grid objects

Post by Rishavs »

crap. you are right. it means i have to write my entire hex code from scratch as all the id generation an such was done for width first loop. Thanks!
User avatar
Rishavs
Party member
Posts: 103
Joined: Sat Oct 17, 2009 5:29 am
Contact:

Re: Assigning element creation order for grid objects

Post by Rishavs »

whoa!
i just flipped x and h in my nested for loops and everything works. I was worried that i will have to redo my every single helper function. o.0
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 2 guests