Среда, 27 Ноября 2024, 05:10

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
Вопрос - Ответ (Game Maker)
mafon2Дата: Четверг, 17 Ноября 2016, 20:20 | Сообщение # 5821
был не раз
Сейчас нет на сайте
Да, LEVEL_1_SYS на месте.

Такая, вроде, простая вещь, а сколько проблем. Спасибо за внимание.

Скриншот:



Сообщение отредактировал mafon2 - Четверг, 17 Ноября 2016, 20:22
ReanДата: Пятница, 18 Ноября 2016, 01:59 | Сообщение # 5822
участник
Сейчас нет на сайте
mafon2, сейчас пригляделся. В общем, проблем чуть меньше, чем дофига :)
Во-первых, несмотря на то, что у тебя:
Код

// В комнате LEVEL_1 объект LEVEL_1_SYS, в нем
// Событие Create
GEMS = 0;

- ссылаться в событии Create на переменную другого объекта НЕЛЬЗЯ:
Код

// Событие Create объекта SYSTEM_INI
global.A1L1_GEMS = LEVEL_1_SYS.GEMS;  // Так делать НЕ правильно

Дело в том, что объекты создаются последовательно, друг за другом, в зависимости от того, какой объект был раньше размещён в комнате, а какой позже. И когда, например, создаётся экземпляр объекта SYSTEM_INI, так как он был размещён в комнате раньше, поэтому получил более меньшее ID, поэтому и создаётся раньше - он ещё не знает о переменной объекта LEVEL_1_SYS, потому как его очередь события Create не подошла. Вариант решения проблемы: для объектов, которые создаются одновременно, лучше объявлять все переменные в теле одного события одного объекта. Например:

Это что касается ОДНОВРЕМЕННОГО создания экземпляров и перекрёстного присваивания значений. Если же нам каким-то образом необходима конструкция:
Код

global.A1L1_GEMS = LEVEL_1_SYS.GEMS

без явного обозначения переменной GEMS у объекта LEVEL_1_SYS, тогда придется прибегнуть к динамическому созданию экземпляра. Например:

Во-вторых, так лучше не делать:
Код

globalvar GEMS; // Глобальная переменная с именем GEMS (P.S. от globalvar лучше совсем избавиться)
global.A1L1_GEMS = LEVEL_1_SYS.GEMS; // Встроенная переменная с именем GEMS

Лучше не использовать одинаковые названия переменных. Если прям необходимо назвать переменные как-то похоже, потому как они выполняют похожую роль, то лучше использовать префиксы, к примеру:

Ну а лучше вообще пересмотреть и переработать иерархию и структуру переменных. Уменьшить их количество, сделать их более понятными и увеличить зону их применения. (но опять же, в меру). К примеру:

В-третьих, если этот код

выполняется в теле события Step объекта LEVEL_1_SYS, то здесь, как я уже сказал выше, возникает конфликт внутренней и глобальной переменных GEMS. Про разные названия переменных я уже сказал, скажу ещё, что одной из причин создания префикса "global." является подобный случай использования.

Вроде, пока всё. Действительно, вещь простая, и особых проблем вызывать не должна, но камнем преткновения здесь является чрезмерно загроможденный код и обилие второстепенных переменных. Я, конечно, не знаю всех тонкостей игры, какие данные где и зачем должны храниться, но что-то мне подсказывает, что всё можно упростить как минимум в два раза.
Ах да, что касается переменных, которые должны хранить данные на протяжении всей игры и не обнуляться при смене комнаты: как вариант, создать объект, например obj_variables, задать ему свойство Persistent в менеджере объекта, и уже в теле события Create объявить все необходимые переменные. Такой объект достаточно разместить только в самой первой комнате, но "жить" он будет на протяжении всей игры, пока игра не закончится или пока объект не будет удалён вручную. Событие Create у такого объекта происходит только один раз, независимо от перехода из/в комнату.


Сообщение отредактировал Rean - Пятница, 18 Ноября 2016, 13:41
mafon2Дата: Пятница, 18 Ноября 2016, 17:44 | Сообщение # 5823
был не раз
Сейчас нет на сайте
Спасибо за подробный разбор, буду пилить.

Код
...что-то мне подсказывает, что всё можно упростить как минимум в два раза


Я в этом и не сомневаюсь, но это и отличает программиста от энтузиаста. У меня, как говорится, – сплошные спагетти.
ReanДата: Суббота, 19 Ноября 2016, 02:05 | Сообщение # 5824
участник
Сейчас нет на сайте
Один из вариантов перемещения между дверьми в платформере:
Doors.gmz

