Matt's thoughts

Matt's thoughts

Matt Benic  //  Game & mobile dev gun for hire and environmental worrier.

Aug 25 / 2:45am

Champ Chase

ChampChase is a project of the Afroes Foundation developed for them by I-Imagine as part of the Nelson Mandela Children's Fund Champions for Children CampaignReleased as an online flash title as well as a J2ME mobile game, the challenges here were to quickly build a Flash equivalent to I-Imagine's flexible J2ME engine, as well as expand on the company's in-house high score system and communicate with it from flash.

The game is a 2D platformer aimed at educating young players about various dangers they may encounter such as criminals, drug abuse and online predation. This was achieved through a combination of stylized characters associating each concept with a familiar object or animal with typically negative connotations, as well as more direct information provided at key points. The game is simple and fun, placing the player in the role of a protector saving children from these dangers.

(download)

Filed under  //  flash   j2me   mobile   portfolio  

Comments (0)

May 24 / 9:47am

Flash development workflow for traditional dev teams, Part 2

Part 1 of this walkthrough ended off with a flash animation linked up to a main application class that would allow regular updates of that application. This time around we'll see how to access objects in your application added in Flash from the library. Once these are in place, your artists can go nuts customizing them, as long as the basic setup stays the same.

The Menu and Button classes
Let's set up a simple menu class that will allow us to continue to gameplay, or quit the animation. In Flashdevelop, create a new class in your package (right-click the package, Add->New Class) called Menu, specifying MovieClip as it's base class. Add two MovieClip members to it for the buttons, called playBtn and quitBtn:

As with the App class, add basic singleton functionality, but this time initialize the singleton in the menu constructor:

Note I'm not clearing the singleton pointer at any stage, but it will be replaced the next time an instance is created, releasing the reference to the last object and allowing it to be garbage collected. This isn't a singleton in the purest sense, but it does allow us global access to the most current instance. Actionscript doesn't have destructors and I'm yet to find a replacement that I'm 100% happy with.

Finally, add a function onButtonReleaseHandler to handle button presses, and implement the (extremely simple) menu logic:

You'll also need to import the App class at the top of the file, using it's fully qualified name:

Note: I've switched on the actual source object here. Actionscript's switch statement is extremely flexible, unlike that in C++ and Java, any object can be used as a case, including strings.

Here is the completed Menu class:

Now we need a simpleMovieClip subclass called Button that will notify the menu when it is pressed. Flash does have it's own Button class, but it's really inflexible in that Button components can't use a custom Button subclass. The norm seems to be to just use a custom MovieClip subclass, and the functionality in the Flash Button class can easily be implemented anyway. For our purposes, a simple class that calls the Menu singleton's onButtonReleaseHandler when it is released will suffice:

Changes to the App class
At this point very little needs to be added to the App class, it just needs the function the Menu class called, playGame. This will move the main clip to the Level frame:

You may also want to remove the trace call in onEnterFrameHandler. It's demonstrative purpose has been served, and outputting text on every frame will just slow down the animation.

The Menu and Button MovieClips
Now we need the actual visual elements used for the menu. First create a new MovieClip in the library (Ctrl+L or Windows-Library to open the library, right click in the library->New Symbol...) called PlayButton. Set it's Type to MovieClip, check the Export for ActionScript checkbox, and specify it's Class as your fully qualified Button class's name (ie including the package):

 
Unknownname

Clicking Ok to dismiss the Create New Symbol dialog causes Flash to open that symbol for editing. Use the flash tools to create a simple button. Eg add a Rectangle for a background, and a TextElement for the text to end up with something similar to this:
 
0unknownname
Copy that symbol as a starting point for the Quit button, right click the symbol in the Library and select Duplicate. In the Duplicate Symbol dialog name the symbol QuitButton and as before enable Export for ActionScript and set it's class to your Button class:

1unknownname

