Созданные ответы форума
-
АвторСообщения
-
Ну, у меня как раз-таки учитывается вариант с разным размером кадров – ведь в каждой анимации у меня хранится массив IntRect, который не только позицию кадра внутри текстуры задаёт, но и её размеры. Плюс к тому же, кадры могут быть расположены где угодно в текстуре, не обязательно в одном ряду.
Однако, я сейчас понял, что физический центр объекта неправильный будет… Т.к. отрисовка всегда от левого верхнего угла будет…
Значит, нужно добавить координаты центра объекта внутри каждого кадра, чтобы корректировать отрисовку кадра. Что ж, это не сложно.Я сейчас подготовил свой формат xml-файла, который будет хранить в себе все объекты, ссылки на текстуры и их анимации.
Теперь вот собираюсь тулзу запилить для удобного создания таких xml-ек.XHTML1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253<xml><objecttype type="SomeType" name="SomeName"><size><width>10</width><height>10</height></size><texture>tileset.png</texture><animations><anim timespan="0" type="IDLE" subtype="RIGHT"><slide>0,0,10,10</slide></anim><anim timespan="0" type="IDLE" subtype="LEFT"><slide>10,0,10,10</slide></anim><anim timespan="200" type="IDLE" subtype="FRONT"><slide>20,0,10,10</slide><slide>30,0,10,10</slide><slide>40,0,10,10</slide><slide>50,0,10,10</slide></anim><anim timespan="200" type="WALK" subtype="RIGHT"><slide>0,10,10,10</slide><slide>10,10,10,10</slide><slide>20,10,10,10</slide><slide>30,10,10,10</slide><slide>40,10,10,10</slide></anim><anim timespan="200" type="WALK" subtype="LEFT"><slide>0,20,10,10</slide><slide>10,20,10,10</slide><slide>20,20,10,10</slide><slide>30,20,10,10</slide><slide>40,20,10,10</slide></anim><anim timespan="300" type="RUN" subtype="RIGHT"><slide>0,30,10,10</slide><slide>10,30,10,10</slide><slide>20,30,10,10</slide><slide>30,30,10,10</slide><slide>40,30,10,10</slide></anim><anim timespan="300" type="RUN" subtype="LEFT"><slide>0,40,10,10</slide><slide>10,40,10,10</slide><slide>20,40,10,10</slide><slide>30,40,10,10</slide><slide>40,40,10,10</slide></anim></animations></objecttype></xml>1
Ещё есть какие-нибудь замечания или комментарии?
Здравствуйте. Как я понимаю, системы анимации так и не дождемся, да?
Можно кратенько обсудить этот вопрос здесь? Не нужно объяснять научно-популярно, я сам преподаю в универе Системы ИИ, основы openGL и ООП, можно сухо и по делу, так и вам и мне лучше будет.С SFML столкнулся буквально недавно, студенты курсачи на нём принесли. Как теперь понимаю, по урокам с вашего сайта писали)))
Я вот думал над системой анимации, и пришёл к некоторой форме, но она мне всё равно не очень нравится.
Суть в следующем – у каждого DrawableObject (абстрактный класс, от которого наследуются остальные) есть список/массив объектов класса Animation, а также указатель/номер на текущую анимацию.
Класс Animation содержит в себе указатель на объект-владелец, указатель на текстуру, тип (int type) и подтип (int subtype), время смены кадров (timespan), время показа (showtime), количество кадров и массив IntRect, хранящий позиции кадров в текстуре.
Типы у меня задефайнены как ANIM_TYPE_IDLE – 10000, ANIM_TYPE_WALK – 20000, ANIM_TYPE_FALL – 30000 и т.д. Подтипы задефайнены как ANIM_SUBTYPE_LEFT – 100, ANIM_SUBTYPE_RIGHT – 200 и т.д.
В итоге для каждого DrawableObject будет выдан массив анимаций, из которого можно будет выбирать нужную анимацию по сумме типа и подтипа, а если есть несколько разных анимаций одного типа и подтипа, то добавлять порядковые числа от 0 до 99.
Такой подход мне кажется будет работать быстрее, чем делать ассоциативный массив и искать по текстовым ключам или хеш-кодам.
При выборе анимации у объекта класса Animation вызывается метод startAnimation, который через указатель на владельца берёт его спрайт и подставляет координаты текстуры первого кадра.
Также у анимации есть метод Update, который обновляет showtime для вычисления текущего кадра и подстановки его, опять-таки, в спрайт владельца.
Ну ещё добавил мелочёвки на вроде статичной анимации (т.е. не меняющихся кадров, как для блоков) – убирает лишние проверки и перерисовки; а также возможность задать одиночное проигрывание анимации с “заморозкой” на последнем/первом кадре.
Вроде всё, что нужно реализовано, а всё равно не нравится.
Откомментируйте, пожалуйста.
Даю кусок кода с классами:
C++1234567891011121314151617181920212223242526272829303132333435363738394041//DrawableObject.hclass Animation{int type;int subtype;int slides;uint timespan; // 0 means static picture, no slide changesTexture * texture;IntRect * coords;uint show_time;int current_slide;DrawableObject * owner;public:Animation(DrawableObject * obj, int _type, int _subtype, int _slides, uint _timespan, Texture * _texture, IntRect * _coords);~Animation();uint UID();void startAnimation();bool isFinished();void Update(uint time_elapsed);};class DrawableObject : public GameObject{protected:Sprite sprite;List<Animation> animations;Animation * currentAnimation;bool repeatAnimation;public:DrawableObject();DrawableObject(Point2D _coords);~DrawableObject();Sprite& getSprite();void addAnimation(Animation * a);void playAnimation(int _type, int _subtype, bool repeat = true);void updateAnimation(uint time_elapsed);void Draw();};C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596//DrawableObject.cppDrawableObject::DrawableObject(){}DrawableObject::DrawableObject(Point2D _coords) : GameObject(_coords){}DrawableObject::~DrawableObject(){animations.clear();}Sprite& DrawableObject::getSprite(){return sprite;}void DrawableObject::addAnimation(Animation * a){animations.push(a);}void DrawableObject::playAnimation(int _type, int _subtype, bool repeat){currentAnimation = animations.lookObj(_type + _subtype);repeatAnimation = repeat;currentAnimation->startAnimation();}void DrawableObject::updateAnimation(uint time_elapsed){if (!repeatAnimation && currentAnimation->isFinished())return;currentAnimation->Update(time_elapsed);}void DrawableObject::Draw(){sprite.setPosition(coords.x, coords.y);window.draw(sprite);}Animation::Animation(DrawableObject * obj, int _type, int _subtype, int _slides, uint _timespan, Texture * _texture, IntRect * _coords){type = _type;subtype = _subtype;slides = _slides;timespan = _timespan;texture = _texture;show_time = 0;owner = obj;coords = new IntRect[slides];for (int i = 0; i < slides; i++)coords[i] = _coords[i];current_slide = 0;}Animation::~Animation(){delete[] coords;}uint Animation::UID(){return type+subtype;}void Animation::startAnimation(){show_time = 0;Sprite &s = owner->getSprite();if (s.getTexture() != texture)s.setTexture(*texture);s.setTextureRect(IntRect(coords[0]));}bool Animation::isFinished(){if (timespan == 0) return true;return (show_time >= timespan*slides);}void Animation::Update(uint time_elapsed){if (timespan == 0) return;show_time += time_elapsed;current_slide = ((int)(show_time / timespan)) % slides;Sprite &s = owner->getSprite();if (s.getTexture() != texture)s.setTexture(*texture);s.setTextureRect(IntRect(coords[current_slide]));}Да, да, надо вынести Animation в отдельные файлы, обязательно потом вынесу. Лень пока.
-
АвторСообщения