How to write unmaintenable code
And old link, that I lost, and that I found again yesterday. I love the opening quote: " Never ascribe to malice, that which can be explained by incompetence"
A funny read: how to write unmaintenable code
And old link, that I lost, and that I found again yesterday. I love the opening quote: " Never ascribe to malice, that which can be explained by incompetence"
A funny read: how to write unmaintenable code
In languages like Java and actionscript, the "runtime" manages memory, using what is called a garbage collector, that reclaims the memory occupied by an object once it determines that object is no longer accessible. In Objective-C, the programmer must release the resources that he or she has previously allocated to be used by the program.
Memory management is not difficult by itself, because the developer must follow only a few rules, but it is the source of many memory leaks, specially when the program behaves in an unexpected way.
So, what happens when we need to throw exceptions?. How can we be sure that we are not producing memory leaks?. Chris Hanson writes about it in Cocoa memory management & exceptions
design-nation is in the papers. In the October's issue of MacWorld Spain, there is an articles written by me, the First Contact with Macromedia Studio 8.
Even with that article, the magazine is full of interesting contents, like a report about the .Mac services, an in-depth article about iMovieHD or a comparison between all the Macs.
If you can read Spanish, you should buy it...
I am sure you have heard about the Head First series and about the Head First Design Patterns book, because it is probably the best introductory book to understand design patterns.
Last week I was browsing amazon when I found this item: Head First Design Patterns Poster.

