Posts Tagged ‘AS3’

Oldschool dissolve function

Posted in Flash on April 26th, 2010 by Thomas H – Be the first to comment

While doing a recent project I wanted to create a fade effect that worked well with the 8bit style design of the application. I wanted to use the dissolve effect, and lo and behold, flash has that function built in to the BitmapData class ( pixelDissolve ). Only problem was that the dissolve is on a pixel to pixel basis, so it did not look really authentic to a 8bit based graphics. All that was needed to do was to mimic the pixelDissolve function but apply them to squares of pixels.

read more »

Keep your flags in order.

Posted in Flash on April 21st, 2010 by hp. – 2 Comments

use a go style iota operator:

package rendering {
	public class RenderFlags {
 
		private static var _i:uint;
		private static function get iota():uint { return _i++; }
 
		public static const GENERIC:uint		= 0x1<<iota;
		public static const DIMENSIONS:uint 		= 0x1<<iota;
		public static const POSITION:uint 		= 0x1<<iota;
		public static const SCALE:uint 			= 0x1<<iota;
		public static const CHILDREN:uint 		= 0x1<<iota;
 
 
		public static const BOUNDS:uint = DIMENSIONS | POSITION;
		public static const ALL:uint = ~ 0x0;		
 
	}
}

Flash9 Popup-blocker developments.

Posted in Flash on January 12th, 2010 by hp. – Be the first to comment

For an introduction on the issue, check the old post Flash 9 for banner-ads (in norwegian).

Download the source files.

Most recent browsers support both navigateToURL and ExternalInterface. However, successful calls to the js-function do not return “YES” nor “NO” but null, causing the navigateToURL method to be called as well.

function openWindowAutoHandler(event:Event):void {
  if (externalInterfaceAvailable) {
    var openEIresult:String = ExternalInterface.call('function() {return (window.open("' + (clickTAG) + '", "_blank", "") ? "YES" : "NO") }');	
  }      
  if ((!externalInterfaceAvailable) || (openEIresult != "YES") || (userAgentString.indexOf("Opera") != -1)) {
    navigateToURL(new URLRequest(clickTAG), "_blank");		
  }
}

openEIresult in Internet Explorer 7.0: null (Loads the URL twice)
openEIresult in Internet Explorer 8.0: null (Loads the URL twice)
openEIresult in Firefox 3.5.6: “YES” (Works as intended)
openEIresult in Opera 10.10: “YES” (Loads the URL twice, caused by third test)

Anyone think of a clever fix to the dual dual loads issue, while still retaining compatibility with older browsers?

Make a regular N-gon, or two.

Posted in Flash on December 7th, 2009 by hp. – 2 Comments
package views.shapes {
import flash.events.Event;
import flash.display.Shape;
 
public class Ngon extends Shape {
 
	protected function redraw():void {			
		var r:Number = radius;
		var a:Number = angle;							
		var s:Number = Math.PI*2/sides;
		graphics.clear();
		graphics.beginFill(color,1);
		for (var i:uint = 0; i<=sides; ++i) {
			graphics.lineTo(r*Math.cos(a+s*i),r*Math.sin(a+s*i));
		}			
	}
 
	private var _sides:uint = 3;
	public function get sides():uint { return _sides; }
	public function set sides(value:uint):void {
		if (value !== _sides) { 
			_sides = value;
			redraw();
		}
	}	
 
	private var _color:uint = 0x0;
	public function get color():uint { return _color; }
	public function set color(value:uint):void {
		if (value !== _color) { 
			_color = value; 
			redraw()
		}
	}
 
	private var _radius:Number;
	public function get radius():Number { return _radius; }
	public function set radius(value:Number):void {
		if (value !== _radius) { 
			_radius = value;
			redraw();
		}
	}
 
	private var _angle:Number;
	public function get angle():Number { return _angle; }
	public function set angle(value:Number):void {
		if (value !== _angle) { 
			_angle = value; 
			redraw();
		}
	}
 
}
}

