Showing posts with label flash. Show all posts
Showing posts with label flash. Show all posts

Tuesday, February 9, 2016

Using a CLIPS Activity in SMART Notebook - Redux

In a post from 2009, Giancarlo Brotto explained how to embed .swf downloads from MathCLIPS into SMART Notebook.  This year, SMART Notebook will be moving away from Flash, and so Giancarlo has updated the video with three methods to embed CLIPS activities, games and tools into a Notebook file.  He even added some promotion for other SMART products, I guess that is what you do if you are Global Education Strategist for SMART.




Wednesday, January 21, 2015

The Rekenrek by mathies app

The team that I work with produces digital resources for Math which are catalogued at mathies.ca.  This week we finally are able to add the Rekenrek for mathies app we developed for the App Store (iOS), the Google Play Store (Android) and desktop computers (Flash-enabled browsers).



The rekenrek is a powerful tool for helping students develop early number concepts.  It can be used to support the learning of addition and multiplication facts by helping students understand different ways these values can be constructed.  Information about how to use the app can be found by clicking on the i button within the app which provides a link to a wiki page with informative screenshots, links to PDF supports and two how-to videos.  It has been really rewarding working with primary educators to understand how learning tools can help students with skills like subitizing which as a secondary teacher I had no idea about.

One feature that is unique about our app is the annotation tool (accessed using the pencil icon) which allows students to draw on the stage and explain their thinking.  It is, in fact, a drawing app in its own right.  You could delete all the rekenrek rods and use it to draw on the screen.  We plan to add the annotation tool to all of our future apps.  One of the next ones under development is a notebook tool which is simply the annotation tool together with some stock backgrounds simulating a plain sheet of paper, grid paper and isometric dot paper.

The app was developed using Flash CS 6 and its export to iOS and Android AIR functionality.  This allows us to develop once and deploy in three versions.

It really has been a thrill to open up the official mobile stores and see our app there, ready for free download.  Please have a look, tell others and perhaps even provide a review.  If your students do something interesting, we would be happy to hear about it and, with their permission, even post their work to our wiki.

Wednesday, January 8, 2014

Using a StyleSheet in Actionscript 2 to display an iTunes img Correctly

There are times when a simple request turns into a flight down the rabbit hole. mathies and mathclips share an XML file with information about learning tools available to Ontario students.  A link to Sketchpad Explorer on the App store needed to be added.  On the mathies webpage, this was easily done with html like:
       

Sketchpad Explorer is available from the 
<a href="http://itunes.apple.com/ca/app/sketchpad-explorer/id452811793?mt=8&amp;uo=4" target="itunes_store">
<img src="http://www.oame.on.ca/mathiesbeta/images/badge_appstore-sm.png" height="15px" width="61px" />
</a>
getting a result like:
where the image was unnecessarily copied from one created with http://linkmaker.itunes.apple.com to the local server.

In Flash, there were two issues:
  1. A phantom underline preceded the image as the result of a <u> tag surrounding the <a>...<img /> tags
  2. The topic list, a feature only of the mathclips tool tab,  appeared next to the image and not below it, despite <br /> tags.  This is due to Flash floating images.
The wrapping issue was solved using an idea from Panax and StyleSheets and the underline issue was solved by creating a blueNoUnderline class.

The StyleSheet is created in code as follows:
var myStyleSheet:TextField.StyleSheet = new TextField.StyleSheet();
myStyleSheet.setStyle("a", {color:'#0000FF', textDecoration:'underline'});
myStyleSheet.setStyle(".blueNoUnderline", {color:'#0000FF', textDecoration:'none'});
myStyleSheet.setStyle(".imageSpacer30", {fontSize:30});
The htmlText is massaged to wrap the <img /> tag inside a <p> tag (red text below).  The dummy paragraph suggested by Panax is added (green text below).  The blueNoUnderline class is added to the <a> tag to avoid a bit of underlined space (blue text below).
       
Sketchpad Explorer is available from the 
<a href='http://itunes.apple.com/ca/app/sketchpad-explorer/id452811793?mt=8&uo=4' target='itunes_store' class='blueNoUnderline'>
<p>
<img src='http://www.oame.on.ca/mathiesbeta/images/badge_appstore-sm.png' width='61px' height='15px' />
</p>
</a>
<p class='imageSpacer30'></p>
<br />
<p><font size=\"10\">(Geometry, Measurement, Simulations)</font></p>
The necessity to precede the "blueNoUnderline" name with period in the setStyle was a late discovery as I did not see it any of the examples I looked at.  For a while, I was convinced that StyleSheets read from .css files were the only ones that worked.

