Tile Merging

Showcase your libraries, tools and other projects that help your fellow love users.
Post Reply
User avatar
AaronWizard
Citizen
Posts: 68
Joined: Sun Nov 06, 2011 2:45 pm
Location: Canada

Tile Merging

Post by AaronWizard »

tile_merge.png
tile_merge.png (37.95 KiB) Viewed 1897 times
I've come up with a way to group tiles into larger rectangles. This is great for physics where you can create rectangles to cover wall tiles without creating a rectangle for every individual tile.

Code: Select all

-- map_width and map_height are the dimensions of the map
-- is_wall_f checks if a tile is a wall

local rectangles = {} -- Each rectangle covers a grid of wall tiles

for x = 0, map_width - 1 do
    local start_y
    local end_y

    for y = 0, map_height - 1 do
        if is_wall_f(x, y) then
            if not start_y then
                start_y = y
            end
            end_y = y
        elseif start_y then
            local overlaps = {}
            for _, r in ipairs(rectangles) do
                if (r.end_x == x - 1)
                  and (start_y <= r.start_y)
                  and (end_y >= r.end_y) then
                    table.insert(overlaps, r)
                end
            end
            table.sort(
                overlaps,
                function (a, b)
                    return a.start_y < b.start_y
                end
            )

            for _, r in ipairs(overlaps) do
                if start_y < r.start_y then
                    local new_rect = {
                        start_x = x,
                        start_y = start_y,
                        end_x = x,
                        end_y = r.start_y - 1
                    }
                    table.insert(rectangles, new_rect)
                    start_y = r.start_y
                end

                if start_y == r.start_y then
                    r.end_x = r.end_x + 1

                    if end_y == r.end_y then
                        start_y = nil
                        end_y = nil
                    elseif end_y > r.end_y then
                        start_y = r.end_y + 1
                    end
                end
            end

            if start_y then
                local new_rect = {
                    start_x = x,
                    start_y = start_y,
                    end_x = x,
                    end_y = end_y
                }
                table.insert(rectangles, new_rect)

                start_y = nil
                end_y = nil
            end
        end
    end

    if start_y then
        local new_rect = {
            start_x = x,
            start_y = start_y,
            end_x = x,
            end_y = end_y
        }
        table.insert(rectangles, new_rect)

        start_y = nil
        end_y = nil
    end
end

-- Example: Use contents of rectangles to create physics bodies
-- phys_world is the world, wall_rects is the list of...wall rectangles

for _, r in ipairs(rectangles) do
    local start_x = r.start_x * TILE_SIZE
    local start_y = r.start_y * TILE_SIZE
    local width = (r.end_x - r.start_x + 1) * TILE_SIZE
    local height = (r.end_y - r.start_y + 1) * TILE_SIZE

    local x = start_x + (width / 2)
    local y = start_y + (height / 2)

    local body = love.physics.newBody(phys_world, x, y, 0, 0)
    local shape = love.physics.newRectangleShape(body, 0, 0,
      width, height)

    shape:setFriction(0)

    table.insert(wall_rects, {body = body, shape = shape})
end
User avatar
SiENcE
Party member
Posts: 792
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: Tile Merging

Post by SiENcE »

You should add this to the wiki as code snippet.
User avatar
AaronWizard
Citizen
Posts: 68
Joined: Sun Nov 06, 2011 2:45 pm
Location: Canada

Re: Tile Merging

Post by AaronWizard »

User avatar
slime
Solid Snayke
Posts: 3134
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Tile Merging

Post by slime »

That's pretty awesome, thanks for sharing it. :)
User avatar
SiENcE
Party member
Posts: 792
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: Tile Merging

Post by SiENcE »

Karma to you.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Tile Merging

Post by Robin »

I wrote something similar for Simon, some months ago. I don't know how it compares to your version, but it might be interesting to look at as well.
Attachments
rectanglify.love
(950 Bytes) Downloaded 76 times
Help us help you: attach a .love.
Post Reply

Who is online

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