Flex vs Silverlight vs AJAX vs JavaFX

15 01 2009

Yesterday, I was having this interesting conversation with a couple of  friends regarding which technology will rule the RIA space in the future. I believe, there’s room for all four of these as per my observations and experience. In fact, all these will have a separate domain and overlap at only few places. For example, AJAX is widely popular for creating community building apps,  portals, mashups, and so on. Flex is used for multimedia rich requirements, for example, interactive maps, photo albums, portfolios, games, product websites, etc. Silverlight is a direct competition here but might have more presence in the Enterprise apps market.

Flex has an advantage of running on the Flash platform which has a very wide reach on the internet and an integrated support from other Adobe products such as Photoshop, Flash, Illustrator, Fireworks, After Effects and some upcoming products – Catalyst, Thermo, Cocomo, and more. These are industry leading tools that help in building visually rich images, animations, and videos. AIR version adds value by having a desktop version of an app that is integrated with the online one.

Silverlight has the benefit of a huge community of .Net developers who will not need to learn anything new from scratch and utilize the huge libraries of .Net components available in the framework. It has a seamless integration between desktop and online version as well. Because of this, building enterprise applications will be the area in which Silverlight might edge over others.

AJAX, ofcourse, has two big advantages which has no competition as of now. These are – no plugin required and SEO enabled. That’s why apps like eBay, Amazon, MySpace, Blogs, and many more will continue to be largely based on AJAX with a few widgets/components built on either of the other three technologies.

JavaFX, is a late entry into this domain, although it all started with a Java product only i.e. Applet. Java enthusiasts will definitely lap onto this. It just remains to be seen what kind of value add JavaFX will bring over others. You never know, since it’s Java, the most reliable internet technology when it comes to providing security to user’s data.

There can, maybe, a scenario where a single app (for example eBay) utilizing all the four technologies for its different features.

So, whatever may happen, it’s the user who will benefit the most with a wide array of technologies to choose from. For developers, it will be important to specialize in one and at least have a good understanding of the rest to provide the best solution to a customer.





Mantra for successful app development

26 12 2008

Just wanted to jot down a few aspects of application development that can ensure success:

1. Version control: Manage your source code using a version control system. It will save you from accidents such as ” omygod!! an important file got deleted”, “damn! my hard disc crashed”, “shucks! client is asking for a previous version which has been updated now”, and more.  you can try MS VSS or TortoiseCVS. Client side TortoiseCVS is free to use.

2. TDD: Apply Test Driven Development so that much of the bug testing and fixing is done in the development phase and the code is relatively bug free. For Flash and Flex development you can use ASUnit or FlexUnit. FlexUnit gives you a very nice Flex based interface which is a nice advantage.

3. OOP and design patterns: Apply relevant OOP concepts and design patterns for ensuring optimized code that is reusable, scalable, and flexible.

4. UML modeling: Always start your project with creating the architecture class diagram. Spend as much time as possible on this. A robust diagram in the beginning will ensure less coding time and also flexibility or scaling issues in the later stages can be handled effectively.

5. Error handling: Incorporate effective error handling for saving your application crash from unexpected bugs while running and also letting the user know what might’ve gone wrong and provide an alternate path.

6. Be friendly with your fellow coders and share a good laugh :-) Okay, that’s a given for any kind of team work.

I’m sure there are lots more but right now I could think of  these as the most important ones from a developer’s perspective.





BitmapData effects

23 12 2008

Recently there was an actionscript competition at The Flash Blog – 25 lines that would impress Einstein. You need to create something innovative using only 25 lines of code. The absolutely fantastic  results were declared on Dec 18. It’s amazing to see what people can do with only 25 lines of code in Flash. Check out the top entries here…

http://theflashblog.com/?p=503

I noticed one common thing being used to create some of these effects is the BitmapData class for manipulating bitmap objects. Here, I will share a very basic example to show what can be done using this object.

1. Create a new file (actionscript 3.0) in Flash CS3 IDE.

2. Change the stage dimensions as 400 x 200 and frame rate as 24 fps.

3. Select frame 1. Copy the following code in code editor:

//import bitmap classes
import flash.display.Bitmap;
import flash.display.BitmapData;

