Blow an Image Away with a Custom Wind Effect

Blow an Image Away with a Custom Wind Effect

Tutorial Details
  • Difficulty: Intermediate
  • Program: AS3: FlashDevelop (or Flash)
  • Estimated Completion Time: 45 mins
This entry is part 6 of 11 in the GreenSock Tweening Platform Session
« PreviousNext »

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in March, 2010.

In this tutorial, we will create a custom class which breaks a picture into a thousand pieces and simulates a wind blowing them away. I created this project purely with AS3 and FlashDevelop – Flash not required!


Final Result Preview

Let’s take a look at the final result we will be working towards. Go ahead and click anywhere inside the SWF:


Quick Intro to FlashDevelop

FlashDevelop is a free code editor for Flash and Flex. You can use it to edit your class files when working with Flash software, or you can create an AS3 Project that doesn’t require Flash at all – and that’s exactly what we’ll be doing in this tutorial.

So download FlashDevelop and install it. Unfortunately, FlashDevelop only runs on Windows. Mac alternatives include FDT and Flex Builder, though neither are free. You can use Flash itself, and I’ll explain how to do this as we go along.


Step 1: Create a New Project

Open FlashDevelop and click Project>New Project…


Step 2: Set Up

Choose Actionscript 3 > AS3 Project. For the name of the Project put in “WindEffect.” For the location, click and navigate to the folder you would like to save it into. Leave the “Create Directory For Project” checkbox selected and click OK.

If you want to use Flash CS3/CS4, create a new Flash file and set the width and height of the stage to 550x250px, set the background color to black. Name it “windEffect.fla” and save it anywhere you like.


Step 3: Move the Source Image

For FlashDevelop, open the project directory and copy or drag windEffect.jpg from the source download (linked at the top of the page) into the \bin\ folder.

For Flash, copy or drag windEffect.jpg from the source download into the same folder where you have windEffect.fla.


Step 4: Install TweenLite

We’re going to use TweenLite by Greensock for the tweening. You can download the latest version of the component here; I’ve also included it in the source download.

For FlashDevelop, go ahead and copy or drag greensock.swc from the source download into the \lib\ folder for this project.

From FlashDevelop, click View>Project Manager


Step 5: External Library

Still in FlashDevelop, click the ‘+’ sign to the left of the lib folder to expand it. Right-click greensock.swc and select Add To Library.

For Flash, copy or drag the \com\ folder from the source download into the same folder as your windEffect.fla file.


Step 6: The Document Class

For FlashDevelop, open the project manager again (refer to Step 4), expand the \src\ folder and double-click Main.as. Below the imports and right above the class definition, add the following metadata tag to set up the stage properties:

[SWF (width = 550, height = 250, frameRate = 30, backgroundColor = 0)]

Within the init () method after the comment ‘entry point’, add the following code:

stage.scaleMode = StageScaleMode.NO_SCALE;	//don't stretch the stage
var effect:WindEffect = new WindEffect('windEffect.jpg');	//we will create the WindEffect class soon
addChild (effect);

That’s it for the Main document class.

For Flash, create a new Main.as class in the same folder as your project. Make sure the Main.as class is in the same folder as the fla. & com folder. Add the following lines:

package
{
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;

	public class Main extends Sprite
	{

		public function Main():void
 		{
 			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
 		}

		private function init(e:Event = null):void
 		{
 			removeEventListener(Event.ADDED_TO_STAGE, init);
 			stage.scaleMode = StageScaleMode.NO_SCALE;	//don't stretch the stage

 			var effect:WindEffect = new WindEffect ('windEffect.jpg');	//we will create the WindEffect class soon
 			addChild (effect);
 		}
 	 }
}

Open Flash and assign “Main” as the Document class.

(Not sure what this is all about? Read this quick introduction to using a document class.)

If you try to run this now, you will get an error since we haven’t created the WindEffect class yet. Just make sure you save the file and leave it for now.


Step 7: Create the WindEffect Class

