LUA скрипт [ Гайд ] HUD-элементы на мета-таблицах (классах)

Дизайнер
Статус
Оффлайн
Регистрация
18 Авг 2017
Сообщения
1,931
Реакции[?]
2,258
Поинты[?]
146K
Товары в продаже
1
Во всех скриптах, которых я видел, индикаторы создаются отдельно. Для них выделяют разные функции, то есть они ничем не объединены. Когда ты захочешь что-то поменять -- тебе придется менять это во всех функциях. А когда кода много, это то еще страдание.

Сегодня я покажу, как создавать HUD на мета-таблицах. Гайд пишу для более менее продвинутых кодеров. API - эвольв.

1. Для начала
Код:
-- --- ------- -------- -------- -------
-- Эта функция облегчит создание классов

function Class()
    local class = {}

    local mClass = {__index = class}

    function class.instance() return setmetatable({}, mClass) end
    return class
end
Потому что так легче создавать классы на метатаблицах.


2. Класс
Код:
-- --- -----
-- Сам класс

local HUD = Class()
Теперь начинается самое интересное


С помощью этого метода, мы сможем объявлять/создавать свои HUD-элементы. Нам нужно разместить здесь переменные, чтобы иметь к ним доступ с остальных методов.
Код:
-- Создание элемента HUD. Аргументы можно задать свои
function HUD:new(name, color, x, y, w)
    local self = HUD.instance()


    -- Здесь вы можете объявить все переменные класса. Они всегда будут доступны.
    -- Я не буду создавать рабочие индикаторы, это всего-лишь пример.

    -- главные переменные
    self.name, self.color = name, color
    self.x, self.y, self.w, self.h = x or 200, y or 400, w or 160, 20

    -- переменные для драга
    self.drag_x, self.drag_y = 0, 0
    self.is_dragging = false


    ------ ----
    return self
end

Следом идет перетаскивание. Добавил для примера.
Код:
-- Драг (спастил, мб есть лучше вариант)
function HUD:drag()
    local is_hovered = (mx > (self.x) and mx < (self.x + self.w) and my > (self.y) and my < (self.y + self.h))

    if is_hovered then
        if input.is_mouse_down(0) and not self.is_dragging then
            self.is_dragging = true
           
            self.drag_x = self.x - mx
            self.drag_y = self.y - my
        end
    end

    if not input.is_mouse_down(0) then
        self.is_dragging = false
    end

    if self.is_dragging and gui.is_menu_open() then
        self.x = (self.drag_x + mx)
        self.y = (self.drag_y + my)
    end
end

Остальное. В основном здесь рендер
Код:
-- Наш контейнер
function HUD:container()
    render.rect_filled (self.x, self.y, self.x + self.w, self.y + self.h, render.color("#00000026"))
    render.rect_filled (self.x, self.y, self.x + self.w, self.y + 2, self.color)
    render.text (font, self.x + self.w / 2, self.y + self.h / 2 + 1, self.name, render.color("#FEFEFE"), 1, 1)
end

-- Эта функция предназначена для рендера своих элементов. Например, кейбинды
-- В ней ничего писать не будем
function HUD:paint() end

-- И наконец, для вызова нашего класса
function HUD:draw()
    self:container()
    self:paint()

    self:drag()
end


3. Создание объектов класса. Сами HUD-элементы
Код:
-- ----- -----  ------ -------- ------- ------------ ---
-- Класс готов, теперь осталось создать какой-нибудь HUD.

-- Объявляем
local keylist = HUD:new("keylist", render.color("#00acf5"), 200, 600)  -- необязательно указывать все аргументы, у нас есть дефолтные

-- Рисуем
function keylist:paint()
    render.text (font, self.x + self.w / 2, self.y + self.h + 4, "Готово", render.color("#FEFEFE"), 1, 0)
end


-- --------
-- Вызываем

function on_paint()
    -- это для драга
    mx, my = input.get_cursor_pos()

    keylist:draw()
end


Результат:
1639313988964.png

Мы получили контейнер кейлиста. Вы можете создавать любые элементы таким способом, можете модифицировать, улучшать, добавлять что-то новое. Текст "Готово" принадлежит конкретно кейлисту. У других объектов класса его не будет

Использование класса облегчило наш код, он стал меньше (большую часть кода займет сам класс, нежели его объекты).​
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
29 Дек 2019
Сообщения
381
Реакции[?]
168
Поинты[?]
3K
Во всех скриптах, которых я видел, индикаторы создаются отдельно. Для них выделяют разные функции, то есть они ничем не объединены. Когда ты захочешь что-то поменять -- тебе придется менять это во всех функциях. А когда кода много, это то еще страдание.

Сегодня я покажу, как создавать HUD на мета-таблицах. Гайд пишу для более менее продвинутых кодеров. API - эвольв.

1. Для начала
Код:
-- --- ------- -------- -------- -------
-- Эта функция облегчит создание классов

function Class()
    local class = {}

    local mClass = {__index = class}

    function class.instance() return setmetatable({}, mClass) end
    return class
