Воскресенье, 26 Мая 2024, 21:23

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
Результаты поиска
ReanДата: Вторник, 15 Ноября 2016, 12:30 | Сообщение # 161 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
Huricane, только сейчас увидел твой комментарий. В принципе, ничего сложного, я в начале подумал, что тебе нужны динамические имена переменных. Здесь же достаточно массива-инвентаря в каждом из персонажей.
Персонажи - отдельные объекты, созданные заранее. Все наследуются от объекта, например, characters.
Предметы - отдельные объекты, наследуемые от объекта, например, staff. У каждого предмета в событии Create описываем общие для Staff переменные: Name, Weight, Durablity, Cost and etc.

Дальнейшее действие таково: если нам надо будет для всех "Меч обыкновенный" поменять цену - мы просто заходим в данный объект, открываем событие Create и меняем нужное значение.
Подробней допишу вечером.

Добавлено:
В общем, набросал сегодня проектик, в котором реализовал некоторого рода инвентарь и случайную выдачу объектов юнитам.
Скриншот:

Смысл какой: есть группа персонажей (в моем случае, из двух юнитов), которые случайным образом получают заданные предметы из сундука.
Чтобы это осуществить, нам необходимо: доступ отдельно к каждому персонажу (или массивом), отдельный инвентарь (в моем случае, список DS List) для каждого персонажа, список (массив) объектов, которые необходимо выдать.

В моём примере, все юниты являются отдельными объектами и наследуются от общего объекта - characters. Вся общая реализация происходит именно там. Главное, что нас сейчас интересует - инвентарь. В этом примере, я его реализовал с помощью списка - DS_List.

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

Теперь, когда какой-либо из юнитов подходит близко к сундуку, он открывается и срабатывает ранее написанная функция
Код
GiveItem (char, items, rate)

Первый аргумент - персонаж, которому будут выданы предметы
Второй аргумент - массив этих самых предметов
Третий аргумент - шанс выпадения предметов.

Два последних аргумента хранятся у сундука, юнита(ов) можно получить различным способом, в моём случае, для теста, ссылки на них уже были заготовлены заранее. Так как юнитов у меня два, то и функцию я вызывал два раза, каждый раз передавая в аргументе ссылку на нужного юнита.
Что из себя представляет функция GiveItem():

Всё достаточно просто. Теперь у каждого юнита есть отдельный инвентарь со своим набором предметов. Экземпляры предметов разные. То есть, несмотря на то, что, например, Sword у мага и рыцаря создан из одного объекта (stf_sword), который имеет параметры:
Код
name = "Sword";
cost = 200;
durability = 100;

В дальнейшем, обратившись к инвентарю одного из персонажа, параметры ЕГО меча можно изменить на желаемые. Так, например, у рыцарского меча со временем будет уменьшаться durability (если это реализовать, конечно. Как вариант - после каждой удачной атаки мечом, прочность уменьшается на -5, для примера).
В общем, как-то так. Если нужен будет проект - могу куда-нибудь скинуть, хотя, думаю, и так понятен принцип. Если есть какие-то вопросы по реализации - постараюсь ответить.


Сообщение отредактировал Rean - Среда, 16 Ноября 2016, 01:09
ReanДата: Вторник, 15 Ноября 2016, 12:19 | Сообщение # 162 | Тема: Нужна помощь по написанию скрипта для движения по лестнице
участник
Сейчас нет на сайте
Zazaza, а каким образом будет определятся "идти прямо" или "идти наверх"?

Наипростейшее решение видится таким: "кидаем" два невидимых триггера по обеим концам лестницы и при пересечении, например, с нижним триггером, если игрок нажал "UP + LEFT", то ставим флаг isOnLeftStairs (у нас же лестницы будут не только в одну сторону, на карте могут быть и наоборот). И уже в Step персонажа обрабатываем движение при флаге isOnLeftStairs (или флаге isOnRightStairs), меняя анимацию на анимацию подъёма/спуска и увеличивая/уменьшая координату y.