Friday, January 13, 2012

AS2 Farming out compile work to a swf

Thanks to Crystal's vivid imagination, the CLIPS team has created a Hops on Lines Tool that consists of 27 .as files averaging 25K or so.  When compiled, the .swf is about 700K.  When an activity uses the Hops Tool as well as other classes, the compile can be very slow or can max out available memory and fail.  We decided to farm out the job of compiling to another .swf and load it into any activities that require it.

Unfortunately, this means that the activity.swf cannot be run standalone.  Users will either have to be online, so that the Hops .swf can be found at mathclips.ca, or they will have to save the Hops .swf to a predictable location on their hard drive.



Originally, an instance of the Hops tool was created using a call to a static create method as described in a previous post.

     HopsOnLines.create(target, "instanceName", initObj);

To farm out this work and keep all the current code backwards compatible, we rename HopsOnLines to be OriginalHopsOnLines and make the new HopsOnLines.as contain:

class HopsOnLines extends MovieClip {

 public static function init(myCreatorReference:MovieClip){
  _root.theToolCreator = myCreatorReference;
 }

 public static function create(container:MovieClip, instanceName:String, initObj:Object, depth) {
  return _root.theToolCreator.create(container, instanceName, initObj, depth);
 }
}

In order to use this new version of the class, an initialization step must be performed to tell the class where the movieclip containing the compiled swf is.
The .fla used to create the .swf contains:

System.security.allowDomain("*");
import HopsOnLinesOld;
stop();

function create(target:MovieClip, toolName:String, initObject:Object, depth:Number){
 return HopsOnLinesOld.create(target, toolName, initObject, depth);
}

In this way, the .fla compiles the HopsOnLinesOld, with all its imported classes and exposes a create method that simply shuttles the job to the legacy creator.  This is one of the few times when the .fla is many times smaller than the compiled .swf.

In order to use this compiled swf. An activity must load it into a movieclip. When it is completed, call init to tell it where that movieclip is, and then any HopsOnLines.create statements will work without any modifications. Here is some sample code from an activity .fla:

import HopsOnLines.as;
System.security.allowDomain("*");

var testingLoader:MovieClipLoader = new MovieClipLoader();
var testingListener:Object = new Object();

testingListener._parent = this;
testingLoader.addListener(testingListener);

this.createEmptyMovieClip("testingContainer", this.getNextHighestDepth());
this.createEmptyMovieClip("testingLooper", this.getNextHighestDepth());

testingLoader.loadClip("http://www.myDomain.ca/HopsOnLinesCreator.swf", this.testingContainer);

testingListener.onLoadInit = function(which){
 trace("onLoadInit with "+which);
 this._parent.testingContainer.init(this._parent.testingContainer);
 this._parent.testingContainer.create(this._parent, "myHops_mc", {_x:50, _y:50});
 if (this._parent.myHops_mc == undefined){
  trace("onLoadInit has an error not picked up by onLoadError");
 }
}

There are a couple of things that I still wonder about. I get incompatible context errors related to security and sometimes they seem to make it not work. Also, if the file does not exist, onLoadInit seems to be called rather that onLoadError.  Also, I seemed to have the make the reference in the new .as file to _root - I had tried a static property and a _global but that did not work as well, I am not sure why.

Monday, October 24, 2011

Actionscript 2: Extending MovieClip class without using a Library Object

Thanks to Wouter Verweirder, we are creating all of our classes for the CLIPS project without requiring library objects.

The following is a short example of a class that creates a red square, the size and scale of which can be changed.  The size is changed either through the private property _side or the virtual public property, side.  The scale is changed by a public method, scale().

/**This class creates a square on the stage.
It is purely illustrative.  

*/

class edu.clips.test.ubSquare extends MovieClip {
 //used to register this class as though it was in the Library
 static var symbolName:String = "__Packages.edu.clips.test.ubSquare";
 static var symbolOwner:Function = ubSquare;
 static var symbolLinked = Object.registerClass(symbolName, symbolOwner);

