Archive for the 'Flash AS 3.0' Category

Tweener Tips

We’ve been using Tweener here for a few of our examples and while looking for info on Bezier Movement like the old MC_Tween used to support I came across one of Tweener’s co-creator’s blogs: labs.zeh.com.br
It has a really good post about how he decided on the syntax for the bezier Tween. It also includes a terrific example that applies it to a Papervision3D camera object.

Also:

  • For those not already familiar with Tweener there are some decent flas here.
  • And some pretty neat tricks (especially tip 3) for the more experienced Tweenerers here.

Happy Tweenering.

E4X & XMLList fails when defined in a switch statement.

This one had me REALLY confused, for a good bit of time, luckily a co-worker helped be go through a rather vigorous debugging session to pinpoint the problem. Apparently if you are attempting to access a piece of a larger XML object using the new E4X capabilities and you attempt to do it with a single line of code, it will return a null object instead of the expected XMLList object it should. After looking into it further, I discovered that if you define the variable, but don’t set it’s value on the same line, then it works fine… See wonky huh?

Example (Based on Adobes example documentation):

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package
{
import flash.display.Sprite;
 
public class XMLListExample extends Sprite
{
	private var books:XML;
 
	public function XMLListExample()
	{
		books =		<books>
			<book publisher="Addison-Wesley" name="Design Patterns" />
			<book publisher="Addison-Wesley" name="The Pragmatic Programmer" />
			<book publisher="Addison-Wesley" name="Test Driven Development" />
			<book publisher="Addison-Wesley" name="Refactoring to Patterns" />
			<book publisher="O'Reilly Media" name="The Cathedral & the Bazaar" />
			<book publisher="O'Reilly Media" name="Unit Test Frameworks" />
		</books>;
 
		showBooksByPublisher();
	}
 
	private function showBooksByPublisher():void
	{
		var ner = "ren";
		switch(ner){
			case "ren":
			// the working code
			var results:XMLList;// = new XMLList();
			results = books.book.(@publisher == "Addison-Wesley");
			trace("results:\n"+results); // returns a the first 4 items (which contain "Adison...")
 
			// now for the fun!!!
			var otherResults:XMLList = books.book.(@publisher == "O'Reilly Media");
			trace("other results:\n"+otherResults); // returns null? (actually a null object)
 
			// just to see if oneline variable definitions work
			var test:String = 'ner';
			trace("test string: "+test);
 
			// seeing what else is a problem to do this way
			var objTest:Object = {ner:"ren"};
			trace('test object: '+objTest.ner); // yup works fine.
			//
			var xmlTest:XML = <ners>
			<ner>ren</ner>
			</ners>;
			trace('test xml:\n'+xmlTest); // no problem here either.
			//
			var numTest:Number = 45;
			trace('test number: '+numTest); // this is fine too.
			break;
		}
		if(ner == "ren")
		{
			var otherOtherResults:XMLList = books.book.(@publisher == "O'Reilly Media");
			trace("other other results:\n"+otherOtherResults); // works fine as well.
		}
	}
}// end of class
}

Download the code.

Tell your friends, I’m letting Adobe know. And please let us know if your testing shows differently.

As3 event management

Recently while working on an as3 project the project manager of the project came over to me and asked that something happen automatically that was currently happening only on a mouse click. Normally I would have said fuck you that is impossible and get the hell out of my face. I was feeling confident today though with the event model of as3 so I said yeah I think we can make that happen. The logic was that at worst I would have to make a separate function based on the one I already had. So in a quest to solve this problem I offer you the most awesome kick ass thing you could ask for.

With as3 you quite literally fake an event. And you can do so very easily. All you need to do is import the events classes:

?View Code ACTIONSCRIPT
1
import flash.events.*;

Then any time you have a button you can fake whatever event you want. You can fake all sorts of events not just button. But faking a click is often the most useful. The code for doing such a thing is as follows.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// note you must make a symbol and link it in order to make an instance.
function init(){
	mybutton = new customSymbolIHaveLinked();
	mybutton.mouseChildren = false;
	mybutton.mouseEnabled = true;
 
	// this makes the button listen for the click event
	mybutton.addEventListener(MouseEvent.CLICK, functiontorun);
	// now if you would like to automatially run this event on start up to perhaps ensure the user is at a default
	// position you simply need to dispatch an event
 
	mybutton.dispatchEvent(new Event(MouseEvent.CLICK));
}
function functiontorun(evt:Event){
	trace("recieved event from "+evt.target);
}

That’s all there is to it really. I hope this has been helpful. It has been a lifesaver for me. Thanks again as3 for making life a hell of a lot easier…

Animator Class Enhancement

I don’t know how much exploration of the Animator class many people have done out there, but a current project seemed like a good place to experiment with it. I’m pretty impressed with Adobe’s implementation of it—though I’m far more impressed with the capabilities of E4X XML tools that make it possible—but some things are less then ready for prime-time.

Basically, flashes Animator.play()

Example

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

How it works

This Assumes the code is on frame 1 of the main timeline.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import fl.events.*;
import fl.motion.*;
 