end
Потому что так легче создавать классы на метатаблицах.


2. Класс
Код:
-- --- -----
-- Сам класс

local HUD = Class()
Теперь начинается самое интересное


С помощью этого метода, мы сможем объявлять/создавать свои HUD-элементы. Нам нужно разместить здесь переменные, чтобы иметь к ним доступ с остальных методов.
Код:
-- Создание элемента HUD. Аргументы можно задать свои
function HUD:new(name, color, x, y, w)
    local self = HUD.instance()


    -- Здесь вы можете объявить все переменные класса. Они всегда будут доступны.
    -- Я не буду создавать рабочие индикаторы, это всего-лишь пример.

    -- главные переменные
    self.name, self.color = name, color
    self.x, self.y, self.w, self.h = x or 200, y or 400, w or 160, 20

    -- переменные для драга
    self.drag_x, self.drag_y = 0, 0
    self.is_dragging = false


    ------ ----
    return self
end

Следом идет перетаскивание. Добавил для примера.
Код:
-- Драг (спастил, мб есть лучше вариант)
function HUD:drag()
    local is_hovered = (mx > (self.x) and mx < (self.x + self.w) and my > (self.y) and my < (self.y + self.h))

    if is_hovered then
        if input.is_mouse_down(0) and not self.is_dragging then
            self.is_dragging = true
          
            self.drag_x = self.x - mx
            self.drag_y = self.y - my
        end
    end

    if not input.is_mouse_down(0) then
        self.is_dragging = false
    end

    if self.is_dragging and gui.is_menu_open() then
        self.x = (self.drag_x + mx)
        self.y = (self.drag_y + my)
    end
end

Остальное. В основном здесь рендер
Код:
-- Наш контейнер
function HUD:container()
    render.rect_filled (self.x, self.y, self.x + self.w, self.y + self.h, render.color("#00000026"))
    render.rect_filled (self.x, self.y, self.x + self.w, self.y + 2, self.color)
    render.text (font, self.x + self.w / 2, self.y + self.h / 2 + 1, self.name, render.color("#FEFEFE"), 1, 1)
end

-- Эта функция предназначена для рендера своих элементов. Например, кейбинды
-- В ней ничего писать не будем
function HUD:paint() end

-- И наконец, для вызова нашего класса
function HUD:draw()
    self:container()
    self:paint()

    self:drag()
end


3. Создание объектов класса. Сами HUD-элементы
Код:
-- ----- -----  ------ -------- ------- ------------ ---
-- Класс готов, теперь осталось создать какой-нибудь HUD.

-- Объявляем
local keylist = HUD:new("keylist", render.color("#00acf5"), 200, 600)  -- необязательно указывать все аргументы, у нас есть дефолтные

-- Рисуем
function keylist:paint()
    render.text (font, self.x + self.w / 2, self.y + self.h + 4, "Готово", render.color("#FEFEFE"), 1, 0)
end


-- --------
-- Вызываем

function on_paint()
    -- это для драга
    mx, my = input.get_cursor_pos()

    keylist:draw()
end


Результат:
Посмотреть вложение 183922

Мы получили контейнер кейлиста. Вы можете создавать любые элементы таким способом, можете модифицировать, улучшать, добавлять что-то новое. Текст "Готово" принадлежит конкретно кейлисту. У других объектов класса его не будет

Использование класса облегчило наш код, он стал меньше (большую часть кода займет сам класс, нежели его объекты).​
просто лучший
 
Эксперт
Статус
Оффлайн
Регистрация
10 Фев 2021
Сообщения
1,740
Реакции[?]
559
Поинты[?]
2K
Молодец, я даже не знал что такое мета таблицы и с чем их едят, слышал разве.
 
Посрал
Участник
Статус
Оффлайн
Регистрация
28 Ноя 2020
Сообщения
523
Реакции[?]
153
Поинты[?]
1K
Во всех скриптах, которых я видел, индикаторы создаются отдельно. Для них выделяют разные функции, то есть они ничем не объединены. Когда ты захочешь что-то поменять -- тебе придется менять это во всех функциях. А когда кода много, это то еще страдание.

Сегодня я покажу, как создавать HUD на мета-таблицах. Гайд пишу для более менее продвинутых кодеров. API - эвольв.

1. Для начала
Код:
-- --- ------- -------- -------- -------
-- Эта функция облегчит создание классов

function Class()
    local class = {}

    local mClass = {__index = class}

    function class.instance() return setmetatable({}, mClass) end
    return class
end
Потому что так легче создавать классы на метатаблицах.


2. Класс
Код:
-- --- -----
-- Сам класс

local HUD = Class()
Теперь начинается самое интересное


