tduk, а ты пробовал при этом менять настройки сопротивления, гравитации, массы у компонента Rigidbody? Конечно, как альтернатива, можно покопать в сторону самописной гравитации или интерполяции/smoothdamp, но вряд ли этот велосипед будет лучше. Особенно, если не знаком с этим. А при условии, что будет обрабатываться какая-никакая коллизия, и Rigidbody так или иначе понадобиться - не пользоваться встроенными средствами не совсем рационально. Поразбирайся, возможно, ты не до конца раскрыл потенциал встроенной физики.
BESS55555, всё так, всё так. Мне этот "ориентир" не понравился ещё на заре появления Construct 2, когда ещё даже не было экспорта в standalone-приложение. С другой стороны, если наверное "клепать" html5 игрушки для агрегаторов и издателей, то Construct 2 вполне неплохо подходит для этой цели (если, конечно, речь не идёт о поддержке издательского SDK). Но не смотря на всё это, у Construct'а вполне неплохой потенциал среди standalone-приложений. Если, конечно, разработчики не будут забивать на это дело.
Если это формат игрового архива, то не имеет смысла обращать внимание именно на расширение файла - иногда оно может абсолютно ничего не значить. Могу только порекомендовать посмотреть в сторону программ по типу Dragon UnPACKer: умеет открывать множество игровых архивов, в числе которых могут оказаться и архивы Tekken 6.
Сообщение отредактировал Rean - Среда, 23 Ноября 2016, 23:08
Да понятно зачем. Necrolich, хочет единообразно обращаться к объектам имеющим разную логику.
Да это и так понятно. Меня интересует конкретный контекст использования. По сути, примеров выше должно хватать с головой без добавления доп. компонентов, используя исключительно возможности наследования.
Элементарно: если у нас есть несколько типов врагов, каждый из которых перемещается и атакует по-своему, но при касании любого из них игрок проигрывает, то достаточно в обработчике игрока проверить на коллизию с общим классом <Врага>, получив компонент Врага. Если компонент не удалось получить - значит это не враг.
Если контекст другой, более изощренный, то надо с ним ознакомиться, может действительно лучше раскидать логику по разным классам.
Сообщение отредактировал Rean - Понедельник, 21 Ноября 2016, 18:23
Повторяем рандом до тех пор, пока текущий индекс строки больше 1 (то есть, по факту как минимум третий), и пока два предыдущих в строке равны полученному рандому. Тоже самое для столбца.
Necrolich, не могу понять зачем. По факту твой дочерний класс и так имеет все атрибуты родительского. Для чего именно ты хочешь это сделать? Ещё пример:
Код
// Родительский класс public class ParentClass : MonoBehaviour {
// Use this for initialization void Start () {
}
// Update is called once per frame void Update () {
}
public void Who() { Debug.Log("I'm Father"); } } ////////////////////////////////////////// // Дочерний класс public class ChildClass : ParentClass {
// Use this for initialization void Start () {
}
// Update is called once per frame void Update () {
}
public void Who() { Debug.Log("I'm Son"); } } ///////////////////////////////////////// // Manager public class Manager : MonoBehaviour {
public GameObject _child;
// Use this for initialization void Start () { _child.GetComponent<ParentClass> ().Who(); }
// Update is called once per frame void Update () {
} } ////////////////////////////////////////// // Результат: I'm Father - то есть, исполнится родительский метод
Если использовать переопределение метода (virtual-override), выдаст:
Код
I'm Son
То есть, по факту можно получить доступ к методам родителя. Но, конечно, нужен контекст использования. В C# не "аля полиморфизм", а самые настоящий, как наследование и инкапсуляция, в общем, все столпы ООП
Добавлено: Забыл сказать, если в это примере вызвать так:
Код
public class Manager : MonoBehaviour { ... void Start () { _child.GetComponent<ParentClass> ().Who(); _child.GetComponent<ChildClass> ().Who(); } ... }
То результат сперва будет "I'm Father", а потом - "I'm Son".
Сообщение отредактировал Rean - Воскресенье, 20 Ноября 2016, 18:43
Купил, поиграл - забавно Мне симпатизирует графика в стиле "Family Guy", общая атмосфера, вставочки в начале уровня (с наушниками), динамика - в общем, всё очень даже хорошо. Но я, видимо, нуб, отвыкший от более-менее сложных платформеров, потому как даже на уровне "Hero" не удается пройти с 10-го раза то или иное место. Но мне кажется, что такая сложность вполне имеет место. Хотя, я бы не отказался от постепенного наращивания сложности. Ну, музыка тоже, конечно, огонь. Вообще, искренне желаю удачи в продвижении и продажах!
Один из вариантов перемещения между дверьми в платформере: Doors.gmz
Основной принцип реализации: Все двери являются экземплярами одного объекта, но с уникальными значениями двух переменных: doorId (идентификатор двери) и goToDoor - номер двери, в которой должен появиться персонаж после перехода. Переход выполняется при нажатии игроком стрелки вверх, при пересечении двери персонажем. Персонаж плавно исчезает возле одной двери и появляется возле другой.
Весь необходимый код, в принципе, комментирован, необходимо, думаю, только пояснить пару моментов: - у дверных спрайтов коллизионная маска выставлена точкой (или очень коротким отрезком). Сделано это для того, чтобы игрок мог пересечься с дверью, только когда он полностью находится на спрайте двери (то есть, он не торчит за пределом двери ни слева, ни справа).
- также, у каждой двери, размещённой в комнате, изменено событие Create. Это сделано, чтобы можно было легко и просто настроить "какая дверь куда ведёт". Достаточно определить всего лишь значения двух переменных: doorId и goToDoor. Если параметр goToDoor будет равен "-1", то дверь никуда не будет вести (имеется ввиду, без вываливания ошибки).
mafon2,
Цитатаmafon2 ()
Я в этом и не сомневаюсь, но это и отличает программиста от энтузиаста. У меня, как говорится, – сплошные спагетти.
Понимаю. Всё отлично. Главное, что есть желание разбираться, а это уже половина успеха
Сообщение отредактировал Rean - Суббота, 19 Ноября 2016, 02:16
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 не подошла. Вариант решения проблемы: для объектов, которые создаются одновременно, лучше объявлять все переменные в теле одного события одного объекта. Например:
Код
// Есть событие Create у объекта SYSTEM_INI // Здесь мы будем объявлять все переменные // И глобальные, и встроенные в экземпляры LEVEL_1_SYS.GEMS = 135; // Вот, мы объявили переменную экземпляра LEVEL_1_SYS, теперь можем использовать её в данном теле события Create global.TOTAL_A1_GEMS = 0; global.A1L1_GEMS = LEVEL_1_SYS.GEMS;
Это что касается ОДНОВРЕМЕННОГО создания экземпляров и перекрёстного присваивания значений. Если же нам каким-то образом необходима конструкция:
Код
global.A1L1_GEMS = LEVEL_1_SYS.GEMS
без явного обозначения переменной GEMS у объекта LEVEL_1_SYS, тогда придется прибегнуть к динамическому созданию экземпляра. Например:
Код
// Событие Create объекта LEVEL_1_SYS GEMS = 0; // Объявили все необходимые переменные, теперь создаём другие объекты instance_create(0, 0, SYSTEM_INI); ... ... ... // Событие Create объекта SYSTEM_INI SomeVariableName = LEVEL_1_SYS.GEMS // Profit!
Во-вторых, так лучше не делать:
Код
globalvar GEMS; // Глобальная переменная с именем GEMS (P.S. от globalvar лучше совсем избавиться) global.A1L1_GEMS = LEVEL_1_SYS.GEMS; // Встроенная переменная с именем GEMS
Лучше не использовать одинаковые названия переменных. Если прям необходимо назвать переменные как-то похоже, потому как они выполняют похожую роль, то лучше использовать префиксы, к примеру:
Код
global.GEMS = 0; LEVEL_1_SYS.inst_GEMS = 0; // добавили префикс inst_, чтобы легко отличить, что это переменная экземпляра (instance)
Ну а лучше вообще пересмотреть и переработать иерархию и структуру переменных. Уменьшить их количество, сделать их более понятными и увеличить зону их применения. (но опять же, в меру). К примеру:
Код
// Хотим определить направление движения игрока: сервер, запада, юг или восток // Как в большинстве случаев НЕ надо делать isNorth = false; isWest = false; isSouth = true; isEast = false; // Легко запутаться, нагородить ошибок, да к тому же выделяем лишнюю память. // Лучше поступить так: объявляем числовую переменную dir, которая может принять 4 различных значения // 0 - Север, 1 - Запад, 2 - Юг, 3 - Восток. // и получаем: dir = 2; // Игрок смотрит на Юг. // А если хотим сделать ещё нагляднее, можно использовать перечислители, enum: enum Direction { North = 0; West = 1; South = 2; East = 3; } dir = Direction.South; // Запись, конечно, увеличилась, зато ни у кого не вызовет никаких сомнений, что она означает.
В-третьих, если этот код
Код
//Step
//Код A1L1_GEMS = GEMS;
выполняется в теле события Step объекта LEVEL_1_SYS, то здесь, как я уже сказал выше, возникает конфликт внутренней и глобальной переменных GEMS. Про разные названия переменных я уже сказал, скажу ещё, что одной из причин создания префикса "global." является подобный случай использования.
Вроде, пока всё. Действительно, вещь простая, и особых проблем вызывать не должна, но камнем преткновения здесь является чрезмерно загроможденный код и обилие второстепенных переменных. Я, конечно, не знаю всех тонкостей игры, какие данные где и зачем должны храниться, но что-то мне подсказывает, что всё можно упростить как минимум в два раза. Ах да, что касается переменных, которые должны хранить данные на протяжении всей игры и не обнуляться при смене комнаты: как вариант, создать объект, например obj_variables, задать ему свойство Persistent в менеджере объекта, и уже в теле события Create объявить все необходимые переменные. Такой объект достаточно разместить только в самой первой комнате, но "жить" он будет на протяжении всей игры, пока игра не закончится или пока объект не будет удалён вручную. Событие Create у такого объекта происходит только один раз, независимо от перехода из/в комнату.
Сообщение отредактировал Rean - Пятница, 18 Ноября 2016, 13:41
mafon2, у тебя проблема с объявлением переменных. Во-первых, постарайся избегать определений по типу:
Код
globalvar SomeVariableName;
Сами YoYo НЕ рекомендуют использовать данную конструкцию, так как она используется лишь для совместимости со старыми проектами. Наиболее правильный вариант:
Код
global.SomeVariableName = 0
Внимательно смотреть на регистр написания наименований переменных. И из представленного кода не ясно, где ты прописываешь:
Код
globalvar GEMS;
В любом случае, замени его на код выше. Если есть возможность, либо сделай скриншоты с местами, где ты объявляешь переменные и где они вызывают ошибку, либо прикрепи файл с проектом.
Добавлено: Но а вообще, is_undefined по-моему не должен сработать на глобальной переменной. То есть, необходимо местами заменить глобальные переменные на переменные экземпляров. В процессе игры можно работать с такой переменной, а потом, в конце уровня, передать её значение глобальной переменной.
Сообщение отредактировал Rean - Четверг, 17 Ноября 2016, 15:49
seregakalenik, а захочется ли делать оптимизацию в конце? Правильный ответ, думаю, будет: делать надо и в начале, и в конце. А полный рефакторинг приложения, полностью построенного на "костылях" - не благодарное занятие.
MaxHunter, ну так правильно, спрайт-то флиппается относительно якоря, а Collider, подозреваю, остаётся неизменным. Лучшим решением будет нормализовать анимацию, чтобы без всяких якорей анимация проигрывалась нормально.
Сообщение отредактировал Rean - Четверг, 17 Ноября 2016, 01:36
EnviyngEarth, поиграл я в демо. Какие есть наблюдения: - Третий уровень. Мне показались лишние новые платформы. В принципе, без них было не сложно, а вполне нормально. - После пятого уровня перекидывает в меню, и если не знать, что можно выбрать уровень, то кажется, что это вся игра. - После шестого уровня тоже перекидывает в меню. Но это, как я понял, потому что ещё седьмого нет. - Шестой уровень получился достаточно сложным. Игра превратилась из миленькой игрушки про мышёнка, в "I wanna be the RAT!": неожиданные шипы, гири. К тому же как-то странно отрабатывает прыжок: если двигаться и нажать прыжок ближе к краю платформы, то мышь не прыгает. И получается, что ты просто падаешь вниз. Поэтому приходилось достаточное количество раз проходить 6-ой уровень. - После проигрыша, в ряду с кнопками "Домой" и "Выбор уровня" не хватает третьей - Переиграть. Её надо прямо ОБЯЗАТЕЛЬНО. Иначе приходится каждый раз выбирать нужный уровень.
Для Free версии, думаю, было бы неплохо сделать 10 уровней с нарастающей сложностью, чтобы "подцепить" игрока. Сложные уровни лучше оставить для полной версии. Да, баланс одно из самых, наверное, кропотливых занятий Ну а так, игрушка получается занимательной. Какой управление будет на сенсере?
mafon2, немного сумбурно излагаешь. Для начала напиши все задействованные переменные для подсчёта highscore и их области видимости. Где, в каких событиях и каким образом их определяешь.
Как я понимаю, некоторые переменные у тебя объявляются в событии Create (либо комнаты, либо какого-то объекта). Например, если мы используем конструкцию
Код
global.GEMS = 0
при создании комнаты, то каждый раз, когда она будет создаваться - глобальная переменная GEMS будет установлена в значение 0. Вариантом для решения подобной проблемы будет проверка переменной на существование:
Код
if is_undefined(global.GEMS) global.GEMS = 0;
Если переменная не определена, то определяем её, присвоением значения 0. Очень похоже именно на подобную проблему, с постоянным присваиванием начального значения.