//stage.frameRate = fps;
//trace(stage.frameRate);
stop();
 
 
/*************  this is the speed controller (or delay controller) *************/
var player:Timer = new Timer(33,30); // "33"/1000th of a second is pretty much 30 fps and the animation is "30" frames long
	player.addEventListener(TimerEvent.TIMER, playAnimator);
	player.start();
 
function playAnimator(e:TimerEvent)
{
	if(e.currentTarget.currentCount < 30){
		ner_animator.time = e.currentTarget.currentCount;
	}else{
		ner_animator.stop();
		ner_animator.rewind();
		player.reset();
		player.start();
	}
}
 
/************* speed controlled animator (taken straight from the clipboard but with the Animator.play() removed *************/
var ner_xml:XML = <motion duration="30" xmlns="fl.motion.*" xmlns:geom="flash.geom.*" xmlns:filters="flash.filters.*">
	<source>
		<source frameRate="10" x="95" y="114" scaleX="1" scaleY="1" rotation="0" elementType="movie clip" instanceName="ner" symbolName="Symbol 1">
			<dimensions>
				<geom:Rectangle left="0" top="0" width="42" height="42"/>
			</dimensions>
			<transformationPoint>
				<geom:Point x="0.5" y="0.5"/>
			</transformationPoint>
		</source>
	</source>
 
	<keyframe index="0" tweenSnap="true" tweenSync="true">
		<tweens>
			<simpleEase ease="0"/>
		</tweens>
	</keyframe>
 
	<keyframe index="29" tweenSync="true" x="253"/>
</motion>;
 
var ner_animator:Animator = new Animator(ner_xml, ner);
//ner_animator.play(); // removed because we play it with the new player function

So as you can see, it’s just replacing whatever the built in play() function does (likely some kind of onEnterFrame event) with a Timer driven, and thus framerate independent animation. Which allows old slow computers to keep things moving more like the Tween or Tweener class, frames will be skipped to keep the timing more or less on track (as much as possible).

I’m planning on releasing an class that extends the Animator class built into flash—or possibly building a new one from scratch—that will include this speed feature as well as other enhancements I’ve required in the last project (also coming soon).

Auto-scrolling select box

Recently I worked on a project that required a very customized select box. Instead of a scrollbar the box would auto scroll depending on the mouse position. The items needed to be click-able and also have a rollover state. I came up with the MaskedSlider class to solve my sliding problems. Currently the function for the scrolling is hardcoded. I leave it as an exercise to the reader to implement whatever scrolling animation function the see fit.
(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

download the source here slider demo

The class is fairly easy to use and can be instantiated as a UP_DOWN list or a LEFT_RIGHT list by setting the proper value in the constructor, as shown below in the simple example. Futhermore, you may set a background color, width, height, and the extra hit width and height you would like to allow. The hit length allows the movement to continue even when you have moused off the compnent.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package {
	import TopLevel;
	import hg.paginators.*;
	import flash.events.*;
	public class main extends TopLevel
	{
		private var slider1:MaskedSlider;
		private var slider2:MaskedSlider;
 
		public function main()
		{
			slider1 = new MaskedSlider(195,170,MaskedSlider.UP_DOWN,0xFFFFFF,10,10);
			slider2 = new MaskedSlider(460,42, MaskedSlider.LEFT_RIGHT, 0xFFFFFF,10,10);
 
			this.addChild(slider1);
			this.addChild(slider2);
 
			// add 15 items
			for(var i=0; i<15; i++){
				slider1.addItem( new item,rOver,rOut);
			}
 
			for(var j=0; j< 15; j++){
				slider2.addItem(new item,rOver,rOut);
			}
 
			slider1.x=30;
			slider1.y=30;
			slider2.y=220;
			slider2.x=30;
		}
 
		public function rOver(evt:Event){
			evt.target.alpha=0.7;
		}
 
		public function rOut(evt:Event){
			evt.target.alpha=1;
		}
	}
}

There are some interesting properties in this class as well as a changed event that you can subscribe to. Below are the relevent methods and properties from the class, a brief description of the functionality, and usage examples.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
//three methods worth using
 
//change background
slider1.background(0xFF99FF);
 
//set speed
slider1.setSpeed(3);
 
//empty contents of the slider so that you can populate with new items
slider1.empty();
//set the default selected item useful for making sure there are no null values passed to other objects
// where 3 is the item number
slider1.setDefaultSelect(3);

So that block took you through some of the useful methods implemented for you. There is one piece of functionality I have left out. The slider is written so that you can select an item from a list of items. Below is a brief example of how you would accomplish this.

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
// you must subscribe to the change even
slider1.addEventListener(MaskedSlider.EVENT_ON_CHANGE, doSomething);
 
public function doSomething(evt:Event){
//to get the selected item
trace(evt.target.sItem);
//to get the index chosen
trace(evt.target.itemIndex);
}

That should get you started using this class. Although it is far from complete, I think the slider would make a great addition to many projects. Be creative with what you scroll. Remember an item can be any movie clip :)