1
\$\begingroup\$

I'm creating a simple 2d game with c++ and SFML, and I've got a simple framework going for animating a sprite using a "SpriteSheet" image (an big image containing all the "frames" of an animation)

I've got it working fairly well, I've attempted to copy the concept from another engine i'm familar with (Starling for Flash).. in which they use a "Juggler" which updates a sprite's properties based on a timeline, independant of the sprite...

I've got the animation working for swapping frames using a class i created called Tween... it calls a function update(float gameTime); which updates the sprites subRect to the correct frame...

I'd like to make this a more rebust solition, allowing the Tween class to do more than just frame animations.. I've been trying to use polymorphism to create Children to Tween such as "Anim", "Move", "Rotate", and "Scale" which all have a update() function which updates the sprite accordingly... The idea being a list of a number of these classes (for instance, a Scale and Rotate) can be added to a vector list and then each can call their update function, each updating their specific functions.. the problem seems to be that if i create a list of Tweens, then call update, it uses Tweens implementation of Tween.update() and not it's inherited children, I don't know how/if it's possible to allow this...

\$\endgroup\$
1
  • \$\begingroup\$ Tween should be a abstract class(interface) and TweenMove, TweenAnim, TweenRotate and TweenScale subclasses of it. So you can put all these subclasses in a container of tweens. (Maybe not what you're looking for.) \$\endgroup\$ Mar 6, 2012 at 1:32

1 Answer 1

4
\$\begingroup\$

The problem seems to be that if i create a list of Tweens, then call update, it uses Tweens implementation of Tween.update() and not it's inherited children, I don't know how/if it's possible to allow this...

Of course it's possible, that's the whole idea of polymorphism. You just need to ensure two things:

1) Mark the Update method as virtual in your Tween base class:

class Tween
{
public:
    virtual void Update(float elapsed) {}
    virtual ~Tween() {}
}

Note #1: It's really important that you make your destructor virtual too whenever you intend to use polymorphism. This is needed so that you can delete the objects correctly through a pointer to the base class.

2) Make sure that you create your list so that it holds pointers to Tween instead of Tween objects directly:

std::vector<Tween*> tweens;

Afterwards all you have to do is the fill the list with objects of any type that inherits from Tween and when calling Update on them the program will automatically choose the right version for each object. No extra code needed:

tweens.push_back(new Anim(parameters));
tweens.push_back(new Move(parameters));
tweens.push_back(new Rotate(parameters));

for(int i=0; i!=tweens.size(); ++i)
{
    // Will call the correct version of Update for each object in the list
    // Because Update is marked as virtual and tweens[i] is a pointer
    tweens[i]->Update();
}

Note #2: And since it doesn't make sense to create a Tween object directly, you should also make the class abstract to prevent this behavior explicitally. In C++ this is done by adding one or more pure virtual methods to the class. When all methods are pure virtual and there are no member variables in the class, it's also known as an interface. The above example would become:

class Tween
{
public:
    virtual void Update(float elapsed) = 0;
    virtual ~Tween() {}
}
\$\endgroup\$
4
  • \$\begingroup\$ I was writing an answer and saw yours appearing. And I stopped as it was almost the same. But I would have done the update function pure virtual. \$\endgroup\$
    – Valkea
    Mar 6, 2012 at 12:42
  • \$\begingroup\$ @Valkea I would have made it pure virtual too! But I didn't want to complicate it with a new notation. I might add as a note at the end instead. \$\endgroup\$ Mar 6, 2012 at 12:47
  • \$\begingroup\$ @Valkea I also just remembered that the destructor should be virtual too. \$\endgroup\$ Mar 6, 2012 at 12:55
  • \$\begingroup\$ Thanks for the help! So far i've got a sprite sheet "Anim" class that loops through a sheets "frames" and a "Move" class which moves a sprite to a location all using the "ITween" interface created as you suggested... GREAT! \$\endgroup\$
    – loogie
    Mar 6, 2012 at 17:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .