function LevelLoadTiles() LevelInfo = {} Tiles = dofile("Mothback/data/tiles.lua") --[[ on level format: id = tile identifier depth = order in the render force = rendering other tile instead of the one in this position overlay = render another tile id overlay_depth = foreground/background overlay depth type = collision type ]] LevelTiles = json.decode(getInput("Mothback/data/levels/"..currLevel..".json")) LevelInfo.Width = LevelGetWidth() LevelInfo.Height = LevelGetHeight() LevelIndexTiles() TileCreateObjects() end function LevelGetHeight() return #LevelTiles * tileProperties.height end function LevelGetWidth() local width = 0 for i = 1, #LevelTiles do if width < #LevelTiles[i] then width = #LevelTiles[i] end end return width * tileProperties.width end function LevelIndexTiles() TileIndex = {} -- number of tiles in tileset! local width = tileProperties.tileset:getPixelWidth()/tileProperties.width local height = tileProperties.tileset:getPixelHeight()/tileProperties.height for i = 0, height do for j = 0, width do TileIndex[i*width+j+1] = love.graphics.newQuad( j*tileProperties.width, i*tileProperties.height, tileProperties.width, tileProperties.height, tileProperties.tileset:getDimensions() ) end end for _, properties in pairs(Tiles) do if properties.animation ~= nil then properties.tileset = love.graphics.newImage("assets/terrain/"..properties.animation..".png") properties.imgs = {} properties.current_image = 1 properties.current_subimage = 1 local tileset = properties.tileset local width = tileset:getPixelWidth()/tileProperties.width local height = tileset:getPixelHeight()/tileProperties.height local image_count = 0 for i = 0, height-1 do for j = 0, width-1 do local quad = love.graphics.newQuad( j*tileProperties.width, i*tileProperties.height, tileProperties.width, tileProperties.height, tileset:getDimensions() ) image_count = image_count + 1 table.insert(properties.imgs,quad) end end properties.image_count = image_count end end end function LevelDisplayForeground() for i = 1, #LevelTiles do for j = 1, #LevelTiles[i] do if LevelTiles[i][j] ~= 0 then local depth = TileGetDepth(LevelTiles[i][j]) DrawTile( LevelTiles[i][j], tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x, tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y, "foreground" ) end end end end function LevelDisplayBackground() for i = 1, #LevelTiles do for j = 1, #LevelTiles[i] do if LevelTiles[i][j] ~= 0 then local depth = TileGetDepth(LevelTiles[i][j]) DrawTile( LevelTiles[i][j], tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x, tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y, "background" ) end end end end function TileGetType(tile_id) for _, properties in ipairs(Tiles) do if properties.id == tile_id then return properties.type end end end function TileGetDepth(tile_id) for _, properties in ipairs(Tiles) do if properties.id == tile_id then return properties.depth end end end function GridDisplay() for i = 1, #LevelTiles do for j = 1, #LevelTiles[i] do love.graphics.rectangle( "line", tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.width) - Camera.pos.x, tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) - Camera.pos.y, tileProperties.scale * tileProperties.width, tileProperties.scale * tileProperties.height ) end end end function TileCreateObjects() objects.collisions = {} objects.platforms = {} objects.ladders = {} for i = 1, #LevelTiles do for j = 1, #LevelTiles[i] do if LevelTiles[i][j] ~= 0 then local type = TileGetType(LevelTiles[i][j]) local base_x = tileProperties.scale * j * tileProperties.width + tileProperties.scale * (levelProperties.offset.x - tileProperties.height) local base_y = tileProperties.scale * i * tileProperties.height + tileProperties.scale * (levelProperties.offset.y - tileProperties.height) if type == "whole" then local col = Collision:New( base_x, base_y, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "half_bottom" then local col = Collision:New( base_x, base_y + tileProperties.height/2 * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "half_top" then local col = Collision:New( base_x, base_y , base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "half_right" then local col = Collision:New( base_x + tileProperties.height/2 * tileProperties.scale, base_y, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "half_left" then local col = Collision:New( base_x, base_y, base_x + tileProperties.height/2 * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "platform" then local plat = Collision:New( base_x, base_y + tileProperties.scale * 2, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2 ) table.insert(objects.platforms,plat) elseif type == "ramp2_bot_left_whole" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x, base_y + k * tileProperties.scale - tileProperties.scale, base_x + k * 2 * tileProperties.scale, base_y + k * tileProperties.scale ) table.insert(objects.collisions,slope) end -- fill lower half local col = Collision:New( base_x, base_y + tileProperties.height/2 * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "ramp2_bot_left_half" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x, base_y + tileProperties.height/2 * tileProperties.scale + k * tileProperties.scale - tileProperties.scale, base_x + k * 2 * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale + k * tileProperties.scale ) table.insert(objects.collisions,slope) end elseif type == "ramp2_top_left_whole" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x, base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale - (k-1) * 2 * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale + tileProperties.scale ) table.insert(objects.collisions,slope) end -- fill higher half local col = Collision:New( base_x, base_y, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "ramp2_top_left_half" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x, base_y - tileProperties.scale + k * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale - (k-1) * 2 * tileProperties.scale, base_y - tileProperties.scale + k * tileProperties.scale + tileProperties.scale ) table.insert(objects.collisions,slope) end elseif type == "ramp2_bot_right_whole" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x + (k-8) * -2 * tileProperties.scale, base_y - tileProperties.scale + k * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale, base_y - tileProperties.scale + k * tileProperties.scale + tileProperties.scale ) table.insert(objects.collisions,slope) end -- fill lower half local col = Collision:New( base_x, base_y + tileProperties.height/2 * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "ramp2_bot_right_half" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x + (k-8) * -2 * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale - tileProperties.scale + k * tileProperties.scale + tileProperties.scale ) table.insert(objects.collisions,slope) end elseif type == "ramp2_top_right_half" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x + (k-8) * -2 * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale + tileProperties.scale ) table.insert(objects.collisions,slope) end elseif type == "ramp2_top_right_whole" then for k = 1, 8 do -- do ramp owo local slope = Collision:New( base_x + (k-8) * -2 * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale + tileProperties.height/2 * tileProperties.scale - k * tileProperties.scale + tileProperties.scale ) table.insert(objects.collisions,slope) end -- fill higher half local col = Collision:New( base_x, base_y, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale ) table.insert(objects.collisions,col) elseif type == "ramp1_bot_left" then for k = 1, 16 do -- do ramp owo local slope = Collision:New( base_x, base_y + k * tileProperties.scale - tileProperties.scale, base_x + k * tileProperties.scale, base_y + k * tileProperties.scale ) table.insert(objects.collisions,slope) end elseif type == "ladder_right" then local ladder = Collision:New( base_x + (tileProperties.width-4)* tileProperties.scale, base_y, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.ladders,ladder) elseif type == "ladder_platform_right" then local ladder = Collision:New( base_x + (tileProperties.width-4)* tileProperties.scale, base_y + tileProperties.scale * 2, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.ladders,ladder) local plat = Collision:New( base_x, base_y + tileProperties.scale * 2, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2 ) table.insert(objects.platforms,plat) elseif type == "ladder_left" then local ladder = Collision:New( base_x, base_y, base_x + tileProperties.scale * 4, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.ladders,ladder) elseif type == "ladder_platform_left" then local ladder = Collision:New( base_x, base_y + tileProperties.scale * 2, base_x + tileProperties.scale * 4, base_y + tileProperties.height * tileProperties.scale ) table.insert(objects.ladders,ladder) local plat = Collision:New( base_x, base_y + tileProperties.scale * 2, base_x + tileProperties.width * tileProperties.scale, base_y + tileProperties.height/4 * tileProperties.scale + tileProperties.scale * 2 ) table.insert(objects.platforms,plat) end end end end end function AnimateTiles() for _, properties in pairs(Tiles) do if properties.animation ~= nil then -- calculate subimage properties.current_subimage = properties.current_subimage + current_dt -- cycle image if properties.current_subimage >= properties.delay then properties.current_subimage = properties.current_subimage - properties.delay properties.current_image = properties.current_image + 1 end if properties.current_image > properties.image_count then properties.current_image = properties.current_image - properties.image_count end end end end function DrawTile(tile_id,x,y,depth) for _, properties in pairs(Tiles) do if tile_id == properties.id then if properties.animation ~= nil then if properties.imgs[properties.current_image] ~= nil and properties.depth == depth then love.graphics.draw( properties.tileset, properties.imgs[properties.current_image], x, y, 0, tileProperties.scale, tileProperties.scale ) end elseif properties.depth == depth then if properties.force ~= nil then love.graphics.draw( tileProperties.tileset, TileIndex[properties.force], x, y, 0, tileProperties.scale, tileProperties.scale ) else love.graphics.draw( tileProperties.tileset, TileIndex[properties.id], x, y, 0, tileProperties.scale, tileProperties.scale ) end end if properties.overlay ~= nil then if properties.overlay_depth == depth or properties.overlay_depth == nil and properties.depth == depth then if properties.overlay_animated then for _, overlay_properties in pairs(Tiles) do if overlay_properties.id == properties.overlay then love.graphics.draw( overlay_properties.tileset, overlay_properties.imgs[overlay_properties.current_image], x, y, 0, tileProperties.scale, tileProperties.scale ) end end else love.graphics.draw( tileProperties.tileset, TileIndex[properties.overlay], x, y, 0, tileProperties.scale, tileProperties.scale ) end end end end end end