As its name says, it is a poster (a big one, in fact) that contains a graph (taken from the original book), not an UML diagram but a graph that explains the pattern and also the page number of the pattern in both the Gang of four and Head First Design Patterns.
It visually summarizes 18 patterns, and it is attached to the wall in front of my computer right now...
(By the way, all the links in this post will NOT earn me a comission).
Strategy. That was the name of the pattern in yesterday's post.
UPDATED: This is the Strategy Pattern. So, the title of the post could be "An example of the strategy pattern in actionscript"
Professor Coupling has been enjoying his well deserved hollidays after conquering the world (yes, since the last time we knew about him he seems to have succeeded with his evil plan).
But ruling the world is quite boring. Professor Coupling misses the old times, when nobody understood him, when he could hate all the world's leaders because they ignored him... Now he has to deal with a lot of paperwork everyday, and he misses when he could hang around with his troops, telling jokes, and drinking beer.
So, he has decided that, to combat this mortal boredom, he wants to see a millitary parade everyday. A different parade everyday, formed by a different selection from his troops. One day he will ask his Marshal to form a parade with the cows from the company B, another day he will want a parade formed by all the sheeps whose name contains an "a"... Evil geniuses...
Continuar leyendo "An example of the guess-its-name pattern" »
We have updated our previous posts about flash 8, adding the source code:
[Flash 8] The sun and its shadow
PS: If you feel that the same functionallity can be achieved with flash 4, build an example, and post a comment with a link to the source code. Thanks
Drag the sun around the earth, and see how the shadow of the earth changes. Of course, you will need the flash player 8 public beta
For this example, I've used the following new features: movieclip filters ( glow, dropshadow and bevel ) that I change dinamically when the position of the sun changes. To calculate distances and angles, I have also used some of the new classes developed for geometrical calculations.
UPDATE 20/9/05: download the source code
Click on the stage
UPDATE 20/9/05: download the source code
Click on the stage
UPDATE 20/9/05: download the source code
Conquering the world is not easy. You and me both know it. And Professor Coupling knows it too.
He has the knowdlege, he has a plan, he has the skills, and he has even the looks, but there are a lot of little details to care for before he can finally conquer the world!!.
In previous posts, be have seen how he has implemented the prototype pattern ( to create his army of clones –hey, I’ve just noticed the joke- ), the extension objects pattern ( to assign their roles ), the command pattern ( to assign them their orders ) and the observer pattern ( to implement a communications system ). It seems that Professor Coupling has had a lot of work, but was it enough?. NO!! ( muhahahahahahaha ).
Continuar leyendo "An example of the memento pattern ( the actionscript version )" »
Don't repeat yourself. When you write the same code more than once, you are starting to paint yourself into a corner.
See, for instance, this example.
I'm working on an application where I'm going to use the UI components. It's a MVC application, so the view is completely abstracted from the application's logic.
There's more than one view ( there are many different screens where I have to show the model data in different ways ), so I've thought that it will be better to build a different class for each view ( each screen ).
So, each view will attach a movieclip that contains the screen's graphics and interactive elements ( buttons, datagrids, whatever ). All those view inherit from a class that implements event dispatching, and some more common code. That's one reason to not inherit from movieclip. There are other ones, but I should not want to discuss them now. Anyway...
Also, I still don't have the definitve graphic assests. Even more, if the budget is big enough, I'll have to develop my own set of components, and use it.
So, imagine that you run the application. The first screen you'll find will be the login screen.
As you see in the screenshot, that screen contains a component. Here's the LoginView code:
import mx.utils.Delegate;
class LoginView
{
private var timeline : MovieClip;
private var loginScreen: MovieClip;
function LoginView( tl: MovieClip )
{
this.timeline = tl;
}
public function init( )
{
this.loginScreen = this.timeline.attachMovie( "LoginScreen", "LoginScreen",
this.timeline.getNextHighestDepth( ), { _x: 0, _y: 0 } );
this.loginScreen.loginBtn.label= "Go!";
this.loginScreen.loginBtn.addEventListener( "click", Delegate.create( this, click ) );
}
private function click( )
{
trace( "click" );
}
}
So, when I want to show that screen, I'll do something like:
var loginView: LoginView = new LoginView( this );
loginView.init( );
And the button doesn't work. It doesn't even shows the right message. Some minutes of googling, and a bit of common sense and knowledge of the platform, told me that maybe, the button is not initialized when the movieclip is attached, so maybe I should wait a frame to assign its text.
import mx.utils.Delegate;
class View
{
private var timeline : MovieClip;
private var loginScreen: MovieClip;
function View( tl: MovieClip )
{
this.timeline = tl;
}
public function init( )
{
this.loginScreen = this.timeline.attachMovie( "LoginScreen", "LoginScreen",
this.timeline.getNextHighestDepth( ), { _x: 0, _y: 0 } );
var theView: View = this;
this.loginScreen.onEnterFrame = function( )
{
theView.initButton( );
delete this.onEnterFrame;
}
}
private function initButton( )
{
this.loginScreen.loginBtn.label= "Go!";
this.loginScreen.loginBtn.addEventListener( "click", Delegate.create( this, click ) );
}
private function click( )
{
trace( "click" );
}
}
It's solved. But this solution smells ( not only because of the scope trick ). I'll have various screens that contain components ( maybe 10-12 ), so I'll have to write that code in 10 classes. Sure, I could write a base class and move that code to that base class, but that's not a solution, because not all my views will have the same amount of buttons, so there's not sense in subclassing just to override later. And my views are subclasses of another base class yet.
Even worse, probably, I'll have to develop my own components, so maybe, that code will have to be changed.
So, I'm repeating code, and that code will be probably changed in a near future. What should I do?. Encapsulate it into its own class.
To do so, I'll use my old Callback class:
class Callback
{
private var callbackObjVal: Object;
private var callbackMethodVal: String;
public function Callback( objParam: Object, methodParam: String )
{
this.callbackObjVal = objParam;
this.callbackMethodVal = methodParam;
}
public function fire( parameter: Object ): Object
{
return this.callbackObjVal[ this.callbackMethodVal ]( parameter );
}
}
So, I'll write a ButtonHandler class:
class ButtonHandler
{
public static function initButton( mc: MovieClip, callback: Callback )
{
var cb: Callback = callback;
mc.onEnterFrame = function( )
{
cb.fire( );
delete this.onEnterFrame;
}
}
}
And I'll use it this way:
import mx.utils.Delegate;
class View
{
private var timeline : MovieClip;
private var loginScreen: MovieClip;
function View( tl: MovieClip )
{
this.timeline = tl;
}
public function init( )
{
this.loginScreen = this.timeline.attachMovie( "LoginScreen", "LoginScreen",
this.timeline.getNextHighestDepth( ), { _x: 0, _y: 0 } );
ButtonHandler.initButton( this.loginScreen, new Callback( this, "initButton" ) );
}
private function initButton( )
{
this.loginScreen.loginBtn.label= "Go!";
this.loginScreen.loginBtn.addEventListener( "click", Delegate.create( this, click ) );
}
private function click( )
{
trace( "click" );
}
}
Overkill?. Well, the solution is a bit complex, but it's the one that most satisfies me, because it's the one that brings more flexibility. If I have to change the way I manage the buttons, I just have to change the implementation of one method in one class, and I don’t have to change any interface. I'm coding for the interface, not for the implementation.
Be aware!. Professor Coupling and his army of clones are ready!.The final attack is going to be launched quite soon!. And their weapons are actionScript and design patterns!
In the previous posts, we’ve seen how Professor Coupling is able to clone any animal, and how he’s able to assign different roles to those clones. Oh, and he has also found the way to assign any animal its orders. Muhahahahahaha
Everything is ready. The sheeps and the cows are cloned, and their roles have been assigned. It’s time for Professor Coupling to launch the final attack. It’s time to conquer the world!!!.
But how will Professor Coupling give his troops the order to launch the attack?.
Do you remember Professor Coupling?. Do you remember his evil plans to conquer the world?.
Today, we’ll see how the Extension Objects pattern ( or “how to change the interface that a class implements at runtime” ) has helped Professor Coupling. It won’t be an easy task, because this is a complex pattern, but who said that being an evil genius was easy?.
Continuar leyendo "An example of the Extension Objects pattern" »
You know that you can assign an as2 class to any movieclip symbol in the library. If that class extends movieclip, when you attach the symbol, you get an instance of that class. But you don’t even need to attach the symbol. You can just put the symbol on the stage at design time, and that’s enough to materialize that class when the timeline gets to the frame where the movieclip is located. That can be helpful when you are building an interface. You just put, for instance, a movieclip that represents a button on the stage, and *magic*, you have an instance of its associated class.
So, imagine you have to create an interface similar to this one:

