27
Feb 12

Introducing HTML5 Game Development by Jesse Freeman (O’Reilly Media)

Jesse Freeman‘s Introducing HTML5 Game Development, Developing Games with Impact is an excellent read for anyone willing to get their hands dirty with JavaScript as language of choice for game development. It offers general insights on what is needed to develop a game. Topics include writing game design docs, using in game stats to analize player behavior, some asset preparation and more. However, it mainly offers a head start in developing JavaScript based games with the Impact game engine, covering next to all it’s features.

Disclaimer

I did not get myself a copy of Impact. Just reviewing the book and not the Impact framework I did not see it as nessecary. Had impact been on sale like it was about a month or so ago I might have gotten my on copy (notch, notch, wink, wink).

The positives

Let’s start with those according to the feedback rules…

To me te book feels like a cookbook to get one specific game done (“type this here …”) at times. It however gives a good overview of most if not all ‘classes’ and possibilities of Impact and how to get up to speed with building a relatively small game with it. Using the accompanying level editor called Weltmeister Jesse shows you how to design levels, how to load them in Impact and bring the level to life. What else can you ask for?

Next to that more or less main goal of the book, you’ll get an overview of the whole process of game development. From initial idea to publishing (and possible deployment on iOS with a template Xcode project that comes with Impact). Good insights from someone who knows what he is talking about.

Finally it contains some heads up on HTML5 development. I’m afraid that is still nessecary with the way browser support is at the moment.

The negatives

The subtitle of book is a nice pun (and the name of the game framework is well chosen), but may be somewhat misleading for the less informed buyer of the book. Actually tagging along with Jesse in building your own game will set you back $99: the subtitle’s “Impact” refers not only to the effect games may aim to have on their player, but also to the commercial Impact game framework written in JavaScript. Just a fair warning ahead.

Another downside I think there is to the book is the intended audience as it states. Personally I don’t think this book is much use without having prior programming knowledge. If you have none, you’ll end up with a working game nonetheless, but I doubt you’ll understand why, how to change it or to build your own in any reasonable fashion.

Finally, usage of stats to analyze players behaviors is stressed, however, the examples may have been a bit more clear (I’m pretty much a GA noob)

Impact

Without having used the software, it seems like a real nice environment to work with. It comes with a good map editor, several debugging and profiling features. To help with the game mechanics there’s collision detection and particle systems and most needed features of the box so you can focus on the creative process.

Concluding

I’d by the book if you want to do some JavaScript game dev, especially if it involves platform games. If you have no programming experience I would get some basics done first but I guess it all depends on your individual talent to pick up programming.
It is a quick read and gets you up to speed with Impact in about a day (or two).

Get HTML5 Game Development


26
Feb 12

Hack, slash & play with kinect at FITC Amsterdam 2012

Today the workshops of FITC 2012 took place. I visited Koen De Weggheleire en Wouter Verweirder their Kinect workshop.

Koen and Wouter are developers of AIRKinect of which version two is almost to be released. Unfortunately my lovely new MacBook refused to install some of the drivers despite Wouter’s persistence. Fortunately they had a spare laptop to use (thanks!).

I’d seen demos and fooled around with the depth image before, but the next version of AIRKinect, used as native extension offers lots more then I’d ever seen possible in AIR (may of course be my ignorance).

Some of the features of the 2.0 preview we got to play with were:

  • depth image
  • point cloud
  • point cloud regions
  • skeletons
  • poses

Depth image

The depth image shows the image the IR camera registers in greyscale. Nearby white, far black. My first ever experiment was that I used this to, pixel by pixel, reconstruct a 2.5D image with Flash’s z-property of sprites. But…

Point cloud

The point cloud is a ByteArray with for each “pixel” an x-, y-, and z-position. This allows for precise tracking of, for instance, the closest thing the IR camera registers. Extend your arm and move stuff around, the famous Minority Report interface in the making.

Point cloud regions

Point cloud regions allow use of hotspots. If a certain region (a box) contains more than a set number of points from the cloud (the count is done by the extension), you could start whatever action you see fit. Du du, du du, du du, du du, ta ta! I can feel it coming in the air tonight … Drum like Phil Collins for instance.

Skeletons

The skeletons you may have seen before. AIRKinect supports 4 skeletons and then some additional center of mass registrations. With the skeletons you have access to the main joints, their position in 3D space, position projected onto the webcam image, orientation and more.

Poses

With the skeletons you can create poses, this is actually not done in the extension, but with a few classes in which you can define poses like assertions: right elbow, above, right shoulder. Combine a few of these rules and you can create complex poses which are easy to check.

There is no doubt more, but the distraction of and annoyance over the failures of installing macports probably made me miss out on some…

All together it requires a somewhat elaborate install sequence (which they will no doubt publish at due time) on the Mac, mine being the odd one out resisting all attempts to get it running. On windows it’s a bit lot less elaborate. Definitely will try at home to get it running on my desktop. When I succeed, hours of fun will be waiting :)

Pointcloud


01
Dec 11

Limit orientation on devices with ActionScript and the application descriptor

A short one…

To limit orientation of the stage on devices you don’t need much. In this example I want the application to only be displayed in landscape mode.

