Archive for March, 2009
ASWCSlideShow Actionscript 2
by admin on Mar.31, 2009, under Tutorials
ASWCslideshow Overview
This is an overview of the many capabilities of the ASWCSlideshow:
Auto resizing:
Set the ASWCSlideshow to any size and it will still display your pictures correctly.
Mixing effect:
Set different in and out effects either as a general effect or on a per picture basis to create your own effects. Combine them with the over 30 different easing transition. Use also the under/over capability to place the incoming picture on top or under the current picture for amazing and fully personalized effects!
No time to resize and crop your pictures? Let ASWCSlideshow do it for you:
These two 640×480 pictures are resized and cropped dynamically by ASWCSlideshow to fit on a 450×114 display!
You can also telll ASWCSlideshow where it should start cropping. In this case the cropping starts at 50 pixels on the horizontal axis and 50 pixels on the vertical:
Polaroid Gallery Actionscript 2
by admin on Mar.31, 2009, under Tutorials
Â
Â
Â
Â
<BACKCOLOR>#000C00,60</BACKCOLOR>
<BACKPICTURE></BACKPICTURE>
<TEXTCOLOR>#000000</TEXTCOLOR>
<TEXTOVERCOLOR>#FF0000</TEXTOVERCOLOR>
<THUMBNAILSIZE>150</THUMBNAILSIZE>
<OUTLINECOLOR>#FFFFFF</OUTLINECOLOR>
<LARGEVIEWSIZE>95</LARGEVIEWSIZE>
<PRINT>true</PRINT>
<DOWNLOAD>true</DOWNLOAD>
<FONT>Arial</FONT>
<FONTSIZE>14</FONTSIZE>
<SOUNDDEFAULT>on</SOUNDDEFAULT>
<DEBUGMODE>false</DEBUGMODE>
<THUMBNAIL></THUMBNAIL>
<LARGEPICTURE></LARGEPICTURE>
<CAPTIONS><![CDATA[Doggies!]]></CAPTIONS>
<SOUND></SOUND>
ASWCSlideShow Actionscript 2
by admin on Mar.31, 2009, under Tutorials
Following are instructions on how to set this light weight application. You can simply browse to the relevant parts if you want using the following links:
ASWCSlideShow General Presentation.
Presentation
The ASWCSlideshow is a powerful Flash slideshow with a high level of options and customization:
. Effects in and out, with the possibility to set effects on a per picture basis.
. Easing in and out
. 30 types of easing.
. Xml driven or server sdie script driven.
. Auto resizing capability.
. Dynamic resizing of pictures with the ability to turn off the dynamic resizing on a per picture basis.
. Display randomly pictures or not.
. Make the slideshow loop by default or stop.
. Display the first picture directly or apply the chosen effect to it.
. Display the incoming picture on top of the current picture or under.
. Apply a default effect or tune it precisely by using options.
. Set transition time and display time.
. Regular updates with more effects and features!
Introduction to Pixel Bender and Shader for Flash Player 10
by admin on Mar.31, 2009, under Tutorials
Here is where the fun really begins. We can very easily apply a pixel Bender filter to a BitmapData which will alter all pixels in it or we can also use a Pixel bender filter as a filter like you would use any other Flash built-in filter. Let’s see this in action, I added a BitmapData in the library and loaded a different filter:
var shader:Shader;
var bitmap:Bitmap = new Bitmap(new Autumn(0,0));
addChild(bitmap);
function onLoadComplete(event:Event):void {
shader = new Shader(loader.data);
stage.addEventListener(MouseEvent.CLICK, addBender);
}
function addBender(e:MouseEvent):void{
shader.data.src.input = new Autumn(0,0);//set the input
var shaderjob:ShaderJob = new ShaderJob(shader, bitmap.bitmapData);//apply the filter on the bitmapdata of our bitmap
shaderjob.start();
}
And here is the result, click once to apply the filter:
This alters directly the BitmapData pixels. Another way is to create a ShaderFilter which you can then apply to any DisplayObject:
var shaderfilter:ShaderFilter;
function onLoadComplete(event:Event):void {
shader = new Shader(loader.data);
shaderfilter = new ShaderFilter(shader)
stage.addEventListener(MouseEvent.CLICK, addBender);
}
function addBender(e:MouseEvent):void{
bitmap.filters = [shaderfilter];
}
Here is the result:
Now that’s not a lot of code. We could now tween properties using either tweens or timer or enterframe events and get quite impressive results. I’ll leave that for you to experiment and come out with your own solutions. But to get to the point I wrote a little class (see Classes section on this site) that does just that so let’s try on some filters here:
The code for all this is quite simple and it’s about the same for all these examples, only the property being animated changes. You can just download all the files and play with all this. Just remember that the property must match the property defined in the Pixel Bender.
import ShaderExtended;
var shader:ShaderExtended = new ShaderExtended("cone.pbj");
shader.addEventListener(ShaderExtended.SHADER_READY, get_filter);
var bitmap:Bitmap = new Bitmap(new Tree(0,0));
addChild(bitmap);
function get_filter(e:Event):void{
stage.addEventListener(MouseEvent.CLICK, addBender);
}
function addBender(e:MouseEvent):void{
shader.setInput({src:new Tree(0,0)});
shader.animate(30, null, { offset:[10,0]}, bitmap.bitmapData, false);
}
That’s all for this introduction to Pixel Bender and Shader. Contact me if you have any questions and don’t hesitate to leave a comment!
Introduction to Pixel Bender and Shader for Flash Player 10
by admin on Mar.31, 2009, under Tutorials
Even though Pixel Bender filters are meant and used to alter pixels, what they really do is applying math operations to numbers. When we use pixel bender filters in Flash, we can actually use them to process numbers or to alter an image. We’ll start by looking at an example with number processing and then we’ll move on to pixel manipulation.
To be able to load a Pixel Bender file in Flash, it needs first to be compiled in a .pbj format and we can do so by selecting “Export filter for Flash Player” in our Pixel Bender Toolkit. I created a simple Pixel Bender filter that will allow us to manipulate numbers, here is how this looks:
<languageVersion : 1.0;>
kernel NewFilter<
namespace : "red divider";
vendor : "aswebcreations.com";
version : 1;
description : "simple dividing on red channel";
>
{
input image1 src;
output pixel3 dst;
void evaluatePixel(){
pixel1 temp = sample(src,outCoord());
pixel1 divided = temp/2.0;
pixel1 squared = sqrt(temp);
dst = pixel3(temp,divided,squared);
}
}
Now you can see that our image input is of type 1 which means it’s expecting one number instead of 3 for a regular pixel (rgb) or 4 for rgba pixels. Our output is pixel3 based and this is a minimum for an output in Pixel Bender (as far as I know). Then in the evaluatePixel() method we get our number and store it in a variable:
pixel1 temp = sample(src,outCoord());
Then we store the result of dividing by 2 in another variable:
pixel1 divided = temp/2.0;
And finally the result of squaring our number in another variable:
pixel1 squared = sqrt(temp);
We of course then pass this result to our output:
dst = pixel3(temp,divided,squared);
You can of course apply this filter to a picture but its real purpose is to process numbers so let’s get started with our actionscript code now:
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoadComplete);
loader.load(new URLRequest("divider.pbj"));Â Â Â Â
function onLoadComplete(event:Event):void {
}
This loads our filter in Flash what we need now is create an instance of the Shader class and get our filter data ready:
var shader:Shader;
function onLoadComplete(event:Event):void {
shader = new Shader(loader.data);
}
Our filter is now ready to be used! There’s 3 data types we can use as Shader input and ouput, BitmapData, byteArray, and Vector.<Number> (note that some filters do not require inputs). I’ve seen already examples on the web about processing numbers using ByteArray so I thought I would use Vector for this tutorial instead. I’m going to create a Vector and populate it with random numbers then set it as the shader input. Then I’ll create another vector that I’ll use to store the results coming from our filter (Note that it’s possible to use the same object as input and output in which case results are building up on preceding results which can be interesting for bitmap alteration for example).
function onLoadComplete(event:Event):void {
shader = new Shader(loader.data);
var vector:Vector.<Number> = new Vector.<Number>();
for(var i:Number = 0; i<9; i++){
vector.push(Math.random()*500);
}
shader.data.src.width = 3;
shader.data.src.height = 3;
shader.data.src.input = vector;
var vector2:Vector.<Number> = new Vector.<Number>();
var shader_job:ShaderJob = new ShaderJob(shader, vector2, 3, 3);
shader_job.start(true);
var txt:TextField = new TextField();
txt.wordWrap = true;
txt.width = stage.stageWidth;
txt.height = stage.stageHeight;
addChild(txt);
for(i = 0; i<vector2.length; i+=3){
txt.appendText((vector2[i]+” divided by 2 = “+vector2[i+1]+” and squared = “+vector2[i+2]+”n”));
}
}
Here is the result:
Let’s look at the code:
var vector:Vector.<Number> = new Vector.<Number>();
for(var i:Number = 0; i<9; i++){
vector.push(Math.random()*500);
}
shader.data.src.width = 3;
shader.data.src.height = 3;
shader.data.src.input = vector;
Here we simply create a Vector.<Number> and populate it with some random numbers (9 numbers in this case). Then we pass some values to our shader input called “src” (defined in the pixel bender). We indicate the size of the input with src.width = 3 and src.height = 3 (which means 9) and finally pass our Vector as the input: src.input = vector.
var vector2:Vector.<Number> = new Vector.<Number>();
var shader_job:ShaderJob = new ShaderJob(shader, vector2, 3, 3);
shader_job.start(true);
We create a new Vector and pass it as the output in the ShaderJob instance. We pass along the Shader we want to use of course and the size of the ouput we are expecting (3,3). The rest of the code creates a text field to display our result. Then:
for(i = 0; i<vector2.length; i+=3){
txt.appendText((vector2[i]+” divided by 2 = “+vector2[i+1]+” and squared = “+vector2[i+2]+”n”));
}
That’s right, we didn’t get 9 numbers back but 27! Remember our output is of type pixel3 so that means 3 numbers for each number that we process!
A ShaderJob instance uses the GPU to process the Pixel Bender filter so this leaves the CPU take care of normal stuff in our Flash applications while the Pixel Bender is running. This creates a multithreaded Flash application! Passing true to the start method makes Flash wait for the result to get back while passing false (or nothing) makes the results asynchronous. You can then add an event listener to your ShaderJob instance and handle the results in your event handler. Now we could make our filter more dynamic by adding a parameter:
input image1 src;
output pixel3 dst;
parameter float div;
pixel1 divided = temp/div;//in the evaluatePixel() method
We now added a parameter in our filter which allows us to change on the fly some value like here the number we are dividing by (defaults to zero). We would rewrite our actionscript code that way:
shader.data.src.width = 3;
shader.data.src.height = 3;
shader.data.src.input = vector;
shader.data.div.value = [6];
Note the array style value. All values passed to parameters must be in array form. Now if we were to save our filter and add this new line of code then our numbers would be divided by 6. We could also of course tween this value and get our results back in real time. In Pixel Bender we can also provide default values, minimum values and maximum values to our parameters which we can then retrieve in our Flash application. But let’s leave this for now and start experimenting with bitmap manipulation.
Dynamic Slide Show AS3 Complete Guide.
by admin on Mar.30, 2009, under Tutorials
Resizing and Autoresizing (or can the swf resizes itself?)
Of course our slide show still needs a lot of improvements and one of them is dynamic resizing. We should be able to re size the pictures we load in while still keeping a good resolution quality. We should also why not give the ability to turn off the resizing of picture and allow cropping of pictures, all this on a per picture basis. We should also be able to do this no matter what the size of the swf is. So let’s get started on this. We’ll create first a simple resizing function that will re size and position our pictures according to the stage dimensions.
This new function takes our picture, the stage width and height as argument and then returns the picture resized and repositioned correctly.
private function resize_picture(target:DisplayObject, Width:Number, Height:Number):DisplayObject{
var ratio:Number = target.width/target.height;//get the ratio, if width is bigger than height then ratio is greater than 1, else ratio is smaller than 1
target.height = Height;//set the picture height to the stage height directly
target.width = target.height*ratio;//apply the ratio so we keep the proportion (multiply)
if(target.width>Width){//now we resized according to the height but is our picture width to large?
target.width = Width;//if yes then resize it now according to the width
target.height = target.width/ratio;//apply the ratio to the height (divide)
}
target.x = Width/2-target.width/2;//position according to left top corner
target.y = Height/2-target.height/2;//position according to left top corner
return target;//return the picture
}
Quite straight forward, now we just need to add a line in our document class. We create a local variable and pass it the resized picture, then we add that to the display list:
var target:DisplayObject = resize_picture(time_manager.picture, stage.stageWidth, stage.stageHeight);
picture_holder.addChild(target);
That works perfectly, you can even set the stage size to anything you want and the pictures will still be re sized and positioned correctly.
can the swf resizes itself?
Sure it can, we are actually all set already for that, all we need is set the stage scale mode to “noscale” and we will be able to set our slide show to any size with still the pictures resizing correctly. Let’s do just that now, add this to our constructor:
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Now open your html file where the slide show is embedded and set different size for the slide show, you’ll see the pictures always fit as much as they can the display size!
When we re size our pictures, we expand or squeeze the pixels depending on the picture size and this might result sometimes on a loss of quality, what we really need to do is create a re sized copy of the picture we load with the right amount of pixels in it. Also the BitmapData class (this is what we’ll use) allows use to smooth the result improving even more the final result quality. So let’s modify our re size function so instead of just resizing it will create a re sized copy of the picture:
private function resize_picture(target:DisplayObject, Width:Number, Height:Number):DisplayObject{
if(Width/Height == Infinity){//if you set the slide show to 0 width and 0 height then instead of crashing the swf it will just return the picture as it is
return target;
}
var ratio:Number = target.width/target.height;
var targetHeight:Number = Height;//now instead of setting the picture size we calculate what the size should be with two new variables.
var targetWidth:Number = targetHeight*ratio;
if(targetWidth>Width){
targetWidth = Width;
targetHeight = targetWidth/ratio;
}
var bmp:BitmapData = new BitmapData(targetWidth, targetHeight); //create a bitmapData and pass it the size that the picture should be
var matrix:Matrix = new Matrix();//create a matrix that we'll use to scale the picture
matrix.scale((targetWidth/target.width), (targetHeight/target.height));//set the scale for the matrix
bmp.draw(target,matrix,null,null,null,true); //draw our bitmapData using our matrix and see at the end "true" used to smooth the picture
var bitmap:Bitmap = new Bitmap(bmp);//create a bitmap and pass it our resized bitmapData
bitmap.x = Width/2-bitmap.width/2;//set the bitmap position
bitmap.y = Height/2-bitmap.height/2;//set the bitmap position
return bitmap;//return the bitmap
}
Perfect now not only the pictures are perfectly re sized but they will also keep a good resolution quality. So now the user can use pictures with any size for the slide show and the picture will be automatically re sized to fit as much as possible the screen no matter what the screen size is. We can now just add this function into our TimeManager class and move on to our next section.
Dynamic Slide Show AS3 Complete Guide.
by admin on Mar.30, 2009, under Tutorials
Loading Pictures (or How do I time this?)
Now that we know how to load our data, we can know load also our pictures which is the next logic step in the process. I went ahead and wraped up our loading data code into a simple class so we can focus now on writing the code for loading the pictures. Let’s start a new Flash document and document class and apply the same setting than in the preceding section.
We start by importing a new class, the Loader class:
import flash.display.Loader;
And of course declare a varialbe to hold a Loader object:
private var picture_loader:Loader;
And in our completeHandler function we can instantiate it:
picture_loader = new Loader();
We use a loader object to load assets like pictures or swfs so that’s exactly what we’ll do here. Let’s give it a try. We use our XML data to pass a path to our Loader and then add the Loader to the stage:
picture_loader.load(new URLRequest(xml_pictures.PICTURES.PICTURE_PATH[0].toString()));
addChild(picture_loader);
Perfect, we now see the first picture! PICTURE_PATH[0] points to the first picture path in our XML data, PICTURE_PATH[1] would point to the second one and so on. We can also use this: PICTURE_PATH.length() to know how many pictures we are dealing with. You can see how easy is to work and access data with XML. Now we need a way to loop through the data and load a picture at a determined interval.
HOW DO I TIME THIS?
There’s many ways to do this, we could use an ENTER_FRAME event which would tie use to the frame rate, we could also use a Timer event which would give us more freedom but is not very time accurate but we could improve it by using the getTimer() method. I chose the last one for this tutorial.
We’ll store in a variable how many pictures we have and create also a variable to hold the time each picture will stay displayed, we also create an index variable that we use to pick up a picture path from the xml data, then finaly we create a Timer to trigger the loading of picture at a regular interval, we of course import the Timer class
import flash.utils.Timer;//import the class
private var number_of_picture:uint;//will hold how many pictures we have
private var current_index:uint;//used to pick a picture path
private var display_time:Number;//how long should a picture stay on the screen
private var display_timer:Timer;//used to time the dsiplaying of pictures
Now we should set all these varaibles only once the XML data is available so we do this in the completeHandler function:
number_of_picture = xml_pictures.PICTURES.PICTURE_PATH.length();
display_time = 5;//let's set it to 5 for now
display_timer = new Timer(display_time*1000);//create our timer, 1000 is one second so display_time*1000 sets the timer to the right time
Now all we have to do is call a function to load our first picture and then let the timer call this same function at regular intervals to load the next pictures:
display_timer.addEventListener(TimerEvent.TIMER, get_next_picture);
display_timer.start();
get_next_picture();
Now let’s write our get_next_picture function:
private function get_next_picture(e:TimerEvent = null):void{//set the event default value to null so we can call it without passing an event
if(current_index == number_of_picture){current_index = 0;}//if we looped through all picture paths we go back to 0 (first picture)
picture_loader = new Loader(); //create a new loader to hold our picture
picture_loader.load(new URLRequest(xml_pictures.PICTURES.PICTURE_PATH[current_index].toString()));//load our picture using current_index
addChild(picture_loader);//display the picture
current_index++;//increase the current_index so next time we run the function it will load the next picture
}
Perfect! It shows all pictures one after another and cycle through. But there’s a lot of things not working well here. We never remove the pictures that are not displayed anymore so they keep adding on top of each other. Our Timer is not very accurate, it triggers the function at more or less 5 seconds so we should make it more accurate, the timer triggers the loading of the picture and not the displaying of the picture so if we really want the picture to show after 5 seconds we should load it first and then display it when the time comes. Let’s address all these issues one by one. First let’s remove the pictures we don’t need anymore, we could add this at the end of our get_next_picture function:
while(numChildren>2){
removeChildAt(0);
}
Only problem is if you were to add other objects to the slide show like textfields for example this code would break, so we need another approach. As always there’s many ways to go about this, here is what I chose to do. Instead of adding the pictures to the stage, I will add them to a main Sprite and then use the preceding code for the main Sprite instead. So let’s modify our code and add a main Sprite:
private var picture_holder:Sprite = new Sprite(); //new variable
addChild(picture_holder);//in the constructor
picture_holder.addChild(picture_loader);//in the get_next_picture function
while(picture_holder.numChildren>2){//at the end of the get_next_picture function
picture_holder.removeChildAt(0);
}
The loader objects we remove will be garbage collected since they lost any reference in the code. Now let’s make our timer more accurate. We can just get the current time and use our timer to check when the targeted time occurs and then trigger our function, that way we’ll get a more accurate timing.
private var current_time:Number;//create a new variable to hold the current time
display_timer = new Timer(50);//we place this inside our get_next_picture function
current_time = getTimer();//we place this inside our get_next_picture function
display_timer.addEventListener(TimerEvent.TIMER, check_target_time);//we place this inside our get_next_picture function
display_timer.start();//we place this inside our get_next_picture function
and here is our new function:
private function check_target_time(e:TimerEvent):void{
if(getTimer()>current_time+(display_time*1000)){//if the actual time passes the initial time + the target time (+5 seconds) then it's time to get a new picture
display_timer.removeEventListener(TimerEvent.TIMER, check_target_time);
get_next_picture();
}
}
Now we got an accuracy of more or less 50 milliseconds. You can get an even better accuracy by reducing the number passed to the timer (new Timer(50)). Now we need to change our code logic so that as soon as we display a picture, we start to load the next one so when the time comes to display it we can just do so. Of course that means also that we need to handle the case when it’s time to display the picture but the picture is not done loading. So even though it’s time to display it, we need to wait somehow until we actually can display it. So instead of having one function loading and displaying pictures we should have two separate functions instead so we can control what happens when. Also the first picture is a special case since we need to display it as soon as we can, so we need a special way to handle it. So let’s get started.
private var isPictureReady:Boolean;//a new boolean variable to keep track of the loading state of the picture
private var isDisplayTime:Boolean;// a new boolean variable to keep track of the timer state
We changed our completeHandler function, we now load directly the first picture and then let the engine load and time the next ones:
private function completeHandler(e:Event):void{
xml_pictures = XML(xml_loader.data);
number_of_picture = xml_pictures.PICTURES.PICTURE_PATH.length();
display_time = 5;
picture_loader = new Loader(); //create a new loader
picture_loader.load(new URLRequest(xml_pictures.PICTURES.PICTURE_PATH[0].toString()));//load the first picture
picture_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, display_picture); // add an event so we know when the picture is ready
current_index++;//increase already our current_index so we’ll load the seond picture next time
}
We create a display_picture function which will set the current time, add the picture to the dsiplay and start the cycle over:
private function display_picture(e:Event = null){
current_time = getTimer();//our timing starts from here
picture_holder.addChild(picture_loader);//show the picture
while(picture_holder.numChildren>2){//we only need two pictures at a time
picture_holder.removeChildAt(0);
}
get_next_picture(); //start loading the next picture
}
And of course our revisited get_next_picture function:
private function get_next_picture():void{
isPictureReady = false;//set the boolean to false
isDisplayTime = false;//set the boolean to false
if(current_index == number_of_picture){current_index = 0;}
display_timer = new Timer(25);//create a new timer
display_timer.addEventListener(TimerEvent.TIMER, check_target_time);//check the timing
display_timer.start();//start the timer
picture_loader = new Loader(); //create a new loader
picture_loader.load(new URLRequest(xml_pictures.PICTURES.PICTURE_PATH[current_index].toString()));//load the picture
picture_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, picture_ready); //when the picture is loade run this new function picture_ready
current_index++;
}
This new picture_ready function:
private function picture_ready(e:Event){
isPictureReady = true;//the picture is loaded so set the boolean to true
if(isDisplayTime){//if this boolean is true then that means the timer ran out so display the picture
display_picture();
}
}
and finally the modified check_target_time function:
private function check_target_time(e:TimerEvent):void{
if(getTimer()>current_time+(display_time*1000)){
display_timer.removeEventListener(TimerEvent.TIMER, check_target_time);
isDisplayTime = true;//check this boolean to true so we know it's time to display the picture
if(isPictureReady){//if the picture is ready then display it
display_picture();
}
}
}
Our slide show now handles in a perfect timely manner the displaying of the pictures. Now of course we still have a bit ow work to do. We set the target time in the code so we need to change that so we can pass the time we want from the XML. We also do not handle the case where a picture does not load (probably because of a wrong path). Finally we probably should wrap all that up in a class. So let’s finish that up. Passing the time from the XML to the application is really not that hard, we can set an attribute in our root XML tag and grab it to set our target time. We could also define a new tag in our XML to hold the time value but let’s stick with an attribute here. Here is our modified XML slide show root tag:
<SLIDE_SHOW DisplayingTime='4'>
Let’s go back in our completeHandler function and grab this value:
display_time = Number(xml_pictures.attribute("DisplayingTime")) || 5; //set or time from the attribute or set it to 5 if the value is not valid
That was hard I know. Let’s assume that the first picture is required to load fine (we could handle that too but I leave it up to you to implement if you want) so now let’s handle any following picture loading error by adding an IOError event to our loader:
picture_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, save_slide_show);
and our new save_slide_show function just saves the day:
private function save_slide_show(e:IOErrorEvent):void{
picture_loader = new Loader();
picture_loader.load(new URLRequest(xml_pictures.PICTURES.PICTURE_PATH[current_index].toString()));
picture_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, picture_ready);
picture_loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, save_slide_show);
current_index++;
}
That’s it, any wrong paths will just be skipped, now remember you might not want that since if you have a wrong path the slide show will still be working fine and you might never realize that you are missing a picture. Also you might want to handle the case when it’s time to display a picture but the picture is not fully loaded yet. So if you want to display any kind of preloader when that happens you’ll do it here:
private function check_target_time(e:TimerEvent):void{
if(getTimer()>current_time+(display_time*1000)){
display_timer.removeEventListener(TimerEvent.TIMER, check_target_time);
isDisplayTime = true;//check this boolean to true so we know it's time to display the picture
if(isPictureReady){//if the picture is ready then display it
display_picture();
}else{
//start your preloader here
}
}
}
then you remove your preloader here:
private function picture_ready(e:Event){
isPictureReady = true;//the picture is loaded so set the boolean to true
if(isDisplayTime){//if this boolean is true then that means the timer ran out so display the picture
display_picture();
//remove your preloader here
}
}
Now let’s wrap all that up into a class. We’ll call it TimeManager class and beside the fact that it will keep our code organized, it will also make it simpler to add more functionality later on. So you’ll find most of the code you saw so far in this new class the only differences being that this class dispatches an event that we use to add new pictures (that we get from this class) to the display list in our document class. That’s it for this section now let’s resize all these pictures (and the swf itself!) in the next section.
Easing Explained for AS2 and AS3
by admin on Mar.30, 2009, under Tutorials
Let’s look at a typical class easing method like in the Back class for example:
public static function easeIn(t:Number, b:Number, c:Number,
d:Number, s:Number = 0):Number
{
if (!s)
s = 1.70158;
return c * (t /= d) * t * ((s + 1) * t - s) + b;
}
We recognize our 4 numbers here t: initial time, b: initial value, c: final value, and d: duration. But there’s another one: s, that’s the amplitude of the back effect. Change this hard coded value to any number you want to get a different back effect, or even better create a public method and then set s as an instance property:
public var amplitude:Number;
public function easeIn(t:Number, b:Number, c:Number,
d:Number):Number
{
return c * (t /= d) * t * ((amplitude + 1) * t - amplitude) + b;
}
Then in your code create an instance of the Back class:
var theBack:Back = new Back();
set the amplitude:
theBack.amplitude = 10;
then run the tween!
var Ytween:Tween = new Tween(this,"theNumber",theBack.easeIn,0,300,1,true);
Now you can also create different effect with the same easing method:
var theBack:Back = new Back();
theBack.amplitude = 1;
var theBackY:Back = new Back();
theBackY.amplitude = 20;
var Xtween:Tween = new Tween(tween_mc,"x",theBack.easeIn,tween_mc.x,tween_mc.x+100,2,true);
var Ytween:Tween = new Tween(tween_mc,"y",theBackY.easeIn,tween_mc.y,tween_mc.y+100,2,true);
Up to you to go through all easing classes and mess with their formulas. Now let’s explore a bit custom easing.
We know that any easing function needs to be able to end up no matter what with the right value. Remember the crazyTween function was giving back random values to the tween while the tween was running but at the final call, it was giving the right value so the object would end up at the right place. Any custom easing method or function should do just that, ending with the right value, but between the start of the tween and the end, you are free to apply any mathematical equation. let’s try a few.
function shakeTween(TimeOrigin:Number,InitialValue:Number,FinalValue:Number,FinalTime:Number):Number{
var i:Number = 0;
if(TimeOrigin/FinalTime<1){
i = Math.random()*FinalTime*10;
}else {i = 0}
return InitialValue+i+FinalValue*(TimeOrigin/FinalTime)
}
This will give a shake effect to your tween.
var i:Number = 0;
var current:Number = 0;
function clockTween(TimeOrigin:Number,InitialValue:Number,FinalValue:Number,FinalTime:Number):Number{
if(TimeOrigin>i){
i += FinalTime/3;
current = InitialValue+FinalValue/FinalTime*(TimeOrigin/FinalTime)
return current;}
return current;
}
I created this one to create a clock effect with a rotation property. Now you know how to create and apply your own easing function so go get your old math books and then share with us your creations!
Drawing curves with AS2
by admin on Mar.30, 2009, under Tutorials
Now let’s add more curveTo() to our initial code and see if we can improve the way our circle looks!
Replace the code we used in the first part by this one:
with (circle_mc) {
beginFill(0xFF0000);
moveTo(100, 100);
curveTo(150,58,200,58);
curveTo(250,58,300,100);
curveTo(342,150,342,200);
curveTo(342,250,300,300);
curveTo(250,342,200,342);
curveTo(150,342,100,300);
curveTo(58,250,58,200);
curveTo(58,150,100,100);
endFill();
}
Hit "Ctrl+Enter" or go to "Control", "Test Movie" to test our Flash movie. You should see this:
Hey, that’s getting better! Still no perfect though. By using 8 curveTo() we certainly got a better result. But we want something that really looks like a circle don’t we? Now in the "help" section of your Flash software there is an example for drawing circle, let’s try it. Replace the code we used before by this one:
drawCircle(circle2_mc, 200, 200, 100);
function drawCircle(mc:MovieClip, x:Number, y:Number, r:Number):Void {
mc.beginFill(0xff0000);
mc.moveTo(x+r, y);
mc.curveTo(r+x, Math.tan(Math.PI/8)*r+y, Math.sin(Math.PI/4)*r+x, Math.sin(Math.PI/4)*r+y);
mc.curveTo(Math.tan(Math.PI/8)*r+x, r+y, x, r+y);
mc.curveTo(-Math.tan(Math.PI/8)*r+x, r+y, -Math.sin(Math.PI/4)*r+x, Math.sin(Math.PI/4)*r+y);
mc.curveTo(-r+x, Math.tan(Math.PI/8)*r+y, -r+x, y);
mc.curveTo(-r+x, -Math.tan(Math.PI/8)*r+y, -Math.sin(Math.PI/4)*r+x, -Math.sin(Math.PI/4)*r+y);
mc.curveTo(-Math.tan(Math.PI/8)*r+x, -r+y, x, -r+y);
mc.curveTo(Math.tan(Math.PI/8)*r+x, -r+y, Math.sin(Math.PI/4)*r+x, -Math.sin(Math.PI/4)*r+y);
mc.curveTo(r+x, -Math.tan(Math.PI/8)*r+y, r+x, y);
mc.endFill();
}
Here is the result:
That’s a pretty good looking circle right here! This makes use of trigonometry to achieve a better result. I’m not covering trigonometry in this tutorial but maybe in a later one. So let’s just use this drawCircle function and make it into a dynamic application.
this.onMouseDown = function(){
count++;
this.createEmptyMovieClip("circle_mc"+count, count);
var theX=Math.random()*Stage.height;
var theY=Math.random()*Stage.width;
var radius=Math.random()*100;
drawCircle(this["circle_mc"+count], theX, theY, radius);
}
function drawCircle(mc:MovieClip, x:Number, y:Number, r:Number):Void {
mc.beginFill(0xff0000);
mc.moveTo(x+r, y);
mc.curveTo(r+x, Math.tan(Math.PI/8)*r+y, Math.sin(Math.PI/4)*r+x, Math.sin(Math.PI/4)*r+y);
mc.curveTo(Math.tan(Math.PI/8)*r+x, r+y, x, r+y);
mc.curveTo(-Math.tan(Math.PI/8)*r+x, r+y, -Math.sin(Math.PI/4)*r+x, Math.sin(Math.PI/4)*r+y);
mc.curveTo(-r+x, Math.tan(Math.PI/8)*r+y, -r+x, y);
mc.curveTo(-r+x, -Math.tan(Math.PI/8)*r+y, -Math.sin(Math.PI/4)*r+x, -Math.sin(Math.PI/4)*r+y);
mc.curveTo(-Math.tan(Math.PI/8)*r+x, -r+y, x, -r+y);
mc.curveTo(Math.tan(Math.PI/8)*r+x, -r+y, Math.sin(Math.PI/4)*r+x, -Math.sin(Math.PI/4)*r+y);
mc.curveTo(r+x, -Math.tan(Math.PI/8)*r+y, r+x, y);
mc.endFill();
var my_color:Color = new Color(mc);
var myColorTransform:Object = new Object();
myColorTransform.ra = Math.random()*200-100;
myColorTransform.rb = Math.random()*510-255;
myColorTransform.ga = Math.random()*200-100;
myColorTransform.gb = Math.random()*510-255;
myColorTransform.ba = Math.random()*200-100;
myColorTransform.bb =Math.random()*510-255;
myColorTransform.aa = 100;
myColorTransform.ab = Math.random()*510-255;
my_color.setTransform(myColorTransform);
mc.cacheAsBitmap=true;
}
Click many times on the following Flash file and see random circles appearing anywhere with random colors!
But of course drawing circles is not the only thing we can do with the curveTo() method. We can assiociate it with the lineTo() method and draw many different shapes like a rectangle with rounded corners:
with (circle_mc) {
beginFill(0xFF0000);
moveTo(100, 110);
curveTo(100,100,110,100);
lineTo(290,100);
curveTo(300,100,300,110);
lineTo(300,190);
curveTo(300,200,290,200);
lineTo(110,200);
curveTo(100,200,100,190);
endFill();
}
This code draws a rectangle with rounded corners:
Then using gradients we can draw pretty much anything:
this.createEmptyMovieClip("circle_mc", 2);
colors = [0xF0E0F0, 0x0000FF];
fillType = "linear"
alphas = [100, 100];
ratios = [0, 0xFF];
spreadMethod = "reflect";
interpolationMethod = "linearRGB";
focalPointRatio = 1;
matrix = new Matrix();
matrix.createGradientBox(110, 1, Math.PI, 00, 100);
with (circle_mc) {
beginGradientFill(fillType, colors, alphas, ratios, matrix, spreadMethod, interpolationMethod, focalPointRatio);
moveTo(100, 110);
curveTo(50,50,110,50);
curveTo(350,50,300,110);
curveTo(300,200,290,200);
curveTo(100,200,100,190);
endFill();
}
this.createEmptyMovieClip("circle2_mc", 1);
colors2 = [0xF0E0F0, 0x0000FF];
fillType2 = "linear"
alphas2 = [90, 90];
ratios2 = [0, 0xFF];
spreadMethod2 = "reflect";
interpolationMethod2 = "RGB";
focalPointRatio2 = 1;
matrix2 = new Matrix();
matrix2.createGradientBox(300, 100, Math.PI, 100, 500);
with (circle2_mc) {
beginGradientFill(fillType2, colors2, alphas2, ratios2, matrix2, spreadMethod2, interpolationMethod2, focalPointRatio2);
moveTo(20, 200);
curveTo(150,130,380,200);
curveTo(400,300,110,250);
curveTo(10,250,20,200);
endFill();
}
In case you are wondering, it’s supposed to be a hat… well, anyway that’s it for this tutorial. I hope you learned enough to start drawing a lot of cool things! Next time we will see how to draw lines. Contact me if you had any problems running these codes.
Drawing lines with AS2
by admin on Mar.30, 2009, under Tutorials
One use that doesn’t come immediatly in mind for the lineStyle() method is for detecting collision between objects. It’s actualy especialy useful for beginners who don’t want to go through heavy calculation and other trigonometry stuff. Let’s take a look at these two balls bouncing around. The code draws a line between the two balls and output the distance between them in the little text field, when the balls collide, the text shows "Collision!":
You can download the fla file and see how it works but following is the code we use to draw the line and check collision:
this.createEmptyMovieClip("line_mc", 5);
line_mc.lineStyle(1,0×000000,100);
line_mc.moveTo(target_mc._x+target_mc._width/2,target_mc._y+target_mc._height/2);
line_mc.lineTo(secondtarget._x+secondtarget._width/2,secondtarget._y+secondtarget._height/2);
}
This function takes two movie clips as parameter and draw a line between them.
var hyp = Math.sqrt((line_mc._width*line_mc._width)+(line_mc._height*line_mc._height));
distance_txt.text=Math.round(hyp);
We call the function passing our two balls as parameters, then we calculate the size of the line and output it in the distance_txt textfield.
distance_txt.text="Collision!":
}
That’s quite a simple collision test but it’s really efficient.
Of course you can create some basic graphic effects with just lines like in this example:
And here is the code:
number=0;//this variable will give a limit to the number of lines
this.onEnterFrame=function(){
rotate++;//I increment the rotation angle
drawLine(rotate);//I call the drawLine function each frame with the rotate variable as parameter
}
function drawLine(rot:Number){
number++;//I increment the line count
if(number>180){number=0}//I don’t want more than 180 lines on the screen
this.createEmptyMovieClip("line"+number, number);//create lines
this["line"+number].lineStyle(4,0×00FF00,100);
this["line"+number].moveTo(0,0);
this["line"+number].lineTo(200,0);
this["line"+number]._x=Stage.width/2;//position lines
this["line"+number]._y=Stage.height/2;//position lines
this["line"+number]._rotation+=rot;//rotate lines
this["line"+number].onEnterFrame=function(){
this._alpha-=0.5;//fade lines
}
}
The last example is about selecting objects. On your desktop when you click in an empty space then you drag the mouse, you create a "box" inside which when you release the mouse everything will be selected. We can do the same by drawing some lines. Click anywhere and drag the mouse to create a little box around some green squares then release the mouse button.
A shadow shows up for the squares that you "selected", of course there’s no other functionality. Let’s take a quick look at the code:
this.createEmptyMovieClip("line_mc", 50);
with(line_mc){
lineStyle(1,0×000000,50);
moveTo(Xpos,Ypos);
lineTo(theWidth,Ypos);
lineTo(theWidth,theHeight);
lineTo(Xpos,theHeight);
lineTo(Xpos,Ypos);
}
}
The drawLine function takes 4 parameters, Xpos is the x position of the mouse when you first click somewhere on the stage, the Ypos is the y position where you first click somewhere on the stage, the theWidth is the x position of the mouse when you drag the mouse and theHeight is the y position of the mouse when you drag the mouse.
for(i=0;i<10;i++){
eval("square"+i).filters = 0;
}
isDown=true;
xpos=_xmouse;
ypos=_ymouse;
};
When you click the mouse, its x and y coordinates are stored in the xpos and ypos variables and a boolean variable is set to true (isDown).
if(isDown){
var thewidth=_xmouse;
var theheight=_ymouse;
drawLine(xpos,ypos,thewidth,theheight);
}
};
When you move the mouse, Flash checks if you also have the mouse button down: if(isDown). If you do, it assigns constanly the x and y position of the mouse to thewidth and theheight, then it calls the drawLine function with the xpos,ypos,thewidth, and theheight as arguments.
That’s it for this tutorial. Contact me if you have any trouble running or understanding these codes.