Wonder wall case study

September 9th, 2011

Post in Actionscript 3.0

Everybody knows and loves Yugo Nakamura and this tha.jp company.
There are alot of “interpretations” on how Nakamura developed the http://wonder-wall.com website.

This is my interpretation of it in a series of tutorials. Hope you like it, comments are disabled.

Get Adobe Flash player



Get Adobe Flash player



Get Adobe Flash player



Over the time I created an easy way to get projects up and running without losing too much time in the logic.
There are a lot of frameworks that do this, and more, but I find that mine is very easy to work with, and I use it in all my projects. love™ isn´t exactly the best name, but its better the foo… right?!

For this post I decided to release a lighter version of the framework, not because I want to keep it a secret, but because there´s no need to complicate what I want to illustrate. Complete version of the framework will be released soon.

The Framework is divided in 3 parts.
-CORE (with events, settings, and logic)
-MEDIA (with custom buttons, animation engines, video players etc…)
-UTILS (with String validatores, math utilities, bitmap utilities, garbage collection, etc)

for this version i significant reduced the MEDIA folder, and the UTILS folder, leaving just the basic to understand and get you running on my framework.

Here is a quick example:

Get Adobe Flash player

You can download the source here.

Open your favorite actionscript editor and import the framework and the TweenMax engine used in this demo.

