Координация нескольких анимаций спрайтов в Cocos2dx

#c #ios #animation #cocos2d-x #sprite

#c #iOS #Анимация #cocos2d-x #спрайт

Вопрос:

У меня есть анимация с 5 кадрами для персонажа на листе спрайтов. Я хотел бы дать этому персонажу несколько «улучшений», таких как солнцезащитные очки, шляпы и т.д. Я не знаю «правильного способа» сделать это, поэтому вот что я сделал:

Я создал слой для представления самого спрайта и сначала добавил символ, а затем шляпу сверху. У меня есть 5-кадровая анимация, где шляпа будет на голове этого персонажа ТАКЖЕ на листе спрайтов, и она анимируется с теми же параметрами, что и у главного героя.

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

Мое текущее решение состоит в том, чтобы установить флажок обновления и вручную перебирать кадры каждый раз, когда проходит некоторое количество миллисекунд, что работает, но я предполагаю, что, поскольку я вручную устанавливаю кадры, он использует больше процессорного времени, чем необходимо.

Итак, каков был бы «правильный» способ добавления шляпы к спрайту без необходимости иметь серию «спрайтов со шляпами» на вашем листе спрайтов и поддерживать их анимацию вместе.

редактировать: извините, это плохо помечено, у меня, по-видимому, недостаточно высокая репутация, чтобы пометить это «cocos2dx», несмотря на то, что это вопрос cocos2dx.

Комментарии:

1. является hat ли спрайт дочерним элементом character

2. Нет, как спрайт персонажа, так и спрайт шляпы добавляются в пустой «класс MovingObjects : public Layer { }», объявленный в моем файле .h, который затем добавляется в сцену. При одновременном запуске 2 анимаций для каждого спрайта они не выполняются синхронно, поэтому прямо сейчас я устанавливаю переменную «_timeToTriggerNextFrame», и когда getTimeTick() превышает это значение, я вручную устанавливаю фрейм для каждого, на основе увеличения переменной «_currentRunFrame » и использования setSpriteFrame для установкиследующий кадр вручную для каждого. Это функционально, но, вероятно, есть лучший способ.

Ответ №1:

Что ж, если у меня такая же ситуация, я буду использовать разные таблицы спрайтов для разных анимаций в соответствии с обновлением персонажа, таким образом, не будет необходимости в двух разных анимациях, кроме того, вы можете настраивать спрайты для достижения наилучшего эффекта, и это не будет мешать другой анимации, единственная проблема в том, что вам нужно создавать разные спрайтыв соответствии с обновлением.

Комментарии:

1. Вайпер, спасибо за предложение! Если бы у нас было только 1 или 2 линейных обновления, это было бы хорошим решением, но если мы говорим о 10 возможных шлемах, 10 доспехах, 10 штанах, 10 перчатках и 10 ботинках, мы говорим о 100 000 листах спрайтов, и если я хочу изменить цвет волос персонажей, мне нужночтобы переделать все 100 000 листов спрайтов. Должен быть способ анимировать персонажа, состоящего из нескольких частей, и поддерживать их синхронизацию.

2. Если, как сказано, спрайтов слишком много, чем использовать анимацию скелета с использованием Spine (платно), создайте анимацию с использованием spine и экспортируйте ее для использования в вашем проекте, вы получите файл .png, файл .json и файл .atlas, используйте их для анимации персонажей, самое приятное, что у вас может быть несколькоанимация в одном файле анимации, и вы можете называть их по имени, и анимация намного более плавная, чем анимация спрайтов. Я использую его в своей игре, где мне нужно выполнять анимации ходьбы и атаки, стоит попробовать. Вы можете увидеть пример в testCpp. дайте мне знать, если это сработает для вас.

3. Не то чтобы я против того, чтобы тратить на это деньги, но я чувствую, что это стреляет в комара из дробовика… Должно быть простое решение, поскольку я видел, как подобные вещи делались во всевозможных играх, начиная с Super Nintendo. Когда персонажи берут один из миллиона игровых мечей, как они прикрепляют его к руке?

Ответ №2:

Какую анимацию вы используете?

Я рекомендую вам анимировать с помощью скелета. Таким образом, очень легко заменить любую часть тела другими спрайтами. В TestCpp у вас есть несколько примеров анимации скелета с использованием CocoStudio (бесплатно) или Spine (платно). У вас даже есть пример анимации, в которой оружие заменяется.

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

Комментарии:

1. у меня сложилось впечатление, что анимация скелетов предназначена в основном для 3D-материалов и гораздо сложнее в сборке. Я пытаюсь анимировать рисованные спрайты и добавлять аксессуары

2. Я мог бы добавить, что если кто-то знаком с Terraria, это хороший пример. Он работает как базовый 2-кадровый спрайт, но есть десятки бонусов, оружия и тому подобного.

3. 2D или 3D — это то же самое, только на 1 измерение меньше, так проще! Как я уже объяснял, одним из самых больших преимуществ скелетной анимации является то, что один статический спрайт присваивается и анимируется с помощью костей. Это позволяет легко заменять спрайты, а также значительно сокращает объем памяти (и размер) вашей игры. Если вы придерживаетесь традиционной анимации кадров, вам нужно будет создавать синхронизированные анимации для каждого отдельного куска ткани, который вы хотите добавить.

4. я в порядке с синхронизированными анимациями, изначально вопрос заключался в том, КАК синхронизировать анимации. Достаточно ли просто запустить 2 анимации одновременно?

5. Если обе анимации выполнены правильно и имеют одинаковое количество кадров (как и должно быть), вы можете обновить обе анимации одновременно, используя один и тот же «_currentRunFrame».

Ответ №3:

Итак, что я в итоге сделал, все спрайты, которые собирают более крупный символьный объект, объединяются в класс вместе с float «_lastFrameUpdateTick» и int «_lastFrameNumber». в моем обновлении (dt) У меня есть переключатель _lastFrameNumber для каждого спрайта, чтобы он знал, прошел ли текущий тик времени после _lastFrameUpdateTick время отображения этого кадра, он должен обновить все спрайты в этом классе до следующего номера кадра (также позволяя мне вручную перемещать относительное положение спрайтов, в тех случаях, когда, скажем, персонаж подпрыгивает вверх и вниз на спине лошади). Это требует от меня многократного размещения копий любых шляп на листе спрайтов для каждой анимации (хотя это, вероятно, можно было бы подделать с помощью plist, если бы кто-то так склонялся). Это также имеет дополнительное преимущество, позволяя некоторым кадрам отображаться немного длиннее или короче, чем другие, позволяя явно пропускать последовательности анимации в зависимости от событий (если происходит землетрясение, и персонаж находится на откинутой части анимации, он падает назад; если он находится на наклоненной вперед рамкеанимации он падает вперед), и его легко остановить анимацию, позволяя другим вещам продолжать работать. Самое главное, что выполнение этого вручную позволяет мне всегда точно знать, в каком кадре находится спрайт, поэтому он может плавно переходить между анимациями без сбоев (я знаю, что если я откинулся назад и хочу бежать вперед, мне нужно сначала выполнить анимацию с наклоном вперед).

Я уверен, что есть лучший способ сделать это, но я не разработчик C , и это работает, поэтому я двигаюсь дальше.