Understanding Recursion

This quote is from the great book about mathematics, logic and art: Gödel, Escher, Bach: An Eternal Golden Braid.

It’s a very elegant and easy to understand explanation of recursion which is one of the basic building blocks of programming. This explains more how a recursive function will traverse and branch out to different function calls, usually in a recursive function after hanging up on one person, you would return the data you learned from that call to the previous level which is missing in the example.

One of the most common ways in which recursion appears in daily life is when you postpone completing a task in favor of a simpler task, often of the same type. Here is a good example:

An executive has a fancy telephone and receives many calls on it. He is talking to A when B calls. To A he says, “Would you mind holding for a moment?” Of course he doesn’t really care if A minds; he just pushes a button and switches to B. Now C calls. The same deferment happens to B. This could go on indefinitely, but let us not get too bogged down in our enthusiasm. So let’s say the call with C terminates. Then our executive “pops” back up to B, and continues. Meanwhile A is sitting at the other end of the line, drumming his fingernails against some table, and listening to some horrible Muzak piped through the phone lines to placate him … Now the easiest case is if the call with B simply terminates, and the executive returns to A finally. But it could happen that after the conversation with B is resumed, a new caller – D – calls. B is once again pushed onto the stack of waiting callers, and D is taken care of. After D is done, back to B, then back to A.

Hofstadter, Douglas R. Gödel, Escher, Bach: An Eternal Golden Braid. New York: Basic Books, 1979.

What I would want in a HTML5 gamedev-stack

There are many good and bad ways of doing things when it comes to games. HTML5 / modern JavaScript is very likely going to be the next big game platform (for web, mobile web & social at least) but it’s still got ways to go before it gets there. Some of the issues “HTML5” is tackling are kind of new and unique. If it is possible to really make a cross-platform – write-once environment, there are still many issues left to solve.

Requirements:

(in no specific order)
HTML5
1. Easy resource management. Something more than just folders on the hard-drive that I have to manually edit and re-arrange all the time and roll my own resource usage code for each type. In Flash and Unity3D this is done by a “Library” where the resources are also cast to a object that the environment understands. Sounds are Sound objects that can be easily played and MovieClips are ready to animate and GameObjects are ready to move.

Flash Pro is a pain in the butt but moving the resources into the system and giving them some basic functionality by default actually works nicely and cuts development time and makes getting a project up and running much smoother. Having just some command line scripts that spit out cryptic files is confusing to other team members.

2. Free! As in free speech. There’s just no excuse to make this proprietary because that would mean we didn’t really go forwards much if at all.

3. Easy debugging and performance/memory profiling. With great browsers like Google Chrome this seems to be soon taken care of.

4. Display API that abstracts all the nasty business out. Browsers can be picky about what they support but since we’re not gonna see browser vendors get together and decide one way of doing things ever, some kind of a Display API that just works would be needed. We don’t want to worry if your browser only supports DOM, or Canvas, or SVG or WebGL. I just want to draw a pixel on the screen and smooth and consistent animation, whether it’s keyframes or transformations.

5. Better coding standards, it should be clear what good JavaScript code looks like. There’s always going to be people who do what they want but everyone working on big projects that have to be maintained can probably agree that wildly different coding styles in the same language – if it should be tolerated at all, should be at least very clearly stated in the project. Functional- and structural JavaScript are gonna look different, but both should have some standards. When every API you use has different looking syntax, the code becomes hard to read and understand. Tools like http://www.jslint.com/ are going to help with some issues, as are new versions of ECMAScript and intermediary languages like CoffeeScript.

5b. Another option is to ship support for some other languages / bytecode support for multiple languages with next gen browsers.

6. Sounds! I’m sure everyone agrees that the support for the Sound API is at best horrible right now. If Flash is the most common fallback, HTML5 is not ready for games yet.

7. Easy to distribute over the web. Flash game developers know how easy it is to get your game everywhere on the internet without having to worry about infrastructure yourself. Your .swf file can be hosted anywhere by anyone. For big companies this isn’t an issue since they have their own hosting but for a indie developer, acquiring enough hosting knowledge and paying the server bills are big hurdles. Many of my old Flash games gained millions of players by ending up on a random Spanish / Brazilian / Thai site that I would’ve never realized to put it on myself.