Основной принцип реализации:
Все двери являются экземплярами одного объекта, но с уникальными значениями двух переменных: doorId (идентификатор двери) и goToDoor - номер двери, в которой должен появиться персонаж после перехода.
Переход выполняется при нажатии игроком стрелки вверх, при пересечении двери персонажем. Персонаж плавно исчезает возле одной двери и появляется возле другой.

Весь необходимый код, в принципе, комментирован, необходимо, думаю, только пояснить пару моментов:
- у дверных спрайтов коллизионная маска выставлена точкой (или очень коротким отрезком). Сделано это для того, чтобы игрок мог пересечься с дверью, только когда он полностью находится на спрайте двери (то есть, он не торчит за пределом двери ни слева, ни справа).

- также, у каждой двери, размещённой в комнате, изменено событие Create. Это сделано, чтобы можно было легко и просто настроить "какая дверь куда ведёт". Достаточно определить всего лишь значения двух переменных: doorId и goToDoor.
Если параметр goToDoor будет равен "-1", то дверь никуда не будет вести (имеется ввиду, без вываливания ошибки).


mafon2,
Цитата mafon2 ()
Я в этом и не сомневаюсь, но это и отличает программиста от энтузиаста. У меня, как говорится, – сплошные спагетти.

Понимаю. Всё отлично. Главное, что есть желание разбираться, а это уже половина успеха :)


Сообщение отредактировал Rean - Суббота, 19 Ноября 2016, 02:16
ZazazaДата: Суббота, 19 Ноября 2016, 09:39 | Сообщение # 5825
был не раз
Сейчас нет на сайте
Цитата Rean ()
Один из вариантов перемещения между дверьми в платформере:
Doors.gmz

А что делать, если у меня только gmx открывает?
vadim74aДата: Суббота, 19 Ноября 2016, 09:53 | Сообщение # 5826
участник
Сейчас нет на сайте
Приветствую.
Я могу использовать купленные ассеты в коммерческих целях?
ReanДата: Суббота, 19 Ноября 2016, 10:37 | Сообщение # 5827
участник
Сейчас нет на сайте
vadim74a, да, он на это и рассчитан. Но, всё же, стоит внимательно ознакомиться со страницей ассета и его лицензионным соглашением.
valera_zaДата: Суббота, 19 Ноября 2016, 10:37 | Сообщение # 5828
участник
Сейчас нет на сайте
vadim74a,
в одном платном из них в
End User Licence Agreement (EULA).


c переводом , но коротко да.
aedginvaelДата: Вторник, 29 Ноября 2016, 21:15 | Сообщение # 5829
был не раз
Сейчас нет на сайте
Подскажите, пожалуйста такой момент:
Есть объект (космический корабль) со спрайтом из нескольких картинок (движение вперед, назад, остановка).
Хочу чтобы независимо от этого спрайта дорисовывались еще два при повороте (один справа, другой слева).
Пытался сделать через draw_sprite, но ничего не рисуется, хотя сам поворот происходит. По какой то причине у меня вообще draw_sprite никогда ничего не рисует.
Что я делаю не так?

if keyboard_check_direct (ord('D' ;) ) {direction -=4;
draw_self();
draw_sprite (spr_rig, 0, x,y);}


Сообщение отредактировал aedginvael - Вторник, 29 Ноября 2016, 21:20
ReanДата: Вторник, 29 Ноября 2016, 22:38 | Сообщение # 5830
участник
Сейчас нет на сайте
aedginvael, не лучшая идея менять значение переменных в Draw Events. Точка с запятой после D не нужна. Объект имеет экземпляры в комнате и активный параметр Visible? Данный код говорит, что отрисовывать объект (сам объект и дополнительный спрайт) необходимо ТОЛЬКО при нажатии D. Всё остальное время ничего отрисовываться не будет.

Добавлено:
а, ну и самое главное - ты рисуешь второй спрайт поверх первого по тем же координатам.


Сообщение отредактировал Rean - Вторник, 29 Ноября 2016, 22:47
aedginvaelДата: Среда, 30 Ноября 2016, 00:35 | Сообщение # 5831
был не раз
Сейчас нет на сайте
1) Там нет точки с запятой. Просто когда я выложил сюда код, в этом месте появился смайл. Сколько я не пытался удалить их от туда, все равно они дописываются и рисуется смайл. Но это отступление от темы.
2)объект в комнате всего 1 и он visible
3)Да, отрисовывать все это нужно ТОЛЬКО при нажатии кнопки D
4) Да, я рисую один спрайт поверх другого с координатами в одной точке, потому что сами спрайты смещены так, что изображение не накладывается. Я сделал так, чтобы не путаться с координатами.
LosiahДата: Среда, 30 Ноября 2016, 00:46 | Сообщение # 5832
почетный гость
Сейчас нет на сайте
В событие draw
Код