Это если решение с ходу. Если подумать, то, возможно, где-то можно упростить/что-то добавить. Но общая идея такова.

Добавлено: забыл сказать - при повторном пересечении с одним из триггеров, флаги (isOn..Stairs) убираем, чтобы игрок мог двигаться дальше прямо.


Сообщение отредактировал Rean - Вторник, 15 Ноября 2016, 12:21
ReanДата: Понедельник, 14 Ноября 2016, 23:57 | Сообщение # 163 | Тема: [2D] The Hungry Mouse
участник
Сейчас нет на сайте
EnviyngEarth,
Цитата EnviyngEarth ()
Это только в последнем уровне?

Да, только в последнем. Больше ничего такого не заметил. Ждём новые уровни :)
ReanДата: Понедельник, 14 Ноября 2016, 01:32 | Сообщение # 164 | Тема: [2D] The Hungry Mouse
участник
Сейчас нет на сайте
EnviyngEarth, прошу прощения, не увидел новой ссылки - смотрел только в нулевом посте.
Прошел версию 0.2 два раза подряд - новые уровни уже интересней. Проблемы с управлением как в старой версии нет, но вот с досрочным завершением уровня - осталось. Последний уровень на втором круге прохождения завершился, как только я взял звезду.
ReanДата: Понедельник, 14 Ноября 2016, 00:25 | Сообщение # 165 | Тема: [2D] The Hungry Mouse
участник
Сейчас нет на сайте
EnviyngEarth, небольшой баг-репорт:
- в версии "Alfa ver. 0.1", если пройти игру и после попадания в главное меню, снова начать игру, то любой уровень заканчивается, как только подберешь звезду (появляется менюшка перехода на новый уровень).
- в версии под спойлером "Старая версия", также если начать новую игру, то после прохождения первого уровня по второму кругу, на втором уровне мышь не реагирует на управление.

Решил обратить на это внимание, чтобы в дальнейшем не получился "снежный ком".
ReanДата: Воскресенье, 13 Ноября 2016, 21:29 | Сообщение # 166 | Тема: Обращение с унаследованным компонентом как с родительским.
участник
Сейчас нет на сайте
Necrolich, что значит
Код
если на объект повешен Forg

Имеется ввиду, что объект является экземпляром класса Frog?

Допустим, что
Код
public class ParentClass : MonoBehaviour {
...
}

и
Код
public class ChildClass : ParentClass {
    
    public int jumpSpeed = 10;
...
}

Последний класс, например, принадлежит префабу. Также у нас есть объект Manager, в котором мы выполняем логику:
Код
public class Manager : MonoBehaviour {

    [SerializeField]
    GameObject _child;
        ...
}

"Кидаем" на на этот GameObject наш префаб со скриптом ChildClass. И теперь где-нибудь в скрипте Manager продолжаем такой функцией:
Код
...
// Объявляем метод прыжка
void Jump (ParentClass parent)
{
    ChildClass child = parent;
    child.GetComponent<Transform>.Translate(Vector3.up * child.jumpSpeed);
}
...
...
void Update()
{
    if (Input.GetButtonDown("Jump"))
        Jump( _child.GetComponent<ParentClass> ));
}

Вот и весь полиморфизм. Ещё проще, если в Manager переменную _child объявить как ChildClass.


Сообщение отредактировал Rean - Понедельник, 14 Ноября 2016, 01:41
ReanДата: Воскресенье, 13 Ноября 2016, 20:43 | Сообщение # 167 | Тема: [2D] The Hungry Mouse
участник
Сейчас нет на сайте
EnviyngEarth, поиграл в игрушку - достаточно занимательно. Нюансы:
- немного не хватает динамики: в прохождении уровней с поднимающимися-опускающимися платформами нет никакой сложности, только приходится ждать эти самые платформы. Немного тормозит процесс.
- что в самой игре, что на последней картинке (та что "new skin") практически отсутствует контраст между героем и фоном. Всё же, надо как-то выделить и подчеркнуть протагониста. Ну и с другими динамичными объектами та же проблема (за исключением сыра и звёзд - они хорошо заметны)
- Проблема многих платформеров, сделанных на конструкторах - игрок может зацепится за "вертикальный" торец платформы. Было бы неплохо попытаться это исправить.