 /**the length of each side, in pixels.  Default: 20 */
 private var _side:Number = 20;
 
 public static function create(container:MovieClip, instanceName:String,
         initObj:Object, depth:Number) {
  if (depth == undefined) depth = container.getNextHighestDepth();
  trace("attaching ubSquare using the manufactured symbolName");
  container.attachMovie(symbolName, instanceName, depth, initObj);
  trace("casting MovieClip as ubSquare");
  //this avoids compiler errors in other classes involving ubSquare
  return ubSquare(container[instanceName]);
 }

 function ubSquare() {
  trace("in ubSquare");
  this.constructor = ubSquare;
  this.constructor.name = "ubSquare";
  this.drawSquare();
 }
 public function onLoad():Void {
  trace("ubSquare loaded");
 }
 public function get side():Number{
  trace("in ubSquare get side");
  return this._side;
 }
 public function set side(newSide):Void{
  trace("in ubSquare set side");
  var numSide:Number = parseInt(newSide, 10);
  if (!isNaN(numSide)){
   this._side = newSide;
   this.drawSquare();
  }
 }
 public function scale(newScale:Number){
  //this will use set side
  this.side *= newScale;
 }

 private function drawSquare():Void {
  //this won't use the set and get functions, since _side is used
  trace("in drawSquare");
  this.clear();
  this.lineStyle(2, 0xFF0000, 100, true);
  this.moveTo(0, 0);
  this.lineTo(0, this._side);
  this.lineTo(this._side, this._side);
  this.lineTo(this._side, 0);
  this.lineTo(0, 0);
  trace("finished drawSquare");
 }
}

and here is the code in the first frame of a new actionscript 2 .fla that uses it.  Note that you have to save the class in a path ending with edu/clips/test/ubSquare.as and set your Actionscript preferences to be able to find it.

import edu.clips.test.ubSquare;

this.mySquare_ubS = ubSquare.create(this, "mySquare_mc", {_x:50, _y:75, _side:10});

trace("tester settting virtual property side");
this.mySquare_ubS.side = 40;

trace("tester calling public function scale");
this.mySquare_ubS.scale(3);

trace("the side ends up being: ");
trace(this.mySquare_ubS.side);

Here is the output:

attaching ubSquare using the manufactured symbolName
in ubSquare
in drawSquare
finished drawSquare
casting MovieClip as ubSquare
tester settting virtual property side
in ubSquare set side
in drawSquare
finished drawSquare
in ubSquare get side
tester calling public function scale
in ubSquare get side
in ubSquare set side
in drawSquare
finished drawSquare
in ubSquare get side
the side ends up being: 
in ubSquare get side
120
ubSquare loaded

In most of our stuff, we don't use setters and getters at all. We initialize the properties by passing them in the third parameter of create, as I did to initially set the side to 10 px  (see Paul's post).  We change properties using a setProp method that would look something like:

public function setProp(prop:String, val, doDraw:Boolean):Void {
 if (doDraw == undefined) doDraw = true;
 this[prop] = val;
 if (doDraw) this.drawSquare();
}

Senocular's FAQs were also very useful when we were trying to figure out how to extend the MovieClip class.

Monday, September 19, 2011

Flash reverts MovieClips to Original Negative Depth when moving to a Previous Frame

I have been working with Flash for over six years and there are still things that surprise me about Actionscript 2 - surprise but not delight!  This week, I was trying to create a new layer in between two existing ones on the stage, using code only.  I figured that I could create a new MovieClip and swapDepths to put it in the correct location.  Everything worked great except that my created MovieClip would disappear as I navigated to a previous frame.

It bothered me so much, that I created a very simple tester of the problem.  It has an actions layer and one layer with a thick red line drawn on it.  It has a text box that reports which of the four frames you are on.  It has a green button which goes to the next frame and a red button which goes to the previous frame.

On the first frame, I create an empty MovieClip with code, swap its depth with the stage MovieClip and draw a blue line on it.  Everything looks great as you go from Frame 1 to 2 to 3 to 4, but go back from Frame 3 to Frame 2 or from Frame 4 to Frame 3 and the blue line disappears.  If you trace the depth of the stage MovieClip, you see that Flash re-establishes it at its original depth when you navigate to the previous frame. Since your code-created MovieClip is at that depth, it gets wiped out. At least this is my current explanation.

