I have been in on or called in on Flash and Flex applications that perform slowly.
When there is a back end, I recommend an isolation process to eliminate the move from the equation. This includes all data and dynamically loaded assets and movies.
When the backend is out of the way then the focus is on memory. This requires providing calls to memory information as the application is navigated. I provided basic shell code that works below you can consider for integration into a memory monitoring module for your application.
In designing Flash player movies whether you are using Flex or Flash should always side on caution in creating objects and loading assets. Its garbage collector works when it thinks it is ready. As well you need to care for the removal of event listeners when you remove objects.
The System class contains a property totalMemory. Here is an example so you can learn about it.
MemoryMonitor.as
package {
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.system.System;
public class MemoryMonitor
{
private var timer1:Timer = new Timer(1000, 0);
private var timer2:Timer = new Timer(1000, 0);
private var totalMemory:int;
private var totalMemory_last:int = 0;
public function MemoryMonitor():void
{
trace("MemoryMonitor()");
timer1.addEventListener(TimerEvent.TIMER, _displayTotalMemory);
timer2.addEventListener(TimerEvent.TIMER, _displayTotalMemoryOnChange);
}
public function displayTotalMemory():void
{
timer1.start();
}
public function displayTotalMemoryOnChange():void
{
timer2.start();
}
private function _displayTotalMemory(event:TimerEvent):void
{
trace("MemoryMonitor.displayTotalMemory() - System.totalMemory:\t\t" + totalAsMB(System.totalMemory) );
}
private function _displayTotalMemoryOnChange(event:TimerEvent):void
{
totalMemory = System.totalMemory;
if (totalMemory != totalMemory_last)
{
trace("MemoryMonitor.displayTotalMemoryOnChange() - totalMemory_last:\t" + totalAsMB(totalMemory_last) );
trace("MemoryMonitor.displayTotalMemoryOnChange() - System.totalMemory:" + totalAsMB(totalMemory) );
}
totalMemory_last = totalMemory;
}
private function totalAsMB(totalMemory:int):String
{
return (Math.round (((totalMemory / 1024)/1024) * 10)) / 10 + " MB"
}
}
}
Flash Movie frame 1 Actionscript
import MemoryMonitor;
var memoryMonitor:MemoryMonitor = new MemoryMonitor();
// Display memory every 1 second
memoryMonitor.displayTotalMemory();
// Display memory every 1 second if it changes
memoryMonitor.displayTotalMemoryOnChange();
Publishing under Flash CS4 will provide the latest HTML wrapper with a boat load of Javascript. At one time a separate Javascript file was generated from the Flash IDE publishing. Now it is all in the HTML document.
The overall process is the same as it has been since first introduced. You need to publish the HTML one time and then turn it off as you need to edit the HTML document for your FlashVars. Dicing in the FlashVars for the new HTML wrapper appears as follows for the FlashVars variables message1 and name:
I have seen this error when trying to use SWFLoader and LocalConnection with a Flash SWF. The problem is related to using the LocalConnection but the Flash SWF has not played the requisite frame where its side of LocalConnection code appears. As such there is no local connection.
The more RIA shops move web apps into Flex the ugly issue of integration of legacy Flash SWFs into Flex may show up.
The likely Flex component to use for loading Flash SWFs is SWFLoader. It can handle Actionscript 2 legacy Flash 8 or CS3 SWFs.
You may also use SWFLoader for cases of separate independent Flash SWFs that also need to be used into a Flex app and you may not have control over the SWF internal development requiring preparedness for just about anything.
For example you get SWFs with independent inputs from places such as FlashVars, external XML or even another SWF container. Perhaps there are internal functions in place handling these tasks.
However you find that code you need to call from Flex is not available on frame 1. You may find SWFLoader cannot call those functions due to timing inside the Flash SWF and you do not want to recode the SWF.
Then you might find using LocalConnection as a solution. You have the SWF invoke functions in the Flex SWFLoader component to inform ready states such as code available on a certain frame. Then the Flex function can use LocalConnection to call the SWF function.
Here is an example where the requisite code was on frame 10 of the FLA file.
[cc lang=”actionscript” tab_size=”3″ line_numbers = “true”]
System.security.allowDomain(“*”);
var _fromFlex_lc:LocalConnection = new LocalConnection();
_fromFlex_lc.allowDomain(“*”);
This example is remake of Lee Brimelow’s example. I removed the tweener library and used the Flash Tween class.I also took the Actionscript code out of the Fla and created an Actionscript class to give a start for creating a component version.
Developed an eLearning language for generation of Flash movies from client server internet applications. The language can produce learning screens with a variety of assets along with interactive quizzing of students with choices and drag/drop actions.
Design constraints resulted in a low bandwidth (56K) dynamic Flash Movie generator with modular media element component extensibility.
Phase II:
Provided a screen integration team to convert the 4000 screens customer had in their Authorware product to the new screen language.
Phase III:
Added template based gui wizard to generate eLearning language. Designed for less technical educators to develope educational lesson without having to know the eLearning language.
Software allows client technicians to develop and unlimited number of screen templates that control one or more gui dialog windows.
The gui controls are further customizable to limit or expand userĀ“s choices.
Software involved developing a low bandwidth object oriented gui library (windows, buttons, combo boxes, scrollers) with a base movie footprint under 40K.
The gui dialogs were designed using a external dynamic loading component based design. This allows for development an unlimited variety of gui dialogs without increasing the size of the base movie.
After a summer working long hours on micro sites for clients of the advertising agency Digitas in NYC followed by a super car and hiking trip through the US Midwest (videos) for a few weeks and some “retirement” time off, I am back in the tech seat. So I saw this a while ago, but I reluctant to get glued into my PC for too much during my break.
At MAX 2007 Chicago video cameras were rolling to show Adobe’s new direction with Flash/Flex/AIR development. It is code named Astro. What we see now Flash 10 and Astro are the same.
One impressive item was the attempt to allow designers create local test data that normally would server from the internet. This will extend designers further into the development and design cycle without the need to code.
3D is starting to show up in the Flash Player. Right now it is called 3D effects. Not sure how limiting that term is but there is an indication of an API for 3D.
More image processing functionality under the name Hydra that allows custom image filters and effects. Sounds like fun for the showy needs.
In chapter 5 of Keith Peter’s Foundation Actionscript 3.0 Animation: Making Things Move velocity at an angle is explained. I took Keith’s mouse following example demonstrating velocity at an angle and punched it up a small notch.
Download files
[August 10 2010 – I updated this to an Actionscript project in Flex Builder 4. ]
You can build this with the free Flex SDK by using the code in the src folder. Same for Flash CS3 and later versions. You need to create a Flash Document in the src folder and set the document class to Chapter05_FollowMouse. For your convenience the Flash CS4 example download is included.
This article shows the code for the Flex project. This Flex version is a spark implementation.
The arrow will follow the mouse around the stage. It will stop following when requested and start again with a mouse click on the stage. It also waits patiently when the mouse leaves the stage. The arrow gets real frustrated when you put the mouse over it. It always points towards the mouse when the mouse is over the stage.
Application Class – Chapter04_SprayPaint
I added user mouse click interaction to control the start and stop movement of the _arrow sprite. See line 40 and lines 48 to 51.
The movement also stops and starts when the mouse enters and leaves the stage. To accomplish that the stage needed to register a Event.MOUSE_LEAVE event to detect the mouse leaving the stage. The stage object is available when the applicationComplete(...) event occurs. The MouseEvent.MOUSE_MOVE sufficed to detect the mouse back over the stage. The _mouseOverStage variable carries the state of the mouse over the stage.
The rotation of the _arrow sprite is continuous. Gives it a mouse awareness state.
<?xml version="1.0" encoding="utf-8"?>
<!--
Application class to demonstrate animation trigonometry to show velocity at an angle.
Mouse position determines the angle.
<p>Author: Lon Hosford https://www.lonhosford.com 908 996 3773</p>
<p>Reference: Keith Peter's Actionscript 3.0 Animation Chapter 5</p>
-->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="400"
applicationComplete="applicationCompleteHandler(event)"
viewSourceURL="srcview/index.html">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
public static const backgroundColor:Number = 0x0000ff;
public static const backgroundBorderColor:Number = 0x666666;
public static const backgroundBorderWeight:Number = 2;
private var _instructions_tf:TextField; // Instructions for user
[Bindable]
private var _lang_instructions:String = "Click to start and stop. Move mouse for animation."
private var _arrow:Arrow; // Animated sprite is an Arrow
private var _speed:Number = 5; // Movement speed
private var _allowMoving:Boolean = false; // Use allowing moving state
private var _mouseOverStage:Boolean = true; // Mouse on the stage state
/**
* Handler for Application applicationComplete event
* */
protected function applicationCompleteHandler(event:FlexEvent):void
{
// Create Arrow object and add to stage. This is animated.
_arrow = new Arrow();
arrowVisualElement.addChild(_arrow);
_arrow.x = (width - _arrow.width ) / 2;
_arrow.y = (height - _arrow.height ) / 2;
stage.addEventListener(MouseEvent.CLICK, mouseClickEventHandler);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveEventHandler);
}
/**
* MouseEvent.CLICK handler
* */
private function mouseClickEventHandler(event:MouseEvent):void
{
_allowMoving = !_allowMoving;
}
/**
* MouseEvent.MOUSE_MOVE handler
* */
private function mouseMoveEventHandler(event:MouseEvent):void
{
_mouseOverStage = true;
}
/**
* Event.MOUSE_LEAVE handler
* */
private function mouseLeaveEventHandler(event:Event):void
{
_mouseOverStage = false;
}
/**
* Event.ENTER_FRAME handler
* */
private function enterFrameEventHandler(event:Event):void
{
draw();
}
[ad name=”Google Adsense”]
The draw() method on line 77 updates the animation. The dx and dy variables are the distance from the mouse to the registration point of the _arrow sprite. Radians for the angle are computed using the Math.atan2(...) method. The angle in radians is converted for Actionscript rotation property to degrees. These trigonometry formulas are covered in Keith’s book .
The state the user choose to have the mouse follow is tested and if true the moveTo() method on line 98 computes the velocity at an angle discussed in chapter 5.
The _arrow sprite is designed with a center registration point to facilitate the rotation. As a result the _arrow sprite will move until the mouse coordinates reach the registration point. I added the hitTestPoint(...) method on line 105 to adjust so that the movement stops at the edge of the pixels in the _arrow sprite. The result the _arrow sprite’s point comes very close to the mouse versus the center of the _arrow sprite.
/**
* Draw
* */
private function draw():void
{
// Distance of arrow registration point from mouse
var dx:Number = mouseX - _arrow.x ;
var dy:Number = mouseY - _arrow.y ;
// Get angle in radians
var angle:Number = Math.atan2(dy, dx);
// Rotate converting radians to degrees
_arrow.rotation = angle * 180 / Math.PI;
// Is in a mouse following state
if (_allowMoving)
{
// Move based on angle
moveTo(angle);
}
}
/**
* Move arrow
* */
private function moveTo(angle:Number):void
{
// Velocity based on angle
var vx:Number = Math.cos(angle) * _speed;
var vy:Number = Math.sin(angle) * _speed;
// Mouse position overlaps shape and mouse is over a pixel in the object
if (!_arrow.hitTestPoint(mouseX, mouseY, true) && _mouseOverStage)
{
// Add velocity to position
_arrow.x += vx ;
_arrow.y += vy ;
}
}
/**
* Set any stage options per your needs
* */
private function initStage():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
}
/**
* Instructions for user
* */
private function getInstructions_tf():TextField
{
var tf:TextField = new TextField();
tf.autoSize = TextFieldAutoSize.LEFT;
tf.background = true;
var textFormat:TextFormat = new TextFormat();
textFormat.font = "_typewriter";
tf.defaultTextFormat = textFormat;
tf.text = _lang_instructions;
return tf;
}
]]>
</fx:Script>
[ad name=”Google Adsense”]
This part of the application represents the Flex UI based in Spark components.