In your document class import StageDefinition.as and create a class (in this case called App.as that will extend Application.as

package 
{
	import flash.display.Sprite;
 
	import love.core.setup.StageDefinition;
	import pt.example.view.App;
 
	public class Main extends Sprite
	{
		public function Main()
		{
			var root:StageDefinition = StageDefinition.getInstance();
			root.start(this);
 
 
			addChild(new App());
		}
	}
}

So far, we have set the stage definitions, the custom right click menu (this can be override), and we added the App.as class to the stage.

The App.as is the visuals of your project.

package pt.example.view
{
	import flash.events.Event;
 
	import love.core.Application;
	import love.core.events.AppEvent;
	import love.core.setup.Structure;
	import love.media.button.Semi3D;
 
	import pt.example.view.page.Simple;
	import pt.example.view.sobre.Sobre;
 
	public class App extends Application
	{
		private var botao1:Semi3D;
		private var botao2:Semi3D;
		public function App()
		{
			var areas:Structure = Structure.getInstance();
			areas.addArea("about", pt.example.view.sobre.Sobre);
			areas.addArea("simple_page", pt.example.view.page.Simple);
 
			this.addEventListener(Event.ADDED_TO_STAGE, onAdded, false, 0, true);
		}
 
		public override function Navigation(id:String):void
		{
			switch(id)
			{
				case "about":
					botao1.enable(false);
					botao2.enable(true);
					break;
 
				default:
					botao1.enable(true);
					botao2.enable(false);
					break;
			}
		}
 
		private function onAdded(e:Event):void
		{
			this.removeEventListener(Event.ADDED_TO_STAGE, onAdded);
 
			botao1 = new Semi3D(click1);
			botao1.config("About the framework", null, 0xFFFFFF, 0xCCCCCC, 4, true);
			botao1.enable(true);
			botao1.x = 20;
			botao1.y = 20;
			addChild(botao1);
 
			botao2 = new Semi3D(click2);
			botao2.config("Simple Page", null, 0xFFFFFF, 0xCCCCCC, 4, true);
			botao2.enable(true);
			botao2.x = botao1.x + botao1.width + 10;
			botao2.y = botao1.y;
			addChild(botao2);
 
 
			dispatchEvent(new AppEvent(AppEvent.NAVIGATE, {area:"about"}));
		}
 
		private function click1():void
		{
			dispatchEvent(new AppEvent(AppEvent.NAVIGATE, {area:"about"}));
		}
 
		private function click2():void
		{
			dispatchEvent(new AppEvent(AppEvent.NAVIGATE, {area:"simple_page"}));
		}
	}
}

As you have noticed the App.as extends Application.as that handles the views and dispatches events throw the StageDefinition.STAGE (your stage) informing on AppEvent.Navigation type events.

In this example I´ve added 2 pages and 2 buttons.

Every page in a view, and it extends a Base.as class.

Base.as class handles the open and close methods, resize and remove methods, your can override all of this methods, to create custom open and close animations from page to page. In this example I use the default from Right to Left animation (using TweenMax).

The complete version of the framework has Papervision3D and SWFAddress support, custom debug tools, custom buttons, animation engine, and some great utilities to rapidly starting creating your website.

Cheers
André

Sometimes I like to pretend that in every website I do, I have and easter egg.
Sometimes I share it with friends and sometimes I dont. Its a kind of therapy that helps me keep excited about a project. Weird I know.

So, this is how I usually do it.

Somewhere in your Application, you should have this code

package
{	
	import flash.display.Sprite;
	import love.utils.Cheats;
 
	public class Main extends Sprite
	{
		public function Main()
		{		
			var cheats:Cheats = Cheats.getInstance();
			cheats.addWord("lorem ipsum", cheat1);
			cheats.addWord("user has no moustache", cheat2);
			cheats.enable(true);
		}
 
		public function cheat1():void
		{
			trace("do some shit");
		}	
 
		public function cheat2():void
		{
			trace("close website, user is lamme!");
		}
	}
}

So, if the user for some reason type in the sentence “LOREM IPSUM” it automatically call the cheat1 function. This adds a lot of creative possibilities.

package love.utils
{	
	import flash.events.KeyboardEvent;
 
	import love.core.debug.TheDebugger;//this class Is just for debugging, you can change the TheDebugger.lot() to trace().
	import love.core.setup.StageDefinition;//This class stores the stage reference, you can change the StageDefinition.STAGE to Stage.
 
	public class Cheats
	{
		protected static var instance:Cheats;
		private var words:Array = [];
		private var possible:Array = [];
		private var currentChar:uint = 0;
		public function Cheats()
		{
			if(instance != null)TheDebugger.error("Cheats Singleton already constructed!");
			instance = this;
		}
 
		public static function getInstance():Cheats 
		{
			if(instance == null)instance = new Cheats();
			return instance;
		}
 
		public function addWord(word:String, func:Function):void
		{
			var obj:Object	= new Object();
			obj.word	= word;
			obj.func	= func;
			words.push(obj);
		}
 
		public function enable(value:Boolean):void
		{
			if(value)
			{
				StageDefinition.STAGE.addEventListener(KeyboardEvent.KEY_DOWN, checkForSequence);
			}
		}
 
		private function checkForSequence(e:KeyboardEvent):void
		{
			var valid:Boolean = false;
			for(var i:uint = 0; i<words.length;++i)
			{
				if(checkLetterInWord(e.charCode, words[i].word))
				{
					possible.push(words[i]);
					valid = true;
				}
			}
 
			//var char:String = String.fromCharCode(e.charCode);
			checkValidWord(valid);
			possible =[];
		}
 
		private function checkValidWord(valid:Boolean):void
		{
			if(valid)
			{
				currentChar++;
 
				if(currentChar == possible[0].word.length)
				{
					possible[0].func();
					resetCharCount();
				}
			}
			else
			{
				resetCharCount()
			}
		}
 
		private function resetCharCount():void
		{
			currentChar = 0;
		}
 
 
		private function checkLetterInWord(code:Number, word:String):Boolean
		{
			return code == word.charCodeAt(currentChar) ? true : false;
		}
	}
}

Now, lets take this baby for a ride

Get Adobe Flash player

You can download the source here.

Calculating mouse speed

January 10th, 2011

Post in Actionscript 3.0

Usefull for game development.

package
{
	import flash.events.Event;
	import flash.text.TextField;
	public class Example
	{
		private var velocityInfo:TextField;
		private var prevX:Number = mouseX;
		private var prevY:Number = mouseY;
 		private var velX:Number = 0;
		private var velY:Number = 0;
		public function Example():void
		{
			velocityInfo = new TextField();
			velocityInfo.x = 20;
			velocityInfo.y = 20;
			addChild(velocityInfo);
 
 
			addEventListener(Event.ENTER_FRAME, onLoop);
 
			function onLoop(e:Event):void
			{
     				velX = mouseX - prevX;
				velY = mouseY - prevY;
 
				velocityInfo.text = velX + ", " + velY
				prevX = mouseX;
				prevY = mouseY;
			}
		}
	}
}

Its been a while since my last post… I´ve been working alot on new projects, and I haven´t had much time to update my blog. I´m sorry! ;)