Maybe you have a better theory and want to download the .fla to check it out.  Regardless, I currently think that there is no good way to simulate a timeline layer with code.

The code is:

stop();
trace("library_mc starts at depth: "+this.library_mc.getDepth());
this.library_mc.lineStyle(3,0xFF0000,100);
this.library_mc.moveTo(50,100);
this.library_mc.lineTo(200,150);
if (counter == undefined) counter = 0;
counter++;
trace("creating code_mc for the time: "+counter);
this.createEmptyMovieClip("code_mc", this.getNextHighestDepth());

this.code_mc.swapDepths(this.library_mc);

this.code_mc.lineStyle(1,0x0000FF,80);
this.code_mc.moveTo(200,50);
this.code_mc.lineTo(50, 150);

green_btn.onRelease = function(){
	this._parent.nextFrame();
}

red_btn.onRelease = function(){
	this._parent.prevFrame();
}
frame_txt.text = "I am on frame 1";
this.onEnterFrame = function(){
	frame_txt.text = "I am on frame " + _currentFrame;
	trace("library_mc depth "+this.library_mc.getDepth());
}

Friday, October 29, 2010

Why can't my new Dell compile Flash CS4 files faster?



All the serious geeks at Adobe must use Macs.

I have a new Dell Studio XPS 1645 with 8GB of RAM, an i7 Q820 processor @ 1.73GHz, and Windows 7 Ultimate 64 bit OS (giving it a 5.9 Windows Experience score). It takes 39 seconds for this beast to compile one of our CLIPS activities. My confreres running Macs get it done in about 15 seconds. Today, I tried compiling the same .fla on a 4.5 year old MacBook (not a Pro) and it took 18 seconds. Then I tried my 3.5 year old Dell running Windows XP and it took 28 seconds.

Why doesn't an upgrade feel like one?

I have looked around the web for ideas about how to get Flash to compile an .fla faster but haven't found anything helpful. Maybe I should use the XP virtualization that came with the Windows 7 machine or use DropBox to distribute my computing power.

Does anyone have any similar experiences and especially any that will speed up the process?

Sluggish and Lonely in PC land,

Mathfester

Tuesday, September 2, 2008

How does Flash Pass Control as it gotoAndPlays frames?

One of the pleasures of working on CLIPS is the chance to work with some top-notch Ontario educators, like Greg Rodrigo of Georgian College. As part of this summer's work, we we trying to figure out how actionscript is executed as control is passed to different frames and the onEnterFrame method is called. Greg created a little test file similar to the following:

Create seven keyframes and put the following code in each frame:
  1. onEnterFrame = function() {
    trace("I am on frame " + _currentframe);
    }
    trace("Frame 1");

  2. gotoAndPlay(4);
    gotoAndPlay(3);
    trace("Frame 2");

  3. trace("Frame 3");
    gotoAndPlay(5);

  4. trace("Frame 4");
    gotoAndPlay(1);

  5. trace("Frame 5");

  6. trace("Frame 6");
    delete onEnterFrame;

  7. stop();
    trace("Frame 7");
So here is what the teacher would ask you to do:
Determine what Flash's output window will contain when this file is tested.
We learned a lot about how Flash operates by trying to make this prediction.

STOP: Try it yourself now.






If that question is too hard or open-ended, here are some other questions that might be simpler:
  1. What will the output be the first time the onEnterFrame method is executed?
  2. Will the first output "Frame 2" occur before or after the first output "Frame 4"?
  3. Why does "I am on frame 5" not appear in the output window? (I am not sure what the answer to this question is, so perhaps it is not simpler.)
Please feel free to leave a comment about the last question.

If you don't feel like typing this in yourself, I have posted the .fla source file.

Friday, December 14, 2007

Monday, November 12, 2007

Flash Graphing Tools

As part of the CLIPs project, we have been developing learning objects in Flash to support work in the Grade 11 Functions courses. Fortuitously, we came across a set of robust tools created by Doug Ensley, Shippensburg University and Barbara Kaskosz , University of Rhode Island, funded in part by the National Science Foundation, which include fantastic documentation. We have learned a lot about programming in Flash by using the tools.

There has been some functionality that we wanted to add, including labeling of axes and adding control points to graphs that necessitated creating our own version of the classes. Examples of our work and the original examples are available here.