For FlashDevelop, click View>Project Manager, right-click the \src\ folder and choose Add>New Class.


Step 8: Setting Up the Class

Name the class WindEffect, click the browse button for the base class and enter flash.display.Sprite. Hit OK to complete.


Step 9: Importing Other Classes

Add all the necessary imports inside the package brackets right below ‘import flash.display.Sprite;’ and before the class definition. Click Save.

import com.greensock.easing.Strong;
import com.greensock.TweenLite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.net.URLRequest;

For Flash, create a new ActionScript file, name it “WindEffect.as” and save it in the same directory you have been using. It should be right next to the fla. file, com folder, and Main.as.

Add the following code:

package
{
	import com.greensock.easing.Strong;
	import com.greensock.TweenLite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;

	public class WindEffect extends Sprite
	{
		public function WindEffect ()
		{

		}

	}

}

Step 10: Add an Instance Variable

Add a private variable called “_pictureArray.” This is the only variable we will have in this class. Its main purpose is to hold references to all the small sprites that contain the little pieces of the picture once it’s been broken up.

Add the following line of code within the brackets
of the class:

public class WindEffect extends Sprite
{
	//this will house all the pieces of the picture we will animate.
	private var _pictureArray:Array;
}

Step 11: Add the Constructor

Add the following lines after the _pictureArray declaration:

public class WindEffect extends Sprite
{
	//this will house all the pieces of the picture we will animate.
	private var _pictureArray:Array;

	public function WindEffect ($url:String)
	{
		//we just call the load picture in the constructor
		loadPicture ($url);
	}
}

Step 12: Access the Image

Inside the loadPicture () method called by the constructor method, we instantiate a loader to load the windEffect.jpg. We also add a COMPLETE event listener to listen for when the load completes.

Add the following lines of code after the WindEffect () method. (Note that the parameter “$url” is the path to the picture we are loading passed from Main.as.)

private function loadPicture ($url:String):void
{
	//we create a loader with listeners to load the source picture we are using.
	//and then we load the image.
	var loader:Loader = new Loader;
	loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete);		//when it's loaded, call the onLoadComplete () function
	loader.load (new URLRequest ($url));
}

Step 13: Loading

After the image has been imported properly, this method is called. Add the following lines of code after the loadPicture () method and save the file.

private function onLoadComplete (e:Event):void
{
	//for testing
	addChild (e.target.content);
}

Step 14: Test One

Go ahead and hit CTRL + Enter on you keyboard. It should work and the image should be on the left top corner of the stage.

Now that we’ve checked it’s loading correctly, remove the addChild method and replace it with the following code:

createEffect (e.target.content);

Your WindEffect class should look something like this:

package
{
	import com.greensock.easing.Strong;
	import com.greensock.TweenLite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;

	[SWF (width = 550, height = 250, frameRate = 30, backgroundColor = 0)]

	public class WindEffect extends Sprite
	{
		private var _pictureArray:Array;

		public function WindEffect ($url:String)
		{
			loadPicture ($url);
		}
		private function loadPicture ($url:String):void
		{
			var loader:Loader = new Loader;
			loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete);
			loader.load (new URLRequest ($url));
		}

		private function onLoadComplete (e:Event):void
		{
			createEffect (e.target.content);
		}

	}

}

Step 15: Set up the Variables

The createEffect () Method will take the image parameter which is essentially a bitmap and break it down to 1250 pieces.

First we calculate the x- and y-positions to center the image on the stage. We save them into local variables called centerWidth and centerHeight.

Since the size of the image we are using is 300×100, I decided to divide the image 50 times horizontally and 25 times vertically. These values gave a pretty decent result with optimum performance. We save them in local variables, which I named “numberOfColumns” and “numberOfRows.”

We save the result of dividing the image’s width by numberOfColumns into “sizeWidth” and the result of dividing the image’s height by numberOfRows into “sizeHeight.”

The “numberOfBoxes” variable holds numberOfColumns multiplied by numberOfRows.

