DIY OOP
April 30, 1998
by Zac Belado
With all this talk about OOP, it might be handy to have a look at some code instead of reading about theory. Theory is certainly a good thing but I never actually learned anything about OOP theory and terminology until well after I actually started using objects in Director. I always find it's a bit easier to understand the jargon when you've gotten your hands dirty (so to speak) with a bit of code first.
Getting started
First, (if you aren't using the demo movie provided with the article available in Mac or PC format) create a field on the stage. Then add a frame script, at frame 5 for no particular reason, that simply loops in the frame.on exitFrame Go to the frame end
What's an object?
At its most basic, objects in Director let you write a set of generic code that can be adapted to use in numerous situations. Or, more to the point, you can write a piece of code and use it over and over again throughout your Director project. Now before you skip to a different page and mutter something about that being what handlers are about, let's look at a specific case.Let's build a very simple object that simply increments the integer value stored in a field. The object will be told what field it is supposed to interact with and will remember this for you so you don't have to keep track of it. This object will add itself to the actorList so the very first thing we have to do in out movie is;
on startMovie set the actorList to [] end startMovieThis is merely a precaution to stop the actorList from getting filled up with objects that are; a) possibly buggy as you will probably make mistakes while you are experimenting and (and this is really neat) old versions of an object retain their version of the object's code even if you change it and recompile and b) we don't want a lot of objects all trying to act on the same field... could get messy.
What's the actorList?
Well according to the Lingo dictionary it is: ... a list of all child objects currently in the movie.Which really doesn't tell you a hell of a lot. The actorList is a list that you can use to place object references in so that they all get sent a stepFrame event by Director every time the frame head advances. Or, more simply, it's a place where you stuff objects when you want them to act or do an action every frame. You can do all the usual "list things" to the actorList (count, getAt, putAt) and it is a very useful way to organize and, indirectly, track your objects.
Writing the object.
The first question that you have to answer is how to store the name of the field (or the number) that the object will access? Each object can have a set of properties; these are variables that are only available to the object itself (and each instance will have its own versions of those properties as we'll see later) and which it will hold while it is still running. Think of them as global variables for the object that only the object can use. So we can declare a property to hold the name of the field.Open the Script Window and start a new script calling it "numberCruncher" (enter the name in the cast or in the Script Window). Add the following line;
property myFieldThis line tells the Lingo compiler that you want to reserve a space of memory for a property called myFieldName and associate it with the parent script "numberCruncher". Don't forget to change the type of the member (in the cast) to parent from score script. This is very important.
And the jargon starts.
What the heck is a parent script?A parent script is the name that Director uses to describe scripts that are used to "birth" new objects. Think of it as a template that you write to use to create objects. When you create a new object Director uses the parent script to build the objects' methods (handlers) and properties and also needs the parent script so it can tell what information the object needs in order to properly create itself.
Now we have to create a method that Director will use to birth the object.
on new me, theFieldName, defaultValue -- store the field name -- in the object's property set myField to theFieldName -- set the text of the object's field -- to the default value set the text of field myField ¬ to string (defaultValue) -- add the object to the actorList add the actorList, me -- send the object reference back -- to the calling statement return me end newAnd in order to create the object we'll add a line to our startMovie handler.
on startMovie set the actorList to [] set thisObject to new (script "numberCruncher", ¬ "numbers", 0) endIn much the same way that you use the new keyword to create a new bitmap or field, new also creates objects. When you use the new keyword, Director will, after it successfully goes though the new method, assign an object reference to the variable that you chose to store this reference in. In our example, Director will put the object reference into the "thisObject" variable. An object reference is a pointer to a memory location that stores the object and it will look like;
<offspring "numberCruncher" 1 ec1fe4>At this point all you really need to be concerned with is that the object reference is a) a unique reference to an instance of an object and b) will tell you what the name of the parent script was that birthed the object. So if you ever wanted to refer to the object that was created you could simply use the "thisObject" variable.
But to get back to our new method...
What the new method does in this example is simply take the three variables passed to it (the object reference, the name of the field and an integer value) and places the field name into its property for later reference. It then creates a string from the integer value and places it into the field. Notice that it does this by referencing its own property and not the value used in the new methods declaration. It then adds itself to the actorList and then passes its object reference (the me) back to the startMovie handler. In this instance, we don't record the object reference. This is because the object is not going to be modified or have its properties changed.
The only "tricky" thing you have to remember is that you need to add "me" to all the object's methods. This is so the object knows where to send calls to different methods (or to be more precise so that Director knows which area of memory to send the calls).
The line;
set thisObject to new (script "numberCruncher", ¬ "numbers", 0)corresponds to the declarations in the parent script's method
on new me, theFieldName, defaultValueIn this case Director uses the parent script name "numberCruncher" to create a new object reference which it then puts into the memory space that it reserves for the object.
Getting it to work.
So now that we have the object successfully created we need to get it to do something.If you remember, you added the object's reference to the actorList. So all you need to do now is add a stepFrame method to the object.
on stepFrame me -- get the text from the obejct's field set thisText to the text of field myField -- get an integer from the string set thisText to value (thisText) -- incriment the value and put it into -- the object's field set the text of field myField to ¬ string (thisText + 1) end
With the object in the actorList, Director will send a stepFrame call to the object. You can then trap this and use it to create an object that runs independently of any outside control. As long as the movie is running the object will be "fed" stepFrame events that will allow it to run.
And on each frame the object will get the text of its field, convert the text to an integer value, increment it and then put the new value, as a string, back into the field.
Next time we'll look at creating multiple instances of the same object and communicating with objects after you've created them.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.