Whilst loading and unloading stage event listeners, I had problems with the following listener:
This was used in a movieclip that was loaded within a parent movieclip, after the loaded movieclip was discarded threw up null pointer error as the listener was still present on the main stage. The key here is to ensure the event listener has a weak reference:
stage.addEventListener(MouseEvent.MOUSE_UP, stopScroll);
This way it is discarded with the movieclip that instantiated it!
stage.addEventListener(MouseEvent.MOUSE_UP, stopScroll, false, 0, true);
Rather than push loads of code through at the same time, it can be advantageous to delay execution of certain blocks of code:
This is useful to remember as a swf may have a lot to do upon initial load (drawing graphics on screen, preparing data structures etc.) So to delay an animation or resource intensive task may be a smart thing to do.
import flash.utils.*;
var delayStart = setInterval(startCode,3000);
function startCode():void {
// insert delayed code here
// stop setInterval repeating
clearInterval(delayStart);
}
I was working on a large project that incorporated the Strobe Media player (SMP), but for some strange reason my buttons lost their hand cursor once the user interacted with the SMP.
I couldn't figure this out for a long time until I noticed that they were setting the hand cursor on the UI like so:
private function theMouseOut(e:MouseEvent):void {
Mouse.cursor = flash.ui.MouseCursor.ARROW;
}
private function theMouseOver(e:MouseEvent):void {
Mouse.cursor = flash.ui.MouseCursor.BUTTON;
} Working on an old-school project that had an annoying flicker when switching between video's, here is a sample of the code:
function setVideoSequence(url1in:String, url2in:String):void {
movFLV.flvPlayback.activeVideoPlayerIndex = 0;
movFLV.flvPlayback.source = url2in;
movFLV.flvPlayback.activeVideoPlayerIndex = 1;
movFLV.flvPlayback.source = url1in;
movFLV.flvPlayback.visibleVideoPlayerIndex = 1;
movFLV.flvPlayback.play();
url2 = url2in;
movFLV.flvPlayback.addEventListener(fl.video.VideoEvent.COMPLETE, loadNextVideo);
}
function loadNextVideo(e:fl.video.VideoEvent):void {
movFLV.flvPlayback.activeVideoPlayerIndex = 0;
movFLV.flvPlayback.visibleVideoPlayerIndex = 0;
movFLV.flvPlayback.play();
}
Lovely function to randomise the order of elements within an array:
private function randomSort(a:*, b:*):Number {
if (Math.random() else return 1;
}
clipRef.push(movItem1);
clipRef.push(movItem2);
clipRef.push(movItem3);
clipRef.push(movItem4);
clipRef.push(movItem5);
clipRef.push(movItem6);
clipRef.push(movItem7);
clipRef.push(movItem8);
clipRef.sort(randomSort);
Right click menu's are often overlooked and provide a nice touch to any project. Here is a code routine that I've used for many past projects, it should hopefully give you an idea on how to set up a right click menu. for a quick hit use the vars at the top and the last block. The for/switch loops through some items loaded via XML, its code from a live project so perhaps a little verbose.
// context menu
private var nextMenu:ContextMenu;
private var cxLabel:String;
private var cxTarget:String;
private var menuItem:ContextMenuItem;
private function setupContextMenu():void {
nextMenu = new ContextMenu();
nextMenu.hideBuiltInItems();
for(var i:int = 1; i cxLabel = xmlSource.LoaderMax["Item"+i]. @ menuLabel;
menuItem = new ContextMenuItem(cxLabel);
switch (i){
case 1:
menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:Event):void { navigateToURL(new URLRequest(links["1-link"]), "_self"); }, false, 0, false);
break;
case 2:
menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:Event):void { navigateToURL(new URLRequest(links["2-link"]), "_self"); }, false, 0, false);
break;
case 3:
menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:Event):void { navigateToURL(new URLRequest(links["3-link"]), "_self"); }, false, 0, false);
break;
case 4:
menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:Event):void { navigateToURL(new URLRequest(links["4-link"]), "_self"); }, false, 0, false);
break;
case 5:
menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:Event):void { navigateToURL(new URLRequest(links["5-link"]), "_self"); }, false, 0, false);
break;
case 6:
menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:Event):void { navigateToURL(new URLRequest(links["6-link"]), "_self"); }, false, 0, false);
break;
}
nextMenu.customItems.push(menuItem);
}
var menuItemNext:ContextMenuItem = new ContextMenuItem("© 2012 your brand.");
menuItemNext.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, function(e:Event):void {
navigateToURL(new URLRequest("http://www.noursite.co.uk/"), "_self"); } );
menuItemNext.separatorBefore = true;
nextMenu.customItems.push(menuItemNext);
this.contextMenu = nextMenu;
}
If you have a scrolling project, depending on the specifics of the project consider using either:
- Blitting (CPU rendering mode on iOS)
- Scroll Rect (GPU rendering mode on iOS)
Details about with() statement.
The advantages of using a Dictionary object.
for each(var item:Object in movieReference)
{
TweenMax.to(item.movInfoPanel, 0.7, {autoAlpha:0, ease:Quint.easeInOut});
}
Antonio Holguin kindly replied to a tweet regarding in-app monetisation, so I'd thought to pass on his info:
http://pixelpaton.com/?p=3313
http://xavivives.com/how-to-insert-and-properly-display-admob-on-air-for-android
http://blogs.adobe.com/flashplatform/2011/05/displaying-ads-in-your-mobile-air-application.html
http://help.adobe.com/en_US/as3/dev/WS901d38e593cd1bac3ef1d28412ac57b094b-8000.html#WS901d38e593cd1bac-7b2e067c12e72dd6960-8000
In-app purchase is supported on the Blackberry Playbook:
http://renaun.com/blog/2011/01/using-blackberry-paymentservice-with-ad obe-air-for-the-playbook/
edit: Links updated!
Apple Push Notification Service native extension for Adobe AIR
http://www.liquid-photo.com/2011/10/28/native-extension-for-adobe-air-and-ios-101/
Adding push notification for Android is well covered here:
http://www.riaspace.com/2011/09/as3c2dm-air-native-extension-to-push-notifications-with-c2dm/
An amazing article from James Ward to add push notification to Android.
http://www.jamesward.com/2011/05/11/extending-air-for-android/
Here’s a code snippet that references the versionNumber and renderMode:
var appDescriptor:XML = NativeApplication.nativeApplication.applicationDescriptor;
var ns:Namespace = appDescriptor.namespace();
trace( "versionNumber: " + appDescriptor.ns::versionNumber );
trace( "renderMode: " + appDescriptor.ns::initialWindow.ns::renderMode );
Off topic: but I love this series and want to share the links with you:
Since the late 1990′s, Alain de Botton has been breaking down difficult philosophical and literary ideas and seeing how they apply to people’s everyday lives.
He breaks analyses his favourite philosophers and how their teachings can help us in a practical, everyday way.
01 Socrates on self confidence
02 Epicurus on happiness
03 Seneca on anger
04 Montaigne on self esteem
05 Schopenhauer on love
06 Nietzche on hardship
For great iOS performance especially with Air 2.7 try:
Try and use bitmaps as opposed to Vectors.
Rendering: GPU
cache as bitmap on MovieClips.
If you want to use that for a bunch of MovieClip instances, apply the export setting the the nested content, instead of multiple instances. This will cut down on runtime memory usage, since the flash runtime can reuse the same 1 bitmap texture.
TO change the flash player version (provided you have an alternative installed) input:
about:plugins
Using 3rd party filters is expensive for size and CPU cycles.
To create a burn effect use a white solid over the target image, use the 'ADD' blend mode, and reduce opacity to create the effect.
NOTE: blend modes are expensive on CPU also, use sparingly!
(32kb)
source
given the XML fragment
a great way to extract the links is to use the for each loop:
for each (var link:XML in xmlSource.LoaderMax.LinksSet1..Link) {
trace(link.@link);
}
All programming is a matter of style. Many people prefer a shorthand if..else format, which works by condensing the statement into one line. (perhaps at the expense of readability?)
Take a conventional if statement like the following:
if(catLegs >= 4){
trace("cat can run!");
}else{
trace("cat has missing legs..");
}
(condition) ? ifTrueDoThis : ifFalseDoThis;
(catLegs >= 4) ? trace("cat can run!") : trace("cat has missing legs..");
During a recent project I've had to create a set of swf that all run off of a central XML file, this involves:
i) identifying yourself (through flashvars)
ii) the loaction of the central xml files (through flashvars)
iii) extract the snippet relating to your own id then pass into LoaderMax
iv) manipulate the loaded objects within the swf
Use getQualifiedClassName() it returns a few strings, for a movieclip its "flash.display::MovieClip"
if(getQualifiedClassName(getChildByName("level"+i))=="flash.display::MovieClip"){
Given the XML:
trace(xmlSource.LoaderMax.layer.(attribute("type") == "button"));
trace(xmlSource.LoaderMax.layer.(attribute("type") == "button").Button.@name);to drill down
var rssRequest:URLRequest = new URLRequest("Flipz3D.swf");
var loader:Loader = new Loader()
loader.load(rssRequest);
addChild(loader);
loader.x = 750;
[Embed(source="tahoma.ttf",
fontFamily='tahoma',
mimeType="application/x-font",
embedAsCFF="false")]
private var TahomaEmbeddedFont:Class;
forMessage = new TextFormat();
forMessage.font = "Tahoma";
forMessage.color = 0xFFFFFF;
forMessage.size = 80;
// text field
txtMessage = new TextField();
txtMessage.width = 1390;
txtMessage.multiline = true;
txtMessage.defaultTextFormat = forMessage;
txtMessage.autoSize = TextFieldAutoSize.LEFT;
txtMessage.wordWrap = true;
txtMessage.border = false;
txtMessage.embedFonts = true;
txtMessage.sharpness = 400;
txtMessage.selectable = false;
sprMessage.addChild(txtMessage);
txtMessage.x = 0;
txtMessage.y = 0;
sprMessage.alpha = 0;
As always some fundamental code posted for reference:
mask_mc.cacheAsBitmap=true;
maskee_mc.cacheAsBitmap=true;
mask_mc.mask = maskee_mc;