Next we instantiate _pictureArray so we can start putting small sprites into it. Add the following lines of code after the onLoadComplete () method:

private function createEffect ($bitmap:Bitmap):void
{
	//center the image horizontally.
	var centerWidth:Number = (stage.stageWidth - $bitmap.width) * .5;

	//center the image vertically.
	var centerHeight:Number = (stage.stageHeight - $bitmap.height) * .5;

	var numberOfColumns:uint = 50;
	var numberOfRows:uint = 25;
	var sizeWidth:uint = $bitmap.width / numberOfColumns;
	var sizeHeight:uint = $bitmap.height / numberOfRows;
	var numberOfBoxes:uint = numberOfColumns * numberOfRows;
	_pictureArray = [];

}

Step 16: Nested Loops

After instantiating _pictureArray we will add two loops, one inside the other. The first loop will handle moving on the x-position and will loop through all the columns, while the second loop will move on the y-position and will loop through all the rows.

Add the following lines of code inside the createEffect () method right after instantiating _pictureArray, then save the file:

for (var i:uint = 0; i < numberOfColumns; i++)
{
	//these loops are what splits the image into 1250 pieces.
	for (var j:uint = 0; j < numberOfRows; j++)
	{
		//let's see what it does.
		trace ('i:' + i, 'j:' + j);
	}
}

Step 17: Test Two

Test the movie by hitting CTRL + Enter.

As you can see, for every i there is a full loop of j. This is called “nesting loops”. This means that i which represents the x axis stays on one value while the second loop iterates for the y axis.

Put simply, we start with x=0, y=0; then the next iteration is x=0, y=1; then x=0, y=2, and so on.

When y reaches the end, the first loop increments by 1 and then again goes through the 2nd loop: x=1, y=0; x=1, y=1, x=1, y=2, etc. This goes on until the 1st loop completes.

You’ll see what this does when we apply it to some bitmap manipulation in the next few lines.


Step 18: Splitting the Image

From within the second loop, go ahead and remove the trace function we used for testing. Every time we loop we need to create a small picture having the width of “sizeWidth” and the height of “sizeHeight.”

This small picture will take a snap shot of a small part of the image starting from the top-left corner and moving through to the bottom-right. The “tempBitmapData” is where we will draw the small portion of the image. The “sourceRect” is the rectangle we will use to specify which part of the image will be copied.

Add the following lines inside the 2nd loop and save the file:

//1 temporary bitmapdata
var tempBitmapData:BitmapData = new BitmapData (sizeWidth, sizeHeight);

//1 temporary rectangle (x,y,width,height)
//we pass i * sizeWidth for the x parameter  & i * sizeHeight for the y parameter
//and the sizeWidth & sizeHeight for the width and height parameters.
var sourceRect:Rectangle = new Rectangle (i * sizeWidth, j * sizeHeight, sizeWidth, sizeHeight);
trace (sourceRect);//for testing

Step 19: Even More Testing

Test the movie. What it does now is create a rectangle that adjusts its x- and y-positions each iteration.

As you can see, the 1st example shows x=0, y=0 and the next is x=0, y=4. This is what what we use for boundaries of the snap shot taken from the source image. Remove the test function when you’re ready to move on.


Step 20: BitmapData.copyPixels()

We then use the BitmapData.copyPixels () method to copy a small piece of the image based on the sourceRect. The parameters for this method are the bitmap image to copy, the rectangle area to copy and the destination point to where we will copy it.

Add the following line of code below the sourceRect declaration.

tempBitmapData.copyPixels ($bitmap.bitmapData, sourceRect, new Point);

We then create one temporary Bitmap to house the BitmapData we just copied and one temporary Sprite to house that Bitmap.

Then we push a reference of each Sprite onto _pictureArray for access later. After this we add the Sprite to the stage with the same coordinate as where we copied it from, thus recreating the original image.

We then offset the image by centerWidth and centerHeight to center it correctly on the stage.

