Тема: [rb] Lua
[color=#aaaaaa]Репост с Rubash, оригинальный тред: http://forum.toribash.com/showthread.php?t=296427[/color]
[b]
Из этого гайда ты узнаешь, как делать скрипты в Toribash'е, используя Lua.[/b]
[center][b]Часть первая.[/b]
Основы.[/center]
[b]
В первой части данного туториала мы начнём с самого простого - как начать делать скрипты, строки, номера, таблицы и циклы.[/b]
Итак, давай приступим к работе. Но перед тем, как написать свой первый скрипт для торибаша, тебе понадобится Notepad++ (или другой текстовый редактор) и Toribash (разумеется).
[b][center]Здравствуй, мир![/center][/b]
Твоей основой будет фраза "hello world!":
echo("hello world!")Сохраните получившуюся команду в файл "helloworld.lua" (и поместите этот файл в toribash/data/scripts/)
Теперь откройте торибаш и идите в Setup -> Utils -> Scripts => выберите "helloworld.lua" и нажмите "load".
Как только ты запустишь скрипт, в строке чата появится фраза "hello world!" темно-красного цвета. Это и есть функция [b]echo[/b]. Её можно использовать не просто для подобного выведения текста в чатбокс, но для отладки скрипта в целом. Также ты сможешь проинформировать игроков, которые будут в будущем использовать данный скрипт, о том, что он сделан тобой, путём вставки копирайта.
[b]Теперь об этом же, но более продвинуто:[/b]
Вернись в свой helloworld.lua скрипт в notepad++ и вставь в него это:
Message1 = "Hello"
Message2 = "world"
Message3 = "!"
echo(Message1 .. " " .. Message2 .. Message3)Так что же это такое?
Message1 = "Hello"Вот так вы объявляете переменную в Lua. Переменные хранят информацию, такую как числа или текст.
Message2 = "world"
Message3 = "!"Message1, Message2 и Messge3 сейчас содержат текст который нужен для вывода фразы "Hello world!" через echo. Но как мы соединим три сообщения в одну фразу?
echo(Message1 .. " " .. Message2 .. Message3)Знак ".." в lua обозначает объединение. То, что мы получаем в данном скрипте, называется конкатенацией - это когда ты складываешь несколько строк рядом; поэтому мы поставили после Message1 ("Hello") пробел (" "), а затем Message2 ("world") и Message3 ("!"), чтобы в итоге получить фразу "Hello world!".
[center][b]Цифры[/b][/center]
[center][/center]
Цифры в Lua объявляются в точности так же, как строки. Давайте мы поменяем в предыдущем скрипте слова на числа и получим примерно вот
Message1 = 45.23
Message2 = 2312.3
echo(Message1 .. "+" .. Message2 .. "=" .. (Message2 + Message1))В игре это будет выглядеть вот так
45.23+2312.3=2357.53Я думаю, что тут всё достаточно просто выглядит. Message1, имеющий значение "45.23" контактирует с "+" и Message2 со значением "2312.3" и скрипт выводит сумму этих двух чисел.
[b][center]Таблицы и циклы[/center][/b]
Message = { }
Message[1] = "Word"
Message[2] = 23.232
Message[3] = "This is a sentence."
Message[4] = ":D 2323424" .. 23.232 .. "!"
Echo = "Message: "
for i = 1,#Message do
Echo = Echo .. Message[i]
end
echo(Echo)Давайте я объясню, что за скрипт вы видите выше.
Message = { }Эта строка объявляет новую таблицу. Таблицы (или массивы) - это группы из переменных. Они могут содержать какой-либо тип переменных, даже функции.
Message[1] = "Word"Это делает первую переменную в сообщении: "Word".
for i = 1,#Message doЭтот цикл будет идти от 1 (первая переменная в сообщении) до итоговой цифры переменных в сообщении (#Таблицы получают итоговую сумму цифр переменных).
Этот цикл будет повторяться четыре раза (так как в данном случае здесь четыре переменных в сообщении) и каждый раз цифра "i" будет увеличиваться на 1.
Echo = Echo .. " " .. Message[i]Эта строка объединяет соответствующие сообщения на конец строки "echo"
При запуске этого скрипта в игре в чат-боксе появится следующее сообщение
Message: Word23.232This is a sentence.:D 232342423.232![center][b]Часть вторая.[/b]
Условные операторы и функции.[/center]
Окей, во второй части этого гайда я расскажу вам про условных операторов, некоторые связанные с Toribash'ем функции, и про то, как сделать свою функцию.
Пройдя эту часть гайда, мы сможем написать скрипт, выводящий имя победителя в текущем бою.
[b][center]Условные операторы[/center][/b]
Условные операторы - это один из самых важных аспектов любого скрипта. Они позволяют вызывать функции тогда, когда ты хочешь, например:
a = 1
b = 2
if(a+b == 3) then
echo("a + b == 3 :O")
else
echo("a + b ~= 3")
endЕсть три основные части условного оператора: if, then и else. В этом примере условное выражение это "a+b == 3". Если вы используете только один знак равенства, то появится ошибка, так как программа, в которой вы будете запускать скрипт (Toribash) посчитает, что вы пытаетесь установить переменную. Именно поэтому знаков равенства должно быть два.
Вот список всех операторов, которые ты можешь использовать:
== Равно
~= Не равно
> Больше
< Меньше
>= Больше или равно
<= Меньше или равноДля примера давайте рассмотрим небольшой скрипт с использованием оператора ">=":
a = 2
b = 2
if(a >= b) then
echo("a is greater than or equal to b")
else
echo("a is less than b")
endВот, по сути тут нет ничего сложного!
[b][center]
Функции, связанные с Toribash[/center][/b]
Есть достаточно много функций, связанных с Toribash, которые мы можем вызвать в lua.
Для примера давайте возьмем ситуацию, когда мы хотим увидеть, у какого игрока больше очков в конце боя. Мы сравним счета двух игроков и узнаем, у кого больше очков, с помощью следующего скрипта:
Player1_Score = get_player_info(1).injury
Player2_Score = get_player_info(0).injury
if(Player1_Score > Player2_Score) then
echo("Player 1 is winning!")
elseif(Player2_Score > Player1_Score) then
echo("Player 2 is winning!")
else
echo("Draw!")
endКогда ты запустишь этот скрипт, он покажет, у какого из игроков в данный момент больше очков. Довольно прикольно, да?
Вы можете увидеть список некоторых встроенных функций в Toribash в папке /data/scripts/sdk/
[center][b]Создание своих функций
[/b][/center]
Создание своих собственных функций - это жизненно необходимая часть lua, она позволяет повторно использовать код быстро и эффективно.
Например, если мы хотим создать функцию, которая будет показывать, кто побеждает:
function winning()
Player1_Score = get_player_info(1).injury
Player2_Score = get_player_info(0).injury
if(Player1_Score > Player2_Score) then
return "Player 1"
elseif(Player2_Score > Player1_Score) then
return "Player 2"
else
return "Draw!"
end
end
echo("Winning: ^06" .. winning())Теперь каждый раз, когда ты запускаешь этот скрипт, тебе в чат будет выкидывать сообщение "Winning: ..." (вместо "..." будет писаться номер игрока (1 - Тори, 2 - Юки) или "Draw!" в цвете с номером 06 (розовый).
Итак, мы создали нужный нам скрипт, и на этом данная часть гайда заканчивается.
[center][b]Часть третья.[/b]
Хуки и отладка.[/center]
В данной статье я буду рассказывать про хуки и отладку скриптов.
После прочтения этого туториала ты будешь уметь:
- Делать скрипт, который показывает, кто из игроков лидирует по очкам и "замораживает" каждого игрока.
- Устранять неполадки в твоих скриптах.
[b][center]Хуки[/center][/b]
Хук (hook) является еще одним важным аспектом lua. Он позволяют выполнять определенные функции в определенное время.
Хук выглядит примерно вот так:
add_hook("hook name","hook description", functiontocall)Так что они могут сделать? Хуки могут позволить тебе нарисовать текст на экране или писать кто выигрывает каждые (к примеру) 50 фреймов.
Ты можешь найти лист хуков в файле startup.lua (который находится в папке data/script/) в таблице events, но сейчас мы будем использовать хук под названием "enter_freeze".
Давайте используем скрипт, который остался с предыдущего туториала; из него мы можем довольно легко сделать скрипт, который будет повторять текущего лидера.
function winning()
Player1_Score = get_player_info(1).injury
Player2_Score = get_player_info(0).injury
if(Player1_Score > Player2_Score) then
return "Player 1"
elseif(Player2_Score > Player1_Score) then
return "Player 2"
else
return "Draw!"
end
end
echo("Winning: ^06" .. winning())Так, это наш код. Для того, чтобы называть лидера каждый раз, мы должны немного изменить этот код. Прежде всего мы создадим функцию которая называет его (лидера), проще говоря echo(“Winning… и посмотрим что получилось:
function winning()
Player1_Score = get_player_info(1).injury
Player2_Score = get_player_info(0).injury
if(Player1_Score > Player2_Score) then
return "Player 1"
elseif(Player2_Score > Player1_Score) then
return "Player 2"
else
return "Draw!"
end
end
function enter_frame()
echo("Winning: ^06" .. winning())
endДалее нам нужно добавить хук, чтобы наши функции работали. Сделать это можно добавив следующую строку в нижнию часть скрипта:
add_hook("enter_freeze","echowinner",enter_frame)Немного больше о хуках вы узнаете в четвертой части гайда.
[b][center]Отладка
[/center][/b]
Если ты экспериментировал со скриптами, что-то пошло неправильно и ты не смог все починить - значит это все из-за того, что Toribash считает, что ты допустил ошибку в коде. Так как Toribash не показывает, где и на какой строке находится ошибка, есть специальный файл под названием "stderr.txt".
Если ваш скрипт выдаёт ошибку или работает не должным образом, тебе необходимо проверить файл stderr.txt чтобы увидеть, какие ошибки есть в скрипте. Вот пример распространенной ошибки:
Lua script error in file errorscript.lua: data/script/errorscript.lua:2: attempt to index global ‘a’ (a nil value)Давайте рассмотрим это. Прежде всего этот текст говорит нам, что в lua скрипте допущена ошибка. В нашем случае эта часть нам не важна, но будет незаменима, когда мы будем запускать сразу несколько скриптов. Далее нам говорят, где находится скрипт, ошибочная строка (в данном случае 2) и говорят описание ошибки. В нашем случае ошибка расшифровывается так: она говорит что таблица создана не должным образом, то есть нужно чтобы было "a = { }" а у нас, видимо, не так (в данном случае "a=" это переменная а "{}" таблица).
Прочие возможные ошибки:
Lua script error in file errorscript.lua: data/script/errorscript.lua:3: ‘}’ expected (to close ‘(‘ at line 2) near ‘echo’ Ты закрыл не все скобки правильно.
Lua script error in file errorscript.lua: data/script/errorscript.lua:2: attempt to perform arithmetic on global ‘b’ (a nil value)Значение 'b' было не определено.
На этом третья часть этого гайда кончается.
[center][b]Часть четвертая.[/b]
Рисование.[/center]
В четвертой, последней части этого гайда я расскажу тебе, как рисовать в 2D и 3D.
Пройдя её, ты сможешь:
- Рисовать текст с динамическим размером и задним фоном.
- Рисовать шарики.
[b][center]
Рисование в 2D[/center][/b]
Все рисование в lua происходит благодоря хукам, с которыми мы познакомились в третьей части. Чтобы рисовать в 2D, тебе нужно использовать хук draw2d, а для рисования в 3D тебе нужно использовать хук draw3d.
Для начала, давайте рассмотрим рисование в двух измерениях.
add_hook("draw2d","draw", draw2dfunc)Это - хук draw2d. Давайте теперь рассмотрим основные его функции.
set_color(r,g,b,a)Для рисования чего-либо ты должен выбрать цвет. В данном случае используется система RGB с альфа каналом, то есть r = красный цвет, g = зеленый, b = синий и a = прозрачный. Номера должны находиться в диапазоне от 0-1. (0,0,0,1) для черного и (1,1,1,0.5) для белого цвета.
draw_quad(x,y,w,h,texture)Теперь попробуем нарисовать прямоугольник в Lua. х = координата x (ось абсцисс), у = у-координата (ось ординат), W = ширина, Н = высота. Также там имеется опция текстуры, но её рассматривать мы не будем.
draw_disk(x, y, inner, outer, slices, loops, start, sweep, blend)Это - код многоугольника. Значение inner обозначает расстояние с внутреннего радиуса, outer - расстояние с внешнего радиуса, slices - количество углов (3 - треугольник, 4 - четырехугольник).
draw_text(text,x,y,font)Это - код рисования текста. Значение text обозначает текст, который будет нарисован. Шрифт выбирается цифрами от 0 до 5.
[b]Важная заметка:[/b]
Координаты (0,0) обозначают, что текст находится в верхнем левом углу, и чем выше значение "х", тем правее ты рисуеешь, а чем больше "у" значение, тем ниже ты рисуешь.
Итак, давайте начнем рисовать наш первый прямоугольник!
function draw2dfunc()
set_color(0,0,0,1)
draw_quad(10,300,100,200)
end
add_hook("draw2d","draw", draw2dfunc)Этот скрипт рисует прямоугольник с точки (10,300) до точки (110,500).
Давайте нарисуем немного более "продвинуто" и попробуем добавить какой-либо текст и динамическую форму прямоугольника.
text = { } -- Blank table
text[1] = "This is some text"
text[2] = "This is more text"
text[3] = "MOOOOOOOOOO"
text[4] = "Just a basic test really"
text[5] = "weeeeeeeeeeeeeeeeeee"
text[6] = "1231923823982938"
text[7] = 123.23
text[8] = "Blam is the best "
placey = 200
function draw2dfunc()
ScreenWidth, ScreenHeight = get_window_size()
set_color(0,0,0,1)
draw_quad(10,placey,ScreenWidth-20,#text*17.5)
set_color(1,1,1,1)
for i = 1,#text do
draw_text(text[i],12,(i*17)-17+placey,1)
end
end
add_hook("draw2d","draw", draw2dfunc)Так, тут я написал много непонятных тебе вещей, так что давай рассмотрим полученный скрипт по частям.
text = { }
text[1] = "This is some text"
text[2] = "This is more text"
text[3] = "MOOOOOOOOOO"
text[4] = "Just a basic test really"
text[5] = "weeeeeeeeeeeeeeeeeee"
text[6] = "1231923823982938"
text[7] = 123.23
text[8] = "Blam is the best "Это, как ты скорее всего понял, текст, который мы выводим на дисплей.
placey = 200Эта строка определяет, где текст будет отображаться по оси x; в данном случае - 200px сверху вниз.
ScreenWidth, ScreenHeight = get_window_size()ScreenWidth, ScreenHeight - ширина и высота окна, в которых будет отображаться текст.
#text*17.5Тут мы определяем размер шрифта (я предпочитаю именно такой размер, потому что это - самый оптимальный вариант, на мой взгляд)
(i*17)-17+placeyРасположение по оси y.
for i = 1,#text doДобавляем цикл, пройденный нами в первой части.
draw_text(text[i],12,(i*17)-17+placey,1)Ну и, собственно, выводим текст на экран.
[b][center]Рисование в 3D[/center][/b]
Как я уже говорил, рисование в 3d производится с помощью хука draw3d
add_hook("draw3d","draw", draw3dfunc)Для рисования сферы в 3D нужно использовать:
draw_sphere(x,y,z,radius)Сейчас, если мы хотим нарисовать сферу над головой у тори, мы должны узнать позицию нашей головы. Для этого мы можем использовать следующее:
x, y, z = get_joint_pos(0, 0)Здесь x,y, и z являются x,y, и z координатами джоинта шеи нашего тори. Также можно сделать так:
get_joint_pos(player, joint)Список джоинтов здесь
А теперь можно и нарисовать что-нибудь. Я это сделал следующим образом, "надев" тори на голову шар:
function draw3dfunc()
x, y, z = get_joint_pos(0, 0)
set_color(0,0,0,1)
draw_sphere(x,y,z,0.4)
end
add_hook("draw3d","draw", draw3dfunc)Ну вот и всё, на этом данный мини-учебник по Lua заканчивается. Спасибо за прочтение, надеюсь, что вы осилили его до конца.
[right]
Оригинальный текст: Blam
Перевод: Apozzman
Дополнения: sir[/right]
[/center]