Flash content on iPhone and the likes

7 10 2009

Finally, Flash developed content can be viewed on iPod, Android, Blackberry, and many more such devices. The new version of Flash Player – 10.1 will have support on a broader set of devices.

Read announcement from Adobe MAX.

Advertisements




New name for FlexBuilder

29 05 2009

Interesting news!! FlexBuilder is being rebranded to a new name – FlashBuilder. I feel this is more intuitive than earlier. Basically FlexBuilder is a tool for creating flash applications only. Whether you use Flex SDK or just plain actionscript, that’s upto you.

Check this article by Lee Brimelow.






Generate PDF on client side

11 02 2009

I just came across this link which is an open source library for generating PDFs on client side using actionscript 3.0. Wow! it is, obviously, a fantastic utility!

http://alivepdf.bytearray.org/?page_id=2

Alive PDF

Alive PDF





Adobe Flash Catalyst – Coming Soon

6 12 2008

One grievance that Flash designers have about the evolution of Flash IDE is that it has become more developer oriented than (as originally intended) designer friendly. Earlier designers could easily add interactivity using the menu driven coding. The Expert Mode for the code editor was a secondary option (Flash 4 and 5 .)

Well, Adobe is certainly an organization which is very sensitive towards its core customers (i.e. designers.) and have announced a new product called Adobe Flash Catalyst (earlier codenamed Thermo.) Catalyst is a tool targetted for designers who want to add interactivity to their design. The result is that we can create a UI in Catalyst and then just convert graphics into dynamic content by selecting objects and specifying actions from menus. No coding required. Output the file as a SWF or AIR. You can easily build a RIA prototype.

Catalyst will be launched very soon. Read more about it here…

http://labs.adobe.com/technologies/flashcatalyst/





Collision Detection

4 12 2008

Whether it’s a shooting game, a car racing, a pin ball, or a pac man game, collision detection is one of the most important aspects in building games. Without proper colision detection none of these games can exist in Flash. I want to share a very basic collision detection using a ball bounce example. Below, see how the ball bounces back when it hits any of the side walls or the moving wall in the center.

BallBounce.swf

BallBounce in Flash AS3 using hitTestObject()

BallBounce in Flash AS3 using hitTestObject()

Here, collision is detected using two AS3.0 techniques:

1. movieclip1.hitTestObject(movieClip2)
2. checking the overlapping of x and y coordinates of the two movieclips

I have also used a custom event (BounceEvent) that helps in announcing when the ball hits a wall and specifically which wall(or which side.)

There are 5 classes being used in this example:

1. Ball: A ball that will move and bounce around.
2. MovingWall: A movieclip in the center that is constantly moving to create obstruction for the ball.
3. Splat: A movieclip object to show the collision effect.
4. BounceEvent: A custom event to announce that a ball has hit the wall.
5. main: This is the document class. Initiates all the objects and controls the collision detection.

Ball.as

package
{
	import flash.display.MovieClip;
	public class Ball extends MovieClip
	{
		public function Ball(xPos:Number, yPos:Number)
		{

			var b:MovieClip = new MovieClip();
			b.graphics.beginFill(0xFF9933);
			b.graphics.drawCircle(0, 0, 10);
			x = xPos;
			y = yPos;
			addChild(b);
		}
	}
}

Splat.as

package
{
	import flash.display.MovieClip;
	import fl.transitions.Tween;
	import fl.transitions.easing.*;
	public class Splat extends MovieClip
	{
		public function Splat()
		{
			alpha = 0;
		}

		public function explode(xPos:Number, yPos:Number):void
		{
			x = xPos;
			y = yPos;

			new Tween(this, "alpha", Strong.easeOut, 30, 0, 0.2, true);
		}
	}
}

MovingWall.as

package
{
	import flash.display.MovieClip;
	import flash.events.Event;
	public class MovingWall extends MovieClip
	{
		private var wallVelocityY:Number = 3;
		public function MovingWall(xPos:Number, yPos:Number)
		{
			x = 130;
			y = 40;
			setMotion();
		}
		private function setMotion():void
		{
			addEventListener(Event.ENTER_FRAME, moveWall);
		}
		private function moveWall(event:Event):void
		{
			y += wallVelocityY;
			if (y <= 40)
			{
				wallVelocityY = Math.abs(wallVelocityY);
			}
			else if (y >= 120)
			{
				wallVelocityY = -Math.abs(wallVelocityY);
			}
		}
	}
}

BounceEvent.as

package
{
	import flash.events.Event;
	public class BounceEvent extends Event
	{
		public static const BOUNCE:String = "Bounce";
		private var _side:String = "none";

		public function get side():String
		{
			return _side;
		}

		public function BounceEvent(type:String, side:String)
		{
			super(type, true);
			_side = side;
		}

		public override function clone():Event
		{
			return new BounceEvent(type, _side);
		}
	}
}

main.as

