1

私は現在、オブジェクトがベジェ曲線に沿ってアニメーション化するシステムに取り組んでいます。カーブ上のさまざまなユーザー定義のポイントで、アニメーションオブジェクトが反応しなければならないイベントが発生する可能性があります。これは、速度の変更、アニメーションルーチンの変更、向きの変更などである可能性があります。

これまでのところ、次のAnimationEventクラスがあります。

class AnimationEvent
{
private:
    unsigned int    m_eventID;

    float   m_InteroplationPoint;

    float   m_SpeedInMPS;

public:
    AnimationEvent(unsigned int id, float interpolationPoint);
    ~AnimationEvent(void);

    const unsigned int getEventID();
    void setInterpolationPoint(float interpPoint);
    const float getInterpPoint();

    const float getSpeed();
};

各イベントはカーブに沿ってオブジェクトとして割り当てられ、その補間ポイントに到達すると、カーブクラスはgetSpeed()現在のアニメーション速度を変更するために関数を呼び出します。

私が本当にやりたいのは、デコレータデザインパターンなど、イベントを複数のオブジェクトで装飾でき、到達するとすべての装飾が適用されるシステムを実装することです。私が抱えている問題は、親オブジェクトへのポインタを子に渡すことができないことです。これにより、循環依存関係が作成されますが、(コンパイル時に)どのタイプのアクションがわからないという問題もあります。イベントはで飾られます。

これを克服する方法についてのアイデアは大歓迎です!役立つ情報を忘れた場合は、で編集してみます。

4

2 に答える 2

2

以前にオブジェクトに発生したすべてのイベントを追跡する場合は、この問題にデコレータのようなパターンを適用できます。あなたがする必要があるのは、ある種のベクトルに各イベントを保存することです。次に、任意の種類の操作を行うことができます。

#include <iostream>
#include <vector>
using namespace std;

class Animatee;
class AnimateEvent
{
public:
    virtual Animatee & perform(Animatee & on) = 0;
};

class Animatee
{
public:
    Animatee() : value(0){};

    void addEvent(AnimateEvent * event)
    {
        if(event != NULL)
        {
            events.push_back(event);
        }

    }

    Animatee & act()
    {
        for(vector<AnimateEvent * >::iterator it = events.begin(); it != events.end();++it)
        {
            AnimateEvent * event = *it;
            event->perform(*this);
        }

        return *this;
    }

    double value;   //don't do this, but something more encap'ed
private:

    vector<AnimateEvent * > events;
};

class Add : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value + 1;
        return on;
    }
};

class Subtract : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value - 1;
        return on;
    }
};

class Multiply : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value * 2;
        return on;
    }
};

class Div : public AnimateEvent
{
    virtual Animatee & perform(Animatee & on)
    {
        on.value = on.value / 2.0;
        return on;
    }
};

int main() {
    Animatee matee;
    matee.addEvent(new Add());

    //cout << "Before: " << matee.value << " After: " << matee.act().value << endl; <~~~ Undefined btw, acting on the object twice in one "statement"
    double before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Subtract());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Subtract());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Add());
    matee.addEvent(new Add());
    matee.addEvent(new Add());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    matee.addEvent(new Multiply());
    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    before = matee.value;
    cout << "Before: " << before << " After: " << matee.act().value << endl;

    return 0;
}
于 2013-02-25T20:20:48.350 に答える
0

説明したように、微分可能な速度関数は 1 回しかサポートされていません。

2 つの異なる問題があります。1 つ目は、内部アニメーション パラメータの変更の可能性 (これはポジショニング エンジンに対して不透明である必要があります) であり、2 つ目は速度の変更 (不透明ではない) です。

私は2つを直交的に解決します。

速度に焦点を当てた次の質問は、デコレーター同士をどのように構成するかです。それらは、出力速度の上限または下限を加算、乗算、置換、形成しますか?

アクセスが許可されている地方の州に関する情報は?

それらが曲線に沿った位置に供給され、最後の速度デコレータだけが何かを意味すると仮定するとstd::function<double(double)>、速度デコレータのタイプとしてうまくいくでしょう。

virtualこれは、 1 つまたは 2 つの関数を呼び出すのと同じ程度の効率です。そして、インジェクターまたはデコレーターは、内部状態に必要なものを何でもキャプチャできます...

于 2013-02-25T18:45:03.563 に答える