At 7/30/23 02:59 AM, Nabella wrote:
This is really fantastic, by the way. I feel so spoiled by you giving me a full-on graded assessment with notes and everything.
Happy to help!
Awhile back, you explained to me the difference between global variables, local variables, and function parameters. Something that went over my head apparently, now that I'm looking over this, is how valuable the statement 'return' actually is. I'm actually noticing a lot of small things I didn't know I could do previously, like having multiple function parameters (is that limited to ':Point'?)
Nope! Function parameters can be used with any "type" (class) and there can be as many of them in a function as needed (although for readability purposes, most functions typically have fewer than 4 parameters I'd say). For example, take the following function:
function calculateWeightedAverage(valueA: Number, weightA: Number, valueB: Number, weightB: Number): Number {
var weightedSum: Number = (valueA * weightA) + (valueB * weightB)
var totalWeight: Number = (weightA + weightB)
return weightedSum / totalWeight
}
It's a bit contrived since normally we could use a pair of arrays to accept as many values and weights, but for the purpose of demonstration the above function has 4 parameters, which are all of type Number and return a Number - but it doesn't have to be all the same type. They can be any of the "base" or primitive types defined in the language, which are:
- String
- Number (split into int and float in AS3)
- Boolean
They can also be any custom type (i.e. classes) that you've created yourself, or that are available in the standard library (e.g. Point, BlurFilter, BitmapData, Array, etc.)
And of course, passing function parameters makes things FAR more manageable since you don't have to rely on global variables or undocumented object properties to pass information for use by the function.
You can only return 1 type in a function, but you can return multiple types if you encapsulate / wrap them in a compound type (such as a class or even a simple array):
function getValues(): Array {
return [2, "Jason"]
}
// and to use...
var returnedValues: Array = getValues()
var numCars: Number = returnedValues[0]
var ownerName: String = returnedValues[1]
Or the more verbose method of declaring a class with the values contained within, along with their type - so that it becomes self-evident when you try and access the object's properties:
//Person.as
public class PersonInfo {
private var _name:String;
private var _numCars: Number;
public function PersonInfo(name: Number, numCars: Number) {
this._name = name;
this._numCars = numCars;
}
public function get name():String {
return this._name;
}
public function get numCars(): String {
return this._numCars;
}
}
//elsewhere
function getValues(): Person {
return new PersonInfo("Jones", 2);
}
var person: Person = getValues();
var numCars: Number = person.numCars;
var name: String = person.name;
The downside of the above being that (in AS2) you can only define them in their own files, rather than in the FLA. But that's a good practice to do in any case. Regardless, when you try and type "person." then the IDE should automatically tell you that there's two properties, numCars and name belonging to the object pointed to by the variable person. This is unlike if you tried to just return an Array of 2 values, or an Object instead:
function getValues(): Object {
return {"name": "Jonas", "numCars": 2}
}
which would work equally in a pinch, but wouldn't tell you what was contained within at the type level. You'd have to get the information from elsewhere (e.g. code comments), whereas with a separate class, the IDE and compiler will tell you what you can and can't access - saving time on debugging, e.g. if you made a typo somewhere (I've seen it occur quite a bit in the past, and had it happen to myself as well).
Well, in theory anyway. I think the IDE support for AS2 is quite a bit worse than for AS3, or if you try and develop in AS2 then you might want to try an external IDE such as FlashDevelop. Granted, that comes with its own tradeoffs as well, to a degree.
and using something called '.clone'? I'm always learning something new with you.
"clone" is a function of the Point object, defined as part of the Point class. It's just like "gotoAndStop()" which is a function belonging to the MovieClip class. You can find more information about these methods by looking at the official AS2 documentation (for the Point class, it is on page 1011); it lists the methods (i.e. functions) and properties (i.e. variables*) belonging to a particular class, as well as all the classes that come "out of the box" with Flash.
Side note: you might have noticed that the above PersonInfo class has the function
public function get name():String {
return this._name;
}
defined, but when we call it then we refer to it directly, like
person.name
instead of
person.name()
as with any other function. And that's because while name is a function, it's a special type of function called a getter. It allows others to treat this as they would any other variable, and the advantage of this is that it makes it less verbose at times while still gating access when required. They also have setters, which are the equivalent of assignment statements; together, you can see how they achieve the "gated" access to a class's variables - e.g. by having a getter (get) but no setter (set), you can prevent others from changing the variable (e.g. you can't change the name property above, it's only created once and that's it), or you can have a write-only property if it's the opposite (e.g. you change a value, but you can't read from it - although this doesn't tend to get used much because it doesn't often make sense to do things this way)
Java doesn't have getters or setters, and their equivalent code is a tad more verbose. Not by much, but it can make things a bit more pleasing to the eye if it were present; just compare the two:
//Java:
//...rest of class...
public int getAge() {
return this._age;
}
public void setAge(int age) {
this._age = age;
}
//
int age = obj.getAge();
obj.setAge(age + 1);
//AS2
public function get age(): Number {
return this._age;
}
public function set age(age: Number): Void {
this._age = age;
}
var age: Number = obj.age;
obj.age = age + 1 // or just obj.age++
There's also a bunch of best practices that you can use with functions, but those are probably for a later time. They have appeared in some way or the other in the original FLA, so you might be able to guess them already.
*properties can be thought of as variables, but they are mostly used to refer to both variables and getters/setters, likely because of the similar syntax.