Again, dismissing the dialog with Ok opens the component on the stage. Edit it to say Quit instead of Play.

Now create another new Symbol, this time calling it Menu and setting it's class to your Menu class:

2unknownname

Drag the PlayButton symbol from the Library to the stage, and then do the same with the QuitButton. The result should look something like:
3unknownname

The buttons now need to be named to match the members added to the Menu class earlier. To do this, click on a button on the stage to select it (not it's template control in the library), open the Properties window with Ctrl+F3 or Windows->Properties and replace the <instance name> text in the topmost textbox with the appropriate name. Your Play button should be called playBtn and your Quit button quitBtn:


Putting it all together
The last thing to do is add your newly created menu to the appropriate frame at the top level of the timeline. Return to the top level by clicking on Scene 1 above the stage. In the timeline, on the Objects layer, add new keyframes (right click->Insert Keyframe) below the Menu and Level labels (should be frames 10 and 20 respectively). Now with the new keyframe under Menu selected, drag the Menu symbol from the library onto the stage. Frames 10 to 20 on the Objects layer should now be grayed out to indicate content exists on those frames.

 
6unknownname

If you now run the animation with Ctrl+Enter, the menu will be displayed, and clicking Play will take you to the Play frame (which is currently empty). The Quit button may appear to do nothing, but that is just because fscommand ("quit") has no effect when run from the Flash environment. When the generated .swf file is run by double clicking it in an explorer window, the effect is as expected.

The full project so far is attached to the post. That's it for part 2, the next post will go into adding and manipulating objects programmatically.

A note on variables linked to stage objects
In this example, I used variables within a class who's only link to visual objects is their name. That's scary. Actionscript won't tell you if one of these objects is missing, it will just carry on as if nothing is wrong. You can't even expect an error or exception when you call a method on one of these nonexistent member objects. That's terrifying. Now you may be tempted to insist on creating all objects yourself, programmatically, but that's once again taking a certain amount of creative control (placement) away from the artists, which is kind of the whole point of Flash. The only way to be 100% sure objects you expect to be there are actually there is to check them against null and handle the missing case by throwing an exception/error or making the mistake known some other way.
Related to this is the interesting little issue that numeric values in flash are represented by the Number class, as opposed to some kind of integral type, and must be properly initialized like any other object or will be null. This can catch you by surprise with some really wierd behavior, so if you start seeing NaN's in output, there's an uninitialized Number somewhere.

(download)

Click here to download:
WorkFlowProject.zip (10 KB)

Filed under  //  code   flash  

Comments (0)

May 21 / 1:53pm

Some useful regular expression patterns when porting code between languages

I'm currently moving a lot of code from Java to Actionscript, and regex has been a lifesaver. Here are some of the patterns that proved invaluable, and that would work on most c-style languages. The Actionscript replacements are obviously specific to that language, but changing them for a different output language really would be trivial:

Find non-parameter variable declarations and assignments
Note: this will find returns as well, see the next pattern
(\w+)(\s)(\w+)(;|\s=)

Flash replacement:
var$2$3:$1$4

Will replace:
    int myInt;
    boolean myBool = true;
With:
    var myInt:int;
    var myBool:boolean = true;   

Find resulting returns in Flash
This will match all the wonky return statements resulting from the previous replacement.
var(\s)(\w+):return;

Flash replacement:
return$1$2;

Will replace:
    var true:return;
With:
    return true;

Find parameter variable declarations
(\w+)(\s)(\w+)(,|\))

Flash replacement:
$3:$1$4

