FlashCodeLibrary

Main Clips Page



Useful Actionscript
Code to use onEnterFrame to perform an animation Code to allow mouse and keyboard drag and drop Code to drag a control point and have situation adjust Code for an input box for a number Code for using an internally defined stylesheet Useful Math Functions Functions to calculate the _x and _y coordinates of any object relative to the stage Using the Continue button before the animation is finished Synchronizing a Sound File to Animation without Adding Frames to the Timeline Code for "concatenating" text fields and input boxes so resizing doesn't go wonky Code to ensure setTimeout respect pause button Using a CLIPSPod object Function to take a string and return a SAFE version for use in an URL Function to replace all instances of one substring with another Additional Variable when Who Cares Movie is a Swf in the Wrapper For In Loop - Runs through all iterations in a pattern to flash one type of tile Delay setFocus in a Textfield Adding a URL to Part of a Textfield Indirectly Setting Up a Class to Listen to Itself While Loop to Determine Target Path of Scene and Activity Levels For In Loop And Prop to Determine Identity of an Object Using ? in Lieu of If Blocks to Set Variable Values Function to Shuffle an Array Indenting a Line of a Textfield on the Stage Using Regular Expression for Evocative Naming of Objects New Directory Structure Activate and Inactive or Paused Pause/Play When User Clicks on Object to Initiate Animation Displaying Continue Button When Narration Playing Code to detect a double-click Initializing a Broadcaster on a Library Object and Listening to It at Scene Level

Kempenfelt Discoveries Code to display a "Do Something" message after a period of inactivity (Waiting for Code - oh !) Clearing Intervals and Listeners Code for playing an .flv in conjunction with narration

Adding CLIPS uberCalc to existing activity

How to CLIPS Tools (including details about Tool Talk)

Stuff for the GLOBALS & SOUND LAYER



Other Reference Pages
Recording and Converting Audio for use in CLIPS

Code to use onEnterFrame to perform an animation
top

code format="actionscript" //Initial conditions angle = 31;

//This function gets executed every 1/24th of a second, assuming the frame rate is 24fps //This function is executed even if the timeline has been stopped onEnterFrame = function { if (!_global.animationPaused) { //do one iteration of the action .       .        .        //update the control variable angle++; //the ending condition if (angle>60) { //the ending actions will vary but you will want to           //delete onEnterFrame //to stop the action from being performed - here delete onEnterFrame is on frame 5's actions layer gotoAndStop(5); }   } }; code 

Code to allow mouse and keyboard drag and drop
top Frame 1 code format="actionscript" import edu.clips.transform.ubWait; import edu.clips.util.ubMath;

this.red_circle_mc.isMidDrag = false;

