Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Добавить сортировку по цветам
- --Переменная библиотеки
- local doubleBufferLib = {}
- local component = require("component")
- local gpu = component.gpu
- --Символ пробела
- local charSpace = ' '
- local prevBuffer
- doubleBufferLib.widthScreen, doubleBufferLib.heightScreen = gpu.getResolution()
- --Очищает экран
- doubleBufferLib.clearScreen = function()
- gpu.setForeground(0xffffff)
- gpu.setBackground(0x000000)
- gpu.fill(1, 1, doubleBufferLib.widthScreen, doubleBufferLib.heightScreen, charSpace)
- end
- --Копирует таблицу
- doubleBufferLib.getCopyTable = function(table)
- local copyTable = {}
- for k, v in pairs(table) do
- copyTable[k] = v
- end
- return copyTable
- end
- --Вовзращает пустой буфер
- local function setEmptyBuffer()
- local emptyBuffer = {}
- for i = 1, doubleBufferLib.heightScreen do
- for j = 1, doubleBufferLib.widthScreen do
- table.insert(emptyBuffer, charSpace)
- table.insert(emptyBuffer, 0xffffff)
- table.insert(emptyBuffer, 0x000000)
- end
- end
- return emptyBuffer
- end
- --Меняет цвет переднего фона
- doubleBufferLib.setForeColor = function(color)
- if gpu.getForeground() == color then
- return false
- else
- gpu.setForeground(color)
- return true
- end
- end
- --Меняет цвет заднего фона
- doubleBufferLib.setBackColor = function(color)
- if gpu.getBackground() == color then
- return false
- else
- gpu.setBackground(color)
- return true
- end
- end
- --Возвращает индекс пикселя в буфере по координатам, кол-ву переменных, принадлежащих 1 пикселю, и ширине буфера
- doubleBufferLib.getIndexByCoords = function(x, y, numberItems, width)
- width = width or doubleBufferLib.widthScreen
- numberItems = numberItems or 1
- return (y * width - width + x) * numberItems - numberItems
- end
- --Функция сравнивает активный буфер экрана с заданным. Возвращает массив изменений
- local function compareBuffer(buffer)
- local changedPix = {}
- local char, foreColor, backColor
- local curChar, curForeColor, curBackColor
- local index
- for i = 1, doubleBufferLib.heightScreen do
- for j = 1, doubleBufferLib.widthScreen do
- index = doubleBufferLib.getIndexByCoords(j, i, 3)
- char, foreColor, backColor = buffer[index + 1], buffer[index + 2], buffer[index + 3]
- curChar, curForeColor, curBackColor = prevBuffer[index + 1], prevBuffer[index + 2], prevBuffer[index + 3] -- gpu.get(j, i)
- if not(char == curChar and foreColor == curForeColor and backColor == curBackColor) then
- table.insert(changedPix, j)
- table.insert(changedPix, i)
- table.insert(changedPix, char)
- table.insert(changedPix, foreColor)
- table.insert(changedPix, backColor)
- end
- end
- end
- return changedPix
- end
- --Функция групирует пиксели по цвету
- local function groupByColor(changedPix)
- if changedPix == nil then
- return
- end
- local colorArr = {} --Массив цветов и принадлежащих им пикселей
- local x, y, char
- local foreColor, backColor
- for i = 0, #changedPix - 1, 5 do
- x, y, char = changedPix[i + 1], changedPix[i + 2], changedPix[i + 3]
- foreColor, backColor = changedPix[i + 4], changedPix[i + 5]
- --Проверяет наличие пары переднего и заднего цвета
- if i == 0 then
- table.insert(colorArr, foreColor)
- table.insert(colorArr, backColor)
- table.insert(colorArr, {x, y, char})
- else
- local isColorExist = false
- for j = 0, #colorArr - 1, 3 do
- local curForeColor, curBackColor = colorArr[j + 1], colorArr[j + 2]
- if curForeColor == foreColor and curBackColor == backColor then
- table.insert(colorArr[j + 3], x)
- table.insert(colorArr[j + 3], y)
- table.insert(colorArr[j + 3], char)
- isColorExist = true
- break
- end
- end
- if not(isColorExist) then
- table.insert(colorArr, foreColor)
- table.insert(colorArr, backColor)
- table.insert(colorArr, {x, y, char})
- end
- end
- end
- return colorArr
- end
- --Функция возвращает пустую строку указанной длины
- local function isOneChar(str)
- if #str == 1 then
- return true
- end
- local isOneChar = false
- for i = 2, #str do
- if str:sub(i,i) == str:sub(i-1,i-1) then
- isOneChar = true
- break
- end
- end
- return isOneChar
- end
- --Группирует массив по строкам
- local function groupByRow(colorArr)
- if colorArr == nil then
- return
- end
- local rowArr = {}
- local foreColor, backColor
- local pixArr
- for i = 0, #colorArr - 1, 3 do
- local sequenceArr = {}
- foreColor, backColor = colorArr[i + 1], colorArr[i + 2]
- table.insert(rowArr, foreColor)
- table.insert(rowArr, backColor)
- pixArr = colorArr[i + 3]
- local prevX, prevY
- local sequence
- for j = 0, #pixArr - 1, 3 do
- local curX, curY, curChar = pixArr[j + 1], pixArr[j + 2], pixArr[j + 3]
- if curX - 1 == prevX and curY == prevY then
- sequence[3] = curX
- sequence[5] = sequence[5] .. curChar
- else
- if sequence ~= nil then
- table.insert(sequenceArr, sequence)
- end
- sequence = {}
- sequence[1], sequence[3] = curX, curX
- sequence[2], sequence[4] = curY, curY
- sequence[5] = curChar
- end
- --Последний или единтсвенный элемент в массиве
- if j + 3 == #pixArr then
- table.insert(sequenceArr, sequence)
- end
- prevX, prevY = curX, curY
- end
- --Групировка по Y
- if sequenceArr ~= nil then
- local delSequinceIndexArr = {}
- local prevSequence
- local countSequence = 0
- for j = 1, #sequenceArr do
- local curSequence = sequenceArr[j]
- local sequenceHeight = {}
- if prevSequence ~= nil then
- if prevSequence[4] == curSequence[4] - 1 and prevSequence[5] == curSequence[5] then
- countSequence = countSequence + 1
- prevSequence[4] = curSequence[4]
- prevSequence[2] = curSequence[4] - countSequence
- sequenceArr[j] = prevSequence
- table.insert(delSequinceIndexArr, j - 1)
- prevSequence = curSequence
- else
- countSequence = 0
- prevSequence = curSequence
- end
- else
- if isOneChar(curSequence[5]) then
- prevSequence = curSequence
- countSequence = 0
- end
- end
- end
- if delSequinceIndexArr ~= nil then
- for j = #delSequinceIndexArr, 1, - 1 do
- table.remove(sequenceArr, delSequinceIndexArr[j])
- end
- end
- end
- table.insert(rowArr, sequenceArr)
- end
- return rowArr
- end
- local function group(changedPix)
- local colorArr = groupByColor(changedPix)
- local rowArr = groupByRow(colorArr)
- return rowArr
- end
- --Отрисовывает указанный буфер
- doubleBufferLib.draw = function(buffer)
- local changedPix = compareBuffer(buffer)
- local rowArr = group(changedPix)
- local colorOperation, drawOperation = 0, 0
- if rowArr == nil then
- return
- end
- for i = 0, #rowArr - 1, 3 do
- if doubleBufferLib.setForeColor(rowArr[i + 1]) then
- colorOperation = colorOperation + 1
- end
- if doubleBufferLib.setBackColor(rowArr[i + 2]) then
- colorOperation = colorOperation + 1
- end
- local sequenceArr = rowArr[i + 3]
- for j = 1, #sequenceArr do
- local sequence = sequenceArr[j]
- local x1, y1, x2, y2, str = sequence[1], sequence[2], sequence[3], sequence[4], sequence[5]
- --print(x1, y1, x2, y2)
- if y1 ~= y2 then
- local char = sequence[5]:sub(1, 1)
- local width, height = x2 - x1 + 1, y2 - y1 + 1
- gpu.fill(x1, y1, width, height, char)
- else
- gpu.set(x1, y1, str)
- end
- drawOperation = drawOperation + 1
- end
- end
- --print("DRAWNING -", drawOperation, "COLOR -", colorOperation)
- prevBuffer = doubleBufferLib.getCopyTable(buffer)
- end
- doubleBufferLib.getEmptyBuffer = function()
- return doubleBufferLib.getCopyTable(doubleBufferLib.emptyBuffer)
- end
- --Инициализация
- local function init()
- doubleBufferLib.emptyBuffer = setEmptyBuffer()
- prevBuffer = doubleBufferLib.getCopyTable(doubleBufferLib.emptyBuffer)
- end
- init()
- --Возвращает библиотеку
- return doubleBufferLib
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement