It may be useful to abstract the behavior of your Elements. In this tutorial, we are going to create two Elements which inherit from a common base Element.
For this tutorial, we are going to make three Elements: AbstractElement_Wanderer
, Element_Wanderer_Cyan
, and Element_Wanderer_Magenta
. These are in the repository.
First we need to create AbstractElement_Wanderer
. This is going to be very similar to creating any other element, besides a few important differences.
First, we cannot use ElementParameters in the base class. This creates conflicts when saving .mfs files and all children will be loaded with the same parameters.
Second, our constructor must take a UUID
and have no body, like this:
AbstractElement_Wanderer(UUID u) : Element<CC>(u) { }
We should also not define GetDefaultPhysicsColor
, since the children will want to be different colors.
We also cannot define THE_INSTANCE, since an abstract class cannot be instantiated.
We need a behavior method which wanders the same for all children. This looks like:
virtual void Behavior(EventWindow<CC>& window) const { SPoint wanderPt; Random& rand = window.GetRandom(); MDist<R> md = MDist<R>::get(); Dir d = (Dir)rand.Create(Dirs::DIR_COUNT); Dirs::FillDir(wanderPt, d); wanderPt *= Dirs::IsCorner(d) ? (GetWanderDistance() / 2) : GetWanderDistance(); if(window.IsLiveSite(wanderPt)) { if(window.GetRelativeAtom(wanderPt).GetType() == Element_Empty<CC>::THE_INSTANCE.GetType()) { window.SwapAtoms(wanderPt, SPoint(0, 0)); } } } }
Finally, we need a new pure abstract method. This will allow a sub-class to tell this base class how far it would like to wander per event. We write it like this, in a protected
section:
virtual u32 GetWanderDistance() const = 0;
Next, we need some child classes to inherit from this one. We will create two classes, which are nearly identical, to do this.
First, each of these classes gets an ElementParameterS32
named m_wanderDistance
. These need to be initialized with unique tags!
Next, change the class definition and the constructor to use AbstractElement_Wanderer<CC>
instead of Element<CC>
.
Next, define DefaultPhysicsColor
to return 0xff00ffff
for the Cyan element, and 0xffff00ff
for the Magenta element.
Finally, define GetWanderDistance
as such:
protected: virtual u32 GetWanderDistance() const { return (u32)m_wanderDistance.GetValue(); }