Oneupweb : Creating Waves with ActionScript

I’m currently working on a project that requires a non-linear wave effect in flash. Rather than spending time to search for a script and having to figure out how to implement it, I decided to write my own that could be bent to fit my needs. Specifically, I wanted to create something that generated vector graphics that I could then translate into z-space for a 3D animation.

This post wont go into the 3D aspect, but will show you how you can use Points and Math functions to create an authentic wave in the wind effect starting from a static point.

What you’ll get

Below is the class that you can use in any ActionScript3 project. I greatly reduced the code in this tutorial for simplicity. I’ll add more options in a followup post later, so if there’s something specific you would like to see added, please leave a comment.

Wave.as

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;

	public class Wave extends Sprite
	{
		private var _width:Number;
		private var _height:Number;
		private var _segments:Number;
		private var _progress:Number = 0;
		private var _points:Array = [];

		public function Wave(wth:Number=300, hgt:Number=50, seg:Number=20)
		{
			_width = wth;
			_height = hgt;
			_segments = Math.max(2, seg);

			addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			setPoints();
			addEventListener(Event.ENTER_FRAME, waveIt);
		}

		private function setPoints():void
		{
			var amount:Number = 1/(_segments-1)*_width;
			for(var i:uint=0; i<_segments; i++){
				_points.push(new Point(i*amount,0));
			}
		}

		private function waveIt(e:Event):void
		{
			_progress -= .15;
			var amount:Number = 1/(_segments-1);

			graphics.clear();
			graphics.lineStyle(1,0x000000);

			for(var i:uint=0; i<_points.length; i++){
				var p:Point = _points[i];
				var off:Number = i*amount;
				var amt:Number = Math.sin(_progress+Math.PI*2*off)*_height/2*off;
				p.y = amt;
				if(i){
					graphics.lineTo(p.x,p.y);
				} else {
					graphics.moveTo(p.x,p.y);
				}
			}
		}
	}
}

How to use it

The first thing you'll want to do is either place the above class file in the same folder as your fla, or add it to your actionscript folder.

Now that it's accessible, using it couldn't be more simple. Just add the following lines to your timeline via the actions window...

var wave:Wave = new Wave();
wave.y = stage.stageHeight/2;
addChild(wave);

There are also some optional variables available: Wave(width,height,segments)

width effects the length of the line and height effects the largest size of the wave.

segments represent the number of Points generated to achieve the waving effect. The more points used the smoother the wave will look, but will require more computing power.

That's all for now... stay tuned for part two!