StarCraft 2: Основы Galaxy (I вариант)

» Раздел: 1. Основы

Введение в galaxy.

Что такое galaxy

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

Основы языка Galaxy

Итак, для начала создайте новый скрипт карты. Он называется custom code, и будет интегрирован в код вашей карты. Для его создания в редакторе триггеров нажмите "Ctrl+Alt+T".
Переименуйте новый созданный объект в "Custom Map Code".
Именно сюда вы можете вставить свои новые функции, действия, события и условия. Также возможны создания своих операторов и т.п.
Начнем с самого простого:

Условия и Действия.

if (ваше_условие == выражению) 
{
    ваше_действие;
} 
else 
{ 
    иначе_действие; 
} 
Как видите, мало чем отличается от остальных скриптовых языков.
Вообще blizzard сделали язык очень простым и удобным, код теперь напоминает синтакс языка c.
Но обо всем по порядку.
Любая нативная функция, запускается так:
gf_name(arguments);
Как вы наверно заметили перед нативной функцией стоит "gf_", это обозначает "global function" ( глобальная функция ). Эта приставка ничего не делает, и используется только для удобства. В своих функциях мы можете ставить любые приставки, или же вообще не использовать их.

Переменные и аргументы.

В galaxy можно объявлять переменные двух типов: локальные и глобальные. Имена локальных переменных в разных функциях могут совпадать, так как предел их "видимости" ограничен той функцией, в которой переменная была объявлена. При этом обратится к ним, можно будет только в этой функции. А глобальные переменные, доступны в любом участке вашего кода.
Локальные переменные в функции объявляются так:
type lv_myvariable = value;
Здесь "type" означает тип переменной, например "int" или "fixed" или "string" и т.п.
Приставка "lv_" переводиться как "local_variable" и используется по желанию пользователя.
Однако при создании переменных в GUI, они генерируются автоматически.
А "value" означает "начальное" значение переменной. Например "0" - для типа integer, или "" - для строки.
int lv_integer = 0;
// или
string krab = "ya_krab";
Теперь у нас есть локальная переменная lv_integer с начальным значением "0".
Массивы в galaxy выглядят так:
unit [10][5][3][2] my_unit;
Посмотрите на переменную "my_unit". В Galaxy можно создавать массивы до четвертой степени.
Число, указанное в ID массива, показывает максимальное кол-во переменных в массиве.
Т.е обратится к ней можно так:
var1 = my_unit[1][0][0][1];
var2 = my_unit[1][0][0][2];
var3 = my_unit[1][0][0][3];
Параметры объявляются вместе с функцией:
void myfunc(int lp_myparam1, string lp_myparam2){}
Вот так выглядит типичная функция в galaxy. Как видите у неё 2 аргумента, первый имеет "целочисленный" вид, а второй "строковый".
Запустить функцию можно так:
myfunc(1,"abc");

Циклы

Цикл в galaxy выглядит следующим образом:
    while (условие)
    {
        // тут код которые выполняется.
    }
Цикл "while" будет выполнятся бесконечно до тех пор, пока условие в скобках верно.
Что бы сделать бесконечный цикл, достаточно написать это:
    while (true) 
    {
        break;
    }
Вы должны будете вручную останавливать выполнение цикла, для этого существует оператор "break"
После того как программа дойдет до этого оператора, весь дальнейший цикл будет пропущен.

Структуры

Структура это сложный вид переменной, в русском языке называется "Запись".
Она сама является переменной, что позволяет делать целый массив одинаковых структур, а также может включать в себя переменные любых видов, в том числе массивы, и даже другие записи.
Вот простая запись, она не является массивом и заключает в себя 3 переменных. Первую "player" типа "целочисленное", вторую "speed" с типом "вещественное" и третью "damage" с типом "целочисленное"".
struct MyStruct 
{
    int player;
    fixed speed;
    int damage;
};
После создание структур вы должны еще создать переменную со ссылкой на эту запись:
// имя_записи имя_переменной;
MyStruct Bullet;
Здесь "MyStruct" это имя записи которую мы создали ранее, а "bullet" имя переменной которая будет использоваться.
Что бы обратится к нашей новой записи, нужно использовать это:
real_speed = Bullet.speed;
int_player = Bullet.player;
lv_damage = Bullet.damage;
Также можно сделать её массивом.
// имя_записи массивы имя_переменной;
MyStruct[16][10] Bullet;

int Integer = Bullet[i][1].int_player;
fixed Real = Bullet[i][1].speed;
И разумеется, переменные в структурах тоже можно сделать массивом.
int LastDamage = Bullet[u][j].damage[1]

Практика.

