PDA

Просмотр полной версии : [Урок] Введение в ООП в MTA



Disinterpreter
06.02.2016, 18:03
Я не собираюсь объяснять, что такое ООП и для чего оно нужно так как в википедии (https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5) это уже описано, я лишь расскажу, как пользоваться предоставляемыми в MTA методами.

Итак, создадим ресурс, назовем его oop-tutorial, в нем создадим файлы oop_s.lua и meta.xml.
В meta.xml напишем:

<meta>
<oop>true</oop>
<script src="oop_s.lua" type="server" />
</meta>
Обратите внимание на строку "<oop>true</oop>". По умолчанию ООП в MTA не используется и его нужно активировать вручную.
При включении ООП изменяется поведение некоторых функций, каких именно - увидите далее.

Затем откроем файл oop_s.lua и приступим к написанию кода.
Для начала давайте попробуем получить координаты игрока: для этого нам нужно создать команду /pos.


local function commandPos (pPlayer)
local vec = pPlayer:getPosition()
-- Интересный момент: vec у нас в ООП стиле становится областью класса Vector,
-- т.е., в отличие от процедурного стиля, в стиле ООП метод getPosition
-- возвращает объект вектора, а не три координаты (x, y, z).
outputChatBox("Your position: ".. vec:getX() ..", "..vec:getY()..", "..vec:getZ())
end
addCommandHandler("pos", commandPos)

При вводе команды в чат будут выведены ваши координаты, например: «Your position: 2031.8203125, 1523.3330078125, 10.8203125».

Попробуем провернуть нечто подобное с транспортом. Будем менять цвет машине, в которой мы сидим, для этого создадим еще команду /carcolor

local function commandCarColor (pPlayer)
local pVehicle = pPlayer:getOccupiedVehicle()
-- Если pVehicle ~= nil, то игрок сидит в машине.
if pVehicle then
-- Если да, то устанавливаем цвет на красный в формате RGB.
pVehicle:setColor(255,0,0)
else
-- Если нет, то пишем уведомление.
outputChatBox("You're not in a vehicle")
end
end
addCommandHandler("carcolor", commandCarColor)

В итоге, если сядем в машину и введем /carcolor то мы сменим цвет нашему транспорту, если транспорт позволяет менять цвета.

Теперь возьмем пример покруче, нам нужно создать класс. Мы, конечно, можем изучать все эти метатаблицы и шаманить руками, но можно поступить и проще.
Зайдем на https://github.com/sbx320/lua_utils, скачаем оттуда файл classlib.lua и добавим в наш meta.xml.
С помощью этого скрипта сделаем базовый класс для дальнейшего удобства, назовём его CObjects. Файл назовём CObjects.lua добавим его в манифест (meta.xml).
Реализуем в классе функции new и delete, которые также попадут и во все наследуемые от него классы:


CObject = {}

function CObject:new(...)
return new(self, ...)
end

function CObject:delete(...)
return delete(self, ...)
end

Далее мы будем наследоваться от этого класса. Создадим второй класс CNumbers, там мы поиграемся с числами. Назовем файл CNumbers.lua и точно так же добавим его в манифест(meta.xml).


-- Наследуем новый класс от ранее созданного CObject.
CNumbers = inherit(CObject);

-- Задаем параметры num1 и num2 в конструктор,
-- чтобы при создании экземпляра класса (объекта) их записать.
function CNumbers:constructor(num1, num2)
self.m_num1 = num1;
self.m_num2 = num2;
end

-- Реализуем различные арифметические операции над числами.
function CNumbers:add()
return self.m_num1 + self.m_num2;
end

function CNumbers:sub()
return self.m_num1 - self.m_num2;
end

function CNumbers:mul()
return self.m_num1 * self.m_num2;
end

function CNumbers:div()
return self.m_num1 / self.m_num2;
end

function CNumbers:destructor ()
print("hey! I'm a destructor")
end
-- создаем экземпляр класса и задаем числа
numbers = CNumbers:new(1,2)
-- производим сложение и выводим
print(numbers:add())
-- проверяем работу деструктора
numbers:delete()



В самом начале урока я думал, что этот урок нужно написать, но я не знал что сюда написать конкретно, поэтому сделал как есть.
Эту статью я писал для тех, кто знаком с принципом ООП, но не знает как он реализуется в МТА.
Если вам этот урок показался не полным или у вас есть ещё какие-то замечания, напишите об этом в комментариях и я исправлю недочёты или постараюсь реализовать предложенное в следующих уроках.

Важное замечание: Файлы в meta.xml стоит добавлять в том же порядке, в котором они будут загружаться в ресурсе, т.е сначала библиотека, родительские классы, дочерние классы.


Автор: Disinterpreter
Редактор: Daniel_Cortez


https://i.creativecommons.org/l/by-sa/4.0/88x31.png (http://creativecommons.org/licenses/by-sa/4.0/)
Эта статья доступна по лицензии Creative Commons «Attribution-ShareAlike » 4.0 (http://creativecommons.org/licenses/by-sa/4.0/).