SFML и C++ Уроки \ Разработка игр › Форумы › Предложения к администрации сайта › Будующие уроки
В этой теме 21 ответ, 11 участников, последнее обновление JamesListener 7 года/лет, 8 мес. назад.
-
АвторСообщения
-
К сожалению пока выход новых уроков не планируется.. много работы.. может кто то в вики разделе или на форуме напишет – будет здорово. По ИИ много информации в интернете, просто при желании можно перенести на C++
А насчет карты тогда еще можешь подсказать – как сделать вид сверху или вид сзади? или это уже будет объемная – 3д?
Тему создавай в другом разделе.. вид сзади был в игре на сега, например в zero tolerance. попробуй погугли на англ. как она делалась )
Да я в другом разделе писал эту тему, но никто не ответил, к сожалению) спасибо за инфу
Здравствуйте. Как я понимаю, системы анимации так и не дождемся, да?
Можно кратенько обсудить этот вопрос здесь? Не нужно объяснять научно-популярно, я сам преподаю в универе Системы ИИ, основы 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 в отдельные файлы, обязательно потом вынесу. Лень пока.
А что делать, если кадры проигрываемой анимации разного размера (например атака с ударом длинного меча).
Ваш класс сильно похож на мой (Увы исходников не осталось), но я поясню его суть.
Он считывал анимацию с определённого ряда до определённого места, и был рассчитан на много-вариационную анимацию на одном холсте.
Его минус в том, что он был удобен в использовании только в случае если каждый кадр одного размера.Его конструктор принимал аргументы:
Кадров в секунду
С какого ряда начать
Какой ряд считать последним
Кадров в ряду
Кадров в последнем ряду
Vector2f Шир_Выс кадра на текстуре, у вас я так понимаю используете IntRect
Имя анимации (Move, Stand, Attack1, Attack2 и т.п.)Ну, у меня как раз-таки учитывается вариант с разным размером кадров – ведь в каждой анимации у меня хранится массив 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
Ещё есть какие-нибудь замечания или комментарии?
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.