Loop up the aspectRatio and autoOrients tags in the application descriptor file, and make sure it looks like the following:

1
2
3
4
5
<initialWindow>
    ...
    <aspectRatio>landscape</aspectRatio>
    <autoOrients>true</autoOrients>
</initialWindow>

Then, in the application code, check if the stage is set to auto orient, and if so, listen to the ORIENTATION_CHANGING event:

1
2
if( stage.autoOrients )
    stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGING, autoOrient );

In the eventlistener, check what the futute orientation will be, it is stored in the event parameter as it’s afterOrientation property. If that orientation is NOT what you would like it to be, call the event’s preventDefault() method. The stage will not orient itself.

Below you see the two orientations defining the portrait orientation, StageOrientation.DEFAULT and StageOrientation.UPSIDE_DOWN. The other two, StageOrientation.ROTATED_RIGHT and StageOrientation.ROTATED_LEFT represent the landscape orientation. Since the latter are what I want, the first are prevented.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
 * Rotate only to landscape orientations
 * @param event
 *
 */
   
protected function autoOrient(event:StageOrientationEvent):void
{
    switch( event.afterOrientation )
    {
        case StageOrientation.DEFAULT:
        case StageOrientation.UPSIDE_DOWN:                 
            event.preventDefault();
            break;
    }
}

You can find more options at: Adobe’s website

(It turned out to be much easier than reading out the accelerometer and rotating the stage yourself…)

Folowing code is a more complete example in case you want to test some code. It is the main (and only) class from a Flash Builder project (uses AIR 3 and Keith Peters (AKA Bit-101) his minimalcomps):

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package
{
    import com.bit101.components.CheckBox;
    import com.bit101.components.TextArea;
   
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageOrientation;
    import flash.display.StageScaleMode;
    import flash.events.MouseEvent;
    import flash.events.StageOrientationEvent;
   
    [SWF( width="1024", height="768" )]
    public class RotationResearch extends Sprite
    {

        private var noRotationCheckBox:CheckBox;
        private var noPortraitCheckBox:CheckBox;
        private var noLandscapeCheckBox:CheckBox;

        private var noRotation:Boolean;
        private var noPortrait:Boolean;
        private var noLandscape:Boolean;

        private var textArea:TextArea;
       
        private var scaleModifier:int = 3;
       
        public function RotationResearch()
        {
            super();
           
            // support autoOrients
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
       
            if( stage.autoOrients )
                stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGING, handleOrientation );
           
            stage.addEventListener( StageOrientationEvent.ORIENTATION_CHANGE, onOrientation );
           
            buildUI();
        }
       
        /**
         * Create User interface
         *
         */
   
        private function buildUI():void
        {
            noRotationCheckBox = new CheckBox( this, 40, 40, "Stop all rotation", allRotationCheckboxHandler );
            noRotationCheckBox.scaleX = noRotationCheckBox.scaleY = scaleModifier;
           
            noPortraitCheckBox = new CheckBox( this, 40, this.height + 40, "Stop portrait orientation", portraitRotationCheckboxHandler );
            noPortraitCheckBox.scaleX = noPortraitCheckBox.scaleY = scaleModifier;
           
            noLandscapeCheckBox = new CheckBox( this, 40, this.height + 40, "Stop landscape orientation", landscapeRotationCheckboxHandler );
            noLandscapeCheckBox.scaleX = noLandscapeCheckBox.scaleY = scaleModifier;
           
            textArea = new TextArea( this, 40, this.height + 40 );
            textArea.scaleX = textArea.scaleY = scaleModifier;
        }
       
        /*
         * Checkbox eventhandlers
         *
         */

        private function allRotationCheckboxHandler( event:MouseEvent ):void
        {  
            noRotation = noRotationCheckBox.selected;
        }
        private function portraitRotationCheckboxHandler( event:MouseEvent ):void
        {
            noPortrait = noPortraitCheckBox.selected;
        }
        private function landscapeRotationCheckboxHandler( event:MouseEvent ):void
        {
            noLandscape = noLandscapeCheckBox.selected;
        }
       
        /**
         * Output of last rotation after the fact
         *  
         * @param event
         *
         */
   
        protected function onOrientation( event:StageOrientationEvent ):void
        {
            textArea.text = "orientation was: " + event.beforeOrientation + "\norientation is: " + event.afterOrientation
        }
       
        /**
         * Triggered before rotaion takes place.
         *
         * Checks which orientations are allowed based on the checkboxes
         *
         * @param event
         *
         */
   
        protected function handleOrientation(event:StageOrientationEvent):void
        {
            if( noRotation )
            {
                event.preventDefault();
                return;
            }
           
            switch( event.afterOrientation )
            {
                case StageOrientation.DEFAULT:
                    if( noPortrait )
                        event.preventDefault();
                    break;
                case StageOrientation.UPSIDE_DOWN:
                    if( noPortrait )
                        event.preventDefault();
                    break;
               
                case StageOrientation.ROTATED_LEFT:
                    if( noLandscape )
                        event.preventDefault();
                    break;
                case StageOrientation.ROTATED_RIGHT:
                    if( noLandscape )
                        event.preventDefault();
                    break;
            }
        }
    }
}