8. WebGL support. The only option to make 3D games in the foreseeable future with HTML5 is WebGL but the support in browsers is not there. http://caniuse.com/#feat=webgl None of the mobile browsers support it. Internet Explorer is probably never going to support it. Only Chrome has full support today.
Canvas on the other hand is starting to look really nice: http://caniuse.com/#feat=canvas and I love 2D games so it’s gonna be a good kickstart for HTML5 games. But it’s definitely a big step back from Flash and Stage3D which soon supports GPUs from 2005 onwards.

9. A nice IDE you can point people to that will do most things they need. Code-completion, project management, refactoring, debugging, profiling, packaging releases for different platforms, etc. Personally I’m liking WebStorm. It’s getting quite good with each new update.

10. Easy to deliver consistent pixel perfect graphics and typography on all platforms. This isn’t actually my requirement but every graphic designer ever.

Github: Wooga’s HTML5 Pocket Island

Wooga recently released their first full HTML5 game (experiment) on GitHub. Pocket Island is a pretty classical Facebook Building-Stuff-Game™.

Pocket I5land

It’s very rare to to get a glimpse at a large HTML5-game codebase so I think this is definitely worth a look to see how one of the big Facebook devs did things. To be fair Wooga gave up on HTML5 as a platform for now after this project, but it’s nonetheless an educational project to explore.

There’s solid documentation on how to get started with this.

Check it out on GitHub:
https://github.com/wooga/Pocket-Island

Doodle Paint5 – Open source HTML5 painting app

One of my first HTML5 apps was this Canvas-based painting app for the Pokki platform. Pokki adds these web-apps to the taskbar of your OS and launches them very quickly. Doodle Paint5 is an app for quick doodling and painting.

It got the nth place in the first Pokki contest netting me a sweet t-shirt and is the most popular and top rated “Art and Design” app! Also the only one.

Cool campfire

 

Check out the app here:
http://www.pokki.com/app/Doodle-Paint5

Get the full source from GitHub:
Doodle Paint5 on GitHub

Flash Development on Ubuntu Linux

This is an old post from 2010 but I’m publishing it for a little help if anyone is researching this type of development. The situation today is even worse since Adobe has officially dropped Linux support. If you insist on using Eclipse(Flex Builder) for Flash development on Ubuntu, here are the packages you need. They’re not available on these URL’s anymore for some reason but with some research they might still be available somewhere.
Eclipse Classic 3.3. I couldn’t get the Flex Builder plugin to install with 3.6.
http://www.eclipse.org/downloads/moreinfo/classic.php

Flex Builder 3 for Linux (alpha 5) and the debug player
http://labs.adobe.com/technologies/flex/flexbuilder_linux/

The Linux version is still missing some features. I didn’t find any of these essential but your mileage may vary.

  • Design view
  • States view
  • Refactoring
  • Data Wizards
  • Cold Fusion – Data Services Wizard
  • Web Services introspection
  • Profiler

10 shortcuts for Flash Builder / Eclipse that will save your life

These are some Flash Builder, or Flex Builder for older versions (Eclipse) shortcuts I use daily and feel like they increase my productivity by a ton.

 

Programming.
Programming without shortcuts

1. Ctrl-Shift-R – Open any file in the project (really quickly!)

This is the most useful key shortcut for me, it’s a quick search for any files in your open projects and pretty much the only way I open files in my projects. Want to find a .fla file which was called something like UIButtons…, just type in *ui*fla. Or you want to open a source code file which was a State but you don’t remember exactly what, maybe StateMainMenu, type in *state*main*.as

Bonus! Ctrl-Shift-T – Open type, slightly less useful but searches only for classes. Includes built in libraries and such.

2. Ctrl-O – Jump to method/property (inside a source file). Official name is Quick Outline.

Instead of scrolling with your mouse wheel and looking for the right method, just press Ctrl-O and type the first letter or two of the method you’re looking for.

3. Ctrl-Shift-G – Find all references of this method/property. Highlight a methods name and press Ctrl-Shift-G.

Very useful for finding dependencies when refactoring and getting a good general view of how a class fits in with it’s surroundings. See who calls the constructor of your class or figure out easily why is the init() method being called twice.

Bonus! Ctrl-G will find all overrides of a method.

4. F3 OR Ctrl-Click – Open Declaration. Click or move your text input cursor to the top of a method call and press F3. Jumps you to the method declaration.

You have a line that reads

1
gameObject.update(deltaTime)
gameObject.update(deltaTime)

How do you find out what this update method does without first finding what class the gameObject is etc.? Either hold Ctrl and click on the update or press F3.

5. Ctrl-Tab – Switch to the next source file. Maybe obvious but it sure is handy.