Давайте создадим новую математическую функцию, которая будет иметь такой вид:
SimpleMath(a,"+",b);
Для этого напишите в "Custom Map Code" такой текст:
int SimpleMath( int a, string c, int b )
Префикс "Int" перед "SimpleMath" показывает тип объекта которая получится после работы функции. В данном случае функция возвращает "целочисленное".
Как видите функция имеет 3 параметра ( аргумента ):
первый "a" - первое целочисленное число.
второй "c" - строка. Может иметь вид "+" , "-" , "*" , "/"
третий "b" - второе целочисленное число.
Дальше поставьте знак открытия и закрытия функции.
{
}
Код который находится между этими знаками и будет исполнятся функцией.
После этого следует написать проверку на знак "+". Для этого между двумя скобками вставьте код, и все вместе будет выглядеть так:
int SimpleMath( int a, string c, int b )
{
    if (c == "+") 
    {
        return a+b;
    }
}
Эта функция суммирует числа a и b.
Остальные 3 знака ( - , * , / ) подставьте в функцию самостоятельно.
В результате у вас получится вот это:
int SimpleMath( int a, string c, int b )
{

    if (c == "+") 
    {
        return a+b;
    }
    if (c == "-") 
    {
        return a-b;
    }
    if (c == "*") 
    {
        return a*b;
     }
    if (c == "/")
    {
        return a/b;
    }
    return 0;
}
В конце функции можно заметить return 0;. Сделан он для того, чтобы компилятор не выдавал ошибки, в случае если ни одно из условий не выполняется, то есть "c" не равно ни "*", ни "\", ни "-", ни "+".
Функция вернет первый "return", который встретит при проверке, после чего остальная часть кода будет пропущена и функция завершит работу
Теперь в триггере "Melee Initialization" ( на русском языке "Инициализация Карты" ) создайте одну локальную целочисленную переменную "TestMath" в GUI, а также новое действие - "Присваивание переменной".
Теперь присвойте переменной (GUI) "TestMath" результат выполнения функции из раздела "Custom Script" со следующими параметрами:
Теперь при инициализации карты будет запущена эта функция, и переменная (GUI) TestMath будет равна "4".
Можете проверить это с помощью функции Text Message (GUI) ("Текстовое Сообщение") из раздела UI ("ПИ")
При запуске карты вы увидите число "4".
Итак, мы создали копию стандартной функции для математических вычислений. В данном случает наша функция, может умножать, вычитать, складывать и делить.
Все это конечно хорошо, но сделать это можно и без galaxy. А теперь перейдем к более сложным вещам.

Задачи в galaxy.

Допустим нам надо сделать что-то, чего нельзя сделать в GUI. К примеру, задать время дня в игре, используя переменные. Стандартная функция позволяет ввести время дня только вручную. И если перевести это действие в код (Ctrl+F11) мы увидим следующие:
GameTimeOfDaySet("06:55:12");
Итак, мы видим тут что время дня задается на 6 часов, 55 минут и 12 секунд.
Теперь давайте создадим свою функцию, состоящую из 3 целочисленных переменных, которая будет задавать время дня, а также будет иметь графический аналог в GUI.
Первым делом создайте новое GUI действие, для этого в редакторе триггеров нажмите "Ctrl+Alt+R". Назовите его "Set Time of Day" ( установить время дня ).
Теперь создадим 3 параметра ( аргумента ) для нашего действия.
Выделите слово "Parametrs" ( Параметры ) и нажмите "Ctrl+W".
По очереди создайте 3 параметра. Их начальный тип будет "целочисленное", так что ничего кроме имени менять не нужно.
Всего должно быть 3 параметра "hour" (часы), "min" (минуты), и "sec" (секунды).
Теперь создайте одну локальную переменную в этом действие, назовите её "str"
Дальше создайте действие "Custom Script" ( пользовательский скрипт )
И напишите в нем следующую строку:
lv_str = (IntToString(lp_hour)+":"+IntToString(lp_min)+":"+IntToString(lp_sec));
Тут надо пояснить что "lv_str" это наша локальная переменная "str". ( приставка "lv_" обозначает "локальная переменная" )
Эта приставка генерируется автоматически, если вы создаете переменные в GUI.
А lp_hour, lp_min, lp_sec это параметры (аргументы). ( приставка "lp_" обозначает "локальный параметр" )
Тут также приставка "lp_" генерируется автоматически, при создание параметра в GUI.
Добавьте строку:
GameTimeOfDaySet(lv_str);
Теперь при использовании функции мы сможем поменять время в игре на любые 3 целочисленных значения.
Измените grammar text ( текст подсказки ) как: "Задать время как Hourч. Minм. Secс."
Полностью наше действие будет выглядеть так:
Для теста добавьте это действие в наш триггер "Melee Initialization".
Теперь при запуске время игры будет задано как 4 часа ( из переменной MathTest ) и 10 минут.