Add the following lines of code and, once again, save the file:

//we then create 1 temporary bitmap to house the bitmapdata we just copied.
var tempBitmap:Bitmap = new Bitmap (tempBitmapData);

//and 1 temporary sprite to house the bitmap to enable interactivity.
var tempSprite:Sprite = new Sprite;

//we just add each box inside it's own sprite to enable interactivity since bitmaps by themselves are not interactive.
tempSprite.addChild (tempBitmap);

//each sprite is added into the _pictureArray array for access later.
_pictureArray.push (tempSprite);

//then position each of them onto the stage. 
//We add the center width & center height so image centers on the stage.
tempSprite.x = i * sizeWidth + centerWidth;
tempSprite.y = j * sizeHeight + centerHeight;
addChild (tempSprite);

Step 21: Test Three

Go ahead and test it again. You should see the image correctly laid out on the stage. It won’t even look like it’s been separated into 1250 pieces.

Right after the closing bracket of the second loop, before we close the method, add the following line of code:

stage.addEventListener (MouseEvent.CLICK, blowWind);

We add an event listener to the stage to listen for a MouseEvent.CLICK. This will trigger the animation by running the blowWind() function, which we’ll create in the next step.

Your WindEffect class should look something like this:

package
{
	import com.greensock.easing.Strong;
	import com.greensock.TweenLite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;

	public class WindEffect extends Sprite
	{
		private var _pictureArray:Array;
	
		public function WindEffect ($url:String)
		{
			loadPicture ($url);
		}
		private function loadPicture ($url:String):void
		{
			var loader:Loader = new Loader;
			loader.contentLoaderInfo.addEventListener (Event.COMPLETE, onLoadComplete);
			loader.load (new URLRequest ($url));
		}

		private function onLoadComplete (e:Event):void
		{
			createEffect (e.target.content);
		}

		private function createEffect ($bitmap:Bitmap):void
		{
			var centerWidth:Number = (stage.stageWidth - $bitmap.width) * .5;
			var centerHeight:Number = (stage.stageHeight - $bitmap.height) * .5;

			var numberOfColumns:uint = 50;
			var numberOfRows:uint = 25;
			var sizeWidth:uint = $bitmap.width / numberOfColumns;
			var sizeHeight:uint = $bitmap.height / numberOfRows;
			var numberOfBoxes:uint = numberOfColumns * numberOfRows;
			_pictureArray = [];

			for (var i:uint = 0; i < numberOfColumns; i++)
			{
				for (var j:uint = 0; j < numberOfRows; j++)
				{
					var tempBitmapData:BitmapData = new BitmapData (sizeWidth, sizeHeight);

					var sourceRect:Rectangle = new Rectangle (i * sizeWidth, j * sizeHeight, sizeWidth, sizeHeight);
	
					tempBitmapData.copyPixels ($bitmap.bitmapData, sourceRect, new Point);
					var tempBitmap:Bitmap = new Bitmap (tempBitmapData);
					var tempSprite:Sprite = new Sprite;
					tempSprite.addChild (tempBitmap);
					_pictureArray.push (tempSprite);
					tempSprite.x = i * sizeWidth + centerWidth;
					tempSprite.y = j * sizeHeight + centerHeight;
					addChild (tempSprite);
				}
			}
			stage.addEventListener (MouseEvent.CLICK, blowWind);
		}
	}
}

Step 22: Creating the Wind Effect

Start off by removing the MouseEvent.CLICK event listener since we need it to happen only once. Add the following lines of code after the createEffect () method:

private function blowWind (e:MouseEvent):void 
{
	stage.removeEventListener (MouseEvent.CLICK, blowWind);
}

We need to go through all the sprites we assigned into _pictureArray and animate them individually.

TweenLite is applied to animate all the pieces towards the right as if wind were blowing on them.

The parameters are: the target for the tween, the duration of the tween, a variable object that holds all the properties, along with the values you want to apply the tween to.

