Перейти к содержимому

ECS

Гуру
  • Публикации

    533
  • Зарегистрирован

  • Посещение

  • Победитель дней

    203

Сообщения, опубликованные пользователем ECS


  1. Одна из лучших игр, что я когда-либо видел на ОС. И сделана грамотно - списочек со словами динамически подгружаются, и дизайн приятный, и работает быстро, и всякие плюшки вроде счетчика жизней и таймера активности имеются, уважаю столь серьезный подход к делу  :smile9:

     

    Правда, чутка раздражает "Downloading from pastebin.com" в начале, можно использовать wget <ссылка> <имя> -Q или вообще юзать internet.request(), чтобы убрать спам в консоль, но это уже так, придирки. Надо плюсовать парня, надо!

    • Нравится 2

  2. Еще была бы поддержка ключевых знаков по по аналогии с майночатом по типу "&6Привет, &3говнокодер!", а также "&FFFFFFПривет, &A8FFFFговнокодер!" - то вообще сок. А то запоминать все эти буффы, цвета - бр-р-р.

     

    7514d823845dbadcc9b202b6c16ee6b3.png


  3. Красотища какая, кончил радугой, спасибо! хд

     

    Кстати, давно надо бы накодить софтину для удобного редактирования/сохранения 3D-моделей, что-то по аналогии с голограммами Totoro, но уже для распечатки на 3D-принтере. Были даже наработки по теме, но выглядело оно все как-то... убого что ли. Но три вида (сверху, спереди, слева) вполне себе сносно работали, даже на проектор что-то выводилось. Есть какие-нибудь идейки, как можно получше реализовать эту программку?

     

    ee68298b67c96d55fc1265bd3cb4396e.jpg


  4. Ты нарисуешь один раз кучу объектов, подождёшь 0.1 сек, а дальше будет изменение 1 - 10 пикселей.

     

    А пиксели эти будут рисоваться с постоянной сменой цвета и фона, ага. Допустим, на экране изменился прямоугольник 5х2 синего цвета. Как будет работать твой код? Правильно, он выполнит 10 раз операцию gpu.setBackground() и 10 раз операцию gpu.set(), в то время как можно было бы всего лишь gpu.setBackground(); gpu.fill(). Напомню, каждая операция видеокарты - это реальные игровые тики, и при таком подходе к отрисовке любая более-менее сносная игра у тебя попросту будет фризится.

     

    Кроме того, как я и сказал выше, у тебя крайне неразумен расход памяти. Надо скачать ради интереса твою либу и проверить, сколько памяти она сжирает при полноэкранных 160х50 отрисовках. Интересно, вылетит out of memory или нет? Как знать, как знать!

     


     

    P.S. Боже упаси, 823 кбайта памяти сожрало! Изыди, изыди!  :D

     

    491259dce35901551a1218ebfeb0bfff.png

    • Нравится 1

  5. Начнем с того, что тут мы имеем крайне медленную и неоптимизированную отрисовку: цвет фона меняется каждую итерацию в цикле. Например, если мы имеем в памяти линию красного цвета длиной в 150 пикселей, то куда грамотнее будет разово изменить цвет фона на красный, а затем выполнить gpu.fill(), нежели выполнять 150 итераций со сменой цвета и установкой пикселя (скриншот кода с гиста автора ниже). Это нехитрое действо сократит количество GPU-операций в десятки и сотни раз, учитывая размеры мониторов.

     

    Далее рассмотрим таблицу matrix: во-первых, это трехмерный массив, что уже сильно повышает расход оперативной памяти: куда выгоднее сделать одномерную таблицу с последующим получением из нее нужных индексов. Во-вторых, в каждой подтаблице имеется отдельная boolean-переменная, отвечающей за смену пикселя. Это шутка такая? Боюсь себе представить, сколько памяти сжирают эти махинации.

     

    7df06e65166fb8b9ba0c7c2ed3726351.png

     

    Сильно не люблю критиковать других людей, но заявленным "упором на скорость рисования 2D-объектов" тут даже близко не пахнет. Плюс, реализация библиотеки с пародией на ООП лично у меня вызывают лютое отвращение: неудобно, некрасиво, куча лишнего кода при создании программ, бр-р-р. Кроме того, на форуме уже есть прекрасная графическая GML-либа: названия ее методов просты как божий день, да и графика рисуется в разы быстрее. Также рекомендую либу двойного буфера для максимальной скорости рисования.

     

    В общем, шли бы лучше игрушки кодить для опенкомпов - и детишкам понравилось бы, и критики никакой не услышали бы, игры любят все, в любом виде!  :lol:

    • Нравится 2

  6.  

     

    Снимите премодерацию с LeshaInc. Это совершенно безумная и нерациональная мера — ставить вечную прешку, как нубу, за детский флуд в чатике, несмотря ни на вклад (программ много, либ всяких), ни на позитивность человека, ни на дату регистрации, ни на вообще то, что банить на форуме за что-то в чате — тупизм^math.huge. Ибо я всё больше и больше разочаровываюсь в здешней администрации — кажется, без кнопки бана они жить не могут от слова совсем.
     

    Лучшая часть статьи!  :D


  7.  

     

    Я правильно понял, он чей-то код взял? Но тогда это, наверное, открытый проект, и из него можно брать...
     

     

    Не-не-не, тут все куда прозаичнее: на первом скрине код его функций для сериализации таблиц, а на втором дефолтный код из textutils, которые поставляются с CraftOS. Дело не в копипастинге, а в изобретении велосипедов, причем велосипедов без седушки, вилки и педалек, образно выражаясь. Короче, у меня порвало очко от того, что парень по сути сделал либу textutils.serialize, при этом не обеспечив полного ее функционала.


  8. То есть, как я понял, товарищ MrConstructor пишет с нуля ядро оси, ее либы, софт, заменяя все стандартные файлы в CC-компе на кастомные? Идея крайне похвальная, прям зауважал поначалу, но что-то мне все это напоминает... кхм, кхм, что-то до боли знакомое и существующее...

     

    a632002ca5238fd6a9be0a279d7fb520.png

    b7dc031caed175b84675639ab51f3541.jpg

    f3cc698d52ccaede6179acc1804a3720.png


  9.  

     

    Блок проверки только генерит значение. Для того чтобы создать "развилку", надо добавить ромбик-проверку. Оранжевый пунктир показывает, что блок проверки передает с зеленого узла логическое значение.

     

    А, вот оно как. Пасиба. 


  10. e6a8a2012d2c2a033bcb0d6600c4894a.png

     

    122a4c356130c2cece027bb39401749b.png

     

     

    По логике программа спрашивает, стоит ли какой-то блок перед роботом. Если блок есть, то сначала выполняется robot.swing() и двигается вперед, а если нет, то робот просто двигается вперед. Сгенерировался какой-то непонятный код, явно несоответствующий моей логике хд


  11.  

     

    Вынес функционал фотошопа в либу?
     

     

    Тут функционала раза в 4 больше, чем в фотошопе, плюс, сам фотошоп всегда юзал функции из этой либы, являясь как бы графической оболочкой к либе. Хотел на днях перекодить ФШ с нуля, добавить поддержку двойного буфера, слоев, истории - поэтому и интегрировал все функции в либу image. Ну, и выложил ее сюда, чего добру пропадать.

    • Нравится 1

  12. В Lua всё должно быть гораздо проще и изящней. _G.term = {} setmetatable(term, {__index = function(t,k) setmetatable(t,{__index=require("term")}) return t[k] end})

     

    Ну так я и говорю: придется вручную делать некую программку, вешающую на _G указанный перечень библиотек. А ведь можно, кстати, через fs.list() получить список файлов в папке с либами и через цикл создавать метаметоды, как указал swg2you выше - это будет куда удобнее. Правда, в этом случае уже не получится сделать кастомное сокращение библиотек (fs = filesystem, rs = redstone, r = robot и т.д.)

    for file in filesystem.list("lib/") do
      _G[file] = {}
      setmetatable([file], {__index = require(file)})
    end
    

  13. а если еще вспомнить, что он умеет двухбайтовый utf-8

     

    Отличная идейка, надо будет побаловаться. Только есть поправка: некоторые юникод-символы используют аж до 6 байт информации, проверено неоднократно при создании библиотеки изображений. При записи в файл у нас даже пишется отдельный байт, содержащий размер юникод-символа для корректного чтения. Встречались и по 4, и по 5, а в редких случаях и по 6 байт, так что концепция такого диска очень и очень крута.


  14.  

     

    Суть идеи не в том, что при старте ОС превентивно подгружать библиотеки, а в том, что для существующих библиотек в глобальном окружении создаются пустые индексы (заглушки) с маленькой мета-функцией.

     

    А, вот ты о чем. Ну да, занятный способ, правда, довольно потно реализуемый: как именно привязывать заглушки к библиотекам? Вручную описывать все существующие функции в библиотеке term? Т.е. делать заглушку для clear(), read(), setCursor() и т.п.?


  15.  

     

    Мда, посмотришь на весь проделанный труд и писать библиотеки желание пропадает. Как много полезных функций. Я то думал как раз вчера, написать библиотеку работы с цветами или дописывать игру Куб. Выбрал второе.
     

     

    Вот и правильно, библиотек хоть жопой жуй, а игр - раз, два и обчелся. Нужно больше игр!

    • Нравится 1
    • Одобряю 1

  16. 9si3o9g4xr49.png

     

    Хочу представить вам большую библиотеку, предназначенную для работы с изображениями, созданными в нашем Фотошопе. С ее помощью можно манипулировать графикой воистину волшебным образом: изображения можно обрезать, расширять, поворачивать, отражать, инвертировать, изменять их яркость, цветовой тон, насыщенность и добавлять фотофильтры. Разрабатывали мы ее примерно год, содержит она более 1000 строк кода и удовлетворяет практически всем наши требованиям к хорошей графике в OpenComputers, если, конечно, местную графику вообще можно назвать хорошей.

     

    Начало работы

     

    Прежде всего вам потребуются два файла. Первый обеспечивает основные операции над цветом, позволяет конвертировать цвета из одной схемы в другую, а также сжимать цвета без потери качества. Второй же является самой библиотекой image и дает нам полную свободу творчества.

    wget https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/colorlib.lua lib/colorlib.lua -f
    wget https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/image.lua lib/image.lua -f
    

    После загрузки библиотек вы можете подключить image и начинать с ней работать. Далее мы рассмотрим различные методы, с помощью которых мы сможем манипулировать изображениями. Под описанием каждого метода будет картинка и код, демонстрирующие суть работы метода, так что проблем с пониманием возникнуть не должно.

    local image = require("image")

    Структура изображений

    (для общего развития)

     

     

     

     

    Для начала я расскажу вам, как реализовано хранение изображений в оперативной памяти компьютера. Итак, каждое изображение у нас - это обычный массив. Мы специально используем одномерный массив для экономии оперативной памяти, а при отрисовке библиотека сама получает координаты x и y по особым формулам, что совсем не сказывается на производительности. В данном массиве чередуются цвет фонацвет текстаальфа-канал и символ. Это что касается оперативной памяти.

     

    2yk2hua52epk.png

     

    А теперь я покажу вам, каким образом данные о пикселях хранятся в файлах .pic на жестком диске, используя различные методы кодировки (0, 1, 2 или 3). Для наглядности мы будем открывать один и тот же файл "Love.pic", демонстрирующий нашу любовь к моду OpenComputers, сохраненный с различными методами кодировки.

     

    c30bb7a00c712b43f0e1b3a7c6e5e1a7.png

     

    К примеру, при кодировке 0 изображение с сердечком хранится в следующем виде:

     

    c6hya1ahw1s5.png

     

    Видно, что это крайне неоптимизированный метод, никак не сжимающий картинку, все данные хранятся в сыром виде, отсюда и название метода. Он полезен для дебага, когда надо вручную подправить данные. Также видно, что в начале файла у нас 4 байта отводится под сигнатуру (таким образом мы отличаем наш формат .pic от всякой ерунды), а также 1 байт на метод кодирования.

     

    Далее рассмотрим метод кодировки 1. Мы довольно долго пользовались им, он использует простейшее "сжатие", когда данные записываются не в виде символов, а в виде последовательности байт.

     

    ndvhklzb7h5b.png

     

    У него есть один недостаток: в файле постоянно повторяются схожие данные, к примеру, если наше изображение имеет размеры 10х10 пикселей и черный фон, то данные о фоне повторятся в файле 100 раз. Это неправильно.

     

    А теперь давайте посмотрим на метод кодирования 2, он работает схожим образом, однако при нем в файлах отсутствуют повторяющиеся блоки. То есть, опять таки, если у нас в изображении цвет фона только черный, от в файл данные о черном фоне запишутся лишь один раз.

     

    v0wc5n437ouo.png

     

    Видно, что размер файла уже существенно уменьшился. Однако для записи цветов тут используются 3 байта (т.е. белый будет 0xFFFFFF), в то время как палитра OpenComputers поддерживает лишь 256 возможных оттенков. Отсюда вывод, что мы неэкономно храним данные.

     

    Если взглянуть на метод кодировки 3, то сразу видно, что размер файла стал еще меньше. При этом на цвет используется лишь 1 байт (т.е. белый будет 0xFF). Это крайне оптимизированный формат картинок, вылизанный, что называется, дочиста.

     

    dkt1on4yejh2.png

     

     

     

     

    Методы работы с файлами изображений

    (загрузка, отрисовка, сохранение)

     

     

     

     

    image.load( string путь ): table изображение

     

         Загружает существующий файл .pic из указанного пути и возвращает изображение

         в виде массива.

    local myPicture = image.load("MineOS/System/OS/Icons/Love.pic")

    image.savestring путь, table изображение [, int метод кодирования] )

     

         Сохраняет существующий массив изображения в файл по указанному пути. Формат

         файла должен быть .pic. Опционально можно указать метод кодирования от 0 до 3,

         однако крайне рекомендуется использовать 3 для экономии места на диске.

    image.save("copyOfMyPicture.pic", myPicture)

    image.drawint x, int y, table изображение )

     

         Рисует загруженное ранее изображение по указанным координатам.

    image.draw(8, 4, myPicture)

         c30bb7a00c712b43f0e1b3a7c6e5e1a7.png

     

     

     

     

    Методы трансформирования изображений

    (вращение, отражение, обрезание и т.п.)

     

     
    image.expand( table  изображение, string направление, int количество пикселей[, int цвет фона, int цвет текста, int прозрачность, string символ] ): table картинка
     
         Расширяет указанную картинку в указанном направлении (fromRight, fromLeft, fromTop, fromBottom),
         создавая при этом пустые белые пиксели. Если указаны опциональные аргументы, то вместо пустых
         пикселей могут быть вполне конкретные значения.
    image.draw(8, 4, myPicture)
    myPicture = image.expand(myPicture, "fromRight", 10)
    image.draw(53, 4, myPicture)

         f71b8eeb84b15bdde5b870e654e1550e.png

     
    image.croptable изображениеstring направление, int количество пикселей ): table изображение
     
         Обрезает указанную картинку в указанном направлении (fromRight, fromLeft, fromTop, fromBottom),
         удаляя лишние пиксели.
    image.draw(8, 4, myPicture)
    myPicture = image.crop(myPicture, "fromRight", 10)
    image.draw(53, 4, myPicture)

         d7d6c2b5f23e907672b10c4f4ae36ee1.png

     
    image.rotatetable изображение, int угол ): table изображение
     
         Поворачивает указанную картинку на указанный угол. Угол может иметь
         значение 90, 180 и 270 градусов.
    image.draw(8, 4, myPicture)
    myPicture = image.rotate(myPicture, 90)
    image.draw(53, 4, myPicture)

         f198a2151699bdb2ca57d9202922acc4.png

     
    image.flipVerticaltable изображение): table изображение
     
         Отражает указанную картинку по вертикали.
    image.draw(8, 4, myPicture)
    myPicture = image.flipVertical(myPicture)
    image.draw(53, 4, myPicture)

         eb84192cbfea127157c8f0b0d4bb486c.png

     
    image.flipHorizontaltable изображение): table изображение
     
         Отражает указанную картинку по горизонтали.
    image.draw(8, 4, myPicture)
    myPicture = image.flipHorizontal(myPicture)
    image.draw(53, 4, myPicture)
    

         d3aa82b1476473a70f2201cb2d99f541.png

     

     
    Методы работы с цветом
    (яркость, насыщенность, тон и т.п.)
     

     
    image.hueSaturationBrightnesstable изображениеint тонint насыщенностьint яркость ): table изображение
     
         Корректирует цветовой тон, насыщенность и яркость указанной картинки.
         Значения аргументов могут быть отрицательными для уменьшения параметра
         и положительными для его увеличения. Если значение, к примеру, насыщенности
         менять не требуется, просто указывайте 0.
     
         Для удобства вы можете использовать следующие сокращения:
     
              image.huetable изображение, int тон ): table изображение
              image.saturationtable изображение, int насыщенность ): table изображение
              image.brightnesstable изображение, int яркость ): table изображение
              image.blackAndWhitetable изображение ): table изображение
     
    image.draw(8, 4, myPicture)
    --Изменяем цветовой тон к красному, уменьшаем яркость, не изменяя насыщенность
    myPicture = image.hueSaturationBrightness(myPicture, 200, 0, -10 )
    image.draw(53, 4, myPicture)
    

         b0df3eab1f76586e8aa77b484c1781f1.png

     
    image.colorBalancetable изображениеint красныйint зеленыйint синий ): table изображение
     
         Корректирует цветовые каналы указанной картинки. Аргументы цветовых
         каналов могут принимать как отрицательные значения для уменьшения интенсивности канала,
         так и положительные для увеличения.
     
    image.draw(8, 4, myPicture)
    --Делаем изображение "зеленее"
    myPicture = image.colorBalance(myPicture, 0, 255, 0)
    image.draw(53, 4, myPicture)
    

         ee3a0a1730b3be4a475fb68d633ad2c8.png

     

    image.inverttable изображение ): table изображение
     
         Инвертирует цвета в указанной картинке.
    image.draw(8, 4, myPicture)
    myPicture = image.invert(myPicture)
    image.draw(53, 4, myPicture)
    

         2b720ba1c8c23e69efa58c4304178fee.png

     
    image.photoFiltertable изображениеint цветint прозрачность ): table изображение
     
         Накладывает на указанное изображение фотофильтр с указанной прозрачностью.
         Прозрачность может быть от 0 до 255.
     
    image.draw(8, 4, myPicture)
    --Накладываем сиреневый фотофильтр с прозрачностью 80
    myPicture = image.photoFilter(myPicture, 0xFF00FF, 80)
    image.draw(53, 4, myPicture)
    

         f8b9f5e57468903b3b996aaa7b04e10c.png

     

     

     

    • Нравится 9

  17.  

     

    Странно, что отсутствует элементарная функция "обратить цвет". Или например переводчик в чб тона.

     

    Для этого у нас имеется либа image, где реализовано все, что только душе угодно. Там тебе и яркость, и контрастность, и насыщенность, и цветовой тон, и повороты-отражения, и инверсия. ColorLib же нужна именно для базовых операций над цветом, т.е. это основа для более крутых и потных вещей, таких как image. Надо будет, кстати, расписать ее у вас на форуме, полезная штука.


  18.  

     

    то можно избавиться от -1 +1

     

    -1 и +1 необходимы для наших файловых форматов. Вчера писали новый формат изображения, для записи в файл требуются корректные индексы. А если добавлять [0] в тот массив, то увеличится размер скачиваемого файла, поэтому мы не стали париться и сделали -1 +1, так проще и удобнее.


  19. ab3f7505e192d151f4ff8b85b5568cb2.png

     

    Хочу поделиться с вами крайне полезной в быту библитекой, которую мы с товарищами используем повсеместно. Она позволяет работать с несколькими цветовыми моделями: стандартной RGB, более современной HSB, преобразовывать их в HEX-цвет для OpenComputers и наоборот. Кроме того, она позволяет сжимать 24-битный цвет вида 0xFFFFFF до 8-битного вида 0xFF без потери качества.

     

    Команда для загрузки:

    wget https://raw.githubusercontent.com/IgorTimofeev/OpenComputers/master/lib/colorlib.lua lib/colorlib.lua -f

    Методы

     

     

     

     

    colorlib.HEXtoRGBint HEX-цвет ): int красный, int зеленый, int синий

         

         Преобразует шестнадцатеричный цвет вида 0xFFFFFF в три цветовых канала.

         К примеру, colorlib.HEXtoRGB(0xFF00FF) выдаст 255, 0, 255.

     

    colorlib.RGBtoHEXint красный, int зеленый, int синий ): int HEX-цвет

         

         Преобразует три цветовых канала в стандартный шестнадцатеричный цвет.

         К примеру, colorlib.RGBtoHEX(0, 255, 0) выдаст 0x00FF00.

     

    colorlib.RGBtoHSBint красный, int зеленый, int синий ): int тон, int насыщенность, int яркость

         

         Преобразует три цветовых канала в цвет три параметра цветовой схемы HSB.

         К примеру, colorlib.RGBtoHSB(255, 0, 0) выдаст 360, 100, 100.

     

    colorlib.HSBtoRGBint тон, int насыщенность, int яркость ): int красный, int зеленый, int синий

         

         Преобразует три параметра цветовой схемы HSB в три параметра цветовой палитры RGB.

         К примеру, colorlib.HSBtoRGB(200, 50, 50) выдаст 63, 126, 127.

     

    colorlib.HEXtoHSBint HEX-цвет ): int тон, int насыщенность, int яркость

         

         Преобразует цвет вида 0xFFFFFF в три параметра цветовой схемы HSB.

         К примеру, colorlib.HEXtoHSB(0xFF0000) выдаст 360, 0, 0.

     

    colorlib.alphaBlend int первый цвет, int второй цвет, int прозрачность ): int HEX-цвет

         

         Накладывает второй цвет на первый с учетом прозрачности второго. Прозрачность -

         это число в диапазоне от 0 до 255.) С помощью этого метода можно получить красивую симуляцию прозрачности:

     

         67f84178db9a3958a3c7df72eccd19e9.png

     

     

    colorlib.convert24BitTo8Bitint 24-битный HEX-цвет ): int 8-битный HEX-цвет

         

         Сжимает цвет вида 0xFFFFFF до цвета вида 0xFF без потери качества при отображении

         на мониторах OpenComputers. Крайне полезный метод, когда необходимо экономимть

         дисковое пространство или оперативную память.

     

    colorlib.convert8BitTo24Bitint 8-битный HEX-цвет ): int 24-битный HEX-цвет

         

         Распаковывает цвет вида 0xFF до цвета вида 0xFFFFFF. По сути это обратная конвертация

         цвета из предыдущего метода. Необходимо вызывать его перед отрисовкой.

     

     

     

    • Нравится 6
    • Спасибо 1

  20. Отлично!  Дело за малым. Накидать код который будет цеплять на _G метаметод подгрузки запрашиваемой библиотеки, и запихнуть его в автозагрузку. И с require() можно прощаться.

     

    Давно так делал, через init.lua происходило добавление. Правда, в таких случаях в память может грузануться крайне прожорливая либа, которую ты в данном контексте даже использовать не собираешься (например, двойной буфер требует 200 кбайт оперативки), а это в некоторых ситуациях критично. В конце концов немного переосмыслил ситуацию и подгружаю библиотеки во все то же _G пространство через такой вот незамысловатый цикл:

    -- Адаптивная загрузка необходимых библиотек и компонентов
    local libraries = {
    	ecs = "ECSAPI",
    	component = "component",
    	event = "event",
    	term = "term",
    	config = "config",
    	context = "context",
    	buffer = "doubleBuffering",
    	image = "image",
    	SHA2 = "SHA2",
    }
    
    local components = {
    	gpu = "gpu",
    }
    
    for library in pairs(libraries) do if not _G[library] then _G[library] = loadfile(libraries[library])() end end
    for comp in pairs(components) do if not _G[comp] then _G[comp] = _G.component[components[comp]] end end
    libraries, components = nil, nil
    
×
×
  • Создать...