====== Abstract Elements ====== 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. ===== Create abstract class ===== 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(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& window) const { SPoint wanderPt; Random& rand = window.GetRandom(); MDist md = MDist::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::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; ===== Create child classes ===== 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'' instead of ''Element''. 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(); }