В игре основными представителями являются экземпляры различных объектов. В течение запуска игры Вы можете изменить множество аспектов этих экземпляров. Также Вы можете создать новые экземпляры объекта и их уничтожить. Кроме перемещения, связанных с переменными, обсуждаемых выше - будет рассмотрено рисование, связанное с переменными, которые будут обсуждаться ниже. Каждый экземпляр объекта имеет следующие переменные:
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 показывает, выполнять ли события уничтожения и создания.
CHAN, Игра происходит в окне. Это окно имеет множество свойств, например, имеется ли у него граница, или установлен ли полноэкранный режим и т.п. Обычно эти установки размещены в Game Settings. Но Вы можете изменить их в течение игры. Для этого существуют следующие функции:
window_set_visible(visible) Устанавливает видимое игровое окно. В основном Вы захотите, чтобы окно было видимо в течение всей игры. Программа не получит события клавиатуры, когда окно невидимо. window_get_visible() Возвращает видимо ли игровое окно. window_set_fullscreen(full) Устанавливает отображение окна в полноэкранном режиме. window_get_fullscreen() Возвращает работает ли игра в полноэкранном режиме. window_set_showborder(show) Устанавливает границы вокруг игрового окна. (В полноэкранном режиме границы показаны не будут.) window_get_showborder() Возвращает, когда будут показаны границы в оконном режиме. window_set_showicons(show) Устанавливает отображение кнопок границы (свернуть, развернуть, закрыть). (В полноэкранном режиме показаны не будут.) window_get_showicons() Возвращает, если кнопки границ будут отображены в оконном режиме. window_set_stayontop(stay) Устанавливает, должно ли окно всегда оставаться поверх других окон. window_get_stayontop() Возвращает, если окно всегда остается поверх других окон. window_set_sizeable(sizeable) Устанавливает, может ли игрок изменять размер окна. (Игрок может только изменить размер отображаемых границ и в полноэкранный режим переключить не может.) window_get_sizeable() Возвращает, если окно может быть изменено игроком. window_set_caption(caption) Устанавливает строку заголовка для окна. Обычно Вы это указываете при опредении комнаты, что также может быть изменено при использовании переменной room_caption. Итак, эта функция фактически бесполезна, если Вы рисуете свою комнату предпочтительней, чем бы это сделал Game Maker. Заголовок видим только тогда, когда окно имеет границу, и когда игры протекает не в полноэкранном режиме. window_get_caption() Возвращает заголовок окна. window_set_cursor(curs) Устанавливает используемый в окне курсор мыши. Вы можете использовать следующие константы:
В частности, чтобы спрятать курсор мыши, используйте cr_none как значение. window_get_cursor() Возвращает используемый в окне курсор. window_set_color(color) Устанавливает цвет части окна, который не используется для отображения комнаты. window_get_color() Возвращает цвет окна. window_set_region_scale(scale,adaptwindow) Если окно больше чем фактическая комната, то комната будет отображена в отцентрированной области окна. Возможно также указать масштабирование для заполнения по всей области окна, либо частичной области окна. Значение 1 масштабированием не является. Если Вы используете значение 0, то область будет масштабирована, чтобы заполнить целое окно. Если Вы установили бы отрицательную величину, то это будет масштабировано в максимальный размер окна, поддерживая отношение свободной длины к высоте (это часто то, что Вы хотите). adaptwindow - указывает, должен ли размер окна быть приспособлен, если масштабированная комната не установлена. "Приспосабливающееся" окно эффективно только тогда, когда коэффициент масштабирования положительный. window_get_region_scale() Возвращает коэффициент масштабирования для рисуемого изображения.
Окно имеет позицию на экране и размер. (Когда мы говорим о позиции и размере, мы всегда имеем в виду часть клиента окна без границ.) Вы можете изменить это, хотя Вы вряд ли когда-либо сделаете это в течение Вашей игры. Обычно определяются автоматически или игроком. Следующие функции могут быть использованы, чтобы изменить позицию окна и размер. Заметьте, что эти функции имеют дело с оконным режимом. Если окно - в полноэкранном режиме, они могут всё ещё использоваться, но эффект будет только при переключении полноэкранного режима.
window_set_position(x,y) Устанавливает позицию окна (часть клиента) в указанную позицию. window_set_size(w,h) Устанавливает размер (часть клиента) в указанный размер. Заметьте, что указываемый размер слишком мал для установки в рисуемую область, но он содержит достаточно большое значение для установки самой области. window_set_rectangle(x,y,w,h) Устанавливает позицию и размер прямоугольника окна. (Делается обеими предшествующими программами в одном шаге.) window_center() Центрирует окно на экране window_default() Предоставляет окну встроенный размер и позицию (центрированную) на экране. window_get_x() Возвращает текущую x-координату окна. window_get_y() Возвращает текущую y-координату окна. window_get_width() Возвращает текущую ширину окна. window_get_height() Возвращает текущую высоту окна.
Кроме того, Вы, вероятно, никогда не захотите использовать любые позиционирующие функции окна, т. к. Game Maker заботится об этом автоматически.
В редких случаях, Вы могли бы захотеть узнать позицию мыши, что касается окна. (Обычно Вы всегда используете позицию мыши, которая касается комнаты или вида.) Для этого существуют следующие функции.
window_mouse_get_x() Возвращает x-координату мыши в окне. window_mouse_get_y() Возвращает y-координату мыши в окне. window_mouse_set(x,y) Устанавливает позицию мыши в окне с указанными значениями.
save = file_text_open_write('file.map') // Создаём файл для записи с именем file.sav
// Что то туда записываем... file_text_write_string(save,'instance_create('+string(objid.x)+string(',')+string(objid.y)+string(',Osomething)')); file_text_writeln(save);
// И сохраняем... file_text_close(save)
Как вставить в имя файла ('file.map') переменную?
ну например есть у нас переменные:
Код
globalvar worldX, worldY;
worldX = -8 worldY = 5
название файла должно создаваться такое "-8,5.map"
Я разобрался как работает запись и чтение файла, сделал тестовый пример но как сделать переменные в имени не осилил...
а про рациональность... мне кажется вполне неплохая. "Переход" очень быстро происходит. И загрука или генерация Проблемы с реализацией у всех и всегда. Щас вот дописываю тестовый блок по сохранению и загрузке.
Наконец то разобрался как работает запись переменных в файл
Код
save = file_text_open_write('save.txt') file_text_write_string(save,'instance_create('+string(ПОЗИЦИЯ-Х)+string(',')+string(ПОЗИЦИЯ-Y)+string(',Osomething)')); file_text_writeln(save); file_text_close(save)
Немного несовместимые понятия. По картинке чистой воды скролл шутер. (это не плохо, жанр интересный)
Чем это они не совместимые? поищите космический рогалик. Эклектика
Цитата
О, да пустой бесконечный мир самое лучшее о чём я мечтал. И чём ты даже эту комнату наполнишь? По теме: На скрине огромнейшие корабли, для РОГАЛИКА они должны быть в разы меньше что бы побольше всего вместить на карту. Куча карт на которых по пять корабликаф занимающих всю карту будут очень унылы.
Я хоть где то заикнулся про пустой мир? Я приложил 2 файла. Первый скролл шутер, с него я начал и его же скриншот. Второй посмотрите всё поймёте.
Цитата
Будут резкие переходы между картами аки локации. А грузить каждый такой кусочек как на скрине придётся примерно раз в пять секунд. Лаги (точнее ими будут казатся мегачастые переходы) будут раздражать любого игрока.
Пример как это работает я тоже приложил. Работает надо заметить отлично.
Цитата
Итог - я не особо понял идею (а если правильно то это тихий ужас) и не могу ничем помочь.
Если вы не посмотрели ссылки и не поняли идею и вопроса, то почему я вижу ваше сообщение здесь?
Цитата
Тогда зачем бросился делать такую сложную идею? Если ты просишь просто так взять и написать твой псевдокод нормальным кодом то давай досвиданья.
Про код писать я тоже не упоминал. Я просил помощи, где рыть или как переделать. Верный ли алгоритм. Да и разве эта идея сложна?
Знаете, лычка «гильдия школоты», у вас в подписи, полностью себя оправдывает, спасибо за дельные советы.
1. ГГ выходит за пределы комнаты. 2. Комната сохраняется в бинарный файл с именем текущей позиции (Например "WX6,WY-3.MAP") 3. Комната очищается. 4. проверяется: если есть сохранение то загружается из файла иначе генерируется новая карта 5. ГГ телепортируется на противоположную выходу позицию (функция типа wrap_screen или вручную)
Я изучаю GML второй день всего, но очень нравится. Вот первая поделка, которая перерастает во вторую. Вот То что получилось
Сначала сделал так:
Потом переделал так:
Так вот вопрос к знатокам... я плохо знаю как gml так и программирование поэтому у меня проблемы с реализацией. Но чтобы не с пустыми руками я написал псевдокод чтобы самому понять. (очень подробный):
Код
global.xpos=0 global.ypos=0 //Псевдопозиция комнаты. Т.е. если ушёл вверх то ypos+1 если в левую часть экрана то xpos-1 //Отсчёт идет от старта
save = file_text_open_write(global.xpos*global.ypos.map); { if instance_position(x,y,obj) file_text_write_string(save,'instance_create('+string(x)+string(',')+string(y)+string(',obj)')); file_text_writeln(save); then instance_destroy() } file_text_close(save)
//смена комнат { ЕСЛИ (Х позиция объекта ГГ) < 0 ТО global.world_xpos = global.world_xpos-1 создать файл ini записать координаты объекТОв в комнате сохранить ini MAP[xpos,ypos].map очистить комнату ЕСЛИ есть файл[xpos-1,ypos].map ТО(загрузить) ИНАЧЕ (сгенерировать новые объекты) (Х позиция объекта ГГ)=(Х позиция объекта ГГ)+ширина_комнаты }
{ ЕСЛИ (Х позиция объекта ГГ) > ширина_комнаты ТО global.world_xpos = global.world_xpos+1 создать файл ini записать координаты объекТОв в комнате сохранить ini MAP[xpos,ypos].map очистить комнату ЕСЛИ есть файл[xpos+1,ypos].map ТО(загрузить) ИНАЧЕ (сгенерировать новые объекты) (Х позиция объекта ГГ) = 0 scr(сгенерировать новые объекты) }
{ ЕСЛИ (Y позиция объекта ГГ) < 0 ТО global.world_xpos = global.world_ypos+1 создать файл ini записать координаты объекТОв в комнате сохранить ini MAP[xpos,ypos].map очистить комнату ЕСЛИ есть файл[xpos,ypos+1].map ТО(загрузить) ИНАЧЕ (сгенерировать новые объекты) (Y позиция объекта ГГ) = высота_комнаты scr(сгенерировать новые объекты) }
{ ЕСЛИ (Y позиция объекта ГГ) > высота_комнаты ТО global.world_xpos = global.world_ypos-1 создать файл ini записать координаты объекТОв в комнате сохранить ini MAP[xpos,ypos].map очистить_комнату ЕСЛИ есть файл[xpos,ypos-1].map ТО(загрузить) ИНАЧЕ (сгенерировать новые объекты) (Y позиция объекта ГГ) = 0 scr(сгенерировать новые объекты) }
В оригинале в том примере который по ссылке используются массивы, но они очень ограничивают размер комнаты. у меня она сейчас 10000*10000 чтоб было где разгуляться. Ну и плюсь.. я плохо понимаю как их использовать.
я так и не смог заставить это работать в своём проекте. уже 12 часов долблюсь(
Буду рад любой помощи.
Сообщение отредактировал dimonnomid - Четверг, 25 Апреля 2013, 16:14