В остальном, желаю удачно довести проект до финальной стадии!


Сообщение отредактировал Rean - Воскресенье, 13 Ноября 2016, 20:44
ReanДата: Воскресенье, 13 Ноября 2016, 01:56 | Сообщение # 168 | Тема: Warning в Аниматоре "Animator is not playing a Playable"
участник
Сейчас нет на сайте
Susanin, ссылку на аниматор как получаешь? Через GetComponent пробовал? Также, когда пытаешься поменять значение, объект активен?
ReanДата: Суббота, 12 Ноября 2016, 16:36 | Сообщение # 169 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
Huricane,
Цитата Huricane ()
Объектов также n кол-во, но для примера пусть будет 3. В одном объекте должно быть от 1 до 3х сущностей.

Вот здесь поподробней: какие именно подразумеваются объекты? GameMaker'ские? Или это абстрактный объект? В общем, разложи конкретно на примере что и как должно выглядеть, прям по типам данных. Пока что это настолько абстрактно, что я не представляю в каком ключе это должно использоваться - от этого и сложность реализации. К примеру, если там подразумеваются какие-то новые GM-омвские объекты, то, думаю, это вряд ли возможно реализовать стандартными средствами конструктора. Если под "объектом" подразумевается, например, массив с ссылками на экземпляры - это уже совсем другое и, соответственно, реализовать в разы проще. Если же там должна хранится ссылка на существующий GM-овский объект, у которого либо есть, либо нет экземпляров - здесь тоже ничего сложного.

Далее, сущности, которые должны быть у объекта - какие-то новые сущности или одни из тех, что указаны в таблице?
Пока не ясна конкретная задача с конкретными определениями - сложно что-то конкретизировать.
Пока представляется следующий алгоритм:

1. Формируем список (например, массив) сущностей, отобранных по определенному критерию
2. Запускаем цикл, в котором перебираем все отобранные сущности
3. Передаем ссылку на сущность в заранее подготовленную функцию SetProperties()

Функция SetProperties():
1. Определяем переменную iGroup и присваиваем ей случайное значение (например, из заранее подготовленного enum) для полученной сущности.
С объектами не всё очевидно, как я уже писал выше, поэтому здесь требуется уточнение
2. Определяем переменную iObject, которой присваиваем ссылку на один из объектов (если объекты могут повторяться, то ссылки на них могут хранится в перечислении enum, если нет - то в стеке, к примеру). Для объекта создаем случайно до 3-х сущностей (опять же, не ясно - сущности УЖЕ должны существовать или нет).
3. В цикле создания сущностей, для каждой новой созданной сущности определяем, к примеру, массив properties[] из двух элементов, либо две отдельные переменные - как душа просит. В момент определения массива или переменных - присваиваем необходимые случайные значения, границы диапазона можно передать в аргументах функции SetProperties, либо исходя из глобальных "констант".

В общем, всё дело в конкретных нуждах и конкретной реализации. Если это реализация некоторого рода искусственного интеллекта масс, то можно посмотреть в сторону одно- и двусвязных списков, членами которого являются экземпляры заранее подготовленного объекта с необходимыми переменными.
ReanДата: Пятница, 11 Ноября 2016, 22:46 | Сообщение # 170 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
Huricane, тогда подробней: по какому критерию надо отобрать объекты? Объекты какие-то определенные или случайные? Тоже самое касается свойств и значений: имена свойств заранее известны и как должно определятся какое имя свойству дать? Лучше, конечно, если будет какой-нибудь наглядный пример использования данной конструкции.

В любом случае, если нужны динамические, например заданные пользователем, имена свойств, к которым нужно будет обращаться, то я бы копал в сторону словарей - DS Map:

Код
// Объявляем массив с объектами для наглядности
objects[0] = obj_knight;
objects[1] = obj_mage;
objects[2] = obj_thief;