if keyboard_check(vk_space){ //рисовка на пробел
  draw_sprite(sprite_index,0,x,y)//рисовка себя
  draw_sprite (spr_rig,0,x,y)//рисовка детали
}

проверь глубину объектов чтобы глубина была самой низкой. чем меньше показатель глубины тем выше остальных будет прорисовка объекта.




Сообщение отредактировал Losiah - Среда, 30 Ноября 2016, 00:58
ReanДата: Среда, 30 Ноября 2016, 00:53 | Сообщение # 5833
участник
Сейчас нет на сайте
1) Для кода лучше использовать специальные теги code.
2, 3, 4 - вот с этого и надо начинать. Чем больше информации, тем больше шансов, что кто-то сможет помочь. А иначе приходится угадывать, что там у кого случилось.

Такой момент: в каком событии код? Всё рисование должно происходить в Draw Event (Draw Begin, Draw End, etc)
И правильно я понимаю, что больше в комнате нет никаких других объектов, фона и прочего? Views не задействованы?


Сообщение отредактировал Rean - Среда, 30 Ноября 2016, 01:01
aedginvaelДата: Среда, 30 Ноября 2016, 13:05 | Сообщение # 5834
был не раз
Сейчас нет на сайте
Да, в комнате есть фон и Views.
Все, спасибо, я понял в чем был не прав.
Появился еще вопрос: как сделать, чтобы direction рисуемого спрайта, совпадал с direction объекта?
ReanДата: Среда, 30 Ноября 2016, 13:24 | Сообщение # 5835
участник
Сейчас нет на сайте
aedginvael, посмотри в сторону функции draw_sprite_ext. Один из аргументов - rot, отвечает за угл поворота спрайта.

Сообщение отредактировал Rean - Среда, 30 Ноября 2016, 13:45
aedginvaelДата: Четверг, 01 Декабря 2016, 13:01 | Сообщение # 5836
был не раз
Сейчас нет на сайте
Да, спасибо! Теперь то, что нужно!
Подскажите, пожалуйста, где почитать о создании кнопок, меню, всплывающих окон и т.д.?

Добавлено (01 декабря 2016, 13:01)
---------------------------------------------
Снова вопрос:
Есть объект - космическая станция. Хочу сделать запрос "Свой/Чужой" по всем объектам в радиусе действия.
Переменная friend имеет значения 0,1,2,3 что соответствует: "Неитрал", "Свой", "Чужой", "Агр чужой"
id_obj получает id экземпляра
Затем проверяется его статус.
В зависимости от результата проверки: или запускаются шлюзы, или запускается система обороны станции (sos);
Пока объект был один, проблем, вроде бы не было. Но как только появились другие (пушки на станции, friend = 1), то все перестало работать. Вернее сказать работать стало все: и шлюзы, и пушки. Причем пушки просто моргали анимацией, не запускаясь полностью.
Подскажите, что я делаю не так?

Код

  id_obj=collision_circle(x,y,500,all,0,1);
  if id_obj >0
  {
  if id_obj.friend = 3
  {
  sos = true;
  }
  if id_obj.friend = 1
  sos = false;
  }


На орудия step:
Код

image_index = 0;

if obj_mir.sos
{
target = obj_mir.id_obj;
if distance_to_object (target) <distan and image_index <4 and done
{
image_index +=1;
done = false;
alarm[0] = done_speed;
}

if distance_to_object(target) <distan-100 and image_index = 4 and canshot
{
image_angle = direction;
instance_create (x,y,obj_lazer);
alarm[1] = speed_shot;
canshot = false;
}

if distance_to_object (target) > distan and done
{
image_index -=1;
done = false;
alarm[0] = done_speed;
}
}


Сообщение отредактировал aedginvael - Среда, 30 Ноября 2016, 23:31
ReanДата: Четверг, 01 Декабря 2016, 16:43 | Сообщение # 5837
участник
Сейчас нет на сайте
aedginvael,
Цитата
Подскажите, что я делаю не так?
Код
  id_obj=collision_circle(x,y,500,all,0,1);
  if id_obj >0
  {
  if id_obj.friend = 3
  {
  sos = true;
  }
  if id_obj.friend = 1
  sos = false;
  }


Во-первых, collision_circle всегда будет возвращать только один instance. И вполне возможно, что это будет один и тот же instance. Если, к примеру, пушка в одно время может иметь только одну цель - то, в принципе, это может сработать. А если надо проверить всех, кто находится в круге - здесь ждёт неудача. К тому же стоит иметь ввиду, что collision_circle не всегда возвращает ближайший объект, а лишь объект который попадает в зону коллизии.
Во-вторых, более читаемый код выглядит с использованием конструкции switch:
Код