For example: TweenLite.to (target, duration, {x:100, y:100, rotation:30, ease:Strong.easeIn, onComplete:trace, onCompleteParams:['hello']}).

The above example’s last two parameters are used for when the tween finishes. The onComplete parameter calls the trace function and the onCompleteParams parameter sends an array containing the string ‘hello’ into the trace function.

Add the following lines of code right after the remove event listener:

for (var i:uint = 0; i < _pictureArray.length; i++)
{
	TweenLite.to (
	_pictureArray[i],
	getRandomInRange (.25, 2, false),
	{
		x: stage.stageWidth + 100,
		y:_pictureArray[i].y + getRandomInRange (-100, 100, false),//
		rotation: getRandomInRange (-90, 90),
		ease:Strong.easeIn,
		onComplete:removeSprite,
		onCompleteParams:[_pictureArray[i]]
	}
	);
}

In the actual implementation, when we call TweenLite from within the loop, we assign the target as _pictureArray[current iteration].

For the duration we assign a value for the length of the tween to a random time between .25 seconds and 2 seconds.

The variable object holds 5 properties:

  • x:stage.stageWidth + 100 which will animate the sprite’s x property.
  • y:_pictureArray[i].y + getRandomRange (-100,100,false) which will get the current sprite’s y position and add a random number between -100 and 100 to give the animation an expanding effect.
  • rotation:getRandomRange (-90,90) rotates the current sprite to anywhere between -90 and 90 degrees.
  • ease:Strong.easeIn which makes the tween start slowly and suddenly speed up.
  • onComplete:removeSprite which calls the removeSprite method once the tween has finished and the Sprite is off the screen.
  • onCompleteParams which sends the array [_pictureArray[current iteration]] as the parameter for removeSprite.

Step 23: removeSprite () Method

This method is called from TweenLite when the animation for a particular tween has finished. We just remove the Sprite from the display list so there’s no clutter. Add the following lines of code after the blowWind () method:

private function removeSprite ($sprite:Sprite):void
{
	removeChild ($sprite);
}

Step 24: getRandomInRange () Method

I’m sure you’re familiar with this one (if not, Carlos Yanez has written a Quick Tip on the subject.) My version has an option of returning either whole numbers (int, uint) or floats (fractions).

Add the following lines of code. If you’re using FlashDevelop, you can save it as a custom snippet so it’s easily added to any class/project. I have it declared as a public static method for full accessibility.

public static function getRandomInRange ($min:Number, $max:Number, $rounded:Boolean = true):Number
{
	if ($rounded) return Math.round (Math.random () * ($max - $min) + $min);
	else return Math.random () * ($max - $min) + $min;
}

That’s it! Run the movie. If there’s anything wrong, check your code against the WindEffect class I’ve included in the source download.


Conclusion