// Создаём стэк и заполняем его нужными нам свойствами
attributes_stack = ds_stack_create();
ds_stack_push( attributes_stack, "Health", "Stamina", "Mana", "Stealth",  "Science", "Intellect", "Luck" );

// Распихиваем свойства
do
{
        var obj = irandom( array_length_1d( objects ) - 1)          // Получаем id случайного объекта из массива выше              
        var inst = irandom( instance_number( objects[obj] ) - 1)    // Получаем id случайного экземпляра объекта, выбранного выше
        var inst_temp = instance_find( objects[obj], inst );        // Находим экземпляр
        
        if (is_undefined( inst_temp.map_id ))                       // Если у экземпляра ещё нет "карты"...
            inst_temp.map_id = ds_map_create()                      // ...то создаём "карту" и присваиваем идентификатор экземпляру
            
        ds_map_add( inst_temp.map_id, ds_stack_pop( attributes_stack ), irandom(10) );    // Добавляем в "карту" свойство из стека.
                    // Вместо стека можно использовать и очередь, и пронумерованную очередь...
                    // ...в общем, как захочется.               
}
until (!ds_stack_empty( attributes_stack ));                        // Повторяем действия до тех пор, пока стек не закончится

// Достаём свойства в специальной функции, которая возвращает false, если у экземпляра нет карты
{
        var obj = irandom( array_length_1d( objects ) - 1)          //  
        var inst = irandom( instance_number( objects[obj] ) - 1)    // Как и выше - получаем случайный экземпляр случайного объекта
        var inst_temp = instance_find( objects[obj], inst );        //
        
        if (is_undefined( inst_temp.map_id ))                       // Если "карты" для этого объекта нет, то выходим из функции
            return false;

        var ID, key, value;                    // Объявляем временные переменные, в которых будем хранить идентификатор, ключ и значение "карты"
        ID = inst_temp.map_id;                    // Получаем id "карты" - чисто для краткости написания
        key = ds_map_find_first(ID);                    // Получаем первый ключ "карты"

        for (var i = 0; i < ds_map_size(ID); i++)                   // Перебираем все ключи в "карте"
        {
             value = ds_map_find_value(ID, key);                    // Получаем значение по ключу
             show_debug_message( key + " : " + value );             // Выводим сообщение с "КЛЮЧ : ЗНАЧЕНИЕ" в консоле отладки
             key = ds_map_find_next(ID, key);                       // Получаем следующий ключ
        }
}

По хорошему, надо бы проверок добавить: пустая карта или нет, имеет ли значение данный ключ или нет и т.д.

Задачка достаточно нетривиальная. Можно попробовать менее красивый, топорный, но более наглядный путь: использовать одномерный массив вместо DS MAP. В массиве, например, каждый нечётный элемент хранит ключ, а каждый чётный - значение:
Код

...
properties[1] = "Health";
properties[2] = 100;
properties[3] = "Mana";
properties[4] = 70;
...

Использование так или иначе будет похожим. Вместо номера идентификатора карты присваиваем экземпляру непосредственно массив. В общем, вариантов много - всё зависит от конкретных задач.


Сообщение отредактировал Rean - Суббота, 12 Ноября 2016, 01:13
ReanДата: Пятница, 11 Ноября 2016, 22:07 | Сообщение # 171 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
Huricane, речь идёт о разных объектах или о разных экземпляров одного объекта? Если про экземпляры (instance), то можно попробовать перебрать с помощью цикла for:
Код

// Пример из справки
var i;
for (i = 0; i < instance_number(obj_Enemy); i += 1)
   {
   enemy[i] = instance_find(obj_Enemy,i);
   }

Если разные объекты, то, думаю, массив будет наиболее предпочтителен.

Добавлено: "случайное название из пула" - это типа, переменные с динамическим именем?


Сообщение отредактировал Rean - Пятница, 11 Ноября 2016, 22:22
ReanДата: Пятница, 11 Ноября 2016, 19:51 | Сообщение # 172 | Тема: Перетаскивание фона
участник
Сейчас нет на сайте
MAFIT33, как вариант: двигать камеру на расстояние, которое прошел курсор, после зажатия клавиши мыши.
ReanДата: Пятница, 11 Ноября 2016, 18:31 | Сообщение # 173 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
dildo_bomber, что-то вроде того:
Код