It has been a big buzz about HTML5 for a while now, and is it or is it not going to “kill Flash”. I´ve worked with some people that believe Flash is going to be overrun by HTML5. And I was laughing in silence with sentences like:

No, we cannot use Flash Player 10, because its to damn recent and almost no one has it (including our clients).
mmmm, ok, but this was said yesterday (22nd, October 2010) and Flash Player 10 has been around since late 2008?

The same people told me:
Lets start learning HTML5 and do some works for our clients using this technology
mmmm, ok, but arent these clients the same clients from above? The ones who dont use Flash Player 10 because its to damn recent, and still use Internet Explorer 6 (released in 2001)? How will they manage to see (or even imagine) HTML5 using that?

Again:
Hey, I just bought this iPad abroad, lets start making apps for iPhone and iPad
mmmm, ok, I love programming in Cocoa, but is this app just for you and the client? Because you know, that iPad is still unavailable in Portugal, and only you, the client and well… me, can actually afford it. Shouldn´t we be doing apps for the clients target and not for the client itself?

Well, maybe in this last one I´m beeing just vicious. But this is just to illustrate the “fire at sight” policy that some people use and abuse, and how the sentence “Hey, Its new, let´s use it” can only apply with HTML5 or Cocoa. And in Flash Player 10 its more like “Hey, Its new, we can´t use it”.

First of all, I´m very excited about HTML5!!!

a) Do I fear for my job as a Flash Developer? No!
b) Am I learning HTML5 and Cocoa because I might fear for my Job subconscious? No!

I´m learning HTML5, Cocoa, Javascript, PHP, mySql, Arduino, Android, C++, etc, because I LOVE PROGRAMMING, and I LOVE TO CHALLENGE MYSELF.
Nothing gives me more pleasure then learning new stuff and after a while doing things I tough I could´t do before.

So, do I think Flash Player is going to be overrun by HTML5? No!

Flash Player will still grow and so will HTML5. They are different things, and none of them will crush the other.

Here´s some thoughts from Youtube on HTML5 vs Flash.
And Please check this and this HTML5 experiences. They are great!!!

Flash Developers, be in peace! I am!

Here´s a simple loop to check every property in a object, just in case u dont know what you are getting.

var infoObject:Object = {info:"a string", name:"another String", data:["hello", "there","sir"], object:{}};
for (var propName:String in infoObject)
{
	trace(propName + " = " + infoObject[propName]);
}

While making a video stream project, I had to convert seconds to HH:MM:SS and vice versa, so I created this class.

/*
USAGE:
TimeUtils.encode(90);
TimeUtils.decode("00:01:30");
*/
package euro.utils
{
	public class TimeUtils
	{
		public function TimeUtils():void
		{
		}
 
		public static function encode(_seconds:int):String
		{
			var seg = _seconds %60;
			var min = _seconds/60 %60;
			var hor = _seconds/60 /60;
 
			return String(normalize(hor,2) + ":" +  normalize(min,2) + ":" + normalize(seg,2));
		}
 
		public static function decode(_string:String):Number
		{
			var parts:Array = _string.split(":");
 
			var seconds:Number	= parts[2];
			var minutes:Number	= parts[1];
			var hours:Number	= parts[0];
 
			return seconds + 60 * minutes + 60 * 60 * hours;
		}
 
		private static function normalize(_int:int, _size:int):String
		{
			var temp:String = String(_int)
 
			for (var i = 1; i < _size; i++)
			{
				if (_int < Math.pow(10,i))
				{
					temp = "0" + temp;
				}
			}
			return temp;	
		}
	}
}

