Code to associate file extensions with your application[wxWidgets]

Hi, this is a mini tutorial on how to associate file extensions to your application, so they load on double-click and show a custom icon.

This is how I'm doing it in Flan, a tilemap editor for Flixel that I made.

First of all, you must support loading of files as a parameter to your application executable.
You can add something like this to your derived wxApp class' OnInitialize function:

bool MyApplication::OnInit()
{

\t//...Create windows and stuff...

\tif(argc \g 1) {
\t\tLoadMapFromPath(argv[1]);
\t}
}

Then in your Frame or Dialog implementation file, add this two headers:
#include \lwx/msw/registry.h\g
#include \lwx/stdpaths.h\g


Then somewhere you can use this code to associate (replace .flan with your own file extension)

wxString exePath = wxStandardPaths::Get().GetExecutablePath();

wxRegKey regKey;


regKey.SetName("HKEY_CLASSES_ROOT\\\\.flan\\\\DefaultIcon");
regKey.Create();
regKey.SetValue("", wxString::Format("%s,1", exePath));
regKey.Close();

regKey.SetName("HKEY_CLASSES_ROOT\\\\.flan\\\\shell\\\\open\\\\command");
regKey.Create();
regKey.SetValue("", wxString::Format("\\"%s\\" \\"%%1\\"", exePath));
regKey.Close();

wxLogMessage(_("\\".flan\\" files successfully associated.\\n"
\t"Sometimes it takes a PC restart is required to show the proper icons."));


If you want to have a custom icon show up, you should add it as a resource to your application.
You can see how to do that in this tutorial, but with a difference:
You must add another icon to the resource (.rc) file i.e.:
IDI_APP     ICON       "app_icon.ico"
IDI_FILE ICON "file_icon.ico"


I hope you find this useful.
Best regards
-Martín

Popup-blocker workaround for flixel buttons

Well, I've implemented a little hack to enable FlxButtons to open external urls without the browser blocking it as a popup.

Thanks to AdamAtomic for the tip on how the openURL call should be called inside the mouse handler to avoid the popup-blocker.

Check it out at the Flixel forums!

-Martín

Automatic conditional debug/release execution in ActionScript 3 (Flex 3)

Hi, this time I'll show you how to automatically detect if you Flash has been compiled in debug or release mode.

What's this all about?

I don't know if someone else did this (sorry if it's the case) but I just figured out a way to automatically detect if the Flex 3 (AS3) application has been compiled in debug or release mode, without having to change a single line on your source code.

This comes from the fact that Flex 3 doesn't have a native pre-compiler and not even a _DEBUG global constant to be able to know how it was compiled.
I used to make a global constant myself but a lot of times forgot to change it, having debug info on release mode or debugging a Flash to later find out it did absolutely no traces whatsoever Y_Y.

Well, there's actually a hackish way to know: The Call stack. If you used Flash for a while you would know that there's a difference in the call stack when we are on release mode: No file or line information is showed.
Luckily for us, the Error class has a way to get the call stack string.
So throwing a bogus error, catching it and checking it against a regular expression will give us the information we wanted: Are we in debug mode or not?

Source code

Add this two files to you project root, and call Debug.initialize() somewhere. Then you'll be able to use the _DEBUG boolean anywhere on your code to check for compilation mode.

_DEBUG.as

// Copyright (C) 2009 - Martín Sebastíán Wain - http://www.tbam.com.ar
// Shared under the MIT permissive licence. Please do not remove this comment.

package {
\tpublic var _DEBUG:Boolean = false;
}

Debug.as
// Copyright (C) 2009 - Martín Sebastíán Wain - http://www.tbam.com.ar
// Shared under the MIT permissive licence. Please do not remove this comment.

package {

\tpublic class Debug {
\t\t
\t\tstatic public function initialize():void {
\t\t\ttry {
\t\t\t\tthrow new Error("Intentional error to get call stack");
\t\t\t}
\t\t\tcatch(e:Error)
\t\t\t{
\t\t\t\t//Test the call stack for file/line info
\t\t\t\tvar re:RegExp = /\\[.*:[0-9]+\\]/;
\t\t\t\t_DEBUG = re.test(e.getStackTrace());
\t\t\t}
\t\t}
\t\t
\t}
\t
}

Usage example
if(_DEBUG)
\tplayer.health = 999999;
else
\tplayer.health = 100;\t

If you liked this tutorial, please link to it. I'll appreciate it.
Good luck with your projects!

-Martín

Caverns

Caverns is a tiny little experimentation flash game about lifeforms coexisting in a cavern.

You can change the enviroment by using a palette of materials and see what new life flourishes from your actions.