Will replace:
    public int foo(int intParam, boolean boolParam) {
With:
    public int foo(intParam:int, boolParam:boolean) {

Find function signatures with parameters in c/java format
(\w+)(\s)(\w+\([\s?\w\s\w+,?]*\))(\s?\{)

Flash replacement:
function$2$3:$1$4

Will replace:
    public int foo(int intParam, boolean boolParam) {
With:
    public function foo(int intParam, boolean boolParam):int {


Find function signatures with parameters in Actionscript format
(\w+)(\s)(\w+\([\s?\w+:\w+,?]*\))(\s?\{)

Flash replacement:
function$2$3:$1$4

Will replace:
    public int foo(intParam:int, boolParam:int) {
With:
    public function foo(intParam:int, boolParam:int):int {

Find numeric types
(,|;|\(|\)|=|\s)(int|long|short|float|double|byte)(,|;|\(|\)|=|\s)

Flash replacement:
Number

Will replace:
    var myInt:int;
    long myLong;
    float foo(byte bar) {
With:
    var myInt:Number;
    Number myLong;
    Number foo(Number bar) {

Filed under  //  code   flash   j2me   java  

Comments (2)

May 17 / 7:35am

Getting frame numbers from frame labels in Actionscript

Flash's frame-based development paradigm is unlike anything I've ever worked with before, and with it's labels makes for an ideal and intuitive way for programmers and artists to communicate object state. Provided the artist uses the required labels in a MovieClip's timeline, it's easy for a programmer to change animation state as required when the corresponding object's state changes. Unfortunately, Adobe didn't provide a direct way to get the frame numbers corresponding to frame labels.
This calls for a more brute force way of doing things. Given an array of expected labels though, it's not difficult at all. Provided you have implemented a MovieClip subclass, corresponding to the exported MovieClip in the main .fla file's library, the following setup will work just fine.

First, set up an array with labels for your intended states (STATE_LABELS), and a set of values representing the indices into that array as static members in your class (in other languages I would denote these as constants, but Actionscript 2 has no constant support, AS3 does):

 
 
You'll also need a static array member STATE_FRAMES  to hold the frame numbers, but leave it uninitialized. I'm using a static value here because I expect a 1:1 relationship between the class and MovieClip symbol. It's quite feasible that in some situations you may reuse the same class for multiple symbols, in which case you would rather keep this non-static to allow the artist flexibility:
 
 
Now within the constructor, check if STATE_FRAMES is null (since in this case a static array is being used it only needs to happen when the first instance of this class is instantiated) and if it is create and populate the array, jumping back to the starting state either way:
 
 
There are two things to note here, firstly we are assigning values for both the label and index in the array. Actionscript use associative arrays, so this is perfectly legal, and it gives us the freedom to later reference the frame numbers based on whichever value we happen to have handy, the label or the index. Secondly, this approach will jump your movieclip to each of the labelled frames (but ONLY the first one corresponding to your object), so be cognisant of any effects that may have.
 
You now have the ability to check if an object is on the start frame of a given state, and if your artists are constrained to keeping states in a particular order, even checking if you are within the frame range of a certain state. The full code of the sample class is listed below, and you can download the .as file and a sample .fla showing the symbol setup here.
 
Filed under  //  code   flash  

Comments (0)

Apr 28 / 5:11pm

Flash development workflow for traditional dev teams, Part 1

I'm a fairly old-school developer, and probably a little on the obsessive compulsive side, so the (perceived) messiness of flash development always frightened me a little. Flash development (as I've always understood it) has some nasty elements that go against everything I consider 'proper' development practices:

  • Large amounts of code are essentially stored inside what should be art resources.
  • A large chunk of the project is tied up in a single file that can only have binary differences applied to it (and hence can't be safely worked on by multiple team members without an exclusive svn lock) .
  • Either programming seems largely reactionary to what the artist adds, or the artists are restricted to some obscure naming convention imposed on them by the programmers.
  • There's no clear boundary between user interface and logic layers, with the mix of layers, frames and code potentially anywhere, finding the bit of code that actually does something a pain and unit testing almost impossible.
  • There's no clear documentation system.
  • Code editing in Flash is archaic. No autoformatting, limited lookup and completion, basically it's like coding in Notepad-but notepad's text area doesn't lose focus every time you swap away to another app and back again.
Of course Flash development has some compelling properties that make writing it off completely just plain silly:
  • It gives artists incredible creative power, they can do all sorts of cool stuff without a programmer needing to be involved or writing frameworks and tools for animation, effects, etc.
  • It allows artists to see what the end product will look like at any stage-essentially providing them with unit testing that programmers take for granted.
  • It has a HUGE install base, across just about every platform and does a solid job of delivering on the "write once, run anywhere" promise (especially if you stick to older standards that are compatible with many mobile devices).
  • Chances are, there's no big download required for the user, they are very likely to already have flash installed.
  • There are tons of programmers and artists out there familiar with the toolset, so hiring for teams or finding contractors is made a lot easier.
So when a new project came along that needed to be implemented in Flash and I couldn't find any resources on Flash project management that suited my needs, it was an opportunity to set up the kind of workflow that both programmers and artists on the team could be comfortable with. What follows is a description of the results.
 
Requirements
For reference, these were my limitations:
  • Use Flash Lite 2.0 and Actionscript 2.0 (for the most part this should all apply to other versions as well though)
  • Use Adobe Creative Suite 4 (solutions that removed the actual flash tools from the workflow kind of defeated the point of having artist friendly tools)
I ended up settling on FlashDevelop as an IDE as it does a good job of implementing the code editing features missing from Flash itself.
 
Setting up the project
In FlashDevelop, create a new ActionScript 2 Flash IDE project as shown in Screenshot 1.
You can obviously change the settings to your liking.
 
In the Project view, create the folders (right click the project icon, Add->New Folder) that will house your source and output files. The FlashDevelop wiki suggests a convention of src to hold your source (in this case meaning .fla and .as files and any resources not intended for distribution) and bin for your distribution binaries. It's also worth creating your code package folders at this stage (as in Java style packages, or C++ namespaces). See Screenshot 2 for what the result should look like.
 
By default FlashDevelop uses your project root as the classpath, so this needs to be updated for the new layout. Open the Project Properties (right click the project icon in the Project view, select Properties...) and in the Classpaths tab, click Add Classpath and select your newly created src folder. After clicking Ok in the file dialog, the result should look like Screenshot 3.
 
The main flash file
Now open up Flash, create a new Flash file using whatever settings are appropriate for your project, and save it in your new src folder (directly in src, not in a subfolder). You'll want to configure the file to be exported to your bin folder. To do this open up the publish settings dialog (File->Publish Settings) and on the Formats tab, change both the Flash and HTML File values to include "..\bin\" as in Screenshot 4.
 
If you now compile and execute the flash file (Ctrl+Enter), you'll see the resulting .swf is created in your bin folder.
 
Note: for source control purposes, you can add a rule to ignore all .swf files in the bin folder, to avoid bloating your repository or having conflicts due to binary differences.
 
At this point it's a good idea to set up layers for your (two lines of) Actionscript code, frame labels and scene objects; and to set up the top level state frames for your application. Don't worry if this sounds like the 'messy' flash you've heard of, it's just to keep things well organized.
First add two new layers to the timeline (probably at the bottom of the Flash window, Right Click on the name of the automatically added Layer 1 and select Insert Layer). Now rename the layers, from top to bottom, to Actions, Labels and Objects respectively. To rename a layer, just double-click on it's existing name. Your timeline should now look something like Screenshot 5.
 
Now add the labels for your states. Open up the Properties view (most likely one of the tabs near the top-right of your Flash window). In the timeline, click on the first frame in the Labels layer and set it's Name in the Properties view to Init. You should notice a little red flag now in the timeline indicating this is a named frame. Now add another frame by right-clicking in frame 10 on the Labels layer and selecting Insert KeyFrame. Name the frame (in the Properties view) Menu. Add another keyframe at frame 20, and call it Level. Finally add another keyframe at frame 30, don't worry about naming it, it's sole purpose is to ensure your previous label is visible. Your timeline should now look like Screenshot 6.
 
You can think of these named frames as the main states your application will be in. Init will be the the frame the application starts in (and where we'll do our ActionScript magic), Menu is where the application will be advanced to once initialization is complete to allow the user to interact with a menu, and Level will be the actual game level. At a later stage you can easily add to these states.
 
The application class
Note: This is a workaround for there not being a document class in Actionscript 2. In Actionscript 3 this can apparently be done in a far less hacky way, by specifying an application class in the IDE.
 
Moving back to FlashDevelop, create a new class in your package (right-click the package, Add->New Class) called App, and set it's Base Class to MovieClip as illustrated in Screenshot 7.
 
A class template will be generated for you that includes a constructor and not much else:
 
/**
 * ...
 * @author Matt Benic
 */
class us.benic.matt.App extends MovieClip
{
       
        public function App()
        {
                
        }
        
}
 
Note: The comment block at the top of the file with the @author tag in it is Javadoc commenting. FlashDevelop has full support for Javadoc, a well established system typically used to document Java libraries. The doc generator can be found under Tools->Flash Tools->Documentation Generator..
  
 At this point if you click Check Syntax button on the toolbar your code should compile successfully. If it doesn't, make sure you set the project classpath as described earlier.
 
There should only ever be one instance of this class in existence, and it'll be useful to be able to access it from other classes in the app (no more dodgy calls to a named root document), so add very basic singleton access:
 
/**
* The main MovieClip instance.
*/
private static var instance:App;

/**
* Singleton accessor.
*/
public static function getInstance():App
{
return instance;
}
 
         
Because this class is a MovieClip subclass, Flash actually allows the main document's prototype class to be replaced with it at runtime. To take advantage of this, add a main() function that will achieve this:
 
/**
* Application entry point.
*/
public static function main(movieClip:MovieClip):Void
{
movieClip.__proto__ = App.prototype;
movieClip.init();
}
 
Because the actual MovieClip instance has already been instantiated (with the default MovieClip constructor) it's necessary to do the additional initialization in a standard method. There are tricks to force the subclassed constructor to run, but that seems a little too hacky for my liking. Here's the init method:
 
/**
* Initialize the instance.
*/
private function init():Void
{
// Set static instance
instance = this;

// Register frame event handler
this.onEnterFrame = this.onEnterFrameHandler;

// Jump to the Menu named frame
gotoAndStop("Menu");
}
 
 
In addition to setting the singleton pointer, the init method sets the document's onEnterFrame event handler and progresses the MovieClip to the Menu named frame created earlier. The onEnterFrame event fires every frame and becomes your update loop (there is no explicit render loop). For now just provide a simple implementation for the function that outputs the current frame:
 
/**
* Frame event handler.
*/
public function onEnterFrameHandler():Void
{
trace("Frame: " + instance._currentframe);
}
  
For a complete listing of the App class thus far, click here.
 
Registering the application class 
Now to actually get the App class registered and updating. Go back to Flash, click on the first frame in the Actions layer and open Flash's Actionscript editor (F9 or Window->Actions). Import your package, and call the App class's (static) main function as follows:
 
import us.benic.matt.*;
App.main(this);
 
Now if you run the Flash file, you should see "Frame: 10" repeatedly output to the Output view in Flash. Our custom handler has replaced the document's prototype with itself, grabbed a reference to it, advanced to the Menu frame and is now updating on each render. Note that despite the call to gotoAndStop in the init method, our object is still receiving updates. This is because while the timeline is stopped at that frame, the document itself is still rendering at a steady framerate, and re-entering the same frame. Any objects in this frame, however, will continue animating within their own timeline.
 
For the full project so far, click here. In the next post on this subject I'll go into how you can cleanly import MovieClips from additional Flash files for modular resource control, and associate them with classes in your framework, gaining easy access to their sub-objects.

 

(download)

Filed under  //  code   flash  

Comments (0)