This is where the real action happens. First we instantiate the ball, movingWall, and the splat objects. Then we set the ball in motion. And then, using hitTestObject() we check when the ball hits the side walls. Using the custom BounceEvent we make an announcement when the ball hits a wall. The event also lets us know which wall has been hit. For the moving wall after checking with hitTestObject() we also need to find out which side of the wall has been hit. For that we check the overlapping of x and y coordinates of the ball and the moving wall.

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

	public class main extends Sprite
	{
		private var ballVelocityX:Number = 2;
		private var ballVelocityY:Number = 3;
		private var ball:MovieClip;
		private var movingWall:MovingWall;
		private var splat:Splat;
		public function main()
		{
			stage.frameRate = 36;
			setGraphicObjects();
			startBallMotion();
		}
		private function setGraphicObjects():void
		{
			ball = new Ball(100, 100);
			addChild(ball);
			movingWall = new MovingWall(130, 40);
			addChild(movingWall);
			splat = new Splat();
			addChild(splat);
		}
		private function startBallMotion():void
		{
			ball.addEventListener(Event.ENTER_FRAME, moveball)
			addEventListener(BounceEvent.BOUNCE, bounceHandler);
		}
		private function moveball(event:Event):void
		{
			event.target.x += ballVelocityX;
			event.target.y += ballVelocityY;
			sideWallCollision();
			movingWallCollision();
		}
		private function sideWallCollision():void
		{
			if (ball.hitTestObject(wallLeft))
			{
				ballVelocityX = Math.abs(ballVelocityX);
				ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "left"));
			}
			else if (ball.hitTestObject(wallRight))
			{
				ballVelocityX = -Math.abs(ballVelocityX);
				ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "right"));
			}
			if (ball.hitTestObject(wallTop))
			{
				ballVelocityY = Math.abs(ballVelocityY);
				ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "top"));
			}
			else if (ball.hitTestObject(wallBottom))
			{
				ballVelocityY = -Math.abs(ballVelocityY);
				ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "bottom"));
			}
		}
		private function movingWallCollision():void
		{
			if (ball.hitTestObject(movingWall))
			{
				var movingWallLeft:Number = movingWall.x;
				var movingWallRight:Number = movingWall.x + movingWall.width;
				var movingWallTop:Number = movingWall.y;
				var movingWallBottom:Number = movingWall.y + movingWall.height;
				if (ball.x >= movingWallLeft)
				{
					ballVelocityX = -Math.abs(ballVelocityX);
					ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "center left"));
				}
				else if (ball.x <= movingWallRight)
				{
					ballVelocityX = Math.abs(ballVelocityX);
					ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "center right"));
				}
				if (ball.y >= movingWallTop)
				{
					ballVelocityX = -Math.abs(ballVelocityY);
					ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "center top"));
				}
				else if (ball.y <= movingWallBottom)
				{
					ballVelocityX = Math.abs(ballVelocityY);
					ball.dispatchEvent(new BounceEvent(BounceEvent.BOUNCE, "center bottom"));
				}
			}
		}
		private function bounceHandler(event:BounceEvent):void
		{
			trace("Bounce on " + event.side + " side");
			splat.explode(event.target.x, event.target.y);
		}
	}
}

You can download all the files here:

BallBounce.zip





Keeping your code clean

17 11 2008

Quite often we are in a situation where we have to work on a code that was written a few months (or years) back by self or someone else. Sounds a little scary? To ensure that reworking on a code is not as difficult as mining a coal mine I always try and keep my code clean. Now, what is clean? There can be a lot of ways to keep your code clean, but two thumb rules that I follow are:

1. One responsibility per class: For example, I’m working on building a media player in Flash that will run audio and video files. I’ve kept the code for playing the video and audio in separate classes that are sub-classes of one common MediaPlayer class. VideoPlayer class carries the responsibility of playing the video, and AudioPlayer class encapsulates properties and methods for playing audio only. Then, I also have a separate class called VideoUI for laying out the user interface for the video player and a AudioUI class for building the audio player UI.

2. One task per method: In the above example of VideoPlayer class, there’s a separate method for each of the tasks that it needs to perform – playVideo(), pauseVideo(), stopVideo(), and so on. In some cases, it means that you make a separate method for even a one line code. 

Following the above two principles really help in keeping my code clean, readable,  scalable, and reusable.





Reading Flash Vars in AS3.0

13 11 2008

Very often your flash app is required to read variables from the wrapper html page. We define the variables as a name-value pairs string in “FlashVars” param tag. Then, read the variable values in Flash using the LoaderInfo object. See the details below:

The HTML looks like this:

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="550" height="400" title="ReadingFlashVars">
	<param name="movie" value="ReadingFlashVars.swf" />
	<param name="quality" value="high" />
	<param name="FlashVars" value="day=Thursday&month=November&year=2008" />
	<embed src="ReadingFlashVars.swf" width="550" height="400" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" FlashVars="day=Thursday&month=November&year=2008"></embed>
</object>

Notice, the param tag with name as FlashVars. It is passing 3 variables to the SWF file – day, month, and year with values as Thursday, November, and 2008 respectively.

Now, the actionscript part goes something like this – you take the params property of the root loaderInfo object and store it in an object reference. Then, using a for in loop, run through each of the name-value pairs.

var displayData:TextField = new TextField();
displayData.width = 300;
displayData.border = true;
addChild(displayData);
displayData.text = " < Display Flash Vars > ";
var objParam:Object = LoaderInfo(this.root.loaderInfo).parameters;
for (var key:String in objParam)
{
	displayData.appendText("\n " + key + " :: " + objParam[key]);
}

Following result should get displayed when the HTML page is loaded in browser:

Read FlashVars in AS3.0

Read FlashVars in AS3.0