Copying or cloning arrays

Posted in Flash on November 20th, 2009 by Thomas H – 1 Comment

Obviously, this is something you already know, but if like me, you didn’t know what happens when you copy arrays this might help.

var a:Array = [new Object(), new Object(), new Object()];
var b:Array;
 
//Create a new reference to the array
b = a;
 
//Create a new array but have the same reference to its objects ( shallow copy )
b = a.slice();
b = a.concat(); //faster
 
//A way to actually clone an array and get new instance of the array and new instances of its objects
function clone(source:Object):* // function for deep copy
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
b = clone(a);

Don’t know if this is necessary needed for arrays containing numbers or string values, but for arrays with objects it is.

Read more here

Automatically embedding a Subversion revision number

Posted in Flash on November 20th, 2009 by Simen – 1 Comment

One of the biggest annoyances when trying to test a Flash application is when you don’t know what version your user is currently looking at, this might be due to caching issues and what not.

The obvious solution is making sure your user can see the version number of your application at run-time and include that with a bug report or similar. I’ll be covering two different techniques to accomplish this.

Using conditional compilation

Our initial and current approach is using svnversion and compiler.define via Ant to include the version number as a constant.

<target name="Build">
	<exec executable="/usr/bin/svnversion" outputproperty="svn.revision">
		<arg value="."/>
	</exec>
 
	<mxmlc file="SomeApp.as" output="bin/MyApp-release.swf" debug="false">
		<source-path path-element="src"/>
 
		<define name="CONFIG::version" value="${svn.version}" />
	</mxmlc>
</target>

This approach works just fine but you’re somewhat tied to using Ant to build you projects.

Embedding your entries file

After using svnversion for a while I thought there has to be a way to embed the version number using any compilation method, which lead me to the [Embed] meta-tag of AS3. This allows you to embed any file when specifying a mimeType of application/octet-stream.

You could for example embed a PSD file and read something from it at run-time.

[Embed(source="SomeFile.psd", mimeType="application/octet-stream")]
var SomeFileByteArray:Class;
var bytes:ByteArray = (new SomeFileByteArray()) as ByteArray;
 
trace(bytes.readUTFBytes(50)); // Read the first 50 bytes

And after tinkering around in the secretive .svn directory I came up with the SVNUtil class.

package {
	import flash.utils.ByteArray;
 
	public class SVNUtil {
		private static const VERSION_PATTERN:RegExp = /dir\xa(\d+)\xa/;
 
		[Embed(source="../.svn/entries", mimeType="application/octet-stream")]
		private static var _entriesByteArray:Class;
 
		public static function get version():String {
			var entries:String = readEntries(20);
			var matches:Array = entries.match(VERSION_PATTERN);
 
			if (matches) {
				return matches[1];
			}
 
			return null;
		}
 
		private static function readEntries(length:uint):String {
			return (new _entriesByteArray() as ByteArray).readUTFBytes(length);
		}
	}
}

To use it, simply refer to it somewhere in your application.

public class MyApplication extends Sprite {
	public static const VERSION:String = SVNUtil.version;
 
	public function MyApplication() {
		trace("Application version:", VERSION);
 
		// Or you can call it directly
		trace("Application version", SVNUtil.version);
	}
}

As a final note this is experimental hacking, but it’s done at compile time so you won’t have to deal with run-time errors, I’m planning on posting up a similar class for Git when time allows.

So.. Flash on the iPhone?

Posted in Flash on October 6th, 2009 by Thomas H – Be the first to comment

Yes, so it seems. Flash Professional CS5 will enable you to build applications for iPhone and iPod touch using ActionScript 3. These applications can be delivered to iPhone and iPod touch users through the Apple App Store.

And according to the guy in the video its supposed to be as fast as your other applications as well. iPhone applications built with Flash Platform tools are compiled into standard, native iPhone executables, just like any other iPhone application.

How it all works

