function LevelLoadTiles() --[[ 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 or, if multiple tiles {id, id, id,} or overlay_depth = foreground/background overlay depth type = collision type ]] -- Level data LevelData = dofile("Mothback/data/levels/"..currLevel..".lua") -- tiles data TileData = dofile("Mothback/data/tileset/library.lua") LevelTiles = LevelData.tiles LevelData.Width = LevelGetWidth() LevelData.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 = {} -- index from tileset local width = LevelData.tileset:getPixelWidth()/tileProperties.width local height = LevelData.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, LevelData.tileset:getDimensions() ) end end -- initialize tile data for _, Properties in pairs(TileData) 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 -- instance level tiles according to the Properties for i = 1, #LevelTiles do for j = 1, #LevelTiles[i] do local id = LevelTiles[i][j] LevelTiles[i][j] = {} local tile = LevelTiles[i][j] tile.id = id for _, Properties in pairs(TileData) do if Properties.id == tile.id then if type(Properties.overlay) == "table" then tile.display_overlay = Properties.overlay[math.random(#Properties.overlay)] else tile.display_overlay = Properties.overlay end if type(Properties.force) == "table" then tile.display = Properties.force[math.random(#Properties.force)] else tile.display = Properties.force end end end end end end function TileGetType(tile) for _, Properties in pairs(TileData) do if Properties.id == tile.id then return Properties.type end end end function TileGetDepth(tile) for _, Properties in pairs(TileData) do if Properties.id == tile.id then return Properties.depth end end end function TileGetLight(tile) for _, Properties in pairs(TileData) do if Properties.id == tile.id then return Properties.light 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 + (levelProperties.offset.x - tileProperties.width)) - Camera.pos.x, tileProperties.scale * (i * tileProperties.height + (levelProperties.offset.y - tileProperties.height)) - Camera.pos.y, tileProperties.scale * tileProperties.width, tileProperties.scale * tileProperties.height ) end end end function TileCreateObjects() LoadedObjects.Collisions = {} LoadedObjects.Platforms = {} LoadedObjects.Ladders = {} for i = 1, #LevelTiles do for j = 1, #LevelTiles[i] do if LevelTiles[i][j].id ~= 0 then local type = TileGetType(LevelTiles[i][j]) local light = TileGetLight(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 light ~= 0 and light ~= nil then CreateLight( base_x + tileProperties.width/2 * tileProperties.scale, base_y + tileProperties.height/2 * tileProperties.scale, light ) end 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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.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(LoadedObjects.Platforms,plat) end end end end end function AnimateTiles() for _, Properties in pairs(TileData) 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,x,y,depth) for _, Properties in pairs(TileData) 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 if Properties.force ~= 0 then love.graphics.draw( LevelData.tileset, TileIndex[tile.display], x, y, 0, tileProperties.scale, tileProperties.scale ) end else love.graphics.draw( LevelData.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(TileData) 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( LevelData.tileset, TileIndex[tile.display_overlay], x, y, 0, tileProperties.scale, tileProperties.scale ) end end end --[[ love.graphics.setColor(0,0,1) love.graphics.print(tostring(tile.display),x+16,y) love.graphics.setColor(1,1,1) ]] end end end