6. Ctrl-D – Delete line. Just removes the current line you’re on. I use this a lot to remove excess line breaks or a satisfying way to destroy a block of code you don’t need any more.

7. Ctrl-Alt-Down/Up – Clone. Select some text, for example a MouseOver listener function. Press Ctrl-Alt-Down/Up to clone it above/below the method. In Flash you often write repetitive code like Mouse listener handlers and this way you can easily clone almost similar parts and just change the event names in the cloned block.

8. Ctrl-Alt-R – Smart rename. Sometimes you have to rename your classes or methods and the built-in Eclipse renaming system is much more efficient than doing it by hand.

9. Alt-Up/Down – Move selected lines one line up/down. This might be one of my personal quirks again but I like moving blocks of code around with this combo instead of cut-pasting for example. Give it a try!

That’s actually 11 already.

Touchscreen D-pad with AIR for Android (part 1 of 2)

A lot of games use the directional pad or arrow keys for movement. When you move to mobile devices with only a touchscreen, you lose one of the staples of your game controls. I’ll show a simple way of getting your D-pad back and hopefully allowing you to make the transition to mobile easier.

We need to listen to the TOUCH_BEGIN, TOUCH_MOVE and TOUCH_END events. If you’re familiar with mouse events already, you can think of BEGIN as MOUSE_DOWN and END as MOUSE_UP. The biggest difference between a mouse and touch screen is that there can be multiple touches so you need to keep track of which is which. If you got three fingers on the screen and only follow the events, it’s gonna be a mess.

How to keep track of the touches then? Each touch has touchPointID associated with it so whenever a touch event is fired, you can dig it up and compare it with all your known touch IDs. For now we will use the first touch to occur and assign that for our D-pad.

Before anything else, let’s set the input mode for the Multitouch class to Touch_Point. This means Flash will only track the basic touch events like when the touch begins, when it moves and when it ends.

1
2
3
private function init():void{
  Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
}
private function init():void{
  Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
}

Then add some basic listeners for Touch events.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// ... extends Sprite
 
private var dpadTouchID:int=-1;
 
public function init():void{
  Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
 
  addEventListener(TouchEvent.TOUCH_BEGIN, touchBegin);
  addEventListener(TouchEvent.TOUCH_END, touchEnd);
}
 
private function touchBegin(e:TouchEvent):void{
  dpadTouchID = e.touchPointID;
}
 
private function touchEnd(e:TouchEvent):void{
  dpadTouchID = -1;
}
// ... extends Sprite

private var dpadTouchID:int=-1;

public function init():void{
  Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

  addEventListener(TouchEvent.TOUCH_BEGIN, touchBegin);
  addEventListener(TouchEvent.TOUCH_END, touchEnd);
}

private function touchBegin(e:TouchEvent):void{
  dpadTouchID = e.touchPointID;
}

private function touchEnd(e:TouchEvent):void{
  dpadTouchID = -1;
}

Something I’ve noticed is that touchPointID’s always start from 0 and go up. We’ll use -1 to tell when there is no touch assigned to the D-Pad.

We shouldn’t assume that there’s only gonna be one touch because there probably will be atleast 2. We’ll add some checks to make sure we’re only looking at the correct touch and add a event listener for TOUCH_MOVE so we can track the movement of the finger.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// ... extends Sprite
 
private var dpadTouchID:int=-1;
 
public function init():void{
  addEventListener(TouchEvent.TOUCH_BEGIN, touchBegin);
  addEventListener(TouchEvent.TOUCH_END, touchEnd);
  addEventListener(TouchEvent.TOUCH_MOVE, touchMove);
}
 
private function touchBegin(e:TouchEvent):void{
  if(dpadTouchID == -1){
    dpadTouchID = e.touchPointID;
  }
}
 
private function touchEnd(e:TouchEvent):void{
  if(e.touchPointID == dpadTouchID){
    dpadTouchID = -1;
  }
}
 
private function touchMove(e:TouchEvent):void{
//make sure a D-Pad touch is assigned at all, and then check if it matches
  if(dpadTouchID != -1){
    if(e.touchPointID == dpadTouchID){
      // success! let's print out the x and y!
      trace('D-Pad is moving!', e.stageX, e.stageY);
    }
  }
 
}
// ... extends Sprite

private var dpadTouchID:int=-1;

public function init():void{
  addEventListener(TouchEvent.TOUCH_BEGIN, touchBegin);
  addEventListener(TouchEvent.TOUCH_END, touchEnd);
  addEventListener(TouchEvent.TOUCH_MOVE, touchMove);
}

