Анимация с использованием указателей на функции


Я много думал о простых/удобных способов для выполнения простых 2D анимацию, используя скелетную графику библиотеки я использую для школы (анимация выхода из области действия класса, я просто экспериментирую.)

Я думал использовать пользовательскую функцию, прошел в класс, чтобы "пользователь" в код, чтобы просто написать свой собственный код, чтобы сделать то, что они хотят спрайт, а затем вернуть управление обновление спрайта (функция). Вот что я так далеко:

// SpriteStuff.h

typedef bool (AnimationStep*)(Sprite* sprite) ANIMATIONSTEP

class Sprite {
    //...
    ANIMATIONSTEP m_currentAnimation;

    void BeginAnimation(ANIMATIONSTEP step);
    void EndAnimation();

    void Update();
    //...
};

void Sprite::BeginAnimation(ANIMATIONSTEP step) {
    if (step != NULL)
        m_currentAnimation = step;
}
void Sprite::EndAnimation() {
    m_currentAnimation = NULL;
}

void Sprite::Update() {
    //...
    if (m_currentAnimation != NULL) 
        if (!m_currentAnimation(this)) EndAnimation();
    //...
}

// (off in some other code...)
void DoAnimateThing() {
    mySprite->BeginAnimation(GeneralFallAnimationStep);
}

bool GeneralFallAnimationStep(Sprite* sprite){
    return sprite->y++ > SOME_LIMIT_SOMEWHERE;
}

// Could possibly end it early...
void CancelAnimationOnThing() {
    mySprite->EndAnimation();
}

Кажется, довольно простой дизайн, который будет делать то, что мне нужно, но почти слишком просто. Я делаю что-то ужасно неправильно, да?

Редактировать: Итак, я получил несколько хороших входов, но теперь мне любопытно... какие-либо предложения, как контролировать скорость этих анимаций? Это может быть сделано в класс Sprite, или что должно осуществляться строго по ANIMATIONSTEP?



1014
4
c++
задан 4 октября 2011 в 08:10 Источник Поделиться
Комментарии
2 ответа

Слишком просто? Вряд ли. Это в значительной степени реализация учебник анимации с помощью обратного вызова на основе модели событий. В производственной-класс версия будет несколько дополнительных проверки и подобные, чтобы проверить на ошибки программирования, но базовые implemation могут быть очень похожи.

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

Одна слабость и возможные решения

Одна вещь, хотя, что может быть проблематично для сложной анимации, что дает функция не рабочее пространство, в котором хранятся все сведения о состоянии (сложная анимация может хочу знать, если это первый или второй раз, когда спрайт был в координате (457,758) например).

Наиболее простым решением является установка дополнительной недействительным * к спрайту. Это будет еще один указатель на функцию анимации можно установить на что угодно (обычно это специфическая структура анимации). Есть метод beginanimation установить этот новый указатель на нуль. Документ о том, что указатель должен быть левый нуль, или выделяется новая. EndAnimation бы удалить указатель на анимации имени, если он не был по-прежнему нулевой, так как анимация не учитывая opertunity для очистки, если EndAnimation называется напрямую.

Там чище, чем выше, но это легко объяснить, и должно работать.

2
ответ дан 4 октября 2011 в 09:10 Источник Поделиться

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

Но поскольку вы пометили это как C++, я бы сказал, что вы делаете это неправильно.

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

Изменения:

typedef bool (AnimationStep*)(Sprite* sprite) ANIMATIONSTEP

В:

class ANIMATIONSTEP
{
public:
virtual bool animationStep(Sprite* sprite) = 0;
virtual ~ANIMATIONSTEP() {}
};

Тогда изменение:

if (!m_currentAnimation(this)) EndAnimation();

В:

if (!m_currentAnimation->animationStep(this)) EndAnimation();

1
ответ дан 4 октября 2011 в 11:10 Источник Поделиться