Continuar leyendo "A situation where we shouldn't extend movieclip" »
I guess you've heard it yet, but Macromedia has opened a contest to see who develops the coolest Flash Lite application. And they are going to give out a lot of cool and expensive prizes!
Here are the details of the contest:
http://www.macromedia.com/mobile/special/contest/
Obviously, you'll need to test your applications in a mobile device. You can request the Flash Lite player for your handset, sending an email to flashlite_contest@macromedia.com, sending also your handset model and IMEI.
If you want to know if your device is supported, you can take a look at:
http://www.macromedia.com/mobile/supported_devices/#tmobile
Hurry up!. The contest closes February 1, 2005. Show the world what you can do!
If you're an experienced developer, I'm afraid you won't find this post interesting.
But, if you're starting to learn about object oriented programming, maybe you've heard about its benefits, about how an object oriented approach can help in developing and maintaining your applications. But, is it true?. Does oop really make our work easier?.
ActionScript does not support the creation of inner classes, at least, not in the way that Java does.
Manuel de la Higuera has made an interesting post about how to implement inner classes in ActionScript, and the effect they have on performance. I think it's worth to be checked.
An interesting discussion about the "over designed" systems. Does the use of design patterns encourage over-engineering?.
In this discussion at the c2 wiki, you could find the opinions of people supporting the use of design patterns, and people that thinks that they should not be used always. And also, a lot of links to very interesting resources. A must read.
So, here's the link:
But there are more heavy weight reasons to favour composition over inheritance.
First, inheritance doesn’t allow to change the implementations of the subclasses at run time, and breaks encapsulation, because the implementation of the superclass is visible through the subclasses.
Continuar leyendo "Favour composition over inheritance ( and III )" »
What happens if our class hierarchy is extremely deep?. Any change in any of the superclasses will mean that we’ll have to make a lot of changes in many different parts of our program.
Continuar leyendo "Favour composition over inheritance ( II )" »
Inheritance is a powerful tool. I can´t imagine my work without it. But it's not good to rely only on inheritance. Composition can be a better solution for many of our problems.
A few weeks ago, someone told me that the discusion about inheritance vs composition was like the discusion about PC vs Mac. But I don't think so. I believe that there are many points that suggest that we should favour composition.
Continuar leyendo "Favour composition over inheritance( I )" »
MaxiVista can turn any Laptop or Tablet PC into an extended monitor of your primary PC. Program windows can be moved and extended across both screens as they would be one big monitor. Just connect up to four PCs via network and enjoy the extended desktop real estate.
This is one of the creational patterns, whose intent is to provide an interface for creating families of related or dependent objects without specifying their concrete classes.
I’ll try to explain it using a "real life" example. Let’s suppose I want to decorate my house. And let’s suppose that there are only two different furniture shops in the town I live. One of them sells modern designs, and other one sells classic furniture. And let’s suppose again, that I’m only going to buy a door and a tv set ( I don’t have too much money ). And, finally, let’s suppose that I can buy the same items in both shops ( doors and tv sets ).
So, if I want to buy a tv set, I just have to any of the shops and ask for one tv set ( and pay it, of course ). And after having it properly installed at home, I know I can do some certain things with my tv set ( switch it on and off, pump the volume up,… ). And those actions could be done both with a modern tv and with and old one, although could be applied in a different way.
Well, I know I can go to the shop ( the modern one or the classic one, depending on what I exactly want ), but I could also pay someone to go and buy my tv and bring it home. I will only have to say "please, bring me a modern tv", and he / she should know that, to buy a modern tv, he / she should go to the “modern” shop and pay for a tv set. This guy / gal is the abstract factory. I don’t care how or what he / she does to bring a modern tv, I just want me tv now.
Before the as2 implementation, it’s time to point out something important. ActionScript doesn’t implement abstract classes. Sure, I can write a class that acts as an abstract class, but the fact is that the language doesn’t support them. So, although the GoF book says that the abstract factory and the factories should extend an abstract class, my implementation will be based on interfaces.
Well, back to code. If I go to the shop myself, or if I ask someone to bring me a tv, I just have to say “I want a tv”. So, both the shops and the guy that buys the tv will implement a common interface ( just to say it clearly, they should extend an abstract class, if possible, but as actionscript doesn’t implement them, they will just implement the same interface ).
Here is the interface:
import net.designnation.patterns.AbstractFactory.*
interface net.designnation.patterns.AbstractFactory.IFactoryActions
{
public function getTV( ): ITVActions;
public function getDoor( ): IDoorActions;
}
There are two actions: getTV and getDoor ( "bring me a tv", and "I want a new door" ).
This is the code for the two shops:
import net.designnation.patterns.AbstractFactory.*
class net.designnation.patterns.AbstractFactory.ModernShop implements IFactoryActions
{
function ModernShop( )
{
trace( "I've picked a modern shop" );
}
public function getTV( ): ITVActions
{
return new BrandNewTV( );
}
public function getDoor( ): IDoorActions
{
return new ModernDoor( );
}
}
import net.designnation.patterns.AbstractFactory.*
class net.designnation.patterns.AbstractFactory.ClassicShop implements IFactoryActions
{
public function ClassicShop( )
{
trace( "I've picked a classic shop" );
}
public function getTV( ): ITVActions
{
return new OldTV( );
}
public function getDoor( ): IDoorActions
{
return new ClassicDoor( );
}
}
Both classes ( shops ) implement the same interface : IfactoryActions ( in other words, they implement two methods: getTV, and getDoor ).
Let’s take a closer look at the getTV method:
public function getTV( ): ITVActions
{
return new OldTV( );
}
Are we creating an instance of the OldTV class, but this method returns an interface?. Sure. That’s what lets us manage all the TV sets the same way. We won’t have to care about where we bought the tv (if it is modern or classic). We just will know that we can do some actions ( switch it on,… ). So, the two classes that represent the two kinds of tv sets will implement the same interface:
interface net.designnation.patterns.AbstractFactory.ITVActions
{
public function pumpUpTheVolume( );
public function shutUp( );
}
The modern TV will be:
import net.designnation.patterns.AbstractFactory.*
class net.designnation.patterns.AbstractFactory.BrandNewTV implements ITVActions
{
function BrandNewTV( )
{
trace( "I've received is my new 42 inches plasma TV" );
}
public function pumpUpTheVolume( )
{
trace( "sure, let me find the remote..." );
}
public function shutUp( )
{
trace( "By pressing down this key, the sound dies" );
}
}
And the classic one:
import net.designnation.patterns.AbstractFactory.*
class net.designnation.patterns.AbstractFactory.OldTV implements ITVActions
{
function OldTV( )
{
trace( "I've bought an old TV" );
}
public function pumpUpTheVolume( )
{
trace( "My old tv has no remote, so I must wake up and pumpUpTheVolume myself" );
}
public function shutUp( )
{
trace( "My old tv has no remote, so........" );
}
}
And will do the same with the doors. If the door is a modern one or a classic one, there will be the same actions: opening and closing it. So, now, the common interface that both classes will share is:
interface net.designnation.patterns.AbstractFactory.IDoorActions
{
public function open( );
public function close( );
}
The modern door:
import net.designnation.patterns.AbstractFactory.*
class net.designnation.patterns.AbstractFactory.ModernDoor implements IDoorActions
{
function ModernDoor( )
{
trace( "ModernDoor constructor" );
}
public function open( )
{
trace( "the modern door is opened" );
}
public function close( )
{
trace( "the modern door is closed" );
}
}
The classic one:
import net.designnation.patterns.AbstractFactory.*
class net.designnation.patterns.AbstractFactory.ClassicDoor implements IDoorActions
{
function ClassicDoor( )
{
trace( "ClassicDoor constructor" );
}
public function open( )
{
trace( "the classic door is opened " );
}
public function close( )
{
trace( "the classic door is closed" );
}
}
Well, it’s the moment to stop, and look back. We have two shops. Both shops sell doors, and tv sets. The classic shop sells classic doors and tv sets, and the modern one sells moderns TVs and doors.
The guy we send to the shop to bring us a tv will be the abstract factory:
import net.designnation.patterns.AbstractFactory.*
class net.designnation.patterns.AbstractFactory.AbstractFactory
{
public static var MODERN : Number = 1;
public static var CLASSIC : Number = 2;
public static function getFactory( shopType: Number ): IFactoryActions
{
if ( ( shopType & MODERN ) == MODERN )
{
return new ModernShop( );
}
if ( ( shopType & CLASSIC ) == CLASSIC )
{
return new ClassicShop( );
}
}
}
This class implements the same interface that both ModernShop and Classic shop implement. So, I will only have to say: “hey, abstract factory, bring me a modern tv”, and I could forget about the details of the process. And the end of the process I’ll have a tv set, but I will not know how it came home, where it was built, or sold…. But how?. Look:
import net.designnation.patterns.AbstractFactory.*
var factory: IFactoryActions = AbstractFactory.getFactory( AbstractFactory.MODERN );
var myTV: ITVActions = factory.getTV( );
myTV.pumpUpTheVolume( );
var myDoor: IDoorActions = factory.getDoor( );
myDoor.close( );
You can download the code here
Flashblog is an opensource blogging system, based on Flash, php and mySQL, that has been developed by some members of the spanish-speaking community.
Although it is not available yet, an initial release is expected in October. Right now, the project and the website are only in spanish, but here is the link, just in case you want some more info.
The largest Flash and Webdesign conference of the Benelux will take place on Monday 27th September.
Flashtival 2004 will be an informative and educational event, completely related to Macromedia Flash, webdesign and Rich Internet Application development.
The Flashtival 2004 program is divided into 3 concurrent tracks, which are: "development", "animation and design", and "general Flash related topics". This way, every visitor will be able to attend a masterclass at his own level and choose the subject of his personal interest.
At the Flashtival website, http://www.flashtival.nl, you will find a complete list of all speakers.
Flashtival 2004 takes place at Congress Centre De Doelen in Rotterdam, Holland.
Well, finally it's time to develop a full game.
This is how our microgame ( "Drops everywhere" ) will work. Drops keep popping on the screen, but we ensure that the number of drops on the screen is lower than a given number. We can remove a drop by clicking on it. And we have to maintain a low number of drops during a given time. If we succeed, we can play again, or finish the game. If we play again, the maximum number of drops will be lower, so we’ll have to click more of them in the same time. The game goes on and on until we decide to finish it, or until the number of drops is higher than the allowed number.
You can see a statechart diagram here.
The code is distributed in three layers. There’s a model, a view, and a controller, although it is not structured as a MVC. The controller listens to the events fired by the model, and notifies the model when there is an action in the view ( a button click, for instance ).
The initialization process of the game is the following: when the swf is loaded, an instance of DropsController is created. This object creates an instance of DropsWorld, registers itself as an event listener, and starts the state machine associated to the world. The class DropsWorld extends another class called EventSource( in the package net.designnation.events ), that provides the ability to fire events , and to register listeners to those events. The controller ( DropsController ) also creates an empty MovieClip, that will be the main “clock”.
So, when the world is created, we have to start its state machine:
public function initWorld( param: Object )
{
this.stageMC = param.baseline;
this.initBehaviour( );
var theClass: DropsWorld = this;
this.base_MC.onEnterFrame = function( )
{
theClass.doProcess( );
}
this.mySMachine.startMachine( );
}
private function doProcess( )
{
this.BEngineVal.doProcess( );
}
So a new cycle of the state machine will be executed with every execution of the base_MC.onEnterFrame event.
We define the state machine here:
private function initBehaviour( )
{
var initGame : State= new State( "initGame",
new CallbackDecl( this, "initGameAction" ) );
var startGame : State= new State( "startGame",
new CallbackDecl( this, "startGameAction" ) );
var createDrop : State= new State( "createDrop",
new CallbackDecl( this, "createDropAction" ) );
var overDrops : State = new State( "overDrops",
new CallbackDecl( this, "overDropsAction" ) );
var endOfTime : State= new State( "endOfTime",
new CallbackDecl( this, "endOfTimeAction" ) );
var defeat : State= new State( "defeat",
new CallbackDecl( this, "defeatAction" ) );
var victory : State= new State( "victory",
new CallbackDecl( this, "victoryAction" ) );
var endOfGame : State= new State( "endOfGame",
new CallbackDecl( this, "endOfGameAction" ) );
new Transition( "initGameToStartGame", initGame, startGame,
new CallbackDecl( this, "initGameToStartGameEval" ) );
//----------------------------------------------------------
new Transition( "startGameToCreateDrop", startGame, createDrop,
new CallbackDecl( this, "startGameToCreateDropEval" ) );
//----------------------------------------------------------
new Transition( "createDropToEndOfTime", createDrop, endOfTime,
new CallbackDecl( this, "createDropToEndOfTimeEval" ) );
new Transition( "createDropToOverDrops", createDrop, overDrops,
new CallbackDecl( this, "createBubbleToOverDropsEval" ) );
new Transition( "createDropToSelf", createDrop, createDrop,
new CallbackDecl( this, "createDropToSelfEval" ) );
//----------------------------------------------------------
new Transition( "overDropsToDefeat", overDrops, defeat,
new CallbackDecl( this, "overDropsToDefeatEval" ) );
//-----------------------------------------------------------
new Transition( "endOfTimeToVictory", endOfTime, victory,
new CallbackDecl( this, "endOfTimeToVictoryEval" ) );
new Transition( "endOfTimeToStartGame", endOfTime, startGame,
new CallbackDecl( this, "endOfTimeToStartGameEval" ) );
//-------------------------------------------------------------
new Transition( "defeatToEndOfGame", defeat, endOfGame,
new CallbackDecl( this, "defeatToEndOfGameEval" ) );
//-------------------------------------------------------------
new Transition( "victoryToEndOfGame", victory, endOfGame,
new CallbackDecl( this, "victoryToEndOfGameEval" ) );
this.mySMachine.resetToInit( initGame );
}
Once the states and the transitions are defined, we must implement the callbacks needed.
The class that we use to manage the drops is a very light controller. It also extends EventSource, so it will be able to fire an event when the drop is clicked. I know the way I’ve implemented this functionallity can start an endless discussion, but I’ve decided that a drop is a drop, not a MovieClip, so the MovieClip with the drop graphic is aggregated to the Drop class, and the Drop class does not extend MovieClip.
I’d also like to say that obiously this is not the final implementation. A lot of the DropsWorld code should be common for any game that we develop, so it will be wise to put that common functionallity on a base class, and make DropsWorld extend that class. The game itself is not completely finished ( there’s an obvious lack of feedback ), but, in general, I believe this example can be considered as a start point. And, for your information, the development time has been of about an hour and a half.
Well, the final result is here:
And the source code can be downloaded here ( don’t forget to set your classpath ).
Packages:
net.designnation.behaviours
net.designnation.data
net.designnation.events
net.designnation.physics
net.designnation.PoppingDrops ( game classpath )
I’d also like to thank Celia Carracedo for the game graphics.
And, finally, a disclaimer. There are some days when I find really dificult to express my thoughts in english. Today was one of them.
Well, maybe this is not new for many of you, but I've noticed today that the whole macromedia.com site can be browsed from my pocketpc. It's amazing!.
I've just created an avantgo channel to read the flash developer center articles offline. ;)
Congratulations. Good work!
Mobilympics is a cool pocketpc application that will help you keep track of seven sports during the Olympic Games, developed by pc de bolso.
If you own a pocketpc, I think it's worth a try, but bear in mind that the program is provided as 'Ad-ware' meaning that you will find some information about the developer's sponsors ( mostly HP ) when entering and leaving Mobilympics.
Thanks to my brother César, I have noticed this Socket server at freshmeat. I have just downloaded it, and i´ll make some tests soon. It can be hosted in any machine running PHP5. It sounds interesting.
Project in freshmeat
CSS ( Cyber Socket Server )
freshmeat
The authors claim that it is similar to Flash Communication Server, and that it can be seamesly integrated in our flash applications.
Maybe this is common place, but it's something that has surprised me.
The problem I've found is related to the last posts I've made about the state machines.
I've been testing a game that I developed some time ago. At a given moment, a transition must be executed when a sound is finished ( that means that something must happen when a sound is finished ). But, although the game always worked, today it didn't!!.
After a two hours debugging session, I've just tried to play the game in a different computer, and it worked!!. And then I remembered. I reinstalled the operating system of my development machine two days ago, after my holydays ( sniff :-( ), and the new system didn't recognize the sound card. In fact, if I look at my control panel, I see that there are not audio devices installed.
So what has happened?. It seems that the onSoundComplete event is never triggered. I don't know if it's the expected behaviour or not, but well, it's something I must remember!
So, it's time for some code.
You can download the code here. But you should take a look also at the linked list and hashmap we published some time ago, because we will need them now.
We have implemented four classes
Transition ( transitions )
State ( states )
SMachine ( state machine )
BEngine( behaviour engine, it's the one that manages all the game's state machines )
Things will work the following way: first we'll create the state machine that we are going to need, then we'll add it its states and transitions, and then we'll register that state machine in the global behaviour engine ( BEngine ). That behaviour engine will have a timer, so it will control the state machines execution.
First, we'll take a look at this engine. To simplify, it's just a list that holds a reference to each state machine that has been registered. So we can add new state machines to that list, remove a machine from it…
class BEngine
{
private var machineListVal: List;
public function BEngine( )
{
this.machineListVal= new List( );
}
public function registerSMachine( machine: SMachine )
{
this.machineListVal.push( machine );
}
public function unregisterSMachine( machine: SMachine )
{
this.machineListVal.deleteElement( machine );
}
public function doProcess( )
{
var it: IIterator= this.machineListVal.iterator( );
while( it.hasNext( ) )
{
SMachine( it.next( ) ).executeCycle( );
}
}
}
The state machine is not a collection with all the states and transitions. However, we hold only a reference to the first state and the current state. Why? Because the states will be linked by the transitions, so we don't need to know all the states of the state machine, only the first one, and the current one ( so we can evaluate its transitions). However, we have to know if the machine is running, or is stopped.
class SMachine
{
.
.
.
.
public function resetToInit( initState: State )
{
this.currStateVal = initState;
this.initStateVal= initState;
}
.
.
.
.
}
Each state will hold a callback and an array with a reference to all the transitions that start at that state
class State
{
.
.
.
.
public function addTransition( transition: Transition )
{
if( transitionDoNotExist( transition ) )
{
this.transitions.push( transition );
}
}
.
.
.
public function evalState( paramater: Object ): fgPair
{
var nextState: State= undefined;
var retPair: Pair;
var nTam: Number= this.transitions.length;
for( var nIx: Number= 0; nIx< nTam && nextState== undefined; nIx++ )
{
var currentTransition: Transition= this.transitions[ nIx ];
if( currentTransition.evaluate( ) )
{
if( this.__traceInfo__ )
{
trace( "TRANSIT:"+ this.id+ "->"+ currentTransition.endState.id+ " BY "+ currentTransition.id );
}
nextState= currentTransition.endState;
retPair = new fgPair( nextState, currentTransition );
}
}
return retPair;
}
public function execute( parameter: Object ): Object
{
if( this.__traceInfo__ )
{
trace( "S[A]:"+ this.id+"; "+ this.actionCallbackVal.callbackMethod );
}
return actionCallbackVal.fire( parameter );
}
.
.
.
.
}
And last, the transitions. Each transition holds a reference to the initial and the final state and has the ability to execute a callback
class Transition
{
.
.
.
public function set initState( state: State )
{
state.addTransition( this );
this.initStateVal= state;
}
public function set endState( state: State )
{
this.endStateVal= state;
}
.
.
.
public function execute( parameter: Object ): Object
{
if( this.__traceInfo__ )
{
trace( "T[A]:"+ this.id+"; "+ this.actionCallbackVal.callbackMethod );
}
return this.actionCallbackVal.fire( parameter );
}
public function evaluate( ): Boolean
{
var retVal: Boolean= true;
if( this.evaluationCallbackVal!= undefined )
{
retVal= Boolean( evaluationCallbackVal.fire( this ) );
}
return retVal;
}
.
.
.
}
Well, now it's time or an example. But that will be in another post.
As we explained in the previous post, we’ll try to manage the object’s behaviour as a collection of related states, so the entity that implements that collection of states ( or state machine ) will be able to transit from one state to another. So we’ll have a classs ( Bubble ) that aggregates a collection of objects ( the states ) and a graphic to manage its presentation ( a movieclip ).
We are going to implement a non-hierarchical, non-concurrent state machine. If you want to read a deeper essay about state machines, I strongly recommend to take a look at FlashSim or quantum-leaps ( thanks to Jonathan Kaye for the links ). We will try to make things as simple as possible for the shale of performance ( remember, we are developing a game ).
First, here are two UML diagrams ( statechart diagrams ):
Let’s take a closer look at the last diagram. There can be seen the different states that we’ve defined:
1.- initGame: General game initialization.
2.- initRound: General initialization of each game round. There will be setted the exploded bubbles counter, the time counter,…
3.- gamePlay. The user is playing the game.
4.- endOfTime: The time is over. We’ll check is the player has exploded enough bubbles.
5.- defeat. The player has not exploded bubbles enough. Ohhhhhhh.
6.- newChallenge. We offer the player the chance to play again, or to leave the game. If the player chooses to play again, we’ll move to initRound, and if the player chooses to leave the game, we’ll move to endOfGame.
7.- endOfGame. The game is over. We can send the player score to a server side script, …
Well, now that the concept has been explained we’ll try to explain how the state machine works.
First of all, when we enter a state an action is executed. In the most common state machine implementation there are three actions for each state, one will be executed when entering the state, another one when the state is executed, and another one when we leave the state. In this example, we’ll try to make everything as simple as possible, for the shake of performance, and we’ll execute just one action for each state.
Each arrow represents a transition. Each state contains a collection of transitions. This transitions can be callbacks that return a Boolean value, so the state machine will move by the transitions that returns a value of true. Usually, these transitions evaluate a given property of the class, and return true or false. Let’s explain it a bit more.
The state machine is closely tightened to a timer. So with every tick of the timer, some logic is executed ( all the transitions that start at the actual state are evaluated ), and state machine will move using the first transition that evaluates as true. So it will move to another state, where ( when the next tick occurs ) it will execute that state action. And next, it will evaluate more transitions, and…
Before taking a look at some code, we’ll try to explain it better going back to the Bubble class ( and diagram ). Let’s remember that this class is not a MovieClip subclass, but a complex entity that aggregates its state machine, and a movieclip.
So, when we create an instance of this class, and we create and start its state machine, will be in the first state: initBall. So, the state action ( initBallAction ) will be executed, and this action will attach a movieclip, and place it on stage. Then it will set a class flag ( isInitFlag, for instance ) to true, and it will set another flag to false ( isOutOfBoundsFlag ). With every timer tick, the transitions associated to this state will be evaluated ( here, there’s only one transition, that starts at initBall, and ends at moveBall ). So if that transitions returns the value of isInitFlag, it will return true, so the state machine will transit to the next state ( moveBall ).
This state has three transitions: the first one , that ends at itself, aonther one that ends at outOfBounds, and another one that ends at destroyBall.
So these transitions will evaluate ( in order ) the following flags: isOutOfBounds== false; isOutOfBounds == true and isClickedFlag == true.
When this state action is executed, first, we’ll calculate the next position of the bubble. Then, we’ll check if that position is out of the stage ( that includes bouncing against the floor ). If the bubble is out of stage, well set isOutOfBounds to true. So, if the bubble as not gone out of the stage, that flag will still be false. So, the transition that will return true will be the one that moves the state machine to the same state ( isOutOfBounds == false ), so well enter again the same state, so we’ll calculate the next ball position again,….
If the ball goes out of the stage, the transition that ends at outOfBounds will be the one to return true. So, the state machine will move to that state, where we’ll change the ball position or its velocity, and then we’ll return again to the moveBall state.
In the next post, we’ll see the code to implement all this, but now, the most important thing is to understand that is the entity itself the one that, just checking the value of some internal flags, changes it’s behaviour. And that that behaviour is separated in a collection of different objects.
There will be more soon.
We are going to try to implement the State pattern to help us develop complex games or games whose entities have a complex or reactive behaviour.
First, we must consider that this implementation is quite lazy, and the example we're going to explain is simple enough to be explained, but with some complexity, so we can consider to implement this solution. Obviously, as the complexity of the game behaviour, or the complexity of the game entities behaviour grows, this will become a better solution. And also remember that my English is very poor, so, please, be nice :$
So, let's start. First, let's see what "state pattern" means. The intent is: Allow an object to alter its behavior when its internal state changes. The object will appear to change its class. ( here you can find a complete explanation )
So, this pattern should be a good solution when , for instance:
1.- The behaviour of an object depends of its internal state, and must change at runtime depending of that state.
2.- To describe the object's behaviour we use long conditional sentences, with multiple branches. We'll try to put each branch in a different object .
So, in other words, we will try to describe an object's behaviour as a collection of different states, in a way that the object itself could manage its behaviour moving from one state to another.
Sounds interesting, isn't it?. Let's try to build an example.
Now we need some imagination. Imagine we have to develop a game ( "Explode the bubble" ). There will be a given number of bubbles on the stage that bounce when they hit the ground, but that don't bounce against the walls ( I mean, if a bubble leaves the stage by its right side, it must appear again by the left side, and the opposite ). There's a given time to explode a given number of bubbles ( clicking them ). When a bubble explodes, another one appears, so there's always the same number of bubbles on stage. The initial position and velocity ( velocity as a vector, not speed ) are setted randomly. So, if we explode less than the minimum number of bubbles, we loose, but we explode more than that minimum number, we are offered to give it another try. Then we can leave the game, or try again, but we'll have to explode more bubbles in less time. And so on., until we loose, or we leave the game.
At first sight, we can separate our code into two different entities: the game world, and the bubble, so we could write two different classes. The first one will manage the top level logic ( putting bubbles on stage, checking if there have been enough exploded bubbles, checking if the time is over… ), and the second one will manage the bubble behaviour ( bounces, explosions,… ). Let's take a closer look at the last one.
Obviously, the graphic representation of the bubble will be a MovieClip. So we could think about the Bubble class as a subclass of MovieClip, where the onEnterFrame method will be responsible of checking if the ball has left the stage, if it must bounce against the floor, that places the ball on the stage depending of those circumstances ( in other words, that implements a mechanism to calculate the bubble's movement equation ), that detects when the user has clicked the ball, and tells it to the game world, that manages the explosion animation…..
Well, I guess this is not the moment to discuss about inheritance and composition ( I hope so, at least ). Anyway, I don't think there's a right way and a wrong way of doing things ( or of writing code ). But, in this case this approach doesn't seem to be the most appropriate.
First, our Bubble class will have to implement a wide open range of functionalities ( from physical behaviours to just graphics presentation ). So the cohesion will be very low. And that's not very good. ( in other words: keep complexity manageable ).
But also, the Bubble behaviour should be implemented using a long switch statement, or a lot of "if" sentences ( if it must bounce, make it bounce; if it leaves the stage, put the bubble in it's new position; if nothing else happens, just calculate its new position and place it ). And that's one of the scenarios to implement this pattern. And, not in this case, but if the entity's behaviour is reactive, everything makes even more sense.
Have we stimulated your curiosity?. There will be more soon.
I want to save a list of registered users, but I don't know exactly where to save it. If the user selects a checkbox ( that represents the internet connection ), I'll send the data to a server-side script, in XML format. If the user unchecks the checkbox ( representing that there is not a physical internet connection ), I'll write the data to a Shared Object.
So, this is a mission for the Proxy Pattern!!. Why?. Because I want to isolate the proccess of saving data from the rest of the application, so I just want to say "hey, save this", and don't worry about how ( or where ) it is saved.
That's what this pattern does. The proxy class stores a reference to an object , that will be the real subject of the action. But, the proxy itself creates that object, so it can create an instance of one class or another depending on certain run-time conditions.
So, all the possible classes to be created by the proxy must implement the same interface. And, depending of the kind of proxy, it can be also a good idea to make the proxy class implement also the same interface, so, if needed, it can be replaced.
Some code will help to understand it. First the interface:
interface ISaveable
{
public function saveUserList( theList: Array );
}
Easy, isn't it?. We want to save a list of users, so we'll have to implement a saveUserList method
Now, the class that handles the "save to server" feature
class myXML extends XML implements ISaveable
{
private var userArray: Array;
function myXML( )
{
this.userArray = new Array( );
}
function sendData( )
{
//this.sendAndLoad( );
}
public function saveUserList( theList: Array )
{
trace( "The XML is handling the data" );
this.userArray = theList;
//create the XML nodes, and send to server
}
}
Not too complicated. Just a public method to receive an array, and then I'll have to create the XMl nodes, and send the XML to the server.
Well, now the class that saves data to disk
class mySO implements ISaveable
{
private var theSO: SharedObject;
private var userArray: Array;
function mySO( )
{
this.userArray = new Array( );
}
public function saveUserList( theList: Array )
{
trace( "The Shared Object handles the data" );
this.userArray = theList;
}
}
Again, this class implements ISaveable, so after receiving the data, it will try to save it to the contained Shared Object
Now, the tricky part. The value of the checkbox ( the connection status ) is represented here by a variable placed at _root. But, to get this variable value, I'll use a Singleton ( here you can find an implementation by Dave Yang ), That's just a way to have a global accesor to that value, but I prefer it that just using globals. Here is the singleton:
class singleton {
private static var inst:singleton;
private function singleton() {}
public static function get instance():singleton {
if (inst == null) inst = new singleton();
return inst;
}
public function isConnected( ): Boolean {
return _root.connected;
}
}
And finally, the proxy class
class saveUserListProxy implements ISaveable
{
private var realClass: ISaveable;
function saveUserListProxy( )
{
var config: singleton = singleton.instance;
var conFlag: Boolean = config.isConnected( );
if ( conFlag )
{
this.realClass = ISaveable( new myXML( ) );
}
else
{
this.realClass = ISaveable( new mySO( ) );
}
}
public function saveUserList( theList: Array )
{
this.realClass.saveUserList( theList );
}
}
So, finally, for this example, in the main timeline, we'll have
var connected: Boolean = false;
var theUserList: Array = new Array( );
theUserList.push( { id: 0, name: "Cesar" } );
theUserList.push( { id: 1, name: "Javier" } );
var myProxy: saveUserListProxy = new saveUserListProxy( );
myProxy.saveUserList( theUserList );
And that's all. Test it changing the values of the variable "connected". And sorry for my poor english. It's been particularly poor tonight :(
The spanish Ministry of Education offers about 5000 sounds in mp3 and wav format, that can be used freely in educational projects. If you can read spanish, it can be of your interest.
Here´s the link:
http://iris.cnice.mecd.es/bancoimagenes/sonidos/index.php
Don't expect anything specially brilliant here. This is just an story that show how mastering interfaces can help you in your daily work ( as it has helped in mine )
I think I've blogged about it before, but here I go again. The last three months I've been working developing an AS2 framework to build games. We are approaching our first deadline ( next Friday ), so we don't have too much free time.
So, yesterday, I started the development of five games which are quite similar. We've called them "the disposition games", because, well, you have to place some items on screen in the right order. There are a given number of spots , and when you place one of the given items over it, some rules are checked, and then the item is placed or is moved back to its initial position.
There are five different games ( one is about placing children in the school bus, another one is about choosing the order of some tasks that must be completed before going on vacation… )
The architecture of the games is quite simple. There's a main class ( called "World" that aggregates another class called "Scenario" which contains the logic of the game ). So the world class is in charge of controlling the gaming time, sending data to server, loading the graphic and sound assets. The five games are so similar, that we've tried to build them with as much common code as possible.
We decided that we'll ha