I always love to see how much the Developers put into details. I love custom mouse icons on rollover, like a close or a zoom or a grab icon. I tought I could share my way of drawing custom shapes.

Some time ago for a competition, I had the need to create custom shapes but I was restricted to not use either external images or movie clips in the library, so I decided to get my hands dirty in the graphics method once again.

At the birth of the game industry all games were basically Tile based games (you can read more in here). So, inspired by that idea I thought I could draw custom shapes using Arrays.

So the main idea is that you transform something like this:

into something like this:

With that in mind, I created a loop to check every number in the multi-arrray and based on the number, we should or shouldn´t draw something.

0 – means empty pixel
1 – means black pixel
2 – means white pixel

So, take the largely used hand cursor for example:

var hand_open:Array = [
	[0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
	[0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0],
	[0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 2, 2, 1, 0, 0, 0],
	[0, 0, 1, 2, 2, 1, 1, 2, 2, 1, 2, 2, 1, 0, 1, 0],
	[0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 1],
	[0, 0, 0, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1],
	[0, 1, 1, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1],
	[1, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1],
	[1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0],
	[0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0],
	[0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0],
	[0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0],
	[0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0],
	[0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0],
	[0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0],
	[0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 0, 0, 0], 
	];
 
 
function draw_Icon(_arr:Array):void
{
	for (var a:uint = 0; a < _arr.length; ++a)
	{
		for (var b:uint = 0; b < _arr[a].length; ++b)
		{
			if(_arr[a][b] != 0)
			{
				_arr[a][b] == 1 ? current.graphics.beginFill(0x000000) : current.graphics.beginFill(0xFFFFFF)
				current.graphics.drawRect(1 * b, 1 * a, 1, 1);
				current.graphics.endFill();
			}
		}
	}
}
 
 
draw_Icon(hand_open);

This icon would be great for some drag and drop kind of application. Have fun creating your custom shapes!

In this example I´m downloading 2 images and merging them into 1.

Image 1

Image 2

Result

Get Adobe Flash player



var bd1:BitmapData;
var bd2:BitmapData;
 
loadImage("http://blog.andrevenancio.com/wp-content/uploads/2010/01/icecream.png");
 
 
function loadImage(url:String):void
{
	var _request:URLRequest = new URLRequest(url);
	var _loader:Loader = new Loader();
	var _context:LoaderContext = new LoaderContext();
		_context.checkPolicyFile = true;
 
	_loader.load(_request, _context);
	_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
}
 
 
function loadComplete(e:Event):void
{
	if (bd1 == null && bd2 == null)
	{
		bd1 = Bitmap(e.target.content).bitmapData;
		trace(bd1.width, bd1.height);
		loadImage("http://blog.andrevenancio.com/wp-content/uploads/2010/01/watermark.png");
	}
	else if (bd1 !=null && bd2 == null)
	{
		bd2 = Bitmap(e.target.content).bitmapData;
		allImagesAreLoaded();
	}
}
 
 
function allImagesAreLoaded():void
{
	var bm:Bitmap = new Bitmap();
	addChild(bm);
 
	bm.bitmapData = mergeBitmap(bd1, bd2);
}
 
 
function mergeBitmap(_data1:BitmapData, _data2:BitmapData):BitmapData
{
	var mergedData:BitmapData = _data1;
		mergedData.draw(_data2);
	return mergedData;
}

The RegExp class lets you work with regular expressions, which are patterns that you can use to perform searches in strings and to replace text in strings.

trace(testRegex("some@email.com")); //returns true
trace(testRegex("some.com"));//returns false
 
function testRegex(_input:String):Boolean
{	
	var validEmailRegExp:RegExp = /([a-z0-9._-]+)@([a-z0-9.-]+)\.([a-z]{2,4})/;
 
	switch (String(validEmailRegExp.test(_input)).toLowerCase())
	{
		case "true":
			return true;
			break;
		default:
			return false
			break;
	}
}