Try to find all the races!

I hope you enjoy it.
-Martín



Screenshots:

Flixel hacks and upgrades

I've made some hacks for the Flixel Flash game library, and wanted to share them in case you wanted.

Input text field
I made this in order to submit initials for some highscores.

Key features:
* It works as any other flixel object. (E.g. if you put it on a layer and hide the layer, the field it won't be drawn.)
* Works with zoomed games.
* Configurable max length
* Optional forcing of uppercase.
* Basic keystroke filtering (none, numbers, alphabet or alphanumeric) and customized with regular expressions.

Forum link

Dynamic Tilemaps
If you're using a FlxTilemap and you need to modify it in-game, here's the hack for you.

Forum link

Blurry text solution for single line FlxTexts
If you're seeing blurry text, here's a hack to solve it. It will only work for single line texts but
you can tailor it your own way.

Forum link




Well that's about it for this time. I hope you make use of them.

-Martín

Flan Alpha 5 released!

Flan, the multi-layer tilemap editor for Adam Atomic's Flixel has been released!

New Features (since Alpha 2 :^O)

  • Sprites! First you define a type and then add sprites of that type to the layer. Center-aligned to tiles or freely.
  • Sprite type list export/import to update different maps if you need to.
  • Full layer tile replacement (all of indexA to indexB).
  • Map name at the title of the application for knowing what you're working on.
  • Visibility tab options now working
  • You can pass a .flan as a parameter to the app to open it
  • Undo/redo for tiles (and nothing else)
  • Highly improved rendering speed/less CPU eating
  • Import and export single layer CSVs. You can load your previous work to Flan!
  • In-editor Parallax testing
  • Several bug-fixes (Special thanks for the Flixel community for pointing them out!)
You can get it by clicking here!


Tutorial: What the F*** is UpdateUI anyway? (wxWidgets)

In this mini tutorial I will try to shear some light on the matter.

What is an Update UI event? What is it used for? Why it's super-cool?

UpdateUI events try to centralize the logic of interface feedback.
Handling these events should make sure that the information showed to the user reflects the state of the application.

Examples:
* Enable/Disable a submit button based on the validity of the form's elements.
* Check/Uncheck a box based on a selected list item, if it should be processed or not.
* Change the text of a menu item according to the visibility of a toolbar (e.g. Show palette/Hide palette)
* Show/Hide controls according to the user permissions.
* Et cetera.

In the form example to change the status of the submit button, instead of having to check on different sorts of "control has changed" event handlers (a whole logic mess), you should do all these checks in the submit button's Update UI event.

How many times you clicked a button and it yelled at you "You don't have permissions to click this button".
If I don't have permission, then it shouldn't be enabled to begin with!

Update UI events are raised on idle time, when all other events have been processed.
By default handlers to these are called for all controls.

Using it!

Update UI events hand you a wxUpdateUIEvent object.
This object allows you to call on common functions (SetText/Check/Enable...) so you don't have to care if you're disabling a button, combo box, gauge or a whole panel!
This object performs the given operation on the real control behind the curtains.

This will be practical sooner than you think (see code below)...

Update UI events are by default broadcasted to the parent if left unhandled, so you can handle all your Frame's children at once instead of defining a handler for each control:

void MyFrame::OnUpdateUI( wxUpdateUIEvent& event )
{
\twxObject *updObj = ev.GetEventObject();
\tif(updObj == myOKButton_ || updObj == myApplyButton_)
\t{
\t\tev.Enable(IsTheFormFilled()); //See? super practical!
\t}
\telse
\t{
\t\tev.Skip()
\t}
}
I find this most useful when I'm using a GUI designer like wxFormBuilder.
You're probably deriving your Frame class from a changing generated base class, and adding UpdateUI events for each control to your custom made derived class is a drag.
Using if's is a great solution if you're not scared to loose a little bit of performance.

My app is sluggish

If Update UI events are making your application slow, no problem you can always call the static function:
wxUpdateUIEvent::SetUpdateInterval( <milliseconds> )
With a delay to wait before sending UpdateUI events, while being idle.

This could cause inconsistency between the application state and the controls, so you're forced to call the window's UpdateWindowUI(wxUPDATE_UI_RECURSE) in order to force the event.
Good places to do so are when you show/activate a window, change the tab in a wxNotebook, etc...

Hope you liked this tutorial
Good luck, and happy coding!
-Martín

Flan Map Alpha 2 released - mini tutorial

Flan Alpha 2 has just been released!
I'll go really fast over the new features.


* Per layer parallaxing (offset + scroll factor)
In the Layers tab, you can add an offset in pixels for the layer and also a scroll factor between 0% and 100%. The scroll factor is used for parallaxing.

* Bounds information: How much pixels does the map use?
Now all maps (AS3) are exported with the following properties:
boundsMinX, boundsMinY, boundsMaxX, boundsMaxY
Useful for FlxG.followBounds().

* Optional generation of a base map class for OOP multiple map loading
Now you can "switch between maps" that are alike (that is: Have the same layer count/names) easily, using a base map class.
This is activated in the Import/Export tab. Useful for stuff like this:
var mapLevels:Array = [MapLevel1, MapLevel2, MapLevel3];
var _map:MapBase = new (mapLevels[currentLevel] as Class);
state.add(_map.layerCommonNameBetweenAll);

* Fixed error in scrolling
Also it takes into account per-layer offsets!

* Better help on Properties window tabs.
Instead of a label, now there is a box named "Hover for help" on most tabs. Putting your mouse on top of that box brings out some tips and basic help.

* Moving one/all layer tiles by a given offset
In the Layer Modifications tab you can now move the selected or all layers by a given tile offset.
Useful for refactoring levels.


You can also check for corrections in the Step by step tutorial for alpha 1


Good luck!
-Martín

Flan Map Editor tutorial

Introduction

In this tutorial I will teach you on how to use the Flan multi-layer tilemap editor (Alpha 1).
This editor is used to make tilemaps for Flixel.
I will post updates on new features when implemented, tagged with the keyword "Flan", so consider subscribing to the rss feed.

EDIT: There are slight changes in Alpha 2 and an error in this tutorial addressed below. Remarks are in red.

We are going to make a 3 layer map in Flan and modify the version of the game Mode that ships with the flixel package.
Here's a sneak peak of how it will look after we finish.

First download the flixel package and the Flan Map Editor.
Create a project on your favourite IDE.
You can read how to configure your project to compile Mode on the following forum threads: FlashDevelop FlexBuilder MXMLC etc...

For example, I made a AS3 Project on FlashDevelop at the "G:\trying_flan" directory.
When you successfuly compile and run Mode, continue reading.

The editor

Now let's open up Flan so I tell you the basics.



In the screenshot you can see the main screen and two tool windows.

On the main window you'll "paint" your maps and save/load single-file ".flan" maps (using the File Menu).
Remember to save from time to time to avoid loosing your work! You can by pressing Ctrl+S, so there's no excuse.

Let's talk about the Properties window because it's where you're going to set all the configurations.

Map Tab
You should fill the Map tab fields with estimative values and a default tileset. When adding new layers they will default their options to this configuration.

  • Make a 40 by 20 map, using the Mode tileset. Click browse button and search in flixel's source "data" directory for"tiles_all.png".
  • Set the name to "Test" (Generated code will use this name).
  • If you want, change the background to black, to be more similar to Mode's.
  • Click on apply changes, this is important.


(The palette shouldn't show anything yet, as there are still no layers.)

Layers tab

In this tab you can add all layers you want. Let's add 3 layers called: Background, Main and Foreground.
I'll guide you on how to configure one and you do the rest.


Click on the add button on the Layers tab. Now go to the Layer options tab.
There you can configure each layer with specefic options.


Let's pause a little to go to the palette window. It's really straight forward.
Left click selects a tile type to paint with it on the main window.
Go on, try it, I know you're probably bored to tears right now :)
There's zooming in case the tiles are too small and you can't see anything.

Well, let's go back to the Layer options tab.
Here you should set the first collidable tile index and the first visible tile index.
If you don't know what is this all about, I recommend you to read some documentation on the FlxTilemap class constructor.
On Mode's tileset, as you can see, the first visible tile is on index 1 (index 0 is the first, as indexes start at zero), and the first collidable on index 3, so let's set it this way.
Let's name the layer "Main", and leave the "Main layer" checkbox on.
Don't forget to click on Apply changes!
If you resize it's dimensions to smaller values, the application will warn you that cropping could occur.

Add the three layers I mentioned before, and on the layers tab, order them like this:
Foreground
Main
Background

Now go to the main window and draw a map. Left click paints.
Use the palette to choose tile types or optionally use the right click as a "pipette".

You can select each layer just by clicking on them at the layers tab, and hide or show a layer for comodity while editting (or performance if it's running slow).

Next there is an example of a map I made (commented).


Exporting AS3 code and CSV tilemaps

This might be a drag, but it's only needed to be done once.

We will now export all the map data to code and comma separated values (CSV) tilemap text files, and fit it in our code.

Go to the Import/Export tab on the properties window.
Choose the directory where you want to put the maps (CSV) and the directory to generate the code to (AS3).
I use the same directory as the sources for the map code, and a "maps" directory inside of it for the tilemap CSV text files.

EDIT: In Alpha 2 there is an option to called Use base map class.
You can deactivate it in order for this tutorial to be more similar, although is better to leave it on.

Click on Export all. You can later use Export only CSVs if you keep the map format (i.e. layer count/names) or have modified the code yourself and don't want to loose the changes but want to update the map tiles.

Let's stop with the editor for a little while, and get to hack Mode's code.

In Mode.as, replace this
import com.adamatomic.Mode.MenuState;
and this
super(320,240,MenuState,2,0xff131c1b,true,0xff729954);

for this
import com.adamatomic.Mode.PlayStateTiles;
and this
super(320,240,PlayStateTiles,2,0xff131c1b,false,0xff729954);
respectively

This will make the game go directly to the gameplay, but not to the randomly generated map like game (Mode's default configuration), but an internal (old?) code that loads from a tileset.

In PlayStateTiles.as remove the following lines:
[Embed(source="../../../data/map.txt",mimeType="application/octet-stream")] private var TxtMap:Class;
[Embed(source="../../../data/map2.txt",mimeType="application/octet-stream")] private var TxtMap2:Class;
[Embed(source="../../../data/tiles_all.png")] private var ImgTiles:Class;

We won't need them anymore

Let's go back to Flan Map Editor for a second.
Click on the "Generate code for FlxState and copy to clipboard" button on the Import/Export tab.

Switch to the text editor again (PlayStateTile.as)
and paste the code.

it will be something like this:
\t\t//PUT THE FOLLOWING INSIDE YOUR DERIVED FlxState CLASS (i.e. under 'class MyState { ...')
\t\tprivate var _map:MapTest;

\t\t\t//PUT THE FOLLOWING INSIDE YOUR DERIVED FlxState CLASS' CONSTRUCTOR (i.e. inside function MyState()...)
\t\t\t_map = new MapTest;
\t\t\tthis.add(_map.layerBackground);
\t\t\tthis.add(_map.layerMain);
\t\t\tthis.add(_map.layerForeground);

You should replace the old "_tilemap" with our generated flan map:
replace this
private var _tilemap:FlxTilemap;
this
_tilemap = new FlxTilemap(new TxtMap,ImgTiles,3);
and this
this.add(_tilemap);

for this
private var _map:MapTest;
this
_map = new MapTest;
and this
this.add(_map.layerForeground);
respectively.

We just need to add only two more generated lines and we're set.
Because we want the main and background layers to be drawn before the player, we should add these two to the FlxState before the player:
this.add(_map.layerBackground);
this.add(_map.layerMain);
before this:
this.add(_player);

EDIT: We should add these layers even before, before the bullets added... or else the bullets will be drawn before the background and main layers!

Finally, as our main layer is the one that's going to be the only collidable one,
all references to "_tilemap" should be replaced by "_map.layerMain".

Compile and run, or see how it looks/works online clicking this link!

Download the project

You can download the FlashDevelop project here. It's already been hacked and it includes the ".flan" file so you can start using it directly.

Just in case, here's the Flan download link again.

Remember to give all feedback you like at the forums or drop a comment on this blog post!
Thanks!

-Martín

How to add an icon to your windows application executable in Microsoft Visual C++ Express Edition

Adding an icon to your ".exe"
In this short tutorial I'll show you how to add an icon to the executable file, so it's seen on the Windows' explorer application.
How? Easy as pie.

Open the notepad application (Start → Run... → "notepad" → OK)
Write this line:

IDI_APP     ICON       "my_icon.ico"
Being "my_icon.ico" the name of your icon file.
Save the file as "resource.rc" to your project's directory (the icon file should be in the same directory too)
Then go to your project view in MSVC, and right click on the "Resource Files" folder, click "Add → Existing item..." and then select the "resource.rc" file.


This works for Microsoft Visual C++ Express Edition version 2008. But I believe it should also work for the 2005 version.

You can add all sorts of resources by hand this way, like bitmaps using the "BITMAP" keyword instead of "ICON" and then access them during run time (Clue: See WINAPI's LoadResource() and FindResource() )
For more information on resources, visit this article from the MSDN.

And how do I make an icon anyway?

You can use the awesome and free IcoFX application to author icons.
After drawing your icon, you must create multiple icon sizes so Windows can use them depending the context (e.g. in report view, in icon view and in the big thumbnail view also).

This is really easy, as IcoFX does it automatically for you.
Click on the Icon menu → Create Windows Icon From Image... → OK. and you're done!
You must save this file as it creates a new one keeping the original safe from modifications.



I hope you liked this tutorial
Good luck!
-Martín