// Устанавливаем мышь в границах игрового окна
window_mouse_set(clamp(window_mouse_get_x(), 0, window_get_width()), clamp(window_mouse_get_y(), 0, window_get_height()));


Сообщение отредактировал Rean - Пятница, 11 Ноября 2016, 18:32
ReanДата: Пятница, 11 Ноября 2016, 17:44 | Сообщение # 174 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
dildo_bomber,
Цитата dildo_bomber ()
Вообще не судите строго, я бы всё с нуля переписал, если бы было не лень ибо щас смотрю на старый код и охереваю, насколько всё можно было проще и лучше написать.

Всё окей, главное развиваться и попутно развивать свой код. Проблема "временных" костылей в том, что с ростом проекта они становятся фундаментом. Очень ненадёжным фундаментом.

Проблема стрельбы в том, что у тебя событие "Left Button" в объекте obj_plane, что означает - срабатывать при нажатии на объект. Поменяй событие на "Global Left Button". Ну и причеши код в присвоение позиции объекта. Вообще, у тебя origin у спрайта смещён?


Сообщение отредактировал Rean - Пятница, 11 Ноября 2016, 17:51
ReanДата: Пятница, 11 Ноября 2016, 16:49 | Сообщение # 175 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
dildo_bomber, в таком коде, без обид, но сам чёрт ногу сломит. Не забывайте комментировать переменные и блоки программы.

Значит, во-первых:

Код


// Код в STEP объекта obj_stats
if pause = 0 then
{
    x_origin = obj_plane.x
    y_origin = obj_plane.y
}
else
{
    x_delta = mouse_x - x_origin  // Расстояние между самолётом и курсором по Х
    y_delta = mouse_y - y_origin  // Расстояние между самолётом и курсором по У
}

//---------------------------

// Код в STEP объекта obj_plane
x = mouse_x - obj_stats.x_delta  // Х приравнивается позиция левее курсора - зачем??
y = mouse_y - obj_stats.y_delta  // У приравнивается позиция выше курсора - тот же вопрос


Вообще, какие изначальные значения у переменных: pause, x_origin, x_delta ? Они формируют дальнейшее положение объекта, но при этом сами имеют не всегда очевидное значение.

Код

// Зачем здесь в коде нули?
if (y < 0 + sprite_get_yoffset(spr_plane))
{
     y = 0 + sprite_get_yoffset(spr_plane)
}
if (x < 0 + sprite_get_xoffset(spr_plane))
{
    x = 0 + sprite_get_xoffset(spr_plane)
}

// Что за константа 125? Можно ли получить её динамически?
if (y > (room_height) - sprite_get_height(spr_plane) + sprite_get_yoffset(spr_plane))
{
    y = (room_height)  - sprite_get_height(spr_plane) + sprite_get_yoffset(spr_plane)
}

if (x > (room_width - 125) - sprite_get_width(spr_plane) + sprite_get_xoffset(spr_plane))
{
    x = (room_width - 125)  - sprite_get_width(spr_plane) + sprite_get_xoffset(spr_plane)
}

// Для подобного рода присвоений, используй функцию clamp(int value, int min, int max)

x = clamp( x, 0, room_width - sprite_get_width(plane)); //
x +=  sprite_get_xoffset(spr_plane);

y = clamp( y, 0, room_height - sprite_get_height(plane))
y +=  sprite_get_yoffset(spr_plane);
// И то, я не уверен, что это оптимальный вариант. Возможно стоит "покурить" мануал в поисках более пригодных функций

Ну и наконец, стрельба:
Код

if can_shoot = 1   // Где формируется значение переменной can_shoot ДО этого места?
    {
        instance_create(obj_plane.x - 15, obj_plane.y - 16, obj_fire1)
        can_shoot = 0
        alarm[0] = obj_control_vars.fire_rate
    }