Итог

FAQ:
В: Что такое GUI?
О: GUI это графический аналог кода. GUI куда более беден на возможность программирования, чем galaxy - но куда более простой для новичков.
В: Что еще за префиксы?
О: При создание переменных, параметров, функций в GUI они генерируются автоматически.
При создание любых функций, переменных и параметров в коде программист сам решает ставить префиксы или нет.
Префиксы не имеют никакого системного значения, они нужны только для более удобного чтения кода.
В: А что за префиксы для функций?
О: Они как раз определяют, какой тип данных возвращает функция после выполнения. Т.е если у нас есть математическая функция, она должна делать что-то, а потом вернуть результат своих вычислений. Префикс void обозначает, что данная функция ничего не возвращает.
В: Что такое запись
О: Запись = Record = Структура = Struct
В: Что такое нативка
О: Нативная функция (native). Является стандартной функцией и вшита в исходный код игры. Не подлежит изменению или удалению.
Надеюсь, вы узнали, как можно использовать galaxy в своих целях. Дальше напишу все упрощения из статьи:
Префиксы:
При создании переменных и функций в GUI, редактор сам будет генерировать эти префиксы. Однако при создании своего кода, ставить их не обязательно.
"lv_" означает "локальная переменная" ( local variable )
"gv_" означает "глобальная переменная" ( global variable )
"gf_" означает "глобальная функция" ( global function )
"lp_" означает "локальный параметр" ( local parametr )
Префиксы для функций:
void - функция ничего не возвращает.
int - функция возвращает целочисленное значение.
string - функция возвращает строку.
bool - функция возвращает логическое значение.
Горячие Клавиши:
«Ctrl+F11» (Data - View Script): смотреть исходный код карты
«Ctrl+F12» (Data - Compile All): Проверка кода на ошибки. При нахождении ошибки откроется окно, где будет указана строка с ошибкой.
«Ctrl+Alt+R» (Data - New - New Action Definition): Создание GUI функции.
«Ctrl+T» (Data - New - New Trigger): Создание Триггера.
См. также:
Можно изменить значок у папок в триггерах. Нажмите на них правой кнопкой мыши и выберите "Label - XXXX" ( самый последний пункт )
» xgm
Статья написана для развития xgm, в поддержку партии Licentia sator.
Помощь в написание статьи - Fedrat.

Просмотров: 9 285

Это сообщение удалено
XimikS #2 - 9 лет назад 1
как то половиногуинчато
H #3 - 9 лет назад (отредактировано ) 0
Это чтобы новичкам было проще разобраться. =\
Статья только введение в galaxy
Версия 1.1
  • Исправлены ошибки
  • Переписано вступление ( Что такое galaxy )
  • Добавлен еще один скриншот
