How can I shoehorn animation into this GUI system

Started by
2 comments, last by Deckhead01 5 years, 7 months ago

I have the following setup in a GUI library I'm making (for fun). Ignore the colors and positions being integers, it's just to serve the purpose of illustration.

Code:


// Example program
#include <iostream>
#include <string>

class Rect
{
public:
    virtual void Draw(const int position) const = 0;    
};

class ColorRect : public Rect
{
public:
    virtual void Draw(const int position) const override
    {
        /* does a draw */
    }

    int color;
};

class TextureRect : public Rect
{
public:
    virtual void Draw(const int position) const override
    {
        /* does a draw textured */
    }

    int texture;
};

class Widget
{
public:
    Rect* background;
    int position;

    virtual void Draw() const
    {
        background->Draw(position);
    }

    virtual void Update()
    {
        /* might do stuff */
    }
};

class Button : public Widget
{
public:
    virtual void Draw() const override
    {
        Widget::Draw();
        border->Draw(position);
    }
    Rect* border;
};

int main()
{
    ColorRect redRect;
    redRect.color = 1;

    ColorRect blueRect;
    blueRect.color = 2;

    TextureRect textRect;
    textRect.texture = 1;

    Button b1;
    b1.border = &blueRect;
    b1.background = &redRect;
    b1.position = 1;

    Button b2;
    b2.border = &blueRect;
    b2.background = &textRect;
    b2.position = 2

    while(true)
    {
        b1.Update();
        b2.Update();
        b1.Draw();
        b2.Draw();
    }
}


I think it should be obvious that the Rect class is a Flyweight that is used by multiple different objects at the same time.

What I want to do now, for example, is have b1 animate it's border Rect. This animation should not affect the other Widget*s that use the same Rect*, i.e their animation needs to be paused, started and have a different "current frame". I'm hesitant to create an "Animated Rect" class or something, because then the only way to handle separate animation is for that class to hold a map of pointers to Widgets that are using it or something.

In addition; I would also want to animate, for example, the position. Which means ideally the interface that you use to animate positions (which are specific to the object), is the same as the one used to animate the texture or color (which is shared amongst objects currently).

Whatever it is that would hold the Animation state would need to hold a few things like frame_rate and probably time_since_updated or something.

I just can't work out where to put it, or what to reorganise to fit in.

 

Advertisement

Here's another design pattern for you. This code has not been compiled, but the idea is roughly there.


class ColorChannel : public Channelled<ColorChannel> {
  // ...
  float r, g, b;
  
  template<>
  ColorChannel mix(float tween, const ColorChannel& other) const {
    float inv = 1.0 - tween;
    return ColorChannel(r * tween + other.r * inv, g * tween + other.g * inv, b * tween + other.b * inv);
  }
};

class ScalarChannel;
class PositionChannel;


template<class T>
class Tuner {
  T& getChannel<T>();
};

class ColorRect : public Rect, public Tuner<ColorChannel> {
  // ...
  
  ColorChannel color;
  ColorChannel& getChannel() { return &color; }
};

// ...

template<class T, class V>
class Animation {
  T * target;
  V from, to;
  float duration, position;
  
  void update(void) {
    float tween = MAX(0.0f, MIN(duration / position, 1.0f));
    target.getChannel() = from.mix(tween, to);
  }
};

// ...

void main() {
  // ...
  
  Animation<ColorRect, ColorChannel> anim(&blueRect, blueColor, whiteColor, 4.0f);
  while(true) {
     // ...
     anim.position += deltaTime;
     anim.update();
     blueRect.draw();
  };
}

 

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

Hey thanks for the response.

This topic is closed to new replies.

Advertisement