Пока мы не узнаем, при каких условиях can_shoot получает значение "1", мы не сможем понять, почему "не стреляет".


Сообщение отредактировал Rean - Пятница, 11 Ноября 2016, 16:54
ReanДата: Понедельник, 07 Ноября 2016, 20:58 | Сообщение # 176 | Тема: Требуется для работы над нетривиальным сюжетным экшеном
участник
Сейчас нет на сайте
Цитата FProgM ()
А что, геймдизы у нас только виденьем и концепцией занимаются? И помимо "дизайна 3d-графики" там ничего нет? Или один человек должен делать всю игру? Баба ещё будет учить мужика как делать игры.

Ох-хо-хо, что-то мне подсказывает, что долго здесь такие на задерживаются...
С таким походом, вряд ли можно найти путного сотрудника.


Сообщение отредактировал Rean - Понедельник, 07 Ноября 2016, 21:02
ReanДата: Понедельник, 07 Ноября 2016, 20:42 | Сообщение # 177 | Тема: Вопрос - Ответ (Game Maker)
участник
Сейчас нет на сайте
smile196, в этой теме на форуме YoYoGames был задан подобный вопрос. Участники, сославшись на лицензионное соглашение, сказали, что ты в праве делать со standalone версией своей игры, что хочешь, в том смысле - публиковать, продавать и т.д.

С другой стороны, на страницы сравнения версий, в колонке Studio FREE отсутствует галочка в строке Marketplace Selling, что как бы заставляет задуматься.
Marketplace Selling - это, как я понял, имеется ввиду их торговая площадка, так что скорее всего первый вариант с форума - верный.


Сообщение отредактировал Rean - Понедельник, 07 Ноября 2016, 20:51
ReanДата: Понедельник, 07 Ноября 2016, 01:52 | Сообщение # 178 | Тема: Переход по комнатам
участник
Сейчас нет на сайте
SovaDeveloper, Леонид правильно сказал по поводу глобальных переменных.
Достаточно создать глобальную переменную

Код

globalvar Money;

ИЛИ

global.Money = 0;


и дальше уже использовать по необходимости. Глобальные переменные сохраняют значения при переходе из комнаты в комнату, а также имеют зону видимости в любом месте программы.
Либо, как альтернатива, можно создать один невидимый объект и дать ему свойство Persistent. Назвать его, к примеру, GameStates и хранить все необходимые глобальные данные в нём. Это не самый оптимальный вариант, при небольшом количестве глобальных переменных они будут предпочтительней. Но вот есть и такой вариант.
ReanДата: Воскресенье, 06 Ноября 2016, 22:15 | Сообщение # 179 | Тема: Проблема с ИИ для игры
участник
Сейчас нет на сайте
Zazaza,

Код
Расстояние(Игрок.X, Игрок.Y, Враг.X, Враг.Y) <= Враг.ЗонаВидимости


Данный кусок кода действует по окружности, то есть если Игрок будет ниже, но направление Врага будет в его сторону, то Враг заметит Игрока. Тут уже надо допиливать под конкретные нужды: добавлять проверки по Y

Код
( abs(Игрок.X - Враг.X) <= Враг.ЗонаВидимости ) И (Игрок.Y <= Враг.Y + некоторое_значение ) И (Игрок.Y >= Враг.Y - некоторое значение)


в таком случае Игрок будет замечен, если попадёт в некоторый прямоугольник зрения Врага.


Сообщение отредактировал Rean - Понедельник, 07 Ноября 2016, 01:59
ReanДата: Воскресенье, 06 Ноября 2016, 21:50 | Сообщение # 180 | Тема: Проблема с ИИ для игры
участник
Сейчас нет на сайте
Zazaza, в таком случае, по этому алгоритму, Враг просто вернётся на исходную и продолжит патрулировать.

P.S. Графика в игре своя? Очень неплохо смотрится. Напоминает Flashback и Another World.


Сообщение отредактировал Rean - Воскресенье, 06 Ноября 2016, 21:50
Поиск:

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