//create a BitmapData object
var myBitmapDataObject:BitmapData = new BitmapData(400, 200, false, 0x00FF0000);

//create a random number which will be used for setting the seed for adding noise to the bitmadata object
var seed:Number = Math.floor(Math.random() * 100);
//set up a channel with a mix of  three main colors - red, blue, green
var channels:uint = BitmapDataChannel.GREEN | BitmapDataChannel.BLUE | BitmapDataChannel.RED
//create a new bitmap with the bitmapdata object
var myBitmap:Bitmap = new Bitmap(myBitmapDataObject);
addChild(myBitmap);
//use enterframe event for animating the bitmap effect
addEventListener(Event.ENTER_FRAME, updateImage);

var velo:int = 10;
function updateImage(e:Event):void
{
	if (velo >= 200)
	{
		velo = -Math.abs(velo);
	}
	//add noise with baseX and baseY properties set to var velo which is constantly changing
	myBitmapDataObject.perlinNoise(velo++, velo++, 6, seed, false, true, channels, false, null);
}

4. Publish the file.

There  you go. You will see a colorful animated cloud being zoomed in and zoomed out.

ColoredCloudEffect.swf

Bitmap Cloud Effect

Bitmap Cloud Effect





Dividing your Flex app in different SWF files

20 12 2008

I came across a Adobe live docs PDF that I believe is very important for any serious Flex developer. Sooner or later you will be developing an application that will scale up to proportions that might become unmanageable in terms of code, file size, and performance.

Flex provides 2 ways to deal with it – modular approach and sub-applications. Both ways you load and unload separate SWF files into the main application for keeping certain functionality separate and available only when required. Besides some other issues this can also give rise to an issue of having different version of Flex for the loading sub apps and that needs to be taken care of early on.

This PDF details all the considerations that should go into making a decision on which approach to follow for building a large application. A must read for all Flex developers.

http://livedocs.adobe.com/flex/3/loading_applications.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





Web 2.0 layouts

21 11 2008

For years one strong rule that influenced designing a web layout was to avoid a vertical scrollbar as far as possible. The user was expected to lose interest if the content is not right in front (without scrolling down). So in order to achieve that, we would design a layout and then try to cram content into it, have hidden menus, small text, small logos etc.

However, times have changed and over the years the user has become quite scrollbar friendly. And the result is that we can design a layout that is more user friendly than ever. These layouts generally follow a similar trend and are termed “Web 2.0 layouts” as they evolved in 2006 at the same time “Web 2.0″ became a buzzword. Some of the characteristic features of these layouts are:

  • Bright colors
  • Clean
  • More whitespace
  • Big fonts
  • Center aligned
  • Fixed width
  • Horizontally divided in columns
  • Use of gradients
  • Less navigation items on top
  • Detailed footer
  • Badges and Flowers (to highlight a section/feature)
  • Top part has less content and more marketing info to attract users
  • More content as the user navigates down the page
  • Rounded corners for boxes
  • A very short sign up form. User can update the detailed profile info later.
  • Text based logos with reflection
     

Following are some very good examples:

Firefox:

Firefox

Firefox

 

Cork’d:

Corkd

Corkd

 

You can study the Web 2.0 layout trends in more details at the following urls:

http://www.styleignite.com/articles/view/analysis-of-web-20-design-layout-trends-part-1-clean-colorful-and-horizontally-divided

http://webdesignfromscratch.com/current-style.php





Cocomo – “Social Networking Mojo” for Flex

20 11 2008

Cocomo

Cocomo

The most popular aspect of Web 2.0 today is social networking websites like Facebook, MySpace, Twitter, etc. Adobe has started a new initiative to add power to the Flex platform for building social networking websites – it is codenamed “Cocomo”.

 

“Add social features to your existing Flex apps or build totally new ones, such as real-time productivity/collaboration apps, multiplayer games, and audio/video chat.

Features of the Cocomo beta include the following:

  • VoIP Audio
  • Webcam Video
  • Chat
  • Multi-User Whiteboards
  • Real-Time File Sharing
  • User Management
  • Roles and Permissions
  • Robust Data Messaging

- Adobe”

Check it out here…

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





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