The key to creating cool effects is to learn and master both image manipulation and animation tweening classes like TweenLite. Please feel free to drop a note for any comments, concerns, or suggestions. Thanks for reading!

  • Tayfi

    Hi,
    I really like your tutorial . Great

  • Pingback: uberVU - social comments

  • Pingback: Tweets that mention Blow an Image Away with a Custom Wind Effect | Activetuts+ -- Topsy.com

  • http://www.superdwayne.co.uk Dwayne Paisley-Marshall

    That was so awesome, my flash skills are coming back to me.

    More tutorials needed. Awesome post

  • http://www.aiveacommerceserver.com/ Aivea

    Excellent post. Keep up the working and looking forward to more great articles in the future.

  • Axel

    maybe its just me but is the actual flash file is not there, only the action script files, the jpeg image, the greenstock, and the greenstock flash component file. am i missing something?

    • Nick

      The author has created the effect in flashdevelop therefore if you set up flash develop and import the files into it you can compile from there and see the effect. Pure AS3 projects are normally done in an external IDE (not the flash environment) as external ide’s have much better actionscript support than flash does..ironic really.

      • Axel

        Thanks, i thought i was doing something wrong! :)

    • bruno crociquia

      you do however need flex sdk to compile trough flash develop though

  • http://gamedive.blogspot.com/ Gamer

    Cool wind :)
    Thanks!

  • http://www.dcomsoft.com/obfuscate-swf.html Roy

    Wind is great! +1

  • sharath

    for me only the the last part of the bitmap gets displayed while running.can u plz suggest me what could be wrong

    • John Reyes
      Author

      Hi,
      Could you explain exactly what happens and when?
      Thanks

  • http://activeden.net/user/flashjunkie FlashJunkie

    Awesome tut, i did something similar a while back for my template that i released.

    Yours is much more efficient and better coded though i must say!

    Keep the tuts coming!

  • http://www.giuliandrimba.com giulian Drimba

    Very nice tutorial!!!

  • treeloy

    I’m pretty new to the AS3 environment and am trying to incorporate this in a flash file based on the timeline. Meaning I would either like to directly incorporate this in the timeline so that each frame can add a different animation directly in flash or to somehow just call to the class file based on the timeline (frame). The latter of which would mean I would have to create a new class for every new animation (each new animation will use a new picture too). Which all brings me to the question I have. Would it be possible to rewrite the code a bit here to be directly incorporated into flash without calling to an external class file? It is probably asking a bit much of you to do this, but my skills at flash (or rather lack thereof) are making it pretty difficult for me to set this up correctly.

    • John Reyes
      Author

      Ok. This would require us to change the WindEffect class just a little bit. Right inside step 23 right below removeChild ($sprite), add the following lines of code –

      if ($sprite == _picturesArray[_picturesArray.length - 1]) dispatchEvent (new Event (WIND_EFFECT_COMPLETE, true));

      Go to the top of the class just on top of – ‘var _pictureArray:Array;’ and right below the class open bracket ‘{‘. Add –

      public static const WIND_EFFECT_COMPLETE:String = ‘windEffectComplete’;

      Save the file.

      Keep the class saved right next to the fla you will use it with. Don’t forget to keep the greensock folder with the file as well as all the pictures you want to use with the WindEffect.

      Open the framescript window in frame 1.
      add an array: var picArray:Array = [];

      inside the square brackets of the picArray, add the names of the pictures in string format delimited by a comma. ex. ['pic1.jpg', 'pic2.jpg', 'pic3.jpg'];

      create a counter variable:
      var counter:uint = 0;

      create a function to start the program:

      function createWindEffect ():void
      {

      }

    • John Reyes
      Author

      Ok. This would require us to change the WindEffect class just a little bit. Right inside step 23 right below removeChild ($sprite), add the following lines of code –

      if ($sprite == _picturesArray[_picturesArray.length - 1]) dispatchEvent (new Event (WIND_EFFECT_COMPLETE, true));

      Go to the top of the class just on top of – ‘var _pictureArray:Array;’ and right below the class open bracket ‘{‘. Add –

      public static const WIND_EFFECT_COMPLETE:String = ‘windEffectComplete’;

      Save the file.

      Keep the class saved right next to the fla you will use it with. Don’t forget to keep the greensock folder with the file as well as all the pictures you want to use with the WindEffect.

      Open the framescript window in frame 1.
      add an array: var picArray:Array = [];

      inside the square brackets of the picArray, add the names of the pictures in string format delimited by a comma. ex. ['pic1.jpg', 'pic2.jpg', 'pic3.jpg'];

      create a counter variable:
      var counter:uint = 0;

      create a function to start the program:

      function createWindEffect ():void
      {
      var windEffect:WindEffect = new WindEffect (picArray[counter]);
      counter++;
      if (counter >= picArray.length) counter = 0;
      windEffect.addEventListener (WindEffect.WIND_EFFECT_COMPLETE, onComplete);
      }

      function onComplete (e:Event):void
      {
      createWindEffect ()
      }

      I think this should do the trick.

      Let me know… = )

      • treeloy

        Wow, thanks for the help. I don’t have the time quite yet to give it a go. But will within the next few days. Either way, this is really awesome of you. Many thanks ahead of time.

      • John Reyes
        Author

        You are welcome! =)

        Don’t forget to add ‘createWindEffect ()’ at the end after the onComplete function. We call it to start the loop.

  • treeloy

    Finally got the time to try my hand at this. I think I was a bit unclear about my original comment. Actually, I wasn’t trying to create a picture loop with the effect, but rather just strip all the private/public from the class to incorporate the same idea within flash. At the moment, I’m in the process of trying to take out all the external class code so that I can incorporate it on a particular frame of the timeline directly. That way, after the tween ends, I can do an onComplete to start another animation (not this effect) and so forth. This way, I can put this code on some frames, and leave others without. This will, in the end, be a long Timeline with several different effects/animations where one picture comes in, then fades out, then another comes in and so forth. So in the end, instead of an external class, I will (try to) incorporate it directly in flash. I’ll keep you updated how I progress (or fail). Or maybe I’m going about this inefficiently?

  • treeloy

    Found a solution to achieve what I was looking for.

    • john reyes
      Author

      good for you! =)

  • http://www.juxt2.com Dimitree

    How about regenerate the bitmap? Can you give a solution John?

    • john reyes
      Author

      You’ll need to add a new class variable and name it something like _positionsArray and assign it [] as you declare it.
      In Step 21, see inside the dual loop where you see the codes:
      tempSprite.x = i * sizeWidth + centerWidth;
      tempSprite.y = j * sizeHeight + centerHeight;

      add below it:
      _positionsArray.push (new Point (tempSprite.x, tempSprite.y);

      Now when the tweens finish and you want the pictures go back to its place on the stage,
      you can create another function:

      public function returnToStagePos ():void
      {
      for (var i:uint = 0; i < _pictureArray.length; i++)
      {
      addChild (_pictureArray[i]);//remember to add them back into the display list.

      TweenLite.to (
      _pictureArray[i],
      getRandomInRange (.25, 2, false),
      {
      x: _positionsArray[i].x,
      y: _postionsArray[i].y,
      rotation: 0),
      ease:Strong.easeIn
      }
      );
      }
      }

      Change the removeSprite () method from step 23 to:

      private function removeSprite ($sprite:Sprite):void
      {
      removeChild ($sprite);

      if ($sprite == _pictureArray[_pictureArray.length-1]) returnToStagePos ();
      }

      Try it out & let me know… =)

      • http://www.juxt2.com Dimitree

        It worked perfect! Thanks for your response.
        Another thing I was wondering, instead of the nested loops could you just use a modulo operator?

      • John Reyes
        Author

        Give it a shot… =)

        What kind of effect are you trying to achieve?

      • http://www.juxt2.com Dimitree

        no, I was wondering that instead of the nested loops you could use a modulo operator to “make” the grid that contains the particles like:

        var boxNum:int = 15;
        var cols:int = 4;

        for (var i:int = 0; i<boxNum; i++) {

        var box:Box = new Box();

        box.x = 50 + box.width * (i % cols);

        box.y = 50 + box.height * int(i / cols);

        }

        I was just wondering If something like that could be also done? (for educational reasons…)

      • John Reyes
        Author

        Oh, yes. So many ways to do it. It’s just a matter of choice.
        You just need to weigh which approach performs best… =)

  • noblesilence

    Excellent tutorial. Thank you so much.

  • treeloy

    Would it be possible to make the picture full width to the screen resolution? Or would that screw up the pieces being divided up. O.K….O.K…..I sure wouldn’t mind an example of how that would be done too :)

  • John Reyes
    Author

    All you have to do is use an image with the width of your choice. Try using a much bigger image. The pieces will not get messed up in any way.

  • Steve MacKenzie

    John, I got the animation working perfectly but I’m embedding it into an HTML file and I would like it to automatically load another html page after the animation is done blowing the image away. How would I go about doing this? Any help would be greatly appreciated! Thanks!

    • briandinlee

      I was curious about this too… Any ideas?

    • John Reyes
      Author

      add the code below at the end of the removeSprite () method:
      navigateToURL(new URLRequest(“http://www.thepageyoudliketoload.com/”));

      then add an import for ‘flash.net.URLRequest;’ at the top of the page with the other imports.

  • Pingback: AS3 Tutorials | cpunx.com

  • surya

    is the revese possible ?
    i mean particles forming in to a image
    can u post a tutorial for that (post the link if already exist)

    • Raymond

      I was going to ask that! Better still would be to have the image blow in from the left. I would also like to have the wind blow the image away to reveal a second image on the background.

    • John Reyes
      Author

      Hey guys… =)
      see the comment I posted on April 27, 2010 at 4:36 pm. (above)
      That should do the trick… =)

  • surya
    • John Reyes
      Author

      Nothing’s coming out of the swf file…
      anyway, try to follow the full tutorial then modify it with the code I posted in reply to Dimitri’s question. It’s a few posts above this one date stamped April 27, 2010 at 4:36 pm.

      Thanks!

  • surya

    please download the file and see

    • John Reyes
      Author

      Hi,
      I downloaded the file again but it’s the same thing, nothing comes out of it. No animation at all?
      Maybe it’s missing its source assets…

  • Phil

    Great tutorial, took a little bit of adapting to Flash builder but not too complicated. Thank you.

  • X10

    This is a fantastic tutorial, thank you John Reyes.
    One question, can this be adapted to create the effect on the current stage image, rather than an external image file?
    I’m using TweenLite to animate and would like to incorporate this effect at one point in the animation, is this something that can be done?
    I’m not very familiar with image manipulation so I would be very greatful for any pointers!

    Thank you,
    X10

    • John Reyes
      Author

      Hi,
      Yes this is easy to apply. Just copy the stage into the bitmapData instead of the loaded image and it should work.
      Good luck!

  • Pingback: Mit reinfliegenden Punkten Bild erzeugen - Flashforum

  • http://blog.flashdesign-store.com/ Horatiu Condrea

    Nice Effect!

  • http://servmet.com James

    I’m trying to beging my image integrated with this effect but i just can’t do it… I’ve do it the inverse (as the tutorial and reintegrated after blow away the image) but I just wanna do it to show up the image with this effect… anyone can help me please!?

    • John Reyes
      Author

      Hi James,
      So sorry for not being able to respond so soon.

      Anyway, to accomplish what you’re describing, when you instantiate the pieces of the image on the stage, save all the correct “x,y” positions into a two-dimensional array then use a random position for the Tween’s start position.

      I hope that helped.

  • Tenri

    Nice tutorial, john! but can i create the effect without using TweenLite. If can, how to doing it..?
    Thanks for your attention…

  • Pingback: Флеш-урок. Сoздaние Эффeктa Вeтpa нa AS3 | flashthemes.ru

  • Steven

    Is there a way to do this in the flash document itself, with an instance named image?

  • smalls009

    Hi, i’m trying to add a website after the animation completes. I saw your earlier post saying that code:

    navigateToURL(new URLRequest(“http://www.thepageyoudliketoload.com/”));

    after: private function removeSprite ($sprite:Sprite):void
    {
    removeChild ($sprite);
    }
    then import the URL request at the top with the others. It doesn’t seem to be working. I’ve tried with my edited sources and the source you’ve provided.
    It just brings up this error for both: 1180: Call to a possibly undefined method navigateToURL.

    Any ideas what i’m doing wrong?
    Thanks :)

    • Steven S

      add to imports:

      import flash.net.navtigatetourl;

      …the problem i’ve run into is that it doesn’t wait for the animation to complete…

  • Steven S

    John, great tutorial, I must admit that my flash skills are not quite at the level where I can understand how to make this happen as a second frame within flash cs5. I have a magazine cover which twirls in from the bottom and I would like to use your windeffect to blow it out to the right, right after it cyclones in…can you explain how I would do this?