Клавиатура
Для взаимодействия с клавиатурой существуют следующие переменные и функции:
keyboard_lastkey Клавиатурный код последней нажатой клавиши. Смотрите ниже - константы клавиатурного кода. Вы можете изменять его, например, установить на 0, если Вы бы нажали клавишу.
keyboard_key Клавиатурный код нажатой в данный момент клавиши (смотрите ниже; 0 - если клавиша не нажата).
keyboard_lastchar Последний нажатый символ (как строка).
keyboard_string Строка, содержащая последний в большинстве 1240 печатных символов. Данная строка может содержать только символы печатного типа. Она также корректно отвечает на нажатие клавиши backspace, стирая последний символ. Чтобы проверить, нажата ли определённая клавиша или кнопка мыши - Вы можете использовать следующие функции. Это бывает полезно при одновременном нажатии кнопок.
Иногда может быть полезным отображение одной клавиши другой. Например, Вы могли бы захотеть позволить играющему использовать как клавиши позиционирования, так и клавиши numpad. И, не дублируя действий, Вы можете отэкземплярить клавиши numpad на клавишах позиционирования. Также Вы могли бы захотеть осуществить механизм, в котором играющий может назначить клавиши для использования. Для этого доступны следующие функции:
keyboard_set_map(key1,key2) Устанавливает клавиатурный код клавиши key1 на key2.
keyboard_get_map(key) Возвращает последнее назначение для клавиши.
keyboard_unset_map() Восстанавливает все клавиши для отображения самих себя.
Для конкретной проверки, нажата ли какая-нибудь клавиша или кнопка мыши, Вы можете использовать следующие функции. Это особенно полезно при одновременном нажатии клавиш.
keyboard_check(key) Возвращает истину, если нажата клавиша с конкретным клавиатурным кодом.
keyboard_check_pressed(key) Возвращает истину, если клавиша с конкретным клавиатурным кодом была нажата с поры выполнения последнего шага.
keyboard_check_released(key) Возвращает истину, если клавиша с конкретным клавиатурным кодом была отпущена с поры выполнения последнего шага.
keyboard_check_direct(key) Возвращает истину, если нажата клавиша с конкретным клавиатурным кодом, проверяемая непосредственно аппаратные средства. Результат независим от того, какое приложение рассматривается. Она учитывается для ещё нескольких проверок. В особенности Вы можете использовать клавиатурные коды: vk_lshift, vk_lcontrol, vk_lalt, vk_rshift, vk_rcontrol и vk_ralt, чтобы проверить, нажат ли левый или правый Shift или клавиша Alt.
|
Для манипулирования клавиатурным состоянием могут быть использованы следующие программы:
keyboard_get_numlock() Возвращает истину, если установлен Numlock.
keyboard_set_numlock(on) Устанавливает (истина) или не устанавливает (ложь) Numlock.
keyboard_key_press(key) Имитирует нажатие клавиши с указанным клавиатурным кодом.
keyboard_key_release(key) Имитирует отпускание клавиши с указанным клавиатурным кодом.
Для виртуальных клавиатурных кодов существуют следующие константы:
vk_nokey клавиатурный код представляет, что не нажата никакая клавиша
vk_anykey клавиатурный код представляет, что нажата любая клавиша
vk_left клавиатурный код для клавиши стрелка "влево"
vk_right клавиатурный код для клавиши стрелка "вправо"
vk_up клавиатурный код для клавиши стрелка "вверх"
vk_down клавиатурный код для клавиши стрелка "вниз"
vk_enter клавиша Enter
vk_escape клавиша Escape
vk_space клавиша Space
vk_shift клавиша Shift
vk_control клавиша Ctrl
vk_alt клавиша Alt
vk_backspace клавиша Backspace
vk_tab клавиша Tab
vk_home клавиша Home
vk_end клавиша End
vk_delete клавиша Delete
vk_insert клавиша Insert
vk_pageup клавиша Pageup
vk_pagedown клавиша Pagedown
vk_pause клавиша Pause/Break
vk_printscreen клавиша Printscreen/SysRq
vk_f1... vk_f12 клавиатурные коды для функциональных клавиш F1 - F12
vk_numpad0... vk_numpad9 клавиши на цифровой клавиатуре
vk_multiply клавиша умножения на цифровой клавиатуре
vk_divide клавиша деления на цифровой клавиатуре
vk_add клавиша сложения на цифровой клавиатуре
vk_subtract клавиша вычитания на цифровой клавиатуре
vk_decimal клавиша десятичной точки на цифровой клавиатуре
|
Для символьных клавиш используйте, например ord('A'). (С заглавной буквы.) Для цифровых клавиш используйте ord('5') чтобы получить клавишу <5>. Следующие константы могут использоваться только в keyboard_check_direct:
vk_lshift клавиша левый Shift
vk_lcontrol клавиша левый Ctrl
vk_lalt клавиша левый Alt
vk_rshift клавиша правый Shift
vk_rcontrol клавиша правый Ctrl
vk_ralt клавиша правый Alt
Для примера, предположим, что Вы имеете объект, которым пользователь может управлять при помощи клавиш курсора, Вы можете поместить следующую часть кода в событие шага объекта:
{ if (keyboard_check(vk_left)) x -= 4; if (keyboard_check(vk_right)) x += 4; if (keyboard_check(vk_up)) y -= 4; if (keyboard_check(vk_down)) y += 4;}Конечно намного проще просто поместить его в событие клавиатуры.
Существует несколько дополнительных функций, имеющих отношение к взаимодействию с клавиатурой.
keyboard_clear(key) Очищает состояние клавиши. Это означает, что больше не будет генерироваться событие клавиатуры, пока оно не повторится.
io_clear() Очищает все состояния клавиатуры и мыши.
io_handle() Обрабатывает ввод/вывод пользователя, модифицируя состояние мыши и клавиатуры.
keyboard_wait() Ожидает, пока пользователь не нажмёт клавишу на клавиатуре.
|
Мышь
Для взаимодействия с мышью существуют следующие переменные и функции:
mouse_x* X-координата мыши. Не может быть изменена.
mouse_y* Y-координата мыши. Не может быть изменена.
mouse_button Нажатая в данный момент кнопка мыши. Используется как значения mb_none, mb_any, mb_left, mb_middle или mb_right.
mouse_lastbutton Последняя нажатая кнопка мыши.
Чтобы проверить, нажата ли конкретная кнопка мыши, Вы можете использовать следующие функции. Это в основном полезно, когда многие кнопки нажимаются одновременно.
mouse_check_button(numb) Возвращает истину, если нажата кнопка мыши (используется как значения mb_none, mb_left, mb_middle или mb_right).
mouse_check_button_pressed(numb) Возвращает истину, если была нажата кнопка мыши с поры выполнения последнего шага.
mouse_check_button_released(numb) Возвращает истину, если была отпущена кнопка мыши с поры выполнения последнего шага.
Следующие функции могут быть использованы для проверки колеса прокрутки мыши.
mouse_wheel_up() Возвращает истину, если колесо было прокручено вверх со времени последнего шага.
mouse_wheel_down() Возвращает истину, если колесо было прокручено вниз со времени последнего шага.
Существует несколько дополнительных функций, имеющих отношение к взаимодействию с мышью.
mouse_clear(button) Очищает состояние кнопки мыши. Это означает, что больше не будет генерироваться событие мыши, пока игрок не отпустит кнопку и не нажмёт её снова.
io_clear() Очищает все состояния клавиатуры и мыши.
io_handle() Обрабатывает ввод/вывод пользователя, модифицируя состояние мыши и клавиатуру.
mouse_wait() Ожидает, пока пользователь не нажмёт кнопку мыши.
Также Вы можете изменять курсор спрайта. Просто назначте этой переменной значение определенного спрайта:
cursor_sprite Указывает спрайт для курсора. (По умолчанию спрайт не используется, значение -1). Вы можете присвоить любой спрайт, который будет рисоваться в позиции курсора. (Вы можете отключить стандартный курсор в Global Game Settings.)
Проверка столкновений
При планировании движений или проверке определённых действий, часто важно знать, имеются ли столкновения с другими объектами в определённых местах. Следующие программы могут использоваться именно для этого. Все они, в общем, имеют три аргумента: аргумент obj - может быть объектом, ключевое слово all , или идентификатор экземпляра объекта. Аргумент prec - указывает, должна ли проверка быть точной или только базироваться на ограничивающем прямоугольнике (bounding box) экземпляра объекта. Точная проверка осуществляется, когда спрайт для экземпляра объекта имеет точную проверку столкновения установленную в опциях. Аргумент notme - указывает, что вызывающий экземпляр объекта не должен проверятся. Все эти функции возвращают идентификатор одного из экземпляров объекта, который сталкивается, или они возвращают отрицательное значение, когда нет столкновения.
collision_point(x,y,obj,prec,notme) Проверяет, есть ли в точке (x,y) столкновение с объектами obj.
collision_rectangle(x1,y1,x2,y2,obj,prec,notme) Проверяет, есть ли столкновение между прямоугольником с указанными противоположными углами и объектами obj. Например, Вы можете использовать это для проверки свободной от препятствий области.
collision_circle(xc,yc,radius,obj,prec,notme) Проверяет, есть ли столкновение между кругом с центром в позиции (xc,yc) с заданным радиусом и объектами obj. Например, Вы можете использовать это для проверки - имеется ли ближайший объект возле конкретной позиции.
collision_ellipse(x1,y1,x2,y2,obj,prec,notme) Проверяет, есть ли столкновение между эллипсом с указанными противоположными углами и объектами obj.
collision_line(x1,y1,x2,y2,obj,prec,notme) Проверяет, есть ли столкновение между отрезком из (x1,y1), в (x2,y2) и объектами obj. Это мощная функция. Вы можете использовать её для проверки - может ли экземпляр объекта "видеть" другой экземпляр, заодно проверяя, пролегает ли отрезок между стеной.
Пути
В Game Maker Вы можете определять пути и задавать их, чтобы экземпляры объекта следовали заданным заранее путям. Хотя Вы можете использовать для этого действия, ниже приведены функции и переменные, которые предоставят Вам больше гибкости и управления:
path_start(path,speed,endaction,absolute) Начинает путь для текущего экземпляра объекта. path - имя пути, который Вы хотите запустить. speed - скорость перемещения. Отрицательная скорость означает, что экземпляр объекта перемещается в обратном порядке (задом наперёд) вдоль пути. endaction - указывает, что должно случиться, когда будет достигнуто окончание пути. Следующие значения могут быть использованы:
0: останавливает путь
1: продолжение со стартовой позиции (если путь не закрыт, мы перескакиваем на стартовую позицию)
2: продолжение из текущей позиции
3: возобновляет путь, что изменяет признак скорости
Аргумент absolute должен быть истиной или ложью. Когда истина - используются абсолютные координаты пути. Когда ложь - путь становится относительно текущего экземпляра объекта. Точнее, если скорость положительная, то стартовая точка пути будет установлена в текущей позиции, и путь будет следовать оттуда. Когда скорость является отрицательной, то завершающая точка пути будет установлена в текущей позиции, и путь оттуда будет следовать в обратном порядке.
path_end() Заканчивает путь для текущего экземпляра объекта.
path_index* Индекс текущего пути, по которому следует экземпляр объекта. Вы не можете изменять это непосредственно, а должны использовать функцию выше.
path_position Позиционирует текущий путь. 0 - начало пути. 1 - конец пути. Значение должно быть между 0 и 1.
path_positionprevious Предшествующая позиция в текущем пути. Это может использоваться, например, в событиях столкновения для установки позиции на предыдущую.
path_speed Скорость (пикселей за шаг), с которым будет следовать экземпляр. Используйте отрицательную скорость для обратного перемещения.
path_orientation Ориентация (против часовой стрелки), в которой путь будет выполнен. 0 - нормальная ориентация пути.
path_scale Масштабирование пути. Увеличьте, чтобы сделать путь больше. 1 - значение по умолчанию.
path_endaction Действие, которое должно быть выполнено при завершении пути. Вы можете использовать вышеуказанные величины.
Планирование движения
Планирование движение поможет Вам перемещать определённые экземпляры объекта от одной позиции к другой, избегая столкновений с другими экземплярами объекта (например, стенами). Планирование движения является трудной задачей. Невозможно даже предоставить общих функций, которые будут работать удовлетворительно во всех ситуациях. Также, обработка столкновения свободных движений является трудоёмкой операцией. Итак, будьте осторожными, применяя это. Пожалуйста, держите эти замечания в уме, когда Вы будете использовать любую из следующих функций.
Различные формы планирования движения предусмотрены в Game Maker. Самая простая форма позволяет, чтобы экземпляр объекта отправился к конкретной целевой позиции, пытаясь по возможности перемещаться прямо. При этом беря другое направление, если первоначальный способ перемещения невозможен. Эти функции должны использоваться в событии шага экземпляра объекта. Они должны соответствовать движениям планированных действий, которые также доступны:
mp_linear_step(x,y,stepsize,checkall) Позволяет экземпляру объекта перемещаться прямо к указанной позиции (x,y). Размер шага указывается stepsize. Если экземпляр объекта уже в позиции, то он не переместится дальше. Если checkall - истина, то экземпляр объекта остановится при контакте с экземпляром любого объекта. Если - ложь, то он остановиться только при контакте с твёрдыми экземплярами объекта. Заметьте, что эта функция не предусматривает "объездов", если экземпляр встречает препятствие. В этом случае это просто терпит неудачу. Функция возвращает истину, если была достигнута целевая позиция.
mp_linear_step_object(x,y,stepsize,obj) Также как и функция выше, но на этот раз, только экземпляры obj считаются как препятствия. obj может быть объектом или идентификатором экземпляра.
mp_potential_step(x,y,stepsize,checkall) Подобно предшествующей функции, но эта функция позволяет, чтобы экземпляр объекта перемещался к конкретной позиции. Но в этом случае, он пытается избегать препятствий. Когда экземпляр объекта должен встретить твёрдый экземпляр объекта (или любой экземпляр объекта, когда checkall - истина), то он изменит направление движения, пытаясь избежать столкновения с другим экземпляром и переместиться вокруг него. Метод не гарантируется, чтобы использовать его всё время, но в большинстве простых случаев - это эффективно переместит экземпляр объекта к нужной цели. Функция Возвращает истину, если была достигнута цель.
mp_potential_step_object(x,y,stepsize,obj) Также как и функция выше, но на этот раз, только экземпляры obj считаются как препятствия. obj может быть объектом или идентификатором экземпляра.
mp_potential_settings(maxrot,rotstep,ahead,onspot) Предшествующие функции делают свою работу, используя множество параметров, которые могут быть изменены с помощью этой функции. Глобально, метод работает следующим образом. Сначала пытается переместить экземпляр прямо к цели. Это предусматривается множеством шагов вперёд, которые могут быть установлены параметром ahead (3 по умолчанию). Уменьшение этого значения означает, что экземпляр объекта запустится с изменённого направления позже. Увеличение значения, означает, что экземпляр объекта будет запущен с изменённого направления раньше. Если проверяется столкновение, то экземпляр "начнёт смотреть", куда ему лучше повернуть - налево или направо. Это происходит в шагах размера rotstep (10 по умолчанию). Уменьшая это значение, мы предоставляем экземпляру объекта больше возможностей перемещения, но это будет медленней. Параметр maxrot - немного трудней объяснить. Экземпляр объекта имеет текущее направление maxrot (30 по умолчанию), которое указывает, насколько позволяется изменять своё текущее направление в шаге. Даже если бы экземпляр мог переместиться, например, прямо в цель, то это завершилось бы только в том случае, если бы были не нарушены максимальные изменения направления. Если Вы делаете maxrot большим, то экземпляр объекта может измениться много каждом шаге. Это позволяет легче найти кратчайший путь, но путь при этом будет беспорядочным. Если Вы делаете значение меньшим, то путь будет более гладким, но экземпляр может при этом выбрать более длинные отклонения (и иногда даже не обнаруживать цель). Когда никакой шаг не выполняется, поведение будет зависеть от значения параметра onspot. Если onspot - истина (значение по умолчанию), экземпляр объекта возвращается в свою точку указанной суммы maxrot. Если - ложь, то экземпляр объекта не переместится совсем. Устанавливать значение "ложь" иногда полезно, например, автомобили будут иметь быстрейший шанс обнаружения пути.
Пожалуйста, заметьте, что метод использует только локальную информацию. Итак, экземпляр только обнаружит путь в том случае, если эта локальная информация достаточно полная, чтобы определить правильное направление движения. Например, экземпляр объекта не найдёт путь (выход) из лабиринта (в большинстве случаях).
Второй тип функций вычисляет путь свободный от столкновений для экземпляра объекта. Как только этот путь будет вычислен, Вы сможете назначить его экземпляру объекта, чтобы переместить его к цели.вычисление пути занимает некоторое время, но после этого, выполнение пути будет быстрым. Конечно, это всё будет правильно, если ситуация не изменится. Например, если препятствия изменяются, то Вам, возможно, понадобиться вычислить путь заново. Снова обратите внимание, что эти функции могут потерпеть неудачу. Эти функции доступны только в Game Maker Pro Edition.
Первые две функции используют прямолинейное движение и потенциальный метод областей, которые также будут использованы для функций шага.
mp_linear_path(path,xg,yg,stepsize,checkall) вычисляет прямолинейную траекторию для экземпляра объекта из своей текущей позиции в позицию (xg,yg), используя указанный размер шага. Это использует шаги подобно функции mp_linear_step(). Указанный путь должен уже существовать, и он будет переписан новым путем. Функция возвращает истину, если путь был обнаружен. Функция остановит и сообщит о неудаче, если никакая прямолинейная траектория не существует между началом и целью. Если это терпит неудачу, то путь всё ещё будет создан, при запуске до той позиции, где экземпляр объекта будет заблокирован.
mp_linear_path_object(path,xg,yg,stepsize,obj) Также как и функция выше, но на этот раз, только экземпляры obj считаются как препятствия. obj может быть объектом или идентификатором экземпляра.
mp_potential_path(path,xg,yg,stepsize,factor,checkall) вычисляет путь для экземпляра объекта из своей текущей позиции в позицию (xg,yg), используя размер указанного шага, чтобы избегать столкновения с препятствиями. Это использует потенциальные шаги области подобно функции mp_potential_step() и также параметры, которые могут быть установлены mp_potential_settings(). Указанный путь должен уже существовать, и он будет переписан новым путем. (Смотрите последующую главу о том, как создавать и уничтожать пути.) Функция Возвращает истину, если путь был обнаружен. Чтобы избегать функций, продолжающих непрерывную обработку, Вам нужно установить длину показателя больше чем 1. Функция остановится и сообщит о неудаче, если она не сможет найти путь короче, чем время показателя расстояния между началом и целью. Показатель 4 - нормальный и достаточно хороший, но если Вы ожидаете длинные отклонения, то Вы можете сделать его дольше. Если это терпит неудачу, то путь всё ещё будет создан при запуске до начала целевой позиции, но её экземпляр не достигнет.
mp_potential_path_object(path,xg,yg,stepsize,factor,obj) Также как и функция выше, но на этот раз, только экземпляры obj считаются как препятствия. obj может быть объектом или идентификатором экземпляра.
Другие функции используют более сложный механизм, используя метод базирующийся на сетке (иногда названной A* алгоритм). Это будет более успешным действием в обнаружении путей (хотя это всё ещё может потерпеть неудачу) и найдёт пути быстрее, но это потребует от Вас дополнительной работы. Основная идея выглядит следующим образом. Прежде всего, мы помещаем сетку в комнату. Вы можете использовать тонкую сетку (медленней) или грубую сетку. Затем, для всех важных объектов, мы определяем ячейки сетки, которые перекрывают сетку (или используя bounding box или точную проверку) и отмечаем эти ячейки как запрещённые. Такая клетка будет выделена как полностью запрещённая, даже если бы она была частично перекрыта препятствиями. Наконец, мы определяем начало и целевую позицию (которая должна быть размещена в свободных клетках), и функция вычисляет самый короткий путь (действительно близкий к самому короткому) между ними. Путь будет работать между центрами свободных клеток. Если ячейки достаточно большие, то экземпляр объекта, установленный в своем центре, будет полностью в нём размещён, что будет иметь успех. Этот путь Вы можете теперь назначить экземпляру объекта.
Метод базирующийся на сетке - очень мощный инструмент (и используется в основном в профессиональных играх), но он требует, чтобы Вы проделывали всё это, мысля очень осторожно. Вы должны определить, какая область и размер ячейки будет соответствовать оптимальному решению для Вашей игры. Также Вы должны определить, какие объекты должны иметь точную проверку столкновений, это важное значение. Все эти параметры сильно влияют на эффективность метода.
В целом, размер ячеек важен. Помните, что ячейки должны быть достаточно велики, так что движущийся объект установленный в начале центра клетки, должен быть размещён полностью в ячейке. (Будьте осторожными с начальной позицией объекта.Также поймите, что Вы можете сдвинуть путь, если начало объекта - не в своём центре!) С другой стороны, меньшие ячейки предоставляют больше возможностей существующих путей. Если Вы делаете ячейки слишком большими, то расстояние между препятствиями может закрыться, поскольку все ячейки пересекут препятствие. Следующие фактические функции для метода базирующимся на сетке доступны.
mp_grid_create(left,top,hcells,vcells,cellwidth,cellheight) Создаётсетку. Это возвращает идентификатор, который должен быть использован во всех других вызовах. Вы можете создать и поддерживать многочисленные структуры сетки в том же моменте. left и top указывают позицию левого верхнего угла сетки. hcells и vcells указывают число горизонтальных и вертикальных ячеек. Наконец, cellwidth и cellheight указывают размер ячеек.
mp_grid_destroy(id) Уничтожает указанную структуру сетки и освобождает используемую память. Не забывайте использовать это, если Вам больше не нужна структура.
mp_grid_clear_all(id) Маркирует все освобождаемые ячейки сетки.
mp_grid_clear_cell(id,h,v) Очищает указанную ячейку. Ячейка 0,0 - верхняя левая ячейка.
mp_grid_clear_rectangle(id,left,top,right,bottom) Очищает все ячейки, что пересекает указанный прямоугольник (в координатах комнаты).
mp_grid_add_cell(id,h,v) выделяет указанную ячейку как запрещённую. Ячейка 0,0 - верхняя левая ячейка.
mp_grid_add_rectangle(id,left,top,right,bottom) выделяет все ячейки, что пересекает указанный прямоугольник как запрещённый.
mp_grid_add_instances(id,obj,prec) выделяет все ячейки, что пересекает экземпляр указанного объекта как запрещёный. Вы можете использовать индивидуальный экземпляр объекта, создавая obj для идентификатора экземпляра. Также Вы можете использовать ключевое слово all , чтобы указывать все экземпляры всех объектов. prec - указывает, что независимо точной проверки, столкновение должна быть осуществлено (будет работать только в том случае, если точная проверка проверена для спрайта используемого экземпляром объекта).
mp_grid_path(id,path,xstart,ystart,xgoal,ygoal,allowdiag) вычисляет путь через сетку. path - должен указать существующий путь, который будет заменён путём, задаваемым компьютером. xstart и ystart - указывают начало пути, и xgoal и ygoal - цель. allowdiag - указывает, что допускаются диагональные перемещения вместо обычных горизонтальных и/или вертикальных. Функция Возвращает истину, если путь успешно обнаружен. (Заметьте, что путь не зависит от текущего экземпляра объекта; это путь через сетку - не путь для специфического экземпляра объекта.)
mp_grid_draw(id) Рисует сетку с зелёными свободными ячейками и красными ячейками - запрещёнными. Эта функция очень медленная и предусмотрена только как отладочное средство.
Экземпляры
В игре основными представителями являются экземпляры различных объектов. В течение запуска игры Вы можете изменить множество аспектов этих экземпляров. Также Вы можете создать новые экземпляры объекта и их уничтожить. Кроме перемещения, связанных с переменными, обсуждаемых выше - будет рассмотрено рисование, связанное с переменными, которые будут обсуждаться ниже. Каждый экземпляр объекта имеет следующие переменные:
object_index* Идентификатор объекта, которому принадлежит текущий экземпляр. Эта переменная не может быть изменена.
id* Уникальный идентификационный номер текущего экземпляра объекта (больше 100000). При создании экземпляров объектов в комнатах Вы можете увидеть id экземпляра объекта, если наведёте на него курсор.)
mask_index Идентификатор спрайта, который используется в качестве маски столкновений для текущего экземпляра объекта. Значение -1 означает, что в качестве маски используется текущий спрайт объекта.
solid Отражает, является ли текущий экземпляр объекта твёрдым. Это может быть изменено в течение игры.
persistent Отражает, является ли текущий экземпляр объекта постоянным, и будет ли он появляться при переходе в другую комнату. Вы часто можете захотеть выключить "постоянность" в определённых моментах. (Например, когда Вы возвращаетесь в первую комнату.)
Есть одна проблема при работе с экземплярами объекта. Идентифицировать индивидуальные экземпляры объекта не так уж легко. У них нет имени. Когда есть только один экземпляр конкретного объекта, то Вы можете использовать имя объекта, но в противном случае, Вам нужно будет получить идентификатор экземпляра. Вы можете использовать его в операторе with и как объектный идентификатор. К счастью, существует множество переменных и функций, которые помогут Вам разместить экземпляры объекта.
instance_count* Содержит общее количество экземпляров в текущей комнате.
instance_id[0..n-1]* Содержит идентификатор конкретного экземпляра. Где n является номером экземпляра.
Заметьте, что присваивания происходят в экземплярах в каждом шаге, поэтому Вы не сможете использовать значения из предыдущих шагов (если они изменились). Также в массиве, описанном выше, список обновляется только в конце шага. Так что удаленные экземпляры остаются в нём до конца шага, поэтому проверяйте действительно ли существует экземпляр. Рассмотрим на примере. Предположим, каждое устройство в Вашей игре имеет определённую мощность, и Вы хотите найти самое мощное устройство, то Вы можете использовать следующий код:
{maxid = -1;maxpower = 0; for (i=0; i<instance_count; i+=1) {iii = instance_id[i]; if (iii.object_index == unit) { if (iii.power > maxpower) {maxid = iii; maxpower = iii.power;}} }}После цикла maxid будет содержать идентификатор устройства с самой большой мощностью. (Не уничтожайте экземпляры объекта в течение такого цикла, поскольку они автоматически будут удалены из массива, и в результате начнут пропускаться экземпляры объекта.) Для конкретно этой ситуации Вы можете ипользовать:
{ maxid = -1; maxpower = 0; with (unit) do { if (power > maxpower) {maxid = self; maxpower = power;}}} instance_find(obj,n) Возвращает идентификатор экземпляра объекта obj за номером (n+1). Если он не существует, то возвращается специальный объект noone. Заметьте, что назначение экземпляров к своим идентификаторам изменяется каждый шаг, так что Вы не можете использовать переменные из предшествующих шагов.
instance_exists(obj) Возвращает (истина), если экземпляр объекта obj существует. obj может быть объектом, идентификатором экземпляра или всеми сразу.
instance_number(obj) Возвращает количество экземпляров объекта obj. obj может быть объектом, идентификатором экземпляра или всеми сразу.
instance_position(x,y,obj) Возвращает идентификатор экземпляра объекта obj, находящегося в точке (x,y). Если в указанной точке находятся несколько экземпляров объекта obj, то функция возвращает идентификатор первого экземпляра. obj может быть объектом, идентификатором экземпляра или всеми сразу. Если он не существует, то возвращается специальный объект noone.
instance_nearest(x,y,obj) Возвращает идентификатор ближайшего к точке (x,y) экземпляра объекта obj. obj может быть объектом, идентификатором экземпляра или всеми сразу.
instance_furthest(x,y,obj) Возвращает идентификатор наиболее отдалённого от точки (x,y) экземпляра объекта obj. obj может быть объектом, идентификатором экземпляра или всеми сразу.
instance_place(x,y,obj) Возвращает идентификатор экземпляра объекта obj, который встретится, если текущий экземпляр поместить в точку с координатами (x,y). obj может быть объектом, идентификатором экземпляра или всеми сразу. Если он не существует, то возвращается специальный объект noone.
Следующие функции могут быть использованы для создания и разрушения экземпляров объекта.
instance_create(x,y,obj) Создаёт экземпляр объекта obj в точке, с координатами (x,y). Функция возвращает идентификатор созданного экземпляра.
instance_copy(performevent) Создаёт копию текущего экземпляра. performent показывает, следует ли исполнять для полученной копии событие создания. Функция возвращает идентификатор копии экземпляра.
instance_destroy() Уничтожает текущий экземпляр объекта.
instance_change(obj,perf) Заменяет текущий экземпляр объекта на экземпляр объекта obj. Переменная perf показывает, выполнять ли события уничтожения и создания.
position_destroy(x,y) Уничтожает все экземпляры, спрайты которых находятся в точке (x,y).
position_change(x,y,obj,perf) Заменяет все экземпляры (находящиеся в точке x,y) экземплярами объекта obj. Переменная perf показывает, выполнять ли события уничтожения и создания.
Деактивация экземпляров
Когда Вы создаёте большую комнату, например, в платформенных играх с небольшим видом, много экземпляров находится за пределами вида. Такие экземпляры всё ещё активны и выполняют назначенные события. Также, например, выполнение проверки столкновения учитывают и эти экземпляры. Это может затратить много времени. (Например, часто бывает неважно, если экземпляр объекта находиться за пределами перемещения вида.) Чтобы решить эту проблему Game Maker содержит некоторые функции, чтобы деактивировать и активировать экземпляры объекта. Перед их использованием, Вы должны ясно понимать, как они работают.
Когда Вы деактивируете экземпляры объекта, то они, в некотором значении, удаляются из игры. Они не являются больше видимыми, и любые события для них не выполняются. И для всех действий и функций они уже больше не существуют. Это экономит много времени, но Вы должны быть всё же осторожны. Например, когда Вы удаляете все экземпляры объекта конкретного типа, деактивированные экземпляры объекта не удаляются (поскольку они не существуют). Так что не думайте, что играющий нажатием клавиши может открыть деактивированную дверь. Кроме этого постоянные объекты не будут переходить в следующую комнату. Убедитесь, что Вы не работаете с экземпляром после деактивации. Особенно, если экземпляр деактивирует самого себя. Вообще, лучше не делать деактивацию самого себя.
Наиболее частую критическую ошибку, которую Вы можете совершить, так это деактивировать экземпляр, который несёт ответственность активацию. Чтобы избежать этого, существуют некоторые подпрограммы, находящиеся ниже, которые не позволят вызываемому экземпляру объекта деактивировать себя.
Вот доступные функции:
instance_deactivate_all(notme) Деактивирует все экземпляры объекта в комнате. Если notme - истина, то вызываемый экземпляр объекта не деактивируется (обычно это то, что Вам нужно).
instance_deactivate_object(obj) Деактивирует все экземпляры объекта в комнате заданного объекта obj. Вы можете также использовать все, чтобы указать, что все экземпляры объекта должны быть деактивированы; или идентификатор экземпляра объекта, чтобы деактивировать индивидуальный экземпляр объекта.
instance_deactivate_region(left,top,width,height,inside,notme) Деактивирует все экземпляры объекта в указанную область (то есть, если ограничивающий прямоугольник bounding box пролегают частично в области). Если в inside установлена ложь, то экземпляры объекта находящиеся за пределами области деактивируются. Если notme - истина, то вызываемый экземпляр объекта не деактивируется (обычно это то, что Вам нужно).
instance_activate_all() Активирует все экземпляры объекта в комнате.
instance_activate_object(obj) Активирует все экземпляры объекта в комнате заданного объекта obj. Вы можете также использовать все, чтобы указать, что все экземпляры объекта должны быть активированы; или идентификатор экземпляра объекта, чтобы активировать индивидуальный экземпляр объекта.
instance_activate_region(left,top,width,height,inside) Активирует все экземпляры объекта в указанной области. Если в inside установлена ложь, то экземпляры объекта находящиеся за пределами области будут активированы.
Например, чтобы деактивировать все экземпляры объекта за пределами вида и активировать их в виде, Вы можете вставить следующее коды в событии шага движущегося персонажа:
{ instance_activate_all(); instance_deactivate_region(view_xview[0],view_yview[0], view_wview[0],view_hview[0],false,true);}На практике, Вы могли бы захотеть использовать область немного большую, чем область вида.
Синхронизация
Хорошие игры требуют осторожную синхронизацию определённых событий. К счастью Game Maker предоставляет Вам эту возможность. Вы убедитесь, что события случаются в постоянном темпе. Этот показатель определяется определением комнаты. Но Вы можете изменить это, используя глобальную переменную room_speed. Так, например, Вы можете медленно увеличить скорость игры, делая её более трудной, добавляя ту же небольшую сумму (подобно 0.001) в room_speed в каждом шаге. Если Ваша машина медленна, ускорение игры не может быть достигнуто таким образом. Это может быть проверено при использовании переменной fps, которая постоянно проверяет фактическое количество кадров в секунду. Наконец, для некоторой расширенной синхронизации, Вы можете использовать переменную current_time, которая предоставляет количество миллисекунд с тех пор, когда компьютер был включен. Вот общий набор доступных переменных (только первая может быть изменена):
room_speed Текущая скорость комнаты (шагов за секунду).
fps* Количество кадров, которые "отрисовываются" в секунду.
current_time* Количество миллисекунд, которые прошли с тех пор, как система была запущена.
current_year* Текущий год.
current_month* Текущий месяц.
current_day* Текущий день.
current_weekday* Текущий день недели (1=воскресенье,..., 7=суббота).
current_hour* Текущий час.
current_minute* Текущая минута.
current_second* Текущая секунда.