С помощью этого метода, мы сможем объявлять/создавать свои HUD-элементы. Нам нужно разместить здесь переменные, чтобы иметь к ним доступ с остальных методов.
Код:
-- Создание элемента HUD. Аргументы можно задать свои
function HUD:new(name, color, x, y, w)
    local self = HUD.instance()


    -- Здесь вы можете объявить все переменные класса. Они всегда будут доступны.
    -- Я не буду создавать рабочие индикаторы, это всего-лишь пример.

    -- главные переменные
    self.name, self.color = name, color
    self.x, self.y, self.w, self.h = x or 200, y or 400, w or 160, 20

    -- переменные для драга
    self.drag_x, self.drag_y = 0, 0
    self.is_dragging = false


    ------ ----
    return self
end

Следом идет перетаскивание. Добавил для примера.
Код:
-- Драг (спастил, мб есть лучше вариант)
function HUD:drag()
    local is_hovered = (mx > (self.x) and mx < (self.x + self.w) and my > (self.y) and my < (self.y + self.h))

    if is_hovered then
        if input.is_mouse_down(0) and not self.is_dragging then
            self.is_dragging = true
          
            self.drag_x = self.x - mx
            self.drag_y = self.y - my
        end
    end

    if not input.is_mouse_down(0) then
        self.is_dragging = false
    end

    if self.is_dragging and gui.is_menu_open() then
        self.x = (self.drag_x + mx)
        self.y = (self.drag_y + my)
    end
end

Остальное. В основном здесь рендер
Код:
-- Наш контейнер
function HUD:container()
    render.rect_filled (self.x, self.y, self.x + self.w, self.y + self.h, render.color("#00000026"))
    render.rect_filled (self.x, self.y, self.x + self.w, self.y + 2, self.color)
    render.text (font, self.x + self.w / 2, self.y + self.h / 2 + 1, self.name, render.color("#FEFEFE"), 1, 1)
end

-- Эта функция предназначена для рендера своих элементов. Например, кейбинды
-- В ней ничего писать не будем
function HUD:paint() end

-- И наконец, для вызова нашего класса
function HUD:draw()
    self:container()
    self:paint()

    self:drag()
end


3. Создание объектов класса. Сами HUD-элементы
Код:
-- ----- -----  ------ -------- ------- ------------ ---
-- Класс готов, теперь осталось создать какой-нибудь HUD.

-- Объявляем
local keylist = HUD:new("keylist", render.color("#00acf5"), 200, 600)  -- необязательно указывать все аргументы, у нас есть дефолтные

-- Рисуем
function keylist:paint()
    render.text (font, self.x + self.w / 2, self.y + self.h + 4, "Готово", render.color("#FEFEFE"), 1, 0)
end


-- --------
-- Вызываем

function on_paint()
    -- это для драга
    mx, my = input.get_cursor_pos()

    keylist:draw()
end


Результат:
Посмотреть вложение 183922

Мы получили контейнер кейлиста. Вы можете создавать любые элементы таким способом, можете модифицировать, улучшать, добавлять что-то новое. Текст "Готово" принадлежит конкретно кейлисту. У других объектов класса его не будет

Использование класса облегчило наш код, он стал меньше (большую часть кода займет сам класс, нежели его объекты).​
Чел, харош.
А теперь - инвайтнешь в эвольв???
 
Начинающий
Статус
Оффлайн
Регистрация
27 Ноя 2019
Сообщения
203
Реакции[?]
27
Поинты[?]
0
Забаненный
Статус
Оффлайн
Регистрация
23 Авг 2020
Сообщения
2,110
Реакции[?]
597
Поинты[?]
10K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Гайд хороший, но я всегда ненавидел когда создают одну функцию для пэинта и туда кидают все функции и запихивают это все в каллбек...
 
Дизайнер
Статус
Оффлайн
Регистрация
18 Авг 2017
Сообщения
1,931
Реакции[?]
2,258
Поинты[?]
146K
Товары в продаже
1
куплю спирт
Пользователь
Статус
Оффлайн
Регистрация
8 Апр 2018
Сообщения
295
Реакции[?]
67
Поинты[?]
0
Гайд крутой, но большого смысла делать это для луа, в которой будет присутствовать лишь один HUD-элемент - не вижу. Новичок скорее запутается, чем сможет рабочее что-то сделать
 
Дизайнер
Статус
Оффлайн
Регистрация
18 Авг 2017
Сообщения
1,931
Реакции[?]
2,258
Поинты[?]
146K
Товары в продаже
1
Гайд крутой, но большого смысла делать это для луа, в которой будет присутствовать лишь один HUD-элемент - не вижу. Новичок скорее запутается, чем сможет рабочее что-то сделать
этот код не для новичков

даже если будет всего один HUD элемент, то есть смысл использовать классы. мало ли захочется добавить еще что-то

для будущего короче полезно будет
 
Nike.lua
Олдфаг
Статус
Оффлайн
Регистрация
13 Окт 2020
Сообщения
2,747
Реакции[?]
1,465
Поинты[?]
2K
Включая то, что в lua отсутствует ООП то реализация неплохая. Очень обидно, что луа скриптинг не имеет классов, ибо функционал у них огромен. Гайд классный!
 
Эксперт
Статус
Оффлайн
Регистрация
14 Ноя 2020
Сообщения
1,800
Реакции[?]
586
Поинты[?]
2K
Сверху Снизу