...
if (id_obj != noone)
    switch (id_obj.friend) {
        case 0: тра-та-та; break;
        case 1: sos = false; break;
        case 3: sos = true; break;
}

Можно, конечно, ещё компактней, но это для тривиальных случаев:
Код

sos = (id_obj != noone) and (id_obj.friend == 3)

В-третьих, в событии Step орудия, ты в начале каждый раз обнуляешь индекс, а потом пытаешься сделать следующий (или предыдущий кадр), но в следующем степе у тебя всё будет заново (нулевой кадр +- 1). Таким образом анимация никогда не проиграется и всегда будет показывать кадры 0, 1.
Думаю, перечисленные выше причины - краеугольный камень проблемы. Решив их, ситуация должна более-менее проясниться.

P.S. Все три конструкции (if distance_to_object (target)...), наверное, лучше расположить в конструкции if-else, чтобы лишний раз не дёргать проверки. Хотя, я не знаю задумку, поэтому здесь тяжело что-то советовать.
P.P.S Вместо image_index += 1, я бы всё же предпочёл устанавливать image_speed. Иначе получается жесткая привязка к room_speed. Ну и при потере кадров, будут пролёты анимации.


Сообщение отредактировал Rean - Пятница, 02 Декабря 2016, 00:50
aedginvaelДата: Четверг, 01 Декабря 2016, 17:42 | Сообщение # 5838
был не раз
Сейчас нет на сайте
Да, обнуление image_index уже увидел.
Проблема с проверкой объектов осталась:
Есть инструмент более подходящий для этой задачи, чем collision_circle? Или может есть способ его более грамотного использования? Цель по сути простая: при верном коде проверки - отношение к объекту "Друг". Если код у объекта (одного или нескольких) не верен, то отношение к объекту "Враг" т.е. атаковать объект.
Имеет смысл каждому орудию писать аналогичный поиск объектов "Враг" для стрельбы, или это не эффективно?
И как рисовать что то относительно рамки экрана, а не относительно комнаты?


Сообщение отредактировал aedginvael - Четверг, 01 Декабря 2016, 19:35
ReanДата: Четверг, 01 Декабря 2016, 21:44 | Сообщение # 5839
участник
Сейчас нет на сайте
aedginvael, вариантов много. Один из:
1. Создать функцию, которая будет перебирать все экземпляры определённого объекта и проверять их на коллизию с необходимой областью. Формирует из них массив и уже с этим массивом мы делаем всё что нам хочется. Ещё один вариант:
Создать объект с прозрачным спрайтом (или спрайтом отображающим нашу область), сделать у него маску (круглую, квадратную, в общем, какую нужно) - простой объект, который будет отвечать за нашу зону видимости. Отключим его отображение (Visible = false) и будем проверять его на коллизию со всеми необходимыми нам объектами. В событии коллизии мы может напрямую обращаться к тому или иному экземпляру, проверяя его свойства и т.д. Главное, чтобы объект-зона всегда совпадал с центром станции/корабля и имел на него ссылку (чтобы выполнять необходимые изменения). Возможно, не самый быстрый, но вполне наглядный и удобный при использовании.
2. Если орудия будут стрелять в одно время только по одному противнику, то лучше сделать функцию поиска-определения только для станции (а она уже будет напрямую связана с орудиями)
3. Если рисовать в методе Draw, то надо взаимодействовать с x и y координатами вида (view_xview, view_yview). Для GUI же лучше использовать события DrawGUI - там будут использованы координаты окна.

Добавлено: вот, набросал пример по первому пункту. CheckCollision.gmz
Добавлено 2: поправил ссылку


Сообщение отредактировал Rean - Пятница, 02 Декабря 2016, 00:55
aedginvaelДата: Суббота, 03 Декабря 2016, 00:56 | Сообщение # 5840
был не раз
Сейчас нет на сайте
Извини, я не очень понял как открывать твой файл. Можешь объяснить?

Добавлено (03 декабря 2016, 00:12)
---------------------------------------------
И еще: за view_xview view_yview - спасибо большое, но появился новый вопрос.
У меня используются два вида. view[0] - это вид в окне, view[1] - это вид в маленьком окошке миникарты.
На view[0] виде я через draw нарисовал небольшой интерфейс. Однако теперь он виден на миникарте view[1]... Как его скрыть от view[1]

Добавлено (03 декабря 2016, 00:56)
---------------------------------------------
Можно описать колижн с группой объектов у которых общий объект родитель? Чтобы не прописывать колижн с каждым объектом отдельно.

Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг