local NineSlice = {} local function tileRegion(batch, atlasW, atlasH, sliceInfo, startX, startY, targetW, targetH) -- Если область нулевая или отрицательная (окно слишком маленькое), ничего не делаем if targetW <= 0 or targetH <= 0 then return end local sx, sy, sw, sh = sliceInfo[1], sliceInfo[2], sliceInfo[3], sliceInfo[4] for y = 0, targetH - 1, sh do -- Вычисляем высоту текущего куска (целый или обрезанный остаток) local drawH = math.min(sh, targetH - y) for x = 0, targetW - 1, sw do local drawW = math.min(sw, targetW - x) -- Создаем Quad именно для этого кусочка и добавляем в батч local quad = love.graphics.newQuad(sx, sy, drawW, drawH, atlasW, atlasH) batch:add(quad, startX + x, startY + y) end end end --- Создает SpriteBatch для заполнения произвольного прямоугольника по принципу 9-slice --- --- Углы фиксированные, стороны тайлятся function NineSlice.create(atlas, slices, width, height) local batch = love.graphics.newSpriteBatch(atlas) local aw, ah = atlas:getDimensions() local tl = slices.topLeft local t = slices.top local tr = slices.topRight local l = slices.left local c = slices.center local r = slices.right local bl = slices.bottomLeft local b = slices.bottom local br = slices.bottomRight -- Размеры углов диктуют отступы local leftW, rightW = tl[3], tr[3] local topH, bottomH = tl[4], bl[4] -- Высчитываем пространство для центра и сторон local innerW = width - leftW - rightW local innerH = height - topH - bottomH -- 1. Рисуем углы (они не тайлятся, просто рисуются 1 раз) tileRegion(batch, aw, ah, tl, 0, 0, leftW, topH) tileRegion(batch, aw, ah, tr, leftW + innerW, 0, rightW, topH) tileRegion(batch, aw, ah, bl, 0, topH + innerH, leftW, bottomH) tileRegion(batch, aw, ah, br, leftW + innerW, topH + innerH, rightW, bottomH) -- 2. Рисуем стороны (тайлим по одной оси) tileRegion(batch, aw, ah, t, leftW, 0, innerW, topH) tileRegion(batch, aw, ah, b, leftW, topH + innerH, innerW, bottomH) tileRegion(batch, aw, ah, l, 0, topH, leftW, innerH) tileRegion(batch, aw, ah, r, leftW + innerW, topH, rightW, innerH) -- 3. Рисуем центр (тайлим по обеим осям) tileRegion(batch, aw, ah, c, leftW, topH, innerW, innerH) return batch end return NineSlice