Overview
GameMaker Language – Руководство для начинающих.Это руководство познакомит вас с основами GameMaker Language.
Введение
Добро пожаловать! Это руководство предназначено для новичков, у которых практически нет опыта работы с GML или программирования в целом. Он познакомит вас с основами программирования и как работает GML. После этого руководства, вы сможете использовать GML для эффективного создания собственных игр!
Добавьте эту страницу в закладки (Нажмите CTRL + D) так как это руководство довольно длинное, вы сможете закрыть его и вернутся к нему потом. Будет отлично, если вы прочитаете его залпом.
Данное руководство теперь доступно для чтения на платформе GitBook![darkpro1337.gitbook.io]Рекомендую читать его именно там, это руководство было перенесено туда и не будет удалено из Steam!
События
Множество событий на выбор
Вы помещаете код внутри события, и этот код работает в зависимости от типа события, в который вы его поместили. В GameMaker есть много событий, которые вы можете выбрать.
Вот краткое введение в события, которые мы будем использовать больше всего:
Код внутри события Create выполняется только один раз: когда экземпляр объекта, запускающий код, сначала создается. Здесь вы можете инициализировать большую часть основных переменных и/или придания движению объекту.
Самое важное и наиболее часто используемое событие – событие Step запускается каждый шаг – если для вашей скорости игры/комнаты установлено значение 30, событие Step будет выполняться 30 раз в секунду. Это можно использовать для вещей, которые должны, повторятся постоянно.
Это событие используется для отрисовки. Например, такие функции, как draw_sprite, который используется для рисования спрайта, или draw_rectangle, который используется для рисования прямоугольника, работают только в событии Draw. Экземпляр объекта не будет отрисовываться (т.е. встроенный спрайт в сам объект), при условии если в событие Draw “что-то” есть, поэтому чтобы избежать этого – используют draw_self().
События таймера запускаются после их установки. Поэтому, если я установил Alarm 0 до 60 в событии Create, код внутри события Alarm 0 будет запущен через 60 шагов.
Добавляя событие столкновения, вы можете выбрать объект для создания события. Это событие будет выполняться только тогда, когда экземпляр, запускающий код, сталкивается с любым экземпляром объекта, указанным при создании события столкновения.
Переменные
Переменные – это контейнеры, содержащие некоторые значения/информацию. У них есть имя. Например, переменная с именем player_health может содержать 100, или переменная с именем player_name может содержать имя игрока («Питер», «Линдси» и т. д.). Зависит только от вас, что вы хотите назвать переменными и, что вы хотите хранить внутри них.
Переменная в GML может хранить:
- Численные значения – 100, 45.534, -42.2
- Строковые значения – “Учитель”, “Питер”
- Логические значения – true или false
Инициализация:
Здесь мы инициализировали переменную с именем price, которая содержит 20 в качестве значения. Если переменная уже была инициализирована ранее, то эта будет изменять ее значение до 20.
Примечание: в GML не обязательно помещать точку с запятой (;) после каждого утверждения. Поэтому не стесняйтесь пропустить её и сосредоточиться на главном коде.
Есть много способов присвоения значения…
Чтобы увеличить значение…
Чтобы уменьшить значение…
Чтобы умножить или разделить…
Также вы можете использовать переменные в математических выражениях…
Здесь c будет хранить 9 из-за выражения a + b (что означает, что 4 + 5 как a равно 4, а b равно 5).
Локальные переменные
Эти переменные инициализируются ключевым словом var. Они сбрасываются, когда событие было инициализировано в конце. Они могут использоваться только внутри события, если только не инициализированы снова.
Этот код инициализирует локальную переменную price. Предположим, что событие, в котором находился этот код, было событием Step; то переменная может использоваться только в событии Step. Если вы попытаетесь использовать её без инициализации в другом событии, то она вернет ошибку, поскольку она там не существует.
Переменные экземпляра
Это обычные переменные, которые инициализируются путем присвоения значения.
Доступ к этим переменным возможен во всех событиях объекта/экземпляра, после того, как они был инициализированы.
Глобальные переменные
Это переменные, к которым могут получить доступ все объекты в вашей игре – отсюда и название «global». Существует два способа создания таких переменных:
Инициализация с помощью ключевого слова globalvar…
Как только переменная была инициализирована через globalvar, она может использоваться любым экземпляром, присутствующим в комнате.
или использовать с global. prefix…
Таким образом, вам не нужно инициализировать переменную с помощью globalvar, но вы должны использовать global. prefix каждый раз, когда вы хотите использовать эту переменную.
Есть также некоторые встроенные переменные, которые означают что-то особенное в GameMaker. Вот несколько примеров…
Встроенные переменные экземпляра
Это встроенные переменные, которые уникальны для каждого экземпляра. Они также могут быть известны как свойства экземпляра. Вот несколько важных примеров…
Вы можете изменять или использовать эти переменные так же, как обычные.
Текст, который появляется после //, является комментарием. Это не влияет на код; он там, чтобы вы могли объяснить, что делает ваш код, или писать важные вещи, которые вы хотели бы запомнить, глядя на ваш код.
Вы также можете написать многострочные комментарии – просто запустите их с /* и закончите с помощью */.
Встроенные глобальные переменные
Эти встроенные переменные, которые являются глобальными для каждого экземпляра.
Вот несколько примеров…
Вот список всех встроенных переменных в GameMaker.[gamemaker.wikia.com]
Функции
Функции выполняют действие и/или возвращают значение, основанное на аргументах, приведенных в скобках, которые идут после имени функции. Если функция должна просто выполнять действие, она написана так…
…но если он также возвращает что-то после выполнения действия, и вы хотите сохранить его в переменной, вы делаете это так…
Функция может и не может содержать аргументы.
Вот несколько примеров…
Условия – оператор if
Условия используются для управления выполнением некоторого кода. Используя условия, вы можете контролировать, работает ли фрагмент кода на основе условий. if оператор являются наиболее часто используемыми условиями. Используя if вы можете убедиться, что часть кода работает только при условии, что само условие или набор условий – истина (true).
Допустим, вы делаете игру, и вы делаете магазин. Здесь игрок должен купить некоторые улучшения. Первое улучшение – улучшение оружия. Оно стоит 200 монет. Таким образом, игрок может купить его только в том случае, если это условие выполнено, то есть если у них есть как минимум 200 монет. В таком случае мы можем использовать условие if:
Знак > открывается в сторону, которая больше, и = конечно же, означает равно. Итак, проверяя, if coins>=200, мы проверяем, больше ли 200 монет или они равны 200.
Таким образом, игрок может купить улучшение только в том случае, если у него достаточно монет. Но что, если он этого не сделает? Мы должны уведомить его, что ему нужно больше монет. Но это нужно только тогда, когда условие не выполняется. Для этого мы используем else.
Код после else выполняется только тогда, когда предыдущее условие if вернуло false. Поэтому, если у игрока меньше 200 монет, он будут уведомлен об этом.
Вы также можете поместить условие после else, так что даже после того, как прежнее условие вернет false, для выполнения кода потребуется еще одно условие else.
Таким образом, вы можете добавить больше else и добавить разный код для разных условий:
Если condition0 истинно, code0 будет запущен, а остальная часть оператора if будет пропущена. Но если condition0 является ложным, оно перейдет к condition1. Если оно истинное, он выполнит code1 и остановится. Но если он тоже ложный, тогда он перейдет в condition2. Если это правда, code2 будет запущен, но если нет, оператор if, наконец, перейдет к последней части и увидит, что нет условия, и выполнится code3.
В предыдущем примере мы проверили, были ли монеты больше либо равны 200. Но условия могут использоваться многими другими путями.
Условия и Функции
Функции также могут использоваться внутри условий. Их можно либо проверять как логические значения (возврат true или false), либо через возврат определенного значения (числа/строки).
Вот несколько примеров, демонстрирующих, как функции могут использоваться внутри условий.
Функция place_meeting() может использоваться для проверки наличия столкновений между экземпляром, выполняющим код, и указанным объектом/экземпляром в позиции. Например,
Эта функция вернет true, если obj_wall сталкивается с obj_player в позиции последнего. Таким образом, чтобы проверить наличие коллизий и выполнить некоторый код, надо поставить эту функцию в условие:
Когда происходит столкновение между obj_wall и obj_player, он устанавливает speed до 0.
Функция instance_exists() возвращает true, если экземпляр указанного объекта присутствует внутри комнаты.
Вышеприведенный код проверяет, существует ли экземпляр obj_player в комнате, и если это истина то, добавляет 1 к score.
Функция floor() заполняет число, указанное в его круглых скобках, и возвращает результат. Например, 4.94 станет 4, 1.13 станет 1 и так далее.
image_index хранит индекс суб-изображения, на котором в данный момент находится спрайт. Суб-изображения находятся в целых числах, но переменная image_index – нет. Поэтому, прежде чем проверять, какой суб-образ включен, вам нужно заполнить переменную.
Условия – оператор switch
Возможно, как новичку, операторы switch, не будут очень полезны для вас, но все же вы должны знать о них.
В операторе switch вы сначала указываете переменную, функцию или комбинацию внутри математическом выражении. Затем вы перечисляете все возможные случаи. Оператор switch вычисляет указанное выражение и переходит к случаю, соответствующему результату. Он выполняет код, следующий за случаем, пока не будет найден разрыв.
Вот пример:
В этом примере level – это переменная, которая содержит номер уровня, на котором игрок находится в данный момент. Когда level равен 1, он переключится в case 1. Он будет запускать код, где он устанавливает level_name для «Overworld». Затем он сталкивается с break и останавливает код.
Если вы не используете break перед запуском другого случая, он будет продолжать выполнять все случаи до тех пор, пока не будет найден разрыв.
Аналогично, когда level равен 2, будет выполняться случай 2. То же самое для случаев 3 и 4.
Но что, если level не соответствует ни одному из этих случаев? В такой ситуации switch перейдет к части default и запустит код идущий после него.
Функция repeat
Функция repeat() может повторять набор операторов определенное количество раз и используется так же, как и оператор if. Вот пример:
Вы знаете, что coins += 1: добавляет 1 к переменной coins. Но поскольку мы используем repeat(5) перед ним, оператор будет выполняться 5 раз, в конечном итоге будет добавляться 5 к переменной coins (1 * 5 = 5).
Функция repeat() представляет собой своего рода цикл, потому что он продолжает цикл, пока он не достигнет конца. Продолжайте читать, чтобы узнать больше о циклах.
Цикл while
Итак, для начала – существуют разные типы циклов, а цикл while – один из них. Поскольку он самый простой, я сначала объясню его.
Циклы называются так, потому что они цикличны. Циклы как оператор if, в них есть условие которое должно быть выполнено для исполнения кода. Здесь рассмотрим оператор if в сравнении с циклом while:
Оператор if проверяет, больше ли money, чем 40, а затем выполняет код. Цикл while проверяет так же, но разница в том, как работает цикл.
Когда условие, указанное для цикла, становится истинным, выполняется идущий после него код, и когда этот блок кода заканчивается, он возвращается к условию и проверяет его снова. Если условие истина, то он снова выполняет код. Затем снова и снова, и если это истина, снова выполняет код. Он продолжает это делать, проверяет условие, а затем код, и так пока условие не станет ложным.
Давайте возьмем пример выше. Скажем, значение money становится больше 40. Цикл while выполнит код, и продолжит делать это до тех пор, пока условие не станет ложным. Для того, чтобы условие оказалось ложным, стоимость денег должна быть ниже или равна 40.
Теперь все в порядке. Если мы уменьшаем значение money на каждый цикл, в какой-то момент оно должно опускаться ниже 40 и останавливать цикл.
Обязательно чтобы вы реализовали, что условие в итоге стало ложным, и тем самым остановить цикл. Если вы этого не сделаете, то цикл станет бесконечным, который никогда не остановится и приведет к вылету вашей игры.
Цикл do…while
Это еще один цикл и вариант цикла while. Посмотрите как он выглядит, прежде чем я объясню как он работает:
Не пугайтесь. Это очень просто.
Помните, как в цикле while мы использовали проверку условия перед выполнением кода?
В цикле do…while часть while(условие) переместилась в нижнюю часть, после блока кода, и был заменен на do:
//код
} while (условие);
Это так потому, что цикл do..while сначала выполняет весь код, который находится в блоке кода, а затем проверяет условие, чтобы убедиться, что это истина, и должен ли он снова выполнить цикл. Если это так, он возвращается наверх и выполняет блок кода. Затем снова переходит к условию. Таким образом, он продолжает цикл до тех пор, пока условие не станет ложным, разница состоит в том, что он сначала выполняет блок кода, даже не проверяя условие.
Точка с запятой (;) должна быть в конце цикла do…while, потому что без нее конечная часть while(условие) может запутаться с запуском другого цикла while.
Цикл do…until
Цикл do…until совпадает с циклом do…while, причем разница заключается в том, что проверка условия do…until перевернута. Поэтому в do…while цикл будет работать снова, если условие было истинным, но в do…until цикл будет выполняться только в том случае, если условие было ложным.
Это так же просто, как сказать: “Продолжайте добавлять 1 к coins, пока они не станут равны 10″. Будет продолжать добавлять 1 к монетам, и когда данное условие станет истинным, когда монеты будут равны 10, тогда цикл будет остановлен.
В GameMaker следует использовать do…until, но не do…while.
Цикл for
Цикл for аналогичен циклу while, так как он сначала проверяет условие, и только потом продолжает цикл до тех пор, пока условие не станет ложным. Но у него есть еще несколько функций. Взгляните на его синтаксис:
Тут вы можете определить состояние посередине. Но что это всё такое?
В основном это для переменной цикла. Переменная цикла в цикле for – это переменная, которая определяет сколько раз повторится цикл. А теперь больше объяснений.
init – здесь вы инициализируете свою переменную цикла, так как в ней указывается имя и значение. Выполняется в начале цикла.
condition – это условие, которое определит, выполняется ли цикл.
increment – это то, где вы устанавливаете переменную цикла, которая должна быть увеличена или уменьшена на определенное значение каждого цикла. Выполняется в конце цикла.
Вот подробное объяснение того, как будет работать этот цикл:
Сначала я инициализирую переменную цикла i с значением 0. Затем это условие проверяется, будет ли i меньше 3. Это означает, что это условие истинна, код выполнится. Как только блок кода завершит выполнение, увеличение будет запущенно: это означает, что i будет увеличиваться на 1 (i ++).
Теперь блок кода завершил своё выполнение, и i был увеличен на 1, что означает, что теперь он равен 1 (0 + 1). Инициализация будет оставлена, поскольку она работает только в начале цикле. Поэтому он перейдет к условию и проверит, меньше ли i, чем 3. Поскольку 1 меньше чем 3, условие будет истинным, и код будет выполнен.
Опять же, после выполнения блока кода, 1 будет добавлен к i, теперь он равен 2. Затем он перейдет к условию, и поскольку 2 меньше чем 3, условие станет истинным, и код будет выполнен снова. Тогда i станет 3 (2 + 1), а затем условие станет ложным, потому что i не меньше 3, оно равно 3. Теперь цикл остановится.
Итак, цикл будет работать три раза:
Если вы не поняли, попробуйте перечитать, это может помочь.
Вот еще один пример цикла for:
Начинается с 3 и продолжает уменьшаться на 1, пока не станет больше 0. Можете рассчитать, сколько раз цикл будет выполнятся? Попробуйте рассчитать и напишите свой ответ в комментариях!
Массивы
Помните, как работают переменные? Вы можете дать им имя и сохранить в них некоторое значение…
Это количество монет только одного игрока. Но что, если игроков 4, вам нужно хранить значение для каждого, и у них есть какое-то количество монет? Как бы вы это сделали?
Сделать вот так, верно? Хранить все эти значения в разных переменных? Это будет работать верно, но есть и другой, более лучший способ сделать это: использовать массивы.
Массивы похожи на переменные, у них также есть имя и хранятся некоторые значения, но в отличие от переменных они могут хранить несколько переменных (элементов) под тем же именем.
Чтобы назначить или получить доступ к элементу внутри массива, поместите идентификатор элемента (число) в квадратные скобки после имени массива. Вот так:
Поэтому в предыдущем примере я добавил четыре элемента (0, 1, 2, 3) к массивам. Если я хочу сохранить второй элемент (со значением 5) к переменной с именем player_2, я сделаю следующее:
Вы также можете использовать переменную вместо идентификатора элемента внутри квадратных скобок, потому что главное – это значение, а не ключевое слово. Поэтому я могу сделать так:
player_2 = coins[i];
Также вы можете использовать массивы внутри цикла:
money[i] = coins[i];
}
Вышеупомянутый код выполняет ту же функцию, что и этот:
Поскольку цикл будет выполняться только 3 раза, когда переменная цикла i будет равна 0, 1 и 2 соответственно, первые три элемента массива money станут равными первым трем элементам массива coins.
Заключение
Это всё для основ.
У вас есть вопросы или какие-нибудь предложения? Не стесняйтесь комментировать ниже. Я отвечу на ваш комментарий, как только смогу!
- Автор оригинального руководства[gdpalace.wordpress.com]
- Оригинал руководства на Английском[gdpalace.wordpress.com]
- Видео-курс по GMS на Udemy (англ.)[gdpalace.wordpress.com]
- Discord сервер, где вам могут помочь с GMS. (англ.)[discord.gg]
- Версия этого руководства на GitBook[darkpro1337.gitbook.io]
Если вы находите ошибки в переводе, оставляйте поправки в комментарии.Для таких людей будет создана отдельная секция в этом руководстве, с благодарностями. Я тоже человек и не владею чистым Английским, я буду вам очень признателен за помощь. Алсо,
более лучшие и удобные формулировки приветствуются.
Удачного вам геймдева! 🙂