add the file ioLib.fla to
/Macromedia/Flash5/Libraries
add the file ioLib.txt to the directory containing your project
open Flash 5
select "Window" menu >> "Common Libraries" >>
"ioLib"
the ioLib.fla will open as a Library
drag an instance of "ac, ioStepLoops" into your movie.
add
#include "ioLib.as"
as code on the first frame of your movie.
(the ioLib.as file must be saved in the same directory as your FLA file)
WARNING:
One (and only one) copy of the ioStepLoops clip must remain on the stage throughout
your project.
Be careful that loaded movies do NOT contain a copy of ioLib. Loaded movies should
be
able to take advantage of ioLib as long as the container movie has ioLib installed.
If your project contains modules which rely on ioLib, and you need to add ioLib
during testing,
temporarily add the ioStepLoops clip on its own layer. Add the #include "ioLib.as"
line.
When testing inside the container movie, comment out the include, and turn the
ioStepLoops layer into a guide.
Re-export the module swf, and then load it into your container project.
TROUBLESHOOTING:
1) If the library is successfully installed, it will write "ioLib installed"
into the Output window when you test your movie in the flash authoring environment.
2) Make sure you included the ioStepLoops actionclip.
3) Read this document.
4) Take a look at template.fla This is a good starting point for creating your
own projects with ioLib
ioDebug
If you've ever attempted to use the debugger included with Flash 5, the existence
of this object will require no explanation.
ioDebug is a drag-and-drop replacement which will dynamically show the contents
of its parent.
// Installation
Drag an instance of the "ioDebugLoader" clip from the ioLib Library into your movie. If you haven't already,
follow the instructions for installing ioLib. (If ioLib is not installed, the debugger will load an alternate version
which pre-includes ioLib)
The replacement debugger uses a pixel font from the Hooge family. In order to prevent problems on machines which do
not have this font installed, the ioDebugLoader clip loads a swf which has the font already embedded. Be careful not
to re-export swf files from ioDebugTemplate.fla if you do not have this font installed.
// Usage
Test your movie. Once the instance containing ioLib is on stage, you should see the ioDebug clip. It should list one item--the
movieClip which contains it. If you added it to the main timeline, it should refer to its parent level.
Click the item in ioDebug. It should expand to show all the objects/variables it contains. Repeat this process for any movieClip
or object contained inside of any other. The heirarchy is analagous to your computer's file system.
Each ioDebug entry has a red button to its left. Pressing this button causes the ioLib system to watch that object/variable
for changes. Values are updated once per frame for each selected item. The button will turn green to indicate that ioDebug
is watching that item. Click the button again to turn off the watch. Due to processor limitations, a watch only processes its
direct children. For example, if you place a watch on the main timeline (_level0), ioDebug will indicate when movieClips appear
or disappear from that timeline. However, it will not indicate changes *inside* those movieClips. Place a watch directly on the
movieClip to keep its listing updated, and so on.
For best performance, only place watches on those items which need constant updates. Watching a variable requires much
less processing than watching an entire object. Therefore, if you only need to watch a specific property of an object, it
is better to place a watch on the specific property rather than the object itself.
References to movieClips appear with the pathname in parenthesis. This is to help distinguish between a movieClip's direct
child movieClips and variable references to movieClips that are nested elsewhere.
Button instances will appear in ioDebug as "instanceXXX" movieClips with a value of "button"
ioDebug is a draggable clip. Click and drag the blue titlebar to position within your movie.
Due to popular demand, ioDebug ver 2.0 includes a scrollBar
NOTE: For usability reasons, functions that are members of Object.io.MovieClip (see below) are not shown in ioDebug
NOTE: Extended prototype chains may cause ioDebug to detect multiple function properties of the same name. This is due to funky behaviour of Flash's "for...in" loop.
The first member will have a normal title (e.g. "push"), additional members will appear with an id number (e.g. "push (id:7)" ). You may notice this when debugging bufferedClutch objects.
NOTE: If you would like a taller (or shorter) ioDebug panel, you'll need to edit the height of the mask in ioDebug???Template.fla
Make sure you have the Hooge pixel font family installed! ioDebug will take care of positioning the other elements.
NOTE: ioDebug uses the ioHashTable object internally. ioHashTable is not documented here because it is not yet
deemed ready for public use. See ioLib.as for source and credits.
Object.io.frameLoop
the frameLoop is the heart of many of ioLib's functions. It's complex, but very powerful.
Occasionally, it's preferable to create frameloops programmatically rather than
creating
movieClip objects for this purpose and then having to deal with attaching/duplicating/removing
them.
Creating frameloops via code can make your projects much more maintainable.
// Constructor
Object.io.frameLoop ()
returns an empty frameLoop object
if a frameLoop object is left running, it will continue to take up system resources,
and may potentially cause frameLoops created
at a later time to function incorrectly. ioLib contains a series of functions
designed to make clean-up an easy process.
See:
Object.io.frameLoop.end()
Object.io.cleanLoops()
Object.io.MovieClip.ioRemoveFrameLoops()
Object.io.MovieClip.ioRemoveFrameLoopsRecursive()
Object.io.MovieClip.ioRemoveMovie()
Object.io.MovieClip.ioUnloadMovie()
// Methods
Object.io.frameLoop.addFrame ( object, method, argumentObject, argumentProperty)
object: the object which contains the method
method: the name of the method to run (passed as a string)
argumentObject: the object which contains the property to be passed
as an argument at runtime
NOTE: argumentObject may be ommited and no argument will
be passed to the method
argumentProperty: the property of the argument object which will be
passed to the method as an argument (passed as a string)
NOTE: argumentProperty may be ommited, and the entire
argumentObject will be passed to the method
addFrame() adds a "frame" to the frameLoop object. If you wish one
action to happen repeatedly (on every frame until
the frameLoop ends) add only one "frame". If you wish two actions
to happen repeatedly (each taking turns, one every
frame until the frameLoop ends) add two "frames"...etc.
// Examples
// create a frameLoop for: _root.fadeUp(10)
myFrameLoop = new Object.io.frameLoop()
myFrameLoop.addFrame ( _root, "fadeUp", 10)
If the argument won't be the same each time, split it into an argumentObject and argumentProperty like this:
// create a frameLoop for: _root.fadeUp(_root.currentPick)
myFrameLoop = new Object.io.frameLoop()
myFrameLoop.addFrame ( _root, "fadeUp", _root, "currentPick")
the frameLoop object also supports running a function to retrieve the argument for your frameloop definition:
// create a frameLoop for: _root.fadeUp(_root.getPick (12) )
myFrameLoop = new Object.io.frameLoop()
myFrameLoop.addFrame ( _root, "fadeUp", _root.getPick, 12)
// create a frameLoop for: _root.fadeUp(_root.getPick () )
myFrameLoop = new Object.io.frameLoop()
myFrameLoop.addFrame ( _root, "fadeUp", _root.getPick)
Object.io.frameLoop.loop ()
this method is called automatically by the ioLib system. You should never need
to call this method directly. It causes
the frameLoop to process one "frame". The loop() method is called
on all active frameLoops, once per frame.
Object.io.frameLoop.setDone ( object, method, argumentObject, argumentProperty)
object: the object which contains the method
method: the name of the method to run (passed as a string)
argumentObject: the object which contains the property to be passed
as an argument at runtime
NOTE: argumentObject may be ommited and no argument will
be passed to the method
argumentProperty: the property of the argument object which will be
passed to the method as an argument (passed as a string)
NOTE: argumentProperty may be ommited, and the entire
argumentObject will be passed to the method
setDone() facilitates an action running automatically when the frameLoop is
destroyed. If setDone() has been called,
the function will run automatically when end() is called. See Object.io.frameLoop.end()
Object.io.frameLoop.setLifeTime (loops)
loops: the number of times to process the frameLoop
after running setLifeTime, end() will be called automatically after the configured
number of iterations have completed.
Object.io.frameLoop.reset ()
occasionally a variable which was used for one frameLoop will be reused for
a new frameLoop. It is best to call
reset() prior to calling the constructor function again. This will automatically
call end() on the old instance of
frameLoop object should that be necessary.
Object.io.frameLoop.end ()
this method is used to destroy an frameLoop that is no longer needed. This MUST
be done in order to free system
resources. If setDone() was called on this frameLoop, the method will be called
by end().
// Properties
Object.io.frameLoop.running
true/false -- this property can be used to determine if an frameLoop is currently
running.
// Related Object.io Methods
Object.io.stepLoops()
Object.io.stepLoops() is called once per frame and is responsible for calling loop() on
all currently active frameLoops.
This is ordinarily handled by a clipEvent(enterframe) installed by ioLib (Remember that clip you dragged on the stage?)
Object.io.cleanLoops()
Object.io.cleanLoops() must be called periodically by any flash system which utilizes
ioLib. cleanLoops is responsible
for de-registering old frameLoops. There is a slight performance hit based on
the total number of frameLoops.
Although it is possible for ioLib to perform this cleanup automatically, it has
no way of knowing when is a
"bad" time v/s a "good" time. Therefore, its implementation
is left up to the individual project.
Object.io.Callback
This object is new to ioLib version 2.0 The callback object simplifies passing a function pointer to a number of ioLib
components. Each callback uses 3 to 4 parameters. This is potentially confusing when a constructor takes more than one
callback (such as the new io.loadMovie method) By using a seperate object to describe callbacks, functions that require callbacks
as parameters aren't nearly so messy.
//Constructor
Object.io.callback (object, method, argumentObject, argumentProperty)
object: the object which contains the method
method: the name of the method to run (passed as a string)
argumentObject: the object which contains the property to be passed as an argument at runtime
NOTE: argumentObject may be ommited and no argument will be passed to the method
argumentProperty: the property of the argument object which will be passed to the method as an argument (passed as a string)
NOTE: argumentProperty may be ommited, and the entire argumentObject will be passed to the method
returns a callback object populated with the specified method definition.
Object.io.clutch
One of the more common tasks in flash development is finding a way to link the
properties of two objects.
Flash has a built-in function -- startDrag() -- for linking the x/y properties
of a movieClip to the mouse x/y,
but what to do if you'd like to create your own links?
if an clutch object is left running (engaged), it will continue to take up system
resources, and may potentially cause frameLoops
created at a later time to function incorrectly (if its container movie is destroyed,
for instance). ioLib contains a series of functions
designed to make clean-up an easy process.
See:
Object.io.clutch.disengage()
Object.io.MovieClip.ioRemoveFrameLoopsRecursive()
Object.io.MovieClip.ioRemoveMovie()
Object.io.MovieClip.ioUnloadMovie()
// Constructor
Object.io.clutch ( inObject, inProperty, outObject, outProperty )
inObject: the object containing the source data
inProperty: the property of inObject containing the source data (passed
as a string)
outObject: the object to which data will be passed
outProperty: the property of outObject which will be set by ioClutch.
(passed as a string)
the constructor returns a clutch object with the specified linkage, but does
not begin processing.
// Methods
Object.io.clutch.engage()
calling engage() causes the linkage to take effect.
Object.io.clutch.disengage()
calling disengage() causes the linkage to be temporarally paused (thus not taking
processor time),
yet without destroying the clutch object.
Object.io.clutch.setTransform (function)
function: the function which will be used to convert from inObject
"coordinates" to outObject "coordinates"
often, the relationship between the linked objects is not 1:1 ioLib allows the
programmer to create transform
functions which will be automatically called by a running clutch. Transform functions
will recieve the following parameters:
inObject: the inObject with which the clutch was created.
outObject: the outObject with which the clutch was created.
inValue: the current value of inObject[inProperty]
Transform functions are expected to then return the correct value for outObject[outProperty]
In most cases, the relationship is a linear one. Here's a template transform function
for use as an example.
//LINEAR EXAMPLE
xform1 = function (inObj, outObj, inValue) {
var inLow = 10
var inHi = 25
var outLow = 100
var outHi = 200
var outValue = (((inValue-inLow)/(inHi - inLow)) * (outHi - outLow)) + outLow
return outValue
}
to use this function as your clutch transform:
myClutch.setTransform (xform1)
Object.io.clutch.setLinger (frames)
frames: number of frames to continue processing after disengage()
In systems which utilize multiple clutch objects, it may become necessary for
processing to continue for a few
frames past the disengage() call in order for data to be successfully recognized
and migrated. This is especially
true if the inObject of one clutch is the outObject of another clutch.
// Properties
Object.io.clutch.ratio
In those cases in which you do not wish to use a transform function, but there
is a constant relationship
between inProperty and outProperty, set the ratio property of the clutch (default
is 1)
//RATIO EXAMPLE
myClutch.ratio = 2 //to multiply the inProperty by 2 before setting outProperty
myClutch.ratio = (1/3) //to divide the inProperty by 3 before setting outProperty
Object.io.clutch.buffer
The buffer property contains the last known value of inObject[inProperty]
// Performance
Projects which rely heavily on the clutch object (more than 20 in movies which
are already performance-challenged) may
experience a performance hit. The dynamic nature of the object contains some inherent
inefficiencies. Developers are generally
advised to continue using the clutch object until the project is complete. During
the optimization process, clutch objects
can be systematically converted to clipEvents with very little effort. The structure
imposed by the clutch object lends itself
towards an overall reduced development time and easy conversion to more efficient
routines. In addition, the ability to dynamically
start and stop the clutch object can oftentimes make it *more* efficient than
the same system built utilizing clipEvents.
Object.io.bufferedClutch
See Object.io.clutch for full description. bufferedClutch extends the clutch object by offering
a setBufferLength method.
There are times in which values of inObject[inProperty] should be recorded for
later use and/or the
outObject should be updated out-of-step from the inObject.
// Constructor
Object.io.bufferedClutch ( inObject, inProperty, outObject, outProperty )
inObject: the object containing the source data
inProperty: the property of inObject containing the source data (passed
as a string)
outObject: the object to which data will be passed
outProperty: the property of outObject which will be set by ioClutch.
(passed as a string)
the constructor returns an bufferedClutch object with the specified linkage.
Object.io.bufferedClutch.setBufferLength ( bufferLength )
bufferLength: number of slots in the buffer
the buffer's length is set to bufferLength and all slots in the buffer are populated
with
the current value of inObject[inProperty]
Object.io.bufferedClutch.setNoDelay()
it may be desirable to retain a history in the clutch while keeping outObject
synchronized with
the most current value as opposed to the oldest value. Call setNoDelay() to accomplish
this.
Object.io.bufferedClutch.setDelay ( delay )
delay: the delay (in frames) between a value being read from inObject[inProperty]
and being sent to
outObject[outProperty]
it may be desirable to retain a history in the clutch that is longer than the
delay between property
updates. Calling setDelay() allows finer control than simply using setNoDelay().
// Properties
Object.io.bufferedClutch.buffer
The buffer property of a bufferedClutch is an Array.
The most recent values of inObject[inProperty] are located at the end of the Array:
newest = myBufClutch.buffer[myBufClutch.buffer.length-1]
The oldest values of inObject[inProperty] are located at the beginning of the
Array:
oldest = myBufClutch.buffer[0]
Object.io.cmlToObj
xmlToObj is a utility function used to create an Object using the attribute/value
pairs passed in an xmlNode.
// Usage
myObject = Object.io.xmlToObj (xmlObject)
the attribute/value pairs found in xmlObject are used to populate myObject
// Example
myXML = new XML ("<exampleData
name='bill' ss='241-95-0000' x='17' y='20' />")
myObject = Object.io.xmlToObj (myXML.childNodes[0]) // send the first (and only)
childNode, not the whole document
//myObject.name = "bill"
//myObject.ss = "241-95-0000"
//myObject.x = "17"
//myObject.y = "20"
NOTE: to convert string values to numeric values for use in computation:
myObject.x = Number (myObject.x)
Object.io.objToXml
Object.io.objToXML is a utility function used to create an XML Object using the data stored
in a movieClip or Object.
// Usage
myXML = Object.io.objToXML ("nodeName", myObject)
the attribute/value pairs found in myObject are used to populate myXML. Passing
a movieClip reference will create
an XML object containing data for _x, _y, _alpha, _xscale, _yscale, _target, etc
// Example
myObject = new Object ()
myObject.x = 27
myObject.y = 100
myObject.name = "bill"
myObject.color = "FFCC00"
myXML = Object.io.objToXML ("myObjectData", myObject)
trace (myXML)
//Should return:
// <myObjectData x="27" y="100" name="bill" color="FFCC00"
/>
Object.io.loadMovie
the ability to load external swf files as movieClips is very powerful and often
used when the developer would like to use a template.
This proves difficult in practice as it becomes neccessary to create and keep
track of preloaders and to wait until the movieClip
is completely loaded to populate it with data. The more movies you're attempting
to load at once, the more difficult the proceedure
becomes.
// Usage
Object.io.loadMovie (myMovieClip, path, varsObject, completeCallback, percentageCallback)
myMovieClip: the containerClip the swf will be loaded into
path: path to the swf file that should be loaded
vars: an object containing the data which should be sent to this movieClip
once it is fully loaded
completeCallback: a callback object which describes the method that should be run once the movieClip is fully loaded
percentageCallback: a callback object which describes the method that should be notified with loading progress.
Object.io.loadMovie will automatically discard the contents of myMovieClip. If the movieClip
contains ioFrameLoop objects, they will
be removed via the end() method. See Object.io.MovieClip.ioUnloadMovie().
Often, you'll need to use movieClip.attachMovie() to create a movieClip instance
to run Object.io.loadMovie() upon.
The ioLib library contains a linked movieClip object called "empty"
which can be used for this purpose.
If the percentageCallback attribute has been set, its function definition will be called every frame while the movie
is loading. This allows the developer to easily implement a status bar or progress animation. If the
argumentObject/argumentProperty of the percentageCallback object was set, the callback will be in the form of:
obj.method(arg, percentLoaded)
if not, the callback will be in the form of:
obj.method(percentLoaded)
This feature allows the developer to take advantage of the full callback object since the percentage argument
(passed automatically by ioLoadMovie) doesn't displace any user-defined argument.
NOTE: movies loaded with Object.io.loadMovie are loaded with visibility set to false.
This allows the developer complete control over
when/where/how the loaded movie appears.
To automatically show the movie once it is loaded, add a _visible attribute to
the varsObject:
myVarsObject = new Object()
myVarsObject._visible = true
Object.io.loadMovie (myMovie, "myExternal.swf", myVarsObject)
//the movie's visibility will automatically be set to true, after the movie is
completely loaded.
// Example
myVarsObject = new Object()
myVarsObject._visible = true
myVarsObject._x = 200
myVarsObject._y = 50
myVarsObject.name = "bob"
myCompleteCallback = new _root.ioCallback ( _root, "notifyMe", myMovie, name)
myPercentageCallback = new _root.ioCallback ( _root, "updateStatus", name)
Object.io.loadMovie (myMovie,"myExternal.swf", myVarsObject, myCompleteCallback, myPercentageCallback)
//once the movie is loaded, it will be moved to _x = 200, _y = 200
//its visibility will be set to true
//a variable called "name" will be set to "bob" on the movieClip's
timeline
//the ioLib system will automatically call: _root.notifyMe(myMovie.name)
//which in this case will be equivalent to: _root.notifyMe("bob")
// Properties
myMovie.ioLoadedPercent
the amount of a movie being loaded via ioLoadMovie that has loaded (0 - 100)
myMovie.ioLoaded
true if the movie is completely loaded, false or null otherwise
Object.io.setVars
sets the variables in a movieClip equal to the variables in another movieClip
or Object
// Usage
Object.io.setVars (myMovieClip, varsObject)
myMovieClip: the movieClip which will have variables set
varsObject: an object containing the data to populate myMovieClip
// Example
myVars = new Object
myVars._x = 100
myVars._y = 50
myVars._alpha = 70
myVars._rotation = 90
myVars.name = "sharron"
myVars.id = 123456
Object.io.setVars (myMovieClip, myVars)
//or
Object.io.setVars (myMovieClip, anotherMovieClip)
//sets all the values of myMovieClip equal to the values of anotherMovieClip
Object.io.implements
adds a custom object to the specified object's prototype chain. This is extremely useful for separating code and graphics.
You should note that you'll need to use ioLib's implements function if you wish to access any of the Object.io.MovieClip extensions.
It's easy:
// Usage
Object.io.implements (object, prototypeObject)
object: (usually a movieClip) which should inherit the functionality of prototypeObject
prototypeObject: an object which contains functions as properties
// Example
Object.io.implements (myMovieClip, Object.io.MovieClip)
//gives myMovieClip access to all the functions found in Object.io.MovieClip
//it is now safe to call:
myMovieClip.ioSetHex ("FFCC00")
Object.io.isNested
returns true if the specified movieClip is nested under this movieClip, otherwise false
// Usage
testVar = Object.io.isNested (myMovieClip, testMc)
Object.io.MovieClip.ioRemoveFrameLoops
calls end() on any running frameLoops in the movieClip
// Usage
myMovieClip.ioRemoveFrameLoops()
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.ioRemoveFrameLoopsRecursive
calls end() on any running ioFrameLoops in the movieClip, including those running
in any internal movieClips or ioClutches.
// Usage
myMovieClip.ioRemoveFrameLoopsRecursive()
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.ioRemoveMovieClip
removes the movieClip (including the instance name) after calling ioRemoveFrameLoopsRecursive()
// Usage
myMovieClip.ioRemoveMovieClip()
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.ioUnloadMovie
unloads movie (leaving the instance name) after calling ioRemoveFrameLoopsRecursive()
// Usage
myMovieClip.ioUnloadMovie()
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
NOTE: the output window within the Flash authoring environment may display an
error which looks something like:
Error opening URL "file:///D|/projects/flash/"
This is because of a peculiarity of using movieClip.unloadMovie(). ioUnloadMovie
uses movieClip.unloadMovie() internally.
This warning should not affect the performance of your projects.
Object.io.MovieClip.ioSetRGB
sets the color of a movieClip object to an RGB value
// Usage
myMovieClip.ioSetRGB (r,g,b)
r: red component (0 - 255)
g: green component (0 - 255)
b: blue component (0 - 255)
// Example
myMovieClip.ioSetRGB (255,255,255)
//turns myMovieClip white
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.ioSetHex
sets the color of a movieClip object to a hexidecimal value
// Usage
myMovieClip.ioSetHex ( hex )
hex: hexidecimal value used to set color (passed as a string)
// Example
myMovieClip.ioSetHex ("FFFF00")
//turns myMovieClip yellow
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.addForce
adds a movement behavior to a movieClip object and returns a unique force id.
See Object.io.MovieClip.killForce()
// Usage
myMovieClip.addForce ( forceFn, arg1, arg2, arg3...)
forceFn: force function to use on this movieClip. Must be a member of Object.io.forces (passed as a string)
argN: arguments to be passed to the force function -- force specific
// Example
myForceId = myMovieClip.addForce
("objAttraction", mc12, .2, .8)
//myMovieClip will now be attracted to mc12
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.killForce
removes a movement behavior from a movieClip object
// Usage
myMovieClip.killForce ( forceId )
forceId: the force id of the force to remove. See Object.io.MovieClip.addForce()
// Example
myMovieClip.killForce (myForceId)
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.getForceIds
returns an array containing the ids of all forces currently acting upon this movieClip,
including any that may be paused.
// Usage
myForceList = myMovieClip.getForceIds ()
// Example
myForceList = myMovieClip.getForceIds ()
var myFlag = true
for (var i in myForceList) {
if (myMovieClip.getForceState[myForceList[i]]) {
myFlag = false
}
}
if (myFlag) {
//only perform the actions here if there are no forces acting on myMovieClip
}
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.pauseForce
temporarily stops a movement behavior without killing the force
// Usage
myMovieClip.pauseForce ( forceId )
forceId: the force id of the force to pause. See Object.io.MovieClip.addForce()
// Example
myMovieClip.pauseForce (myForceId)
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.unPauseForce
resumes a movement behavior that was previously paused
// Usage
myMovieClip.unPauseForce ( forceId )
forceId: the force id of the force to resume. See Object.io.MovieClip.addForce()
// Example
myMovieClip.unPauseForce (myForceId)
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.MovieClip.getForceState
returns true if the force is running, false if the force is paused or no longer
active
// Usage
myBoolean = myMovieClip.getForceState ( myForceId )
forceId: the force id of the force to test
// Example
myBoolean = myMovieClip.getForceState
( myForceId )
if (myBoolean) {
trace ("force " + myForceId + " is active.")
}
else {
trace ("force " + myForceId + " is inactive.")
}
Note: Object.io.implements must be used to add the Object.io.MovieClip extensions to myMovieClip first
Object.io.forces.pointAttraction
attracts or repells to/from an x,y coordinate
// Usage
myMovieClip.addForce ("pointAttraction", x, y, accel, accelUnits,
frictionPercent, range, killFlag)
x: x coordinate to attract/repell to/from
y: y coordinate to attract/repell to/from
accel: acceleration constant: positive values attract, negative values
repell
accelUnits: acceleration units:
"pc" -- percent, each itteration, the movement
force will be a percentage of the distance
"px" -- pixels, each itteration, the movement
force will be a number of pixels
frictionPercent: (0 - 1) percentage of momentum that is maintained
from the last iteration.
values close to 0 retain little momentum, values close
to 1 retain most of their momentum.
range: range is the distance, in pixels from the x/y coordinate, at
which this force will begin decay.
A null range sets an infinite range.
killFlag: (true/false) should this force be automatically removed
once the specified range has been
reached? Default is true. This attribute is most often
used with repulsion (negative acceleration).
NOTE: killFlag may initially appear to be a redundant feature in light of the
"range" attribute.
Keep in mind that multiple forces may act on the same object resulting in the
movieClip being
brought *back* into range. killFlag allows the developer to control behavior under
these
circumstances.
// Examples
//move to (150, 200) accelerating
10% per frame with low enough friction (.9) to give some "springyness"
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("pointAttraction", 150, 200, .1, "pc",
.9)
//move to (150, 200) accelerating 4 pixels per frame until 6 pixels away
//with low enough friction (.9) to give some "springyness"
//NOTE: ommiting range with with acceleration measured in pixels may not produce
the intended effect
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("pointAttraction", 150, 200, 4, "px",
.9, 6)
//move away from (150, 200) accelerating 10% per frame until at least 200 pixels
away
//with low enough friction (.9) to give a smooth stop
//kill the force once this range has been reached
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("pointAttraction", 150, 200, -.1, "pc",
.9, 200, true)
//move away from (150, 200) accelerating 4 pixels per frame until at least 200
pixels away
//with low enough friction (.9) to give a smooth stop
//keep this force active. If myMovieClip gets close enough to (150,200), this
force will take effect again.
//NOTE: using repulsion (negative acceleration) with acceleration measured in
pixels may not produce the intended effect
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("pointAttraction", 150, 200, -4, "px",
.9, 200, false)
Object.io.forces.objAttraction
attracts or repells to/from a movieClip object's coordinates
// Usage
myMovieClip.addForce ("objAttraction", mc, accel, accelUnits,
frictionPercent, range, killFlag)
mc: movieClip whose x/y coordinate to attract/repell to/from
accel: acceleration constant: positive values attract, negative values
repell
accelUnits: acceleration units:
"pc" -- percent, each itteration, the movement
force will be a percentage of the distance
"px" -- pixels, each itteration, the movement
force will be a number of pixels
frictionPercent: (0 - 1) percentage of momentum that is maintained
from the last iteration.
values close to 0 retain little momentum, values close
to 1 retain most of their momentum.
range: range is the distance, in pixels from the x/y coordinate, at
which this force will begin decay.
A null range sets an infinite range.
killFlag: (true/false) should this force be automatically removed
once the specified range has been
reached? Default is true. This attribute is most often
used with repulsion (negative acceleration).
NOTE: killFlag may initially appear to be a redundant feature in light of the
"range" attribute.
Keep in mind that multiple forces may act on the same object resulting in the
movieClip being
brought *back* into range. killFlag allows the developer to control behavior under
these
circumstances.
// Examples
//move towards mc2 accelerating
10% per frame with low enough friction (.9) to give some "springyness"
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("objAttraction", mc2, .1, "pc",
.9)
//move towards mc2 accelerating 4 pixels per frame until 6 pixels away
//with low enough friction (.9) to give some "springyness"
//NOTE: ommiting range with with acceleration measured in pixels may not produce
the intended effect
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("objAttraction", mc2, 4, "px", .9,
6)
//move away from mc2 accelerating 10% per frame until at least 200 pixels away
//with low enough friction (.9) to give a smooth stop
//kill the force once this range has been reached
myMovieClip.ioAddForce ("ioObjAttraction", mc2, -.1, "pc",
.9, 200, true)
//move away from mc2 accelerating 4 pixels per frame until at least 200 pixels
away
//with low enough friction (.9) to give a smooth stop
//keep this force active. If mc2 gets close enough, this force will take effect
again.
//NOTE: using repulsion (negative acceleration) with acceleration measured in
pixels may not produce the intended effect
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("objAttraction", mc2, -4, "px",
.9, 200, false)
Object.io.forces.totalDeltaAttraction
attracts or repells to/from a total x/y change
// Usage
myMovieClip.addForce ("totalDeltaAttraction", dx, dy, accel,
accelUnits, frictionPercent, range)
dx: distance on the x-axis from this movieClip to attract/repell to/from
dy: distance on the y-axis from this movieClip to attract/repell to/from
accel: acceleration constant: positive values attract, negative values
repell
accelUnits: acceleration units:
"pc" -- percent, each itteration, the movement
force will be a percentage of the distance
"px" -- pixels, each itteration, the movement
force will be a number of pixels
frictionPercent: (0 - 1) percentage of momentum that is maintained
from the last iteration.
values close to 0 retain little momentum, values close
to 1 retain most of their momentum.
range: range is the distance, in pixels from the x/y coordinate, at
which this force will begin decay.
ommiting the range attribute sets an infinite range.
// Example
//move 50 pixels to the right,
80 pixels up, accelerating 10% per frame with low enough friction (.9) to give
some "springyness"
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("totalDeltaAttraction", 50, -80, .1, "pc",
.9)
Object.io.forces.angleAttraction
attracts or repells to/from a total x/y change
// Usage
myMovieClip.addForce ("angleAttraction", theta, totalDistance,
accel, accelUnits, frictionPercent, range)
theta: angle (in degrees) to attract/repell to/from
totalDistance: total distance from this movieClip to attract/repell
to/from
accel: acceleration constant: positive values attract, negative values
repell
accelUnits: acceleration units:
"pc" -- percent, each itteration, the movement
force will be a percentage of the distance
"px" -- pixels, each itteration, the movement
force will be a number of pixels
frictionPercent: (0 - 1) percentage of momentum that is maintained
from the last iteration.
values close to 0 retain little momentum, values close
to 1 retain most of their momentum.
range: range is the distance, in pixels from the x/y coordinate, at
which this force will begin decay.
ommiting the range attribute sets an infinite range.
// Example
//move towards 1 o'clock (35
degrees) by 80 pixels, accelerating 10% per frame with low enough friction (.9)
to give some "springyness"
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("angleAttraction", 35, 80, 0, .1, "pc",
.9)
Object.io.forces.accelBy
accelerates the movieClip at the specified rate for the specified number of frames,
then slows to a stop.
// Usage
myMovieClip.addForce ("accelBy", accelRateX, accelRateY, frictionPercent,
lifeTime)
accelRateX: rate of acceleration along x-axis (positive values
move right, negative values move left)
accelRateY: rate of acceleration along y-axis (positive values move
down, negative values move up)
frictionPercent: (0 - 1) percentage of momentum that is maintained
from the last iteration.
lifeTime: lifeTime of this force in frames. After this number of iterations,
the movieClip will cease to accelerate
and will begin to slow to a stop (via frictionPercent)
// Example
// accelerate down and to the
right for 5 frames
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("accelBy", 5, 10, .9, 5)
Object.io.forces.accelAt
accelerates the movieClip at the specified angle and rate for the specified number
of frames, then slows to a stop.
// Usage
myMovieClip.addForce ("accelAt", theta, accelRate, frictionPercent,
lifeTime)
theta: angle (in degrees) at which to accelerate
accelRate: rate of acceleration (in pixels)
frictionPercent: (0 - 1) percentage of momentum that is maintained
from the last iteration.
lifeTime: lifeTime of this force in frames. After this number of iterations,
the movieClip will cease to accelerate
and will begin to slow to a stop (via frictionPercent)
// Example
// accelerate towards 1 o'clock
(35 degrees) by 10 pixels per frame for 5 frames
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("accelAt", 35, 10, .9, 5)
Object.io.forces.moveTo
moves the movieClip to the x/y coordinate in steps of delta
// Usage
myMovieClip.addForce ("moveTo", x, y, delta)
x: the x coordinate to move to
y: the y coordinate to move to
delta: the number of pixels to move per frame
// Example
//move to 20, 50 in 2 pixel
increments
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("moveTo", 20, 50, 2)
Object.io.forces.moveBy
moves the movieClip by the specified amounts in steps of delta
// Usage
myMovieClip.addForce ("moveBy", dx, dy, delta)
dx: the distance to move along the x-axis
dy: the distance to move along the y-axis
delta: the number of pixels to move per frame
// Example
//move to 20 pixels right, 50
pixels down, in 2 pixel increments
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("moveBy", 20, 50, 2)
Object.io.forces.moveAt
moves the movieClip at the specified angle for the specified distance in steps
of delta
// Usage
myMovieClip.addForce ("moveAt", theta, totalDist, delta)
theta: the angle (in degrees) at which to move
totalDist: the total distance to move
delta: the number of pixels to move per frame
// Example
//move towards 1 o'clock (35
degrees), 50 pixels in 2 pixel increments
Object.io.implements (myMovieClip, Object.io.MovieClip)
myMovieClip.addForce ("moveAt", 35, 50, 2)
//Properties
movieClip.ioDx
The amount the movieClip will move along the x-axis during this frame. ioDx is
reset to zero by ioLib
each frame. Custom force functions should add to ioDx. Otherwise, this property
should only be modified via addForce.
In addition, calculations based on the current value will behave erratically.
movieClip.ioDy
The amount the movieClip will move along the y-axis during this frame. ioDy is
reset to zero by ioLib each
frame. Custom force functions should add to ioDy. Otherwise, this property should
only be modified via addForce.
In addition, calculations based on the current value will behave erratically.
movieClip.ioVx
The current speed of the movieClip along the x-axis. This value is calculated
based on movement completed
during the last frame update. This property is read-only.
movieClip.ioVy
The current speed of the movieClip along the y-axis. This value is calculated
based on movement completed
during the last frame update. This property is read-only.
// Creating Custom Forces
The forces included with ioLib are a good starting point for creating your own
custom force functions.
All force functions are expected to follow the following syntax:
forceFn (mc, args, data, ioForceId)
mc: the movieClip object to act upon
args: an array containing the arguments which configure this specific
force
(e.g. coordinates to seek, an acceleration rate, friction
constant, etc)
data: an object containing data specific to this instance of the force
which will be reused from frame to frame
(e.g. acceleration, a force "lifetime" counter,
etc)
ioForceId: the id of the current force.
First, your force function must be accessible to any movieClip which will attempt
to utilize it.
The io.force system ensures this by forcing you to attach your force functions to the Object.io.forces
object.
This will provide access to the force function from any movieClip in your project.
// Example
Object.io.forces.newForce
= function (mc, args, data, ioForceId) {
//force code here
}
Next, if your force needs to utilize iteration data over time, try to avoid storing
this information directly in
the movieClip. Instead, use the data argument. Although slightly more complicated,
this allows one movieClip to
utilize more than one of the same kind of force.
To use the data argument, simply return an object containing your data at the
end of your force function. It will
be passed back to the function (also as an object) during the next iteration.
// Example
Object.io.forces.newForce
= function (mc, args, data, ioForceId) {
//how
much influence did this force have last time?
var
dx = data.dx
var
dy = data.dy
//...edited
for clarity...
//save
this iteration's change data for next time.
var
dataObj = new Object()
dataObj.dx
= dx
dataObj.dy
= dy
return dataObj
}
Your force influences a movieClip by manipulating its ioDx and ioDy properties
instead of changing the _x and _y
properties directly. Again, this adds complexity, but allows you to have lots
of forces influencing a single movieClip.
// Example
Object.io.forces.newForce
= function (mc, args, data, ioForceId) {
this.ioDx += 10
//this force will create an influence to move an object to the right
//10 pixels per frame until it is destroyed.
}
// Extending the Force Concept
Experiment with the arguments of the included force functions and feel free to
use their code as the starting point
for your own forces. They already provide a wide range of behaviors; perhaps the
movement you need can be achieved
by changing the sign of an argument (for instance).
It is actually quite possible to affect properties of your movieClips other than
_x and _y using the provided force system.
You may also wish to experiment with scale, alpha, rotation, etc.
In addition, forces may be the ideal solution to movement problems which do not
immediately appear to be relevant.
Collision detection, bounce physics, etc are possibilities.
Object.io.Mask
Flash's masking does not currently allow the range of possibilities that are sometimes desired. Funky nestings are required to achieve the combination of effects we find ourselves desiring. Object.io.Mask offers a framework designed to allow greater control over your mask effects. Best of all, masks and the objects they mask are elligible for use with the ioLib force behavior set. This combination allows for a stunning array of possibilities.
// Usage
Any project using Object.io.Mask must import the library textfile. If you use it often, feel free to add the contents to ioLib.as
#import "ioMask.as"
To add an ioMask object to your project, first attach an ioMask template from the library. Use the example template in the ioLib.fla library as a starting point.
this.attachMovie("io.mask.star", "mask1", 1)
The actions layer of the template includes the following line of code which causes the movieClip to take on ioMask properties.
Object.io.implements(this, Object.io.mask)
Object.io.mask.setMasked
Sets the underlying masked movieClip which will be viewed through the mask. This should be an exported library clip.
// Usage
Object.io.mask.setMasked ( exportedId )
// Example
myMask.setMasked("pic1")
Object.io.mask.getMask
Returns the mask movieClip which can be used with Object.io.forces. Usage with other functions may yield undesirable results. To move, scale, or rotate the mask, use the provided utility functions.
// Usage
Object.io.mask.getMask ()
// Example
myMc = myMask.getMask()
myMc.addForce("totalDeltaAttraction",x,y,15,"px",.8,10)
Object.io.mask.getMasked
Returns the masked movieClip which can be used with Object.io.forces. Usage with other functions may yield undesirable results. To move, scale, or rotate the masked texture, use the provided utility functions.
// Usage
Object.io.mask.getMasked ()
// Example
myMc = myMask.getMasked()
myMc.addForce("totalDeltaAttraction",x,y,15,"px",.8,10)
Object.io.mask.setMaskRotation
Rotates the mask portion of an io.Mask object
// Usage
Object.io.mask.setMaskRotation (deg)
deg: degrees to rotate
// Example
myMask.setMaskRotation(90)
Object.io.mask.setMaskX
Sets the mask x coordinate on an io.Mask object
// Usage
Object.io.mask.setMaskX (coord)
coord: x-coordinate to move to
// Example
myMask.setMaskX(200)
Object.io.mask.setMaskY
Sets the mask y coordinate on an io.Mask object
// Usage
Object.io.mask.setMaskY (coord)
coord: y-coordinate to move to
// Example
myMask.setMaskY(200)
Object.io.mask.setMaskXDelta
Moves the mask x coordinate of an io.Mask object by the given amount
// Usage
Object.io.mask.setMaskX (delta)
delta: amount of change
// Example
myMask.setMaskXDelta(20)
Object.io.mask.setMaskYDelta
Moves the mask y coordinate of an io.Mask object by the given amount
// Usage
Object.io.mask.setMaskYDelta (delta)
delta: amount of change
// Example
myMask.setMaskYDelta(-20)
Object.io.mask.setMaskXScale
Sets the mask x-scale of an io.Mask object
// Usage
Object.io.mask.setMaskXScale (scale)
scale: percentage scale (100 = 100%)
// Example
myMask.setMaskXScale(200)
Object.io.mask.setMaskYScale
Sets the mask y-scale of an io.Mask object
// Usage
Object.io.mask.setMaskYScale (coord)
scale: percentage scale (100 = 100%)
// Example
myMask.setMaskYScale(200)
Object.io.mask.setMaskedRotation
Rotates the masked portion of an io.Mask object
// Usage
Object.io.mask.setMaskedRotation (deg)
deg: degrees to rotate
// Example
myMask.setMaskedRotation(90)
Object.io.mask.setMaskedX
Sets the masked x coordinate on an io.Mask object
// Usage
Object.io.mask.setMaskedX (coord)
coord: x-coordinate to move to
// Example
myMask.setMaskedX(200)
Object.io.mask.setMaskedY
Sets the masked y coordinate on an io.Mask object
// Usage
Object.io.mask.setMaskedY (coord)
coord: y-coordinate to move to
// Example
myMask.setMaskedY(200)
Object.io.mask.setMaskedXDelta
Moves the masked x coordinate of an io.Mask object by the given amount
// Usage
Object.io.mask.setMaskedX (delta)
delta: amount of change
// Example
myMask.setMaskedXDelta(20)
Object.io.mask.setMaskedYDelta
Moves the masked y coordinate of an io.Mask object by the given amount
// Usage
Object.io.mask.setMaskedYDelta (delta)
delta: amount of change
// Example
myMask.setMaskedYDelta(-20)
Object.io.mask.setMaskedXScale
Sets the masked x-scale of an io.Mask object
// Usage
Object.io.mask.setMaskedXScale (scale)
scale: percentage scale (100 = 100%)
// Example
myMask.setMaskedXScale(200)
Object.io.mask.setMaskedYScale
Sets the masked y-scale of an io.Mask object
// Usage
Object.io.mask.setMaskedYScale (coord)
scale: percentage scale (100 = 100%)
// Example
myMask.setMaskedYScale(200)