We enabled this by using the Low Level Virtual Machine (LLVM) compiler infrastructure. LLVM is a modular, flexible compiler system that is used widely in a variety of projects. The key reason we choose LLVM is its flexibility and applicability to iPhone development.

We created a new compiler front end that allowed LLVM to understand ActionScript 3 and used its existing ARM back end to output native ARM assembly code. We call this Ahead of Time (AOT) compilation—in contrast to the way Adobe Flash Player and Adobe AIR function on the desktop using Just in Time (JIT) compilation. Since we are able to compile ActionScript to ARM ahead of time, the application gets all the performance benefits that the JIT would offer and the license compliance of not requiring a runtime in the final application.

By doing the compilation step, we allow developers to create applications using their Flash skills and their knowledge of ActionScript 3. In the process, we also expose the APIs that developers are familiar with so they can not only use the ActionScript language but follow the customary app-building model. When you build your application for the iPhone, there is no interpreted code and no runtime in your final binary. Your application is truly a native iPhone app.

http://labs.adobe.com/technologies/flashcs5/appsfor_iphone/#resources
http://www.youtube.com/watch?v=kusXgPAmMLw
http://www.adobe.com/devnet/logged_in/abansod_iphone.html

So now lets go and build an app for that!

Focus on key listeners

Posted in Flash on August 31st, 2009 by Knut – Be the first to comment

Being a master at getting odd bugs that nobody else gets I just discovered a little issue with adding and removing KeyboardEvents to an application.

My app has a series of forms arranged in steps. The design of one of the forms required keyboard input to be useful. Every form section is added to stage, showed, verified submitted, hidden and then removed from stage before the next one is displayed.

Two steps into this sequence I required key input and could not get it to work without clicking somewhere first. I first thought it was the old focus security fix that was playing up but since I had already clicked a button to show the form I knew the app had focus.

I found that the stage.focus property was set to the last button clicked. This button was the “next” button in the previous form. Since this button no longer was on stage its button events obviously could not bubble to stage.  Doh! So when setting key listeners: always set focus to the item you want to listen to. Or at least something that’s on stage.

stage.addEventListener(KeyboardEvent.KEY_UP, keyHandler);
stage.focus = stage;

Tweening colors?

Posted in Flash on June 24th, 2009 by Thomas H – 1 Comment

This pretty useful function returns the correct color value between to colors. h1 and h2 params being the colors and p being the position in between in percent.

private function interpolateColor(h1:Number, h2:Number, p:Number) : Number { 
	return ((h1>>16)+((h2>>16)-(h1>>16))*p)<<16
                  |(h1>>8&0xFF)+((h2>>8&0xFF)-(h1>>8&0xFF))*p<<8
                  |(h1&0xFF)+((h2&0xFF)-(h1&0xFF))*p; 
}

Constrain input to textfield bounds.

Posted in Flash on May 25th, 2009 by hp. – Be the first to comment

This is a bit of hack but nonetheless a genuine requisite in many cases.

It checks if text-input break the text out of field.width or field.height, in which case it prevents the change. Works with both single-line, and multiline TextFields Works best with multiline fields.

//Fields from the IDE tend to return wrong numLines initially, so make sure they are empty:
nameField.text = ""
descriptionField.text = ""
 
addEventListener(TextEvent.TEXT_INPUT, textInputhandler);
 
 
private function textInputhandler(event:TextEvent):void {
  var field:TextField = event.target as TextField;
 
  var oldText:String = field.text;
  var selectBegin:int = field.selectionBeginIndex;
  var selectEnd:int = field.selectionEndIndex;
  var newText:String = oldText.substr(0, selectBegin) + event.text + oldText.substr(selectEnd);
  field.text = newText
 
  var maxLines:int = int(field.height / (field.textHeight / field.numLines))
 
  if (field.textWidth > field.width || field.numLines > maxLines) {
  	event.preventDefault()
  }
 
  field.text = oldText;
  field.setSelection(selectBegin, selectEnd);
}