function dragInit(x, y) { //stuff to do when the dragging starts this.red_circle_mc.isMidDrag = true; start_txt.text = "("+x+", "+y+")"; startx = x;   starty = y; }

function updateSituation(x, y) { //stuff to do as the dragging proceeds distance_txt.text = "Distance: "+ubMath.truncate(ubMath.distance(x, y, this.green_rect_mc._x, this.green_rect_mc._y)); }

this.red_circle_mc.onPress = function { //allows an onPress to start the dragging if (!this.isMidDrag) { //avoid the space bar at the end of a keyboard drag to be misinterpreted this._parent.dragInit(this._x,this._y); this.startDrag(true); this.onMouseMove = function { if (this.isMidDrag) { this._parent.updateSituation(this._parent._xmouse,this._parent._ymouse); }       };    } };

this.red_circle_mc.onRelease = this.red_circle_mc.onReleaseOutside=function { //the ending stuff is done by the mouse release or the space bar press trace("The programmer's onRelease"); this.isMidDrag = false; this.stopDrag; delete this.onMouseMove; if (this.hitTest(this._parent.green_rect_mc)) { //a "good" drag this.enabled = false; this._parent.start_txt.text = "Click Continue"; this._parent.distance_txt.text = ""; this._x = this._parent.green_rect_mc._x; this._y = this._parent.green_rect_mc._y; ubWait.clearWaitFor([this]); this._parent.showcontinue; } else { //a "bad" drag this._x = this._parent.startx; this._y = this._parent.starty; myubWaitForInstance = ubWait.waitFor(this,{interactionType:"drag"}); } };

onWaitForKeyboardMove = function (which, element, x, y, oldx, oldy) { //allows the keyboard to start the drag and proceed with it   if (element == this.red_circle_mc) { if (!this.red_circle_mc.isMidDrag) { dragInit(oldx,oldy); }       updateSituation(x,y); } };

onWaitForReleaseAfterCompleted = function (which, waitArray, element) { trace("onWaitForReleaseAfterCompleted seen by programmer"); trace(waitArray+" (the last one touched was : "+element+" ) "); }; code Frame 2 code format="actionscript" stop; import edu.clips.transform.ubWait; distance_txt.text = "Drag the red circle to the green rectangle."; this.red_circle_mc._x = 100; this.red_circle_mc._y = 90; this.red_circle_mc.enabled = true; ubWait.waitFor(this.red_circle_mc, {interactionType:"drag", dragIncrement:26, dragShiftMultiplier:2, useKeyUp:true}); code



Code to drag a control point and have situation adjust
top

code format="actionscript" //keeps track of whether the mouse is moving to drag the control point var beingDragged:Boolean = false; //keeps track of the position of the point from the last time the situation was adjusted var old_x, old_y:Number;

//create the drag point this._parent.attachMovie("ub_endpoint","dragpt_mc",this._parent.getNextHighestDepth); this._parent.dragpt_mc._visible = true; this._parent.dragpt_mc._x = x3; this._parent.dragpt_mc._y = y3;

//create the event handler for when the control point is clicked this._parent.dragpt_mc.onPress = function { this.startDrag; beingDragged = true; old_x = this._x; old_y = this._y; .   .    .    feedback_txt.htmlText = ""; };

//create the event handler for mouse movements this._parent.dragpt_mc.onMouseMove = function { //declare any local variables var … if (beingDragged) { //adjust the situation only if the control point is currently being dragged .       .        .        old_x = this._x; old_y = this._y; }   updateAfterEvent; };

//create the event handler for when the control point is released this._parent.dragpt_mc.onRelease = this._parent.dragpt_mc.onReleaseOutside=function { this.stopDrag; updateAfterEvent; beingDragged = false; }; code



Code for an input box for a number
top Note: much of this is now handled automatically by ubWaitFor. code format="actionscript" //give the input text box focus, so the user can type in it right away Selection.setFocus(sine_answer_txt); //select the entire contents of the field so that they will be replaced if the user starts typing Selection.setSelection(0,sine_answer_txt.length); check_btn._visible = false; feedback_txt.text = ""; . . . //Show the check button only when the input text box has changed sine_answer_txt.onChanged = function { check_btn._visible = true; };

//If the user clicks the check button check_btn.onRelease = function { check_sine_answer(this); };

//If the user presses the Enter key _parent.keyListener.onKeyDown = function { if (Key.isDown(Key.ENTER)) { check_sine_answer(check_btn); } };

//Check that the value supplied is okay function check_sine_answer(target:Object) { //give the field focus again since it might have lost it to the check button Selection.setFocus(sine_answer_txt); Selection.setSelection(0,sine_answer_txt.length);

//Cast the value of the input box as a number var supplied_answer:Number = Number(sine_answer_txt.text); if (isNaN(supplied_answer)) { //not a number feedback_txt.text = "Please enter a valid number."; } else if (supplied_answer == correct_answer) { . . .   } else .       .        .    } }

Key.addListener(_parent.keyListener);

//In the parent declare the following: //var keyListener:Object = new Object; //so that the preceding line of code will work //You will have to remove the listener, once it is no longer wanted //in the parent use //   Key.removeListener(keyListener); //in the child use //   Key.removeListener(_parent.keyListener); code

top



Using Style Sheets
code format="actionscript" //in the activity import TextField.StyleSheet; var sheet:StyleSheet = new StyleSheet;

sheet.setStyle(".boldText", {fontWeight:'bold'}); sheet.setStyle(".boldRed18", {fontWeight:'bold',color:'#ff0000',fontSize:'18'}); sheet.setStyle(".boldWhiteText", {fontWeight:'bold', color:'#ffffff'});

//in the scene patternRuleRep.styleSheet = _parent.sheet; patternRuleRep.htmlText = " (Number of Chairs) = (Number of Tables) x 3 + " + " 2 "; code See [] for more. top



Useful Math Functions
code format="actionscript" //returns the distance between two ordered pairs function distance(x1, y1, x2, y2):Number { return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); }
 * Note**: These functions and others are now incorporated in ubMath as static methods.

//returns a random integer between the two arguments function randint(minnum, maxnum) { return (minnum+Math.floor(Math.random*(maxnum-minnum+1))); } code

top


 * Functions to calculate the _x and _y coordinates of any object relative to the stage**

See MovieClip localToGlobal and globalToLocal for built-in methods to do similar things

code format="actionscript" function xCoordOf ( obj:MovieClip ) :Number { var tmpX = 0; tmpX = obj._x;

var tmpObj = obj._parent;

while (tmpObj != this ) { tmpX += tmpObj._x; tmpObj = tmpObj._parent; }

return tmpX; }

function yCoordOf ( obj:MovieClip ) :Number { var tmpY = 0; tmpY = obj._y;

var tmpObj = obj._parent;

while (tmpObj != this ) { tmpY += tmpObj._y; tmpObj = tmpObj._parent; }

return tmpY; }

code

top



Using the Continue Button before the animation is finished
This is old and unadvisable. code format="actionscript" //on the frame where the continue button is to be shown showcontinue; //the onPress will move to the correct frame //the onRelease in the external .as file will issue the play; bt_large_continue.onPress=function { gotoAndPlay("frame_label"); }

//on the frame before the next part of the sequence //make sure that the frame is labeled with the name used above stop; bt_large_continue.onPress=function { } code

top



Synchronizing a Sound File to Animation without Adding Frames to the Timeline
This is old and unadvisable. code format="actionscript" // A major disadvantage of adding additional frames to synchronize the sound when run locally is that animation plays slower when streamed // so in an online version of the activity, sound and animation will no longer be synchronized.

// Use Audacity or another program to determine the point (special position) in the sound file at which animation should resume; // this number must be converted to milliseconds

//Add this code to the second frame after the animation ends if (_parent.mySound.position<special_position_in_milliseconds) { gotoAndPlay(_currentframe-1); } //Start the new animation in the next frame

//Flash will loop between these two frames (Holding Frame and Looping Code Frame) until the proper sound byte is reached // Animation Ends Frame // Holding Frame // Looping Code Frame // Animation Begins Frame

// An advantage to this is that timelineandsoundpause; can be set in the first frame as both the timeline and sound will be running.

code

top 

Code for "concatenating" text fields and input boxes so resizing doesn't go wonky
When incorporating multiple text fields together, especially of different types (dynamic + input + dynamic again... etc..), the default _x allocations which work fine in the Flash environment will not always look right when the browser / swf is resized to full screen (or shrunk). To get around this problem, use dynamic run-time assignments for _x coordinates. e.g. You need to create this equation, with * representing an input box for the "m" value: y = * x + 2 Use this code:

code format="actionscript" y_txt.type = "dynamic"; y_txt.autoSize = true; y_txt.text = "y = ";

m_txt.type = "input"; m_txt._x = y_txt._x + y_txt._width + 3;

x_txt.type = "dynamic"; x_txt.text = "x + 2"; x_txt._x = m_txt._x + m_txt._width + 3; code The key is using the .autoSize = true value for the dynamic text fields. You may also wish to set selectable = false; to avoid text fields messing up button functionality.

top 

Code to ensure setTimeout respect pause button
If a setTimeout is used to delay, when the delay time is up, a play; command is often issued. HOWEVER, if there is animation going on, and the pause button has been pressed, then the play; should NOT happen until after pause is released. (A similar process would work for set Intervals as well)

code format="actionscript" stop;

intervalid = setTimeout(delay, 1000); // delay before entering next frame TimeOutsArray.push (intervalid);

function delay { if (_global.animationPaused) { onEnterFrame = function { if (!_global.animationPaused) { delete onEnterFrame; play; }  };  } else {   play; } } code

top



Function to take a string and return a SAFE version for use in an URL
This function will convert any dangerous-for-URL-type characters into % unicode format that can be sent safely to any server (or used as input to a php file) - added as a static method to ubString. code format="actionscript" function Safe4URL ( input:String ) :String { var output:String = ""; for (var i = 0; i < input.length; i++ ) { //trace (output + " + " + input.substr(i,1) ); switch (input.substr(i,1) ) { case "#" : output += "%23"; break; case "$" : output += "%24"; break; case "%" : output += "%25"; break; case "&" : output += "%26"; break; case "=" : output += "%3D"; break; case "?" : output += "%3F"; break; default : output += input.substr(i,1) ; }  }   return output; } code

top



Function to replace all instances of one substring with another
This is incorporated now into ubString and RegExp code format="actionscript" // Replace single or multiple chars in a String. // The original string is not affected. Based on a idea of Davide Beltrame (Broly) // Found on http://www.sephiroth.it/proto_detail.php?id=16 String.prototype.replace = function { var arg_search, arg_replace, position; var endText, preText, newText; arg_search = arguments[0]; arg_replace = arguments[1]; if (arg_search.length == 1) { return this.split(arg_search).join(arg_replace); }   position = this.indexOf(arg_search); if (position == -1) { return this; }   endText = this; newText = ""; do { position = endText.indexOf(arg_search); preText = endText.substring(0, position); endText = endText.substring(position+arg_search.length); newText += preText+arg_replace; } while (endText.indexOf(arg_search) != -1); newText += endText; return newText; }; test = ".swflib/actions/test.swf is a .swf"; trace(test+", "+test.replace('.swf', '')); //.swflib/actions/test.swf is a .swf, lib/actions/test is a code

top



Additional Variable for Who Cares Swf in Player
When playing a Who Cares swf movie in the wrapper be aware that both the movie wrapper and the big (mini) wrapper use the same global variables; to prevent interference add an additional check for pause to see if the clip intro is active code if (!_global.animationPaused && _global.clipintroactive) { code top



For Loop through similarly named movieclips
Use a for loop to run through all of the iterations of a pattern and flash either the constant or multiplier pieces as identified by the type of shape code // loop to check all existing iterations in the pattern for (itNum = 0; itNum < 4; itNum++) { // tile is a string which stores the name of objects found in pat1_mc.pattern_mc.iteration0 and so on, in this case it should be "shapen" where n is a number for (tile in pat1_mc.pattern_mc["iteration" + itNum]) { // use the .shape method to check the shape type if (pat1_mc.pattern_mc["iteration" + itNum][tile].shape == "square") { pat1_mc.pattern_mc["iteration" + itNum][tile]._visible = false; }      } } code top



Delay Set Focus to Textfield
To resolve focus issues when focus is set to a textfield after a click on a button; ie focus is only momentarily set in the textfield as flash gives the button back focus; use a setTimeout to delay by 100 ms

Note: This is usually caused by setting focus in an onPress as opposed to an onRelease. Using ubWaitFor will eliminate this issue. code // this code is added to your validation function which is called after a button click timeOutIntervalID = setTimeout(setTheFocus, 100);// delay so focus will stay in the box TimeOutsArray.push(timeOutIntervalID);

function setTheFocus { Selection.setFocus("multiplier_txt"); Selection.setSelection(0,multiplier_txt.length); } code top



Add a URL link to part of textfield
Using an anchor tag and href to add a url link to part of a text field. code robotSpeech_mc.robotFeedback_txt.htmlText += "I recommend you try a  review activity ."; code top



Indirectly Having a Class Listen to Itself
You cannot setup a listener directly on a class [ie this.addListener(this)] so pass the instance object back to the class and initialize the listener on it;

RI - this seems like a false fact to me. code // in activity fractionSimulate = new ubFractionOpToolSimulator; fractionSimulate.fractionOpToolSimulation(fracTool_mc,fractionSimulate,simulator,fractionNum); // in class public function fractionOpToolSimulation(target1:MovieClip, fractionSimulator1:Object, actions1:Array, fractionParts1:Array, target:MovieClip, target2:MovieClip) { ....   // instance of fraction simulator fractionSimulator1 was passed to the class from the activity // listener is set up on this instance via the class fractionSimulator = fractionSimulator1; fractionSimulator.addListener(this); } code top



While Loop to Determine Scope of Scene and Activity Levels
Determine the scoping for the scene and activity levels when the parentage of a movieclip is not known by a class. ubCLIPs.findScene does this. code // target is a movieclip who is a child of scene target = target1; // continually access the parent of the movie clip until you find the scene while (target1.scene == undefined) { target1 = target1._parent; } sceneTarget = target1.scene; activityTarget = target1; code top



Using a For In Loop and Prop to Determine Identity of an Object
If "this" returns an object rather than a reference to a movie clip, a for in loop on prop (properties) will assist you in determining what the object is. ubTrace.as and ubTraceClass have traceObj methods to do this. code for (var prop in this) { trace("this."+prop+" = "+this[prop]); } code top



Using ? in Lieu of If Blocks to Set Value of Variable
Cool idea from Greg to use as an alternative to creating if statements to assign values to a variable --> first value after "?" is true value and other is false value; in this example feedback text is created using this technique

code var posSign:String = (feature[count] > 0) ? "+" : ""; var aboveBelow:String = (feature[count] > 1) ? "above" : "below"; var addS:String = ((feature[count] == 1) || (feature[count] == -1)) ? "" : "s"; feedback_txt.htmlText = "Sorry, " + posSign + feature[count] + " implies " + Math.abs(feature[count]) + " floor" + addS + " " + aboveBelow + " the " + floorDescriptor + ". Try again."; code top



Function to Shuffle an Array
A function which will shuffle an array (code below) if you want the locations to appear random.

Added to ubObject. code // function to shuffle an array Array.prototype.shuffle = function { for (i = 0; i < this.length; i++) { var tmp = this[i]; var randomNum = random(this.length); this[i] = this[randomNum]; this[randomNum] = tmp; } };

// initialize the array floors[0] = "Parking"; floors[1] = "Electrical Room"; floors[2] = "Housekeeping"; floors[3] = "Arcade"; floors[4] = "Restaurant"; floors[5] = "Lobby Check-in"; floors[6] = "Conference Room"; floors[7] = "Vending Machines"; floors[8] = "Fitness Centre"; floors[9] = "Pool"; floors[10] = "Gardens";

trace("floors before the shuffle : " + floors);

// shuffle the array floors.shuffle; trace("floors after the shuffle: " + floors); code top



Indenting a Line of TextField on the Stage
Indenting text on a line. Use the paragraph button to access format options; increase the left margin and make the indent negative --> see picture below



top



Using Regular Expressions for Evocative Naming of Objects
In the example the text from the textfield is used to create the icon name which will access the movieclip associated with this text. Regular expressions are used to remove white spaces and hyphens from the text field text. code import edu.clips.util.RegExp; // set up the expression for white space p1 = new RegExp("\\s", "g"); // set up the expression for the hyphen p2 = new RegExp("-", "g");

// take the text for the textfield var iconName:String = this._parent["floor" + (thisfloor) + "_txt"].text; // remove the white space from the text and add _mc iconName = iconName.replace(p1, "") + "_mc"; // remove any hyphens iconName = iconName.replace(p2, ""); code top



New Directory Structure
New directory structure where classes are at same level as Testbeds; include statements are adjusted to go back up through the tree to find activities_01.as and wrapperCommon.as (they are in the actions folder) code code
 * 1) include "../classes/edu/clips/actions/activities_01.as"
 * 2) include "../classes/edu/clips/actions/wrapperCommon.as

top



Activate and Inactive or Paused Pause/Play When User Clicks on Object to Initiate Animation
If the wrapper is paused or the pause button is grayed out and the user clicks on an object which should initiate animation then the pause/play button must be activated.

There is now a function in activities_0X.as called simulatePlayClick to do this. code // wrapper is paused with sound playing so set button mode to unpause with soundonlypause if ((_global.animationPaused) && (this._parent.usingNarration) && (!isSoundComplete)) { setPauseAndSoundFinished(false,true,true,"ignore"); // pause/play is inactive so activate it for animation only } else if (_global.globalPause == "scenepause") { setPauseAndSoundFinished(false,false,true,"ignore"); }

code top



Displaying Continue Button When Narration Playing
The following code works better for displaying the continue button when narration may be playing; showcontinue(false) does not impact pause/play button. code // narration is being used so let onSoundComplete control pause/play if ((this._parent.usingNarration)&& (!isSoundComplete)) { showcontinue(false); } else { // no narration so gray out pause/play showcontinue; }

code

top



Code to detect a double-click
code // double click detection to display shapeColour change posCounter_mc.onPress = function { if (lastclick - (lastclick = getTimer) + 300 > 0) { //do doubleclick action this._parent._parent.PodLayer_mc.changeCounterPod_mc._visible = true; } } code top



Initializing a Broadcaster on a Library Object and Listening to It at Scene Level
When setting up broadcasters, the broadcaster object must broadcasts to itself; you initialize another object to listen to the broadcast object; do not attempt to broadcast directly to the listener object; code // this needs to be delayed a frame otherwise the listener is created before the broadcast object is onEnterFrame = function { // add a listener on the scene which listens to the elevator door movie clip // the door will broadcast onMovieClipTransformComplete so existing code can work this.elevatorInterior_mc.elevatorDoor_mc.addListener(this); delete onEnterFrame; };

// on the elevator door movie clip, initialize the elevator interior doors as a broadcaster AsBroadcaster.initialize(this);

// when doors are open broadcast message but message is broadcast to the elevator door // and not the scene which is listening; the scene will be able to hear this broadcast however this.broadcastMessage("onMovieClipTransformComplete","doorR_mc");

code top

Main CLIPS page