private function touchBegin(e:TouchEvent):void{
  if(dpadTouchID == -1){
    dpadTouchID = e.touchPointID;
  }
}

private function touchEnd(e:TouchEvent):void{
  if(e.touchPointID == dpadTouchID){
    dpadTouchID = -1;
  }
}

private function touchMove(e:TouchEvent):void{
//make sure a D-Pad touch is assigned at all, and then check if it matches
  if(dpadTouchID != -1){
    if(e.touchPointID == dpadTouchID){
      // success! let's print out the x and y!
      trace('D-Pad is moving!', e.stageX, e.stageY);
    }
  }

}
The red area shows where the touch area is for the finger, right now its overlapping right and up arrows.

Ok, now we’re tracking the D-pad touch around. It’s still pretty much acting like a mouse though. We want to use the touch tracking for a D-pad so we’ll need to figure out based on those X and Y coordinates if the finger is on top of any of the D-Pad buttons. Just for examples sake, we’ll draw a simple graphic to represent the four directional buttons. The buttons are 100×100 pixels in size. The touch area we’ll be using is going to be 60 pixels so it’s small enough to still be precise but big enough so that it can cover two buttons at a time. This way you get 8 directions easily.

Right now we’re using the 60×60 square for the finger area but TouchEvent’s have some interesting properties you might want to look into later. For example; pressure, sizeX and sizeY. Those should come in handy when creating more sophisticated controls.

Next create some simple graphics for the buttons. We’ll name them upArrow, downArrow, leftArrow and rightArrow. They should be a descendant of the DisplayObject class for this.

You want to re-check which buttons your finger is touching whenever it has moved and when it’s first pressed into the screen. So we should modify touchMove(e) and touchBegin(e) to check that.

Stay tuned for part 2!

Some Flex components that might be useful, Indexed RadioButton Group, Flex MovieClip

In my last project I made some possibly useful Flex classes that I’ll briefly explain and share here. Maybe I should set up a GitHub with them soon or something.

