Название статьи: Пауза с использованием "родителей". Виды переменных.
Здравствуйте, дорогие форумчане!
Это моя первая статья.
В ней я подробно расскажу о видах переменных в GML, и об их использовании в родительских объектах.
Далее мы рассмотрим все вышеупомянутое на примере паузы для двигающихся шариков.
Статья рассчитана на людей, уже знакомых с интерфейсом Game Maker-а, но которые не нашли в себе силы прочитать весь форум и справку.
Основой для написания это статьи послужила моя текущая разрабатываемая игра. Все упомянутое здесь уже обсуждалось на форуме, но в виде очень разрозненно поданных сведений (исключая
урок Hummer-а о переменных). Я постарался расписать все очень подробно, чтобы ответить на вопросы всех, даже самых въедливых читателей.
Надеюсь, статья найдет свою аудиторию и окажется полезной начинающим.
К статье приложен файл-исходник, на который я буду ссылаться в процессе.
Итак, переменные.Посмотрев вышеупомянутый урок Хаммера о переменных, становится все понятно. Потому, я дам упрощенный и образный вариант для
быстрого понимания.
Для новичка переменная - это слово, название, в которое можно помещать цифру или текст. Причем название переменной должно быть задано латинскими буквами (также можно использовать цифры и символы подчеркивания).
Как это понять?
Назовем нашу переменную
test_variableнаписав просто так в коде:
test_variable
и выполнив его, мы получим ошибку, потому что мы ничего не помещаем в нее. Исправим ситуацию, поместим в нее число
1:
test_variable = 1;
Обратите внимание, в конце я поставил ";" - этот символ не всегда обязателен, но иногда без него программа работать откажется. Потому привыкаем сразу ставить его после законченной строки кода.
теперь, если я следом выполню код
show_message(test_variable);
у нас появится окошко, с сообщением о содержимом переменной test_variable.
Для демонстрации в приложенном примере нажмите кнопку
Q.
Если подробнее рассмотреть код, написанный в двух скриптах использующихся в этом примере (scr_create_lesson1 и scr_Q_lesson1), переменную мы создаем в одном скрипте, а вызываем ее - в другом. Но оба скрипта используются одним объектом (o_lesson). Это важно. Таким образом, мы создали переменную, которой может пользоваться только этот объект, но в любом месте, в любом событии. И не может пользоваться другой объект (на самом деле можно использовать эту переменную из другого объекта, но только ссылаясь на объекта-хозяина. Но это для нас сейчас несущественно).
Изменим немного код, расположенный в скрипте scr_create_lesson1. Чтобы не мешать примеры, разместим новый код в скрипт scr_create_lesson2:
var test_variable1;
test_variable1 = 1;
Переменную мы назвали чуть иначе (test_variable1) и перед присваиванием переменной, мы написали новую строчку кода. Слово
var говорит, что данная переменная будет доступна только внутри этого скрипта, а не объекта в целом! И предыдущий способ ее использования уже не пройдет!
Чтобы в этом убедиться, нажмем в приложенном примере кнопку
W и увидим ошибку:
Unknown variable test_variable1
это означает, что программе переменная test_variable1 незнакома. Если же мы выполним код
show_message(test_variable1);
в том же самом скрипте после присваивания переменной, то ошибки не будет, и мы снова увидим сообщение с цифрой 1. Для чего нужна такая переменная, которую нигде, кроме данного конкретного скрипта использовать нельзя? Для внутренних расчетов. Если у вас в коде 50-200 переменных, вы начинаете забывать, где и какие имена использовали. Чтобы избежать ситуации, когда один из скриптов портит данные переменной объекта (при этом возникают непредсказуемые и необъяснимые ошибки), и используется такой способ объявления переменных.
Есть еще один способ объявления переменных - глобальное объявление. В коде оно будет выглядеть как:
globalvar test_variable2;
Это демонстрирует скрипт scr_create_lesson3 примера.
объявив таким способом переменную, мы можем использовать ее в любых объектах. Нажмем кнопку
E и вновь увидим сообщение "1". Но переменную, которую использует объект o_lesson1_1, присваивал другой объект - o_lesson.
Если же мы попытаемся из объекта o_lesson1_1 получить нашу первую переменную test_variable, то снова получим ошибку (для демонстрации нажимаем кнопку
R). Потому что эта переменная, как я и говорил, недоступна другим объектам.
Подведем итог:- есть три способа объявления переменных (просто назвать переменную, объявить с помощью
var или с помощью
globalvar)
- различия между ними - в доступности переменных (
var доступна только внутри скрипта,
globalvar везде, просто названная только внутри объекта)
Перейдем к родителям.Разберем пример:
Если у вас есть два шарика, оба должны двигаться по совершенно одинаковым правилам, удобно использовать родительские объекты.
Создадим три объекта: родительский o_parent и два его "ребенка": o_child1 и o_child2
Объекты o_child будут нашими шариками.
А объект o_parent будет содержать правила их движения.
Для демонстрации примера я создал рисунок (и объект) стенки, нарисовал разноцветные шарики для наших "деток". В объекте o_parent я описал правила движения шарика (двигаться в случайном направлении, при столкновении со стенкой отрикошетить).
Так как объект o_parent у нас родительский, его события выполняются у его детей так, будто мы в обоих детках указали свои правила движения (если было бы 100 шариков, мы бы упарились каждому прописывать эти правила, а таким способом можно их указать всего один раз!).
Чтобы применить знания, полученные в первом уроке, пронумеруем шарики через родительский объект.
Цель: задать каждому шарику переменную
num_ball, содержащую номер шарика. И нарисовать в центре шарика его номер.
Для этого при создании объекта o_parent выполним скрипт (scr_parent_create)
var obj_name; // объявляем локальную переменную, хранящую название объекта, который выполняет этот скрипт
globalvar n; // объявляем глобальную переменную-счетчик, с помощью которой будем считать наши шарики
num_ball = 0; // объявляем переменную, персональную для каждого объекта.
// в ней каждый объект будет хранить свой номер
obj_name = object_get_name(self.object_index); // помещаем в переменную название текущего объекта, использующего этот скрипт
if !variable_global_exists(n)
{
n = 0; // если начальное значение глобальной переменной еще не задано, задаем его
};
// в зависимости от того, какой объект вызывает этот скрипт, выполняем разные действия
switch obj_name
{
case "o_child1": // т.к. этот скрипт будет вызван три раза (родителем и
// детками, номера нужно присвоить только деткам)
case "o_child2":
n = n + 1; // увеличиваем счетчик шаров на единицу
num_ball = n; // задаем шару его номер
break;
};
Как видите, нам очень пригодились знания о переменных.
Теперь перейдем к третьей части нашей программы:
Пауза в игреЗная предыдущие две части, создать паузу теперь пара пустяков.
Дописываем в скрипт scr_parent_create:
pause_do; // создаем переменную, переключающую режим паузы
speed_pause = 0; // запомненная скорость объекта
Далее создаем еще один скрипт (scr_parent_pause), который вешаем на выполнение родительского объекта при нажатии кнопки
Pvar obj_name; // объявляем локальную переменную, хранящую название объекта, который выполняет этот скрипт
obj_name = object_get_name(self.object_index); // помещаем в переменную название текущего объекта, использующего этот скрипт
if pause_do == true // в зависимости от значения глобальной переменной
// pause_do создаем паузу или снимаем ее
{
pause_do = false; // снимаем паузу
switch obj_name
{
case "o_child1":
case "o_child2":
speed = speed_pause; // возобновляем скорость объекта
break;
};
}
else
{
pause_do = true; // ставим паузу
switch obj_name
{
case "o_child1":
case "o_child2":
speed_pause = speed; // запоминаем скорость
speed = 0; // и останавливаем объект
break;
};
};
В этом скрипте мы видим уже знакомые действия: определяем, какой объект выполняет скрипт. И объектам o_child1 и o_child2 меняем значение переменной и скорость движения.
Осталось лишь запустить игру, нажимать кнопку
P и любоваться работающей паузой.
Удачи в обучении,
искренне Ваш, Галушко Андрей aka Strateg.