67 lines
2.9 KiB
Lua
67 lines
2.9 KiB
Lua
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
|