The first one is IndexedRadioButtonGroup which improves the spark(Flex4) RadioButtonGroup by adding methods that help you keep track and control the index of which radio button is selected. The main use for this is using radio buttons for navigation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// IndexedRadioButtonGroup.as
package com.designoidgames.ui
{
    import flash.events.Event;
    import flash.utils.getTimer;
    
    import mx.core.IFlexDisplayObject;
    
    import spark.components.RadioButtonGroup;
    
    public class IndexedRadioButtonGroup extends RadioButtonGroup
    {
        
        public function IndexedRadioButtonGroup(document:IFlexDisplayObject=null)
        {
            super(document);
        }
        
        public function getCurrentIndex():int{
            for(var i:int=0;i<this.numRadioButtons;i++){
                if(getRadioButtonAt(i) == this.selection){
                    return i;
                }
            }
            
            return -1;
        }
        
        public function selectIndex(index:int):void{
            selection = getRadioButtonAt(index);
            dispatchEvent(new Event(Event.CHANGE));
        }
        
        public function moveLeft(ignoreEnabled:Boolean=false):void{
            var index:int = getCurrentIndex();
            index = Math.max(0, index-1);
            if(getRadioButtonAt(index).enabled || ignoreEnabled){ 
                selectIndex(index);
            }
        }
        
        public function moveRight(ignoreEnabled:Boolean=false):void{
            var index:int = getCurrentIndex();
            index = Math.min(numRadioButtons-1, index+1);
            if(getRadioButtonAt(index).enabled || ignoreEnabled){
                selectIndex(index);
            }
        }
        
    }
}
// IndexedRadioButtonGroup.as
package com.designoidgames.ui
{
	import flash.events.Event;
	import flash.utils.getTimer;
	
	import mx.core.IFlexDisplayObject;
	
	import spark.components.RadioButtonGroup;
	
	public class IndexedRadioButtonGroup extends RadioButtonGroup
	{
		
		public function IndexedRadioButtonGroup(document:IFlexDisplayObject=null)
		{
			super(document);
		}
		
		public function getCurrentIndex():int{
			for(var i:int=0;i<this.numRadioButtons;i++){
				if(getRadioButtonAt(i) == this.selection){
					return i;
				}
			}
			
			return -1;
		}
		
		public function selectIndex(index:int):void{
			selection = getRadioButtonAt(index);
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		public function moveLeft(ignoreEnabled:Boolean=false):void{
			var index:int = getCurrentIndex();
			index = Math.max(0, index-1);
			if(getRadioButtonAt(index).enabled || ignoreEnabled){ 
				selectIndex(index);
			}
		}
		
		public function moveRight(ignoreEnabled:Boolean=false):void{
			var index:int = getCurrentIndex();
			index = Math.min(numRadioButtons-1, index+1);
			if(getRadioButtonAt(index).enabled || ignoreEnabled){
				selectIndex(index);
			}
		}
		
	}
}

The next two classes are the MovieClipButton and a static skin class for it. This is useful when you want to use embedded MovieClips, like when you have a lot of material inside the Flash IDE and you export it as an .SWC file into your project. The MovieClipButton class is extremely simple, in fact it only adds one method to the spark Button called 'source' (other spark components like Image use the same).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// MovieClipButton.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
          xmlns:s="library://ns.adobe.com/flex/spark" 
          xmlns:mx="library://ns.adobe.com/flex/mx" useHandCursor="true" buttonMode="true">
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    
    <fx:Script>
        <![CDATA[
            public var source:Class;
        ]]>
    </fx:Script>
    
    
</s:Button>
// MovieClipButton.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
		  xmlns:s="library://ns.adobe.com/flex/spark" 
		  xmlns:mx="library://ns.adobe.com/flex/mx" useHandCursor="true" buttonMode="true">
	<fx:Declarations>
		<!-- Place non-visual elements (e.g., services, value objects) here -->
	</fx:Declarations>
	
	<fx:Script>
		<![CDATA[
			public var source:Class;
		]]>
	</fx:Script>
	
	
</s:Button>

Then you supply a skin class for the button, this is the simplest one. It only tries to set the current frame of the MovieClip to a frame with the same name as the current state. Also if the MovieClip has a text label like most buttons do, you can change the text through MXML. Just make sure it's called "label" inside the MovieClip.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// StaticButtonSkin.mxml
<?xml version="1.0" encoding="utf-8"?>
 
<!--- The default wireframe skin class for the Spark Button component. 
        Skin classes in the wireframe package are useful for using as a simple base for a custom skin.
      
       @see spark.components.Button
        
      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4
-->
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
                    creationComplete="creationCompleteHandler(event)" alpha.disabled="0">
    <fx:Metadata>
        [HostComponent("com.designoidgames.ui.MovieClipButton")]
    </fx:Metadata>
 
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            
            private var mc:MovieClip;
            
            
            override protected function stateChanged(oldState:String, newState:String, recursive:Boolean):void{
                super.stateChanged(oldState,newState,recursive);
                
                if(mc==null) return;
                
                mc.gotoAndStop(newState);
            }
            
            protected function creationCompleteHandler(event:FlexEvent):void{
                mc = new (hostComponent as MovieClipButton).source();
                mcHolder.addChild(mc);
                
                mc.gotoAndStop(currentState);
                
                if(hostComponent.label) mc.label.text = hostComponent.label;
            }
    
        ]]>
    </fx:Script>
    
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>
    
    <s:SpriteVisualElement id="mcHolder"/>
 
</s:SparkButtonSkin>
// StaticButtonSkin.mxml
<?xml version="1.0" encoding="utf-8"?>

<!--- The default wireframe skin class for the Spark Button component. 
        Skin classes in the wireframe package are useful for using as a simple base for a custom skin.
      
       @see spark.components.Button
        
      @langversion 3.0
      @playerversion Flash 10
      @playerversion AIR 1.5
      @productversion Flex 4
-->
<s:SparkButtonSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
    				creationComplete="creationCompleteHandler(event)" alpha.disabled="0">
	<fx:Metadata>
		[HostComponent("com.designoidgames.ui.MovieClipButton")]
	</fx:Metadata>

	<fx:Script>
		<![CDATA[
			import mx.events.FlexEvent;
			
			private var mc:MovieClip;
			
			
			override protected function stateChanged(oldState:String, newState:String, recursive:Boolean):void{
				super.stateChanged(oldState,newState,recursive);
				
				if(mc==null) return;
				
				mc.gotoAndStop(newState);
			}
			
			protected function creationCompleteHandler(event:FlexEvent):void{
				mc = new (hostComponent as MovieClipButton).source();
				mcHolder.addChild(mc);
				
				mc.gotoAndStop(currentState);
				
				if(hostComponent.label) mc.label.text = hostComponent.label;
			}
	
		]]>
	</fx:Script>
	
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>
	
	<s:SpriteVisualElement id="mcHolder"/>

</s:SparkButtonSkin>