2 комментария удалено
H #7 - 9 лет назад (отредактировано ) 1
Он на многое похож, они взяли самое лучшее из разного ) че т я как мастер йода написал
Жалко только что нет нормального чекера, а также функции при вводе не появляются в окошечке .. )
4 комментария удалено
krimatoriy #12 - 9 лет назад 0
Класс ХГМ идет в ногу со временем, спасибо.
XimikS #13 - 9 лет назад (отредактировано ) 0
только стандартный функционал кода, и уже созданные функции.
напиши что это нативки
Galaxy является простым языком программирования
скриптования
Возможно, в дальнейшем можно будет подключать к языку свои плагины и расширения в формате .dll
мечты неплохо было бы выпилить, ибо смущают читателя)
довольно странно базовое обучение начинается с if/then/else 0_0 тут лучше поставить функции
Вообще blizzard сделали язык очень простым и удобным, избавили его от лишних слов таких как "call".
напиши лучше что синтаксис c-like
gf_name(arguments);
понятней будет function_name, а про gf_ как дополнение
Локальные могут быть с одинаковыми именами в одной функции
не ясно написанно, лучше так "имена локальных переменных в разных функциях могут совпадать, так как предел их "видимости" ограничен той функцией, в которой переменная была объявлена"
int lv_integer = 0;
unit [10][5][3][2] my_unit;
сразу напиши что тут про массивы
type lv_myvar = def;
ну что за примеры, "type my_variable = value;"
void myfunc(int lp_myparam1, string lp_myparam2){}
нагляднее если бы функция выводила параметры на экран
H #14 - 9 лет назад (отредактировано ) 0
ок, шас исправлю.
fixed
про type myvariable = value
спс, исправил.
XimikS #15 - 9 лет назад 0
хоть в структуры добавь немного философии о оопе.
H #16 - 9 лет назад 0
Если бы я знал что такое оопе ^___^
Guard #17 - 9 лет назад 0
Ahelhot полезная статья. Но если честно я мало чё понял Ж)
Sergey #18 - 9 лет назад 2
Неплохо, в принципе, все понятно. Понравилось, что теперь есть переменные-структуры.
Такой вопрос: а имеюися ли в Galaxy аналоги того, что было в jass? Скажем, custom value и возможность узнать уникальный идентификатор объекта?
ScorpioT1000 #19 - 9 лет назад 0
"например "int" или "real" или "string" и т.п." откуда в ск2 флоат тип ? (я про real, там же fixed) ?
опятьже бред какойто
с химиком не согласен насчет слова "программирование" - всё верно, читаем определение к слову
"В galaxy можно объявлять переменные двух типов локальные и глобальные." двоеточие после слова "типов"
слово "область видимости" лучше заменить на "время жизни"
"Условия и Действия."
про else if забыл упомянуть
структуры в галакси говно, можете забить) их же передавать по указателю нельзя
а так, уже норм. хотя структура и цель статьи очень хромают, но содержание хотябы уже вполне
Sergey, если ты спросил чисто для познания - советую пробежаться по всем сообщениям от меня и toadcop в теме xgm.ru/forum/showthread.php?t=33498
XimikS #20 - 9 лет назад 0
с химиком не согласен насчет слова "программирование" - всё верно, читаем определение к слову
ты не согласен что это не подходит по контексту?)
Sergey, там есть банк aka хеш)
H #21 - 9 лет назад (отредактировано ) 0
слово "область видимости" лучше заменить на "время жизни"
каждый о своем.. ^__^
Кстати в вики написано "Область видимости" )
ScorpioT1000 #22 - 9 лет назад (отредактировано ) 0
область видимости - область в исходном коде, в котором имя объекта будет ассоциироваться у компилятора с этим объектом (это совсем не значит, что в ином случае её совсем не будет), а время жизни - участок кода в программе, во время выполнения которого переменная будет находиться в памяти (т.е. будет "жива")
2 комментария удалено
H #25 - 9 лет назад 0
Такой вопрос: а имеюися ли в Galaxy аналоги того, что было в jass? Скажем, custom value и возможность узнать уникальный > идентификатор объекта?
custom value есть и имеет такой вид
Unit cs 1-x = yyy
Т.е в любого юнита можно записать много данных ( только тип не помню, вроде там любой тип )
Id нету, так как rb тут не нужен )
Revion #26 - 9 лет назад 0
>> структуры в галакси говно, можете забить) их же передавать по указателю нельзя
не поверю, если структуры копируются при передаче в качестве параметра. Я думаю они по нормальному передаются _по_ссылке_. Любые структуры. Было бы очень странно, если бы Близы это не сделали. Хотя я всего лишь предполагаю, я в гэлэкси ещё ничего не писал.
H #27 - 9 лет назад 0
не передаются это факт.
Wulfrein #28 - 9 лет назад 0
наконец-то запилил иконку
dk #29 - 9 лет назад (отредактировано ) 0
Массивы в galaxy выглядят так:
unit [10][5][3][2] my_unit;
Посмотрите на переменную "my_unit". В Galaxy можно создавать массивы до четвертой степени.
Число, указанное в ID массива, показывает максимальное кол-во переменных в массиве.
Т.е обратится к ней можно так:
var1 = my_unit[1][0][0][1];
var2 = my_unit[1][0][0][2];
var3 = my_unit[1][0][0][3];
Последнего элемента в объявленом массиве нет...
anaksimandr #30 - 9 лет назад 0
Массивы в galaxy выглядят так:
unit [10][5][3][2] my_unit;
Посмотрите на переменную "my_unit". В Galaxy можно создавать массивы до четвертой степени.
Число, указанное в ID массива, показывает максимальное кол-во переменных в массиве.
Т.е обратится к ней можно так:
var1 = my_unit[1][0][0][1];
var2 = my_unit[1][0][0][2];
var3 = my_unit[1][0][0][3];
Последнего элемента в объявленом массиве нет...
Может я че путаю, но если ячейки нумеруются с нуля, то и предпоследнего тоже =))
centrino #31 - 6 лет назад 0
Вот вы пишите
Массивы в galaxy выглядят так:
unit [10][5][3][2] my_unit;
Вы имели ввиду четырехмерный массив? Я молчу о новичках, они бы вообще запутались. Также если уж и говорите о массивах, то отсчет элементов с нуля начинается? То есть если размер 2, то индексы 0 и 1, правильн?
Audes #32 - 6 лет назад 0
Лучшая статья, у неё должна быть уже не одна сотня плюсов.