Gaming Your Way

May contain nuts.

Did I say "just"?

Alpha is out, now there are just a few things left to do to improve the useability of the editor and wait for the final informations on how the main game should handle custom levels.

Oh and there are just a few levels to enter ... 130 to be honest.

On Friday I had the "more-than-bloody-stupid" idea to enter a few of them. I did 2.

The one that killed 100% of my motivation was a nightmare of force fields all pointing in different directions:
cc_lvl_22.jpg

Believe me when I say looking at this level in full size can make you want to puke.

After some agonizing hours, I finally started to write a file converter that should be able to read in the binary file format of the original game. OH JOY!

This somehow kills the edia of entering the levels and testing them along the way to see if the engine can handle all the weirdness of the original creators (and I still do believe that some of the levels where purely designed to piss the player off as much as possible).

oh well ...

nGFX

Particle Porn

Well here it is, the "Too early to show mix" of Orbs.

No preloader, so stick with it ( About 700k )

I figure this post is more a show and tell as opposed to anything more. There are lots of bugs so I'm not really after reports ( Thanks ), this is very WIP, and I've only really posted it here due to reasons outlined in the post from the other day.

The gameplay will be more refined in the final version, "Campaign" mode will be the primary game type ahead of arcade ( There's not even an option for it yet ), and there are quite a few more baddie types and a lot of love to go into it yet.

A quick spurt of instructions:
Your objective is to protect the Orb. As long as it's got power it can re-generate your ship. WASD or Arrow keys move you around, aim and shoot with the mouse, P to pause.
Some of the options work ( Stats for example, although there are some unfinished ones in there, and a lot more to go in, along with a lot more medals ), but most don't.

It's mainly a case of looking around and watching the particles right now, but they are quite pretty so far.

As I do more work on it I'll flesh the posts out about the tech. side of it as I've gone to quite a bit of effort to get this bad boy running as fast as possible ( Which is sheer bliss. In real life you never have the time to even write the word optimise never mind doing it ) and hopefully development will go onlong in fits and starts like it has since the project started 'til one day it can go free into the world able to stand on it's own two feet.

Enjoy.

Squize.

Well that's forced my hand

Great day, Geometry Wars2 is out today ( And I've nearly nailed the collision routines in the arkanoid "style" game I'm doing at g5games, but I digress ). Regular readers will know I've been working on Orbs forever now, which is inspired by the GWars look and feel, so I've been keen to check the sequel out ( For the whole week or so since I heard it was coming )

800 points later, and wow. It's sex.

When you shoot a baddie, it drops a geom ( Correct me in the comments if I've given that the wrong name ). When you get close to them, they get sucked towards your ship.

Hmmm, just like the credits I coded the other day in Orbs.

Also there are new things, called "gates" ( Corrections always welcome :) ), where you can shoot them and your bullets rebound to kill baddies. It even keeps track of how many rebound kills you've got.

Hmmm, just like when you shoot the orb and it rebounds and kills a baddie.

Arse. For fear of Orbs coming out and everyone just pointing the finger of copy catness, it's forced my hand ( Yeah the title makes sense now, these posts aren't just thrown together you know ) to release a demo sooner than I'd rather.
Hopefully by Saturday we can have some particle porn up here. I'm just thankful that Bizarre haven't got Pong in the pause mode.

Squize.

Quick AS3 bug / fix - invalid data

I've been pulling my hair out for about an hour with this beauty, and after finding the solution I thought I should share here, if for no other reason that I know I'll get it again and lose another hour ( I'm 36, my memory is shot ).

When trying to make a new bitmap instance of a bitmap in the library, along the lines of:

        [Embed("/_assets/assets.swf",symbol="bouncerBitmap")]
        private var bouncerBitmap:Class;

        var bm:Bitmap=new bouncerBitmap();

I was getting invalid data when running the swf, basically it was failing big time.

Had a bit of a google and found this. For some beautiful unknown reason, sometimes when you import a png to the library and set the compression to jpg ( Although in this case I actually hadn't, Flash just took it upon itself to make it a jpg for me ) it screws up.

Joy.

Anyway all fixed now, and I've even got this as a reminder for next time.

Squize.

SICO

As regular readers will know, we've been done over with a hacked version of "Law of the West". Instead of just bitching about it, we've decided to be pro-active.

This is going to take a number of forms, one of which is SICO, or "Source In, Crap Out".
We looked at what encryption and obfuscator software there is out at there, and came across irrFuscator. It looks pretty cool, and at 69 euros isn't going to to break the bank, but it also looked like it was something we could do ourselves without too much effort.
Where SICO fails compared to irrFuscator is that from what I can tell it takes the whole project and messes it up, so public functions ( And therefore getters / setters ) get screwed with too, whereas our project just takes one file and so has to leave anything which could be called from a different class alone.
Also it converts strings, but it looks costly. Looking at the example on their page, "end" gets converted to irrcrpt(23, "uzd."). That kinda looks like a static class is added to the project with a method called irrcrpt, which takes the first value as the "key", and I guess it's just a simple XOR with the string value.
Fine for scrambling a filename, but I think it would be too harsh [ In performance terms ] to do that to every string in the game, so it's easy enough to just add a method in like that by hand for your filenames / passwords / cheat codes etc.

( In case this reads like I'm just bashing irrFuscator, I'm really not. It's better than SICO, I'm just pointing out the differences ).

So what can our baby do ? Here's the loader class we use for it:

package Classes {  
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    
    public class IO {

//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var loader:URLLoader;
        private var callBack:Function;
        
//---------------------------------------------------------------------------------------
//Constructor
//---------------------------------------------------------------------------------------
        public function IO(){
/*
Null constructor, we don't need to do anything here
*/

        }

//---------------------------------------------------------------------------------------
// Public
//---------------------------------------------------------------------------------------
        public function toString():String {
            return "IO";
        }        

//---------------------------------------------------------------------------------------
        public function loadScript(filename:String,callBackArg:Function):void{
            callBack=callBackArg;
            
            loader = new URLLoader();
            loader.dataFormat=URLLoaderDataFormat.TEXT;
            loader.addEventListener(Event.COMPLETE, xmlLoaded);

            var request:URLRequest = new URLRequest(filename);
            loader.load(request);
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function xmlLoaded(eventArg:Event):void{
            var source:String=eventArg.target.data;
            callBack(source);
        }

//---------------------------------------------------------------------------------------
    }
}

And here's what it looks like after being run through SICO:

package Classes {  
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    
    public class IO {

        private var _V64K0q:URLLoader;
        private var _87qjufb1lsM:Function;
        
        public function IO(){
        }

        public function toString():String {
            return "IO";
        }        

        public function loadScript(M85u8En4i:String,_87qjufb1lsMArg:Function):void{
            _87qjufb1lsM=_87qjufb1lsMArg;
            
            _V64K0q = new URLLoader();
            _V64K0q.dataFormat=URLLoaderDataFormat.TEXT;
            _V64K0q.addEventListener(Event.COMPLETE, _v1zr6rD62q);

            var kDu541CN2C5:URLRequest = new URLRequest(M85u8En4i);
            _V64K0q.load(kDu541CN2C5);
        }

        private function _v1zr6rD62q(_wVl6q:Event):void{
            var n1XScOB03y:String=_wVl6q.target.data;
            _87qjufb1lsM(n1XScOB03y);
        }
    }
}

Pretty mashed up. There are still some quirks to it which need ironing out, and it's not got a list of reserved words or anything that cool, but that code is nasty once run through it.

Next we need to actually make some sort of front-end for it, ideally using Air to get to play with that, more possibly with Zinc to make it easier, and then decide what to do with it. It won't ever be for sale, it may be a case of we just give it to friends and let it spread gradually like that, we're not sure yet, but it will be given away. There's no point bitching about hacking, and then coming up with something that makes our stuff safe and screw everyone else.

And that's part 1 ( Or 0.5 ) of our push to try and get the community as a whole being a bit more protected, there is more to come. Olli and I have had some long chats the past couple of days. We both came to the conclusion that yeah, having hacked games floating around sucks, but there are some things which are more acceptable than others.
If LoW had been hacked to use the hi-score component of the system it's been hacked for ( Some "shovelware portal in a box" system ) and everything else had been left intact, then we can swallow that. Just. The game gets spread so the sponsors happy, we get our credit out so it's not too bad for us, the ad gets seen etc. It's not that bad. It's only when the game is just ripped of everything like that we get pissy.

Part of this process of stopping it is to actually get involved with the boards that link these games, for fear of sounding like a politician, it's about education. A lot of sites with hacked games on are run by decent people, just trying to make a couple of quid, and not really knowing about any harm they could be causing 'cause they never ever have any contact with a developer.
Flash games are percieved as such a throw away commidity that the line between IP theft and hosting becomes very blurred. A lot of people who run boards wouldn't dream of hosting mp3's, but see Flash in a totally different light.

We really fucking resent having to spend time on things like this, but if we're in the position of toying with ads and sponsorship as well as the client based work, then we need to protect our IP. Like we all do.

There's more coming,

Squize.

Game AI for dummies - or making the enemy see.

Sorry folks yet again no image ... but some code :)

The current game (let's call it CC for the sake of it) is getting close to the point where I would declare the main game engine done, most of the events are processed now and the final enemies are going to be done today (hurray!).

As the title suggests (wow it's something post related) I want to write about the dumb ass AI one, nope rather 4 of the enemies in CC use, if you were so bold to call it AI.

While reading up the docs about the original game I read this:

"goes around objects to the left"

And there are 3 more which go around things to the right.

HA!

I first simply ignored the fact of "going around" and just coded a simple "if enemie hits wall turn left".

cc_ai_00.gif
(ok, I lied, there are some images)


So after noticing my mistake I removed the old code and started to write the one that should allow my enemy to move around things. Sounds easy enough.

cc_ai_01.gif
Oh, that's easy.


"Go ahead as long as there is something to the left, if not, turn left ..."

After a while I really lost my temper and just coded something that could deal with right turns as well, by checking 3 tiles + one, as you can see in the next image.

cc_ai_02.gif
Well that is stupid, isn't it?


Jein, it's a dummy approach. (jein is a pseudo German word, combining "ja" and "nein", yes and no).

cc_ai_03.gif
Some of the common situations, the green arrow shows the next direction
and in "D" shows the use of the 4th check.


In order to simplify (though, yet unoptimised) the checking of the tiles I set up an array of points, holding the offset for each of the checks. To make my life even easier I just numbered the directions (which is used all over the game):
0 = north, 1 = east ...

So the array for 0 (north) looks like this:

this._aTest.push( [new Point(0, -1), new Point( -1, -1), new Point( -1, 0), new Point(1, 0)] );

And because this one should move to the left I added a second array that holds the next direction to go to:

this._aDirNext = [3, 0, 1, 2,  1, 2, 3, 0];

(You might wonder why it has eight entries instead of the needed four, I'll come to that later)
I now could just lookup the next direction I need to face by simply checking with the current direction:

this._iDir = this._aDirNext[this._iDir];

Now, with that in place checking the movement was easy:

private function checkMoveBug ():void {
            
    var strTest:String = "";
    var i:uint;
    var xx:int;
    var yy:int;
    
    for (i = 0; i < 4; i++) {
        
        xx = this._pPos.x + this._aTest[this._iDir][i].x;
        yy = this._pPos.y + this._aTest[this._iDir][i].y;
        
        if (this._refChipsGame.getTile(this._refChipsGame.aMapGame[xx][yy][0]).objProperties.bMonster && this._refChipsGame.aMapGame[xx][yy][1] == -1) {
            strTest += "0";
        } else {
            strTest += "1";
        }
        
    }
            
    switch (strTest.substr(0, 3)) {
        case "000":
// "C"
        case "100":
        case "110":
            this._iDir = this._aDirNext[this._iDir]; // turn to the next dir
            break;
        case "111":
// "A"
        case "101":
            if (strTest.charAt(3) == "0") {
                this._iDir = this._aDirNext[this._iDir + 4];
// this one uses the second pair for "A"
            } else {
                this._iDir = this.getOppositeDir(this._iDir); // this one is used vor "D"
            }
            break
        /*
        case "011":
        case "001": // "B"
            these are not needed because we can just move ahead
            (there is something to the left)
            break;
        */

    }
    
}

The final version has the 4th check removed from the loop and just checks it for "111" and "101".

And because we use an array to store the test offsets, we can make the enemy around things to the right by just changing the values (north):

this._aTest.push( [new Point(0, -1), new Point( 1, -1), new Point( 1, 0), new Point(-1, 0)] );

and changing the aDirNext array to face right:

this._aDirNext = [1, 2, 3, 0, 3, 0, 1, 2];

Vioal. Done.

I hope this is quite understandable (the code is, my writing might not)

nGFX




as3 preloader in Flex

Preloading with Flex for actionscript projects still seems to be really under-documented. Personally I've found it to be a bit of a joke that you've got to search half a dozen sites to find out how it's done, I mean it's preloading, it's what Flash does.

So I thought I'd add "my" approach here. It's what I'm using and seems to work well, it's been cobbled together by reading through the half a dozen websites, so I'm not claiming it's all my code or my idea, it's other peoples code who are clever than me shoved together.

Let's start at the begining,

package {
    import flash.display.DisplayObject;
    import flash.display.Loader;
    import flash.display.LoaderInfo;
    import flash.display.MovieClip;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.utils.getDefinitionByName;

    [SWF(width="400", height="600", frameRate="40", backgroundColor="#FFFFFF")]

    public class Preloader extends MovieClip{
//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var logoClass:Class;
        private var logoClassInstance:Object;
        
//---------------------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------------------
        public function Preloader() {
            stop();
            stage.showDefaultContextMenu=false;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality=StageQuality.LOW;

            addEventListener(Event.ENTER_FRAME,mainloop);
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function mainloop(e:Event):void{
            if(framesLoaded >= 2){
                nextFrame();
                triggerLogo();
                removeEventListener(Event.ENTER_FRAME,mainloop);
                addEventListener(Event.ENTER_FRAME,mainloop2);
            }            
        }

//---------------------------------------------------------------------------------------
        private function mainloop2(e:Event):void{
            if(framesLoaded == totalFrames){
//It's all loaded, has the logo finished ?
                if(logoClassInstance.animCompletedFlag==true){
                    removeEventListener(Event.ENTER_FRAME,mainloop2);
                    nextFrame();
                    triggerGame();
                }
            }            
        }

//---------------------------------------------------------------------------------------
private function triggerLogo():void{
            logoClass = getDefinitionByName("PreloaderLogo") as Class;
    if(logoClass) {
        logoClassInstance = new logoClass();
        addChild(logoClassInstance as DisplayObject);
    }
}

//---------------------------------------------------------------------------------------
private function triggerGame():void{
            var main:Class = getDefinitionByName("Main") as Class;
    if(main) {
        var app:Object = new main();
        addChild(app as DisplayObject);
             app.waiting();                        //Call the singleton to kick it all off
                logoClassInstance.dispose();
    }
}

//---------------------------------------------------------------------------------------
    }
}

Just to run through this nice and quickly, the preloader extends the MovieClip class as we're using 3 frames for the game ( The actual preloader class, the PreloaderLogo class and the Main one ( Which is the game itself )).
In the constructor we just do all the stage stuff that we want to do ( Hide that menu ), and then run an eventListener ( Mainloop ) which checks to see how much of the overall game has loaded. If frame 2 has loaded it means how logo is loaded, so we can fire that off ( See the trigger logo method, and below is the PreloaderLogo class )

package {  
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class PreloaderLogo extends Sprite {
//---------------------------------------------------------------------------------------
// Assets
//---------------------------------------------------------------------------------------
        [Embed("/_assets/assets.swf",symbol="gywLogoMC")]
        private var gywLogoMC:Class;

//---------------------------------------------------------------------------------------
// Properties
//---------------------------------------------------------------------------------------
        private var gywLogo:MovieClip;
        public var animCompletedFlag:Boolean=false;
        
//---------------------------------------------------------------------------------------
// Constructor
//---------------------------------------------------------------------------------------
        public function PreloaderLogo(){
            gywLogo=new gywLogoMC();
            waiting();
        }

//---------------------------------------------------------------------------------------
        public function waiting():void{
            addEventListener(Event.ADDED_TO_STAGE,logoAddedToStage);
        }

//---------------------------------------------------------------------------------------
        public function dispose():void{
            stage.removeChild(gywLogo);
        }

//---------------------------------------------------------------------------------------
// Private
//---------------------------------------------------------------------------------------
        private function logoAddedToStage(e:Event):void{
            stage.addChild(gywLogo);
            gywLogo.gotoAndPlay(1);
            gywLogo.addEventListener(Event.ENTER_FRAME,waitingToEnd);
        }

//---------------------------------------------------------------------------------------
        private function waitingToEnd(e:Event):void{
            if(gywLogo.currentFrame==gywLogo.totalFrames){
                gywLogo.gotoAndStop(gywLogo.totalFrames);
                gywLogo.removeEventListener(Event.ENTER_FRAME,waitingToEnd);
                animCompletedFlag=true;
            }
        }


//---------------------------------------------------------------------------------------
    }
}

All that's happening there is the class embeds our logo and plays the animation. The waiting() method checks to see if this class has been added to the display list, if we don't wait then you open up a world of pain where the class can't find the stage.
The waitingToEnd method is as simple as it gets, once the animation has finished it just sets the animCompletedFlag to true.

Going back to the preloader class, after the PreloaderLogo class has been triggered we're running mainLoop2. That's just a check to see if the whole game ( ie all 3 frames ) has loaded. If it has when then check for the animCompletedFlag to be true. If it isn't it means the preloader logo is still running, if it is true, then we're done. The game has loaded and our sexy intro anim is done. From there we do exactly what we did before and trigger our Main class ( The game itself ).

The last part of this is the setting in Flex itself. Right click your project and select properties. From there go to the "ActionScript Compiler" options and pass the following arguments to the compiler

flex.png
(click image to enlarge)

And finally after jumping through an insane amount of hoops you should have a working preloader. The logo class can be whatever you want, and there can be more than 3 frames, if for example you want a loader bar to be displayed quickly and then bring in your logos.

*Update - I've posted the source to Operation Cortex, which includes the preloader code which should make life easier*

Squize.

The curse of the generation C64 ...

This is somewhat of a rant post (again), although, it might just become some sort of history lesson... we'll see where it ends.

My current game somehow managed to be a real endurance test (as you might remember, if not, read it here), a lot of things that I had never done before, or at least not very often. The combination of the specific genre and the "new" language ... well it took it's time.
As a minor update on this, the game now seems to become more playable by the minute (oh, and yes, I rewrote the damn movement routine, dropping about 50% of the code needed making more stable and of course working - yet again I wonder why I haven't wrote it that way in the first place ... well never know.)

So while coding I started to look ahead for my next project. One of the things I didn't want this time, was to re-invent the wheel, so I had a lok at the game-engines I had coded so far and I discovered one, that never had been used in a game before, but was 100% working. It lacked of course all the nice and shiny things, it was just a working, ugly game - but something a lot of people seem to like (looking around the casual game scene).

The decission was quite an easy one, ignoring the fact that this is just a "me too" game.

Let the ideas come ...

Think, think, think.

One by one the ideas came in, this usually a blend of things I like or like to use, but hey, we're just at the beginning.

STOP.

This time I want something less bloated, slick, clean, minimalistic UI. Once again, I've spend a good time just hunting for inspiration, playing a few of some of the best minimalistic games I've managed to find so far, Tonypa's. They are slick, clean, easy to pick up and don't contain more than the barest minimum of visuals.

Great. Wait. It would be nice if I would add a hint of a background story ...
Oh, and for that I have a great set of visuals in mind ...
Hey, what if I let the player decide what to do next, even though it's just a puzzle game ...

Darn. That's for "less bloated, slick, clean, minimalistic".

Why do I think that this belongs into a game - trying to find the answer.

First of all, I don't like 99% of the mini games that are available in flash. this includes all the "tunnel games", "click as fast as you can", and even praised games like "filler" (which is a nice variation of the qix heme) leave me cold.
I think, it may be, because I've seen their predecessor in various forms on different systems before.
OK, so for me there needs to be some sort of substance attached to a game.

I grew up with a c64 and I collected games (as nearly everyone of this time did), I think my collection had over 2000 games, most of them well, not quite legally optained. But I also owned some original games and paid real money for them. (30 DM, which was a fucking amount of money for a 12 year old school kid).

Anyway these games pretty much defined what I like about games and what not, I like pretty visuals (ok, compared to today those old games look really shit), I like good sound (and I think it's essential for a game) and I like some sort of depth (just clicking and holding for creating a filled circle is it not), a simple form of variation ...

I even tried to add that to "Law of the West", which is a bit shallow, to be honest, but there is some sort of variation in it.

Most of the full price games had at least one or the other, even the low price games from Mastertronic had a lot more game to it than some of the hyped flash games.

Back to pen and paper ... and forget "quick and easy"

Just before I started to write this (and bore you to death) I grabbed a pencil and some sheets of empty paper and began to sketch things out, draw a few charts about the progression of the game and what kind of things I want to add in order to distinguish my "me too" game from all the successfull ones that are already out.

So far I like what I came up with, as I believe I have added some unique things to the core gameplay. Of course it is way bigger than what I wanted in the first place and for sure just as I write this, someone had the same ideas.
To make it even more ... well, use a word you like ... I decided to go with a Pirate theme (still very popular, and although my first idea was to make a third LotW themed game, but I couldn't fit in the ideas I wanted to add)

The basic tasklist so far looks like this:
  • draw a worldmap based on the Caribbean Sea around 1500
  • create a set of outdoor images for the menus and ingame screens
  • maybe create some 3d characters (so it won't look like Myst, ... yet I still want to do my own Myst-like flash based adventure game)
  • draw a map of the decissions a player could make
  • draw the level maps/playfields for the levels (I mentioned it's some sort of puzzle game?)
  • decide on extras that can be used to help the player
  • create a list of nice "medals" (more about that in later post, but right now, play the LotW Pinball to see some).
  • find a way to allow savegames, either over the server, or using a code or shared objects

I'll let you know where this ends, and maybe (if there is interest) I go into detail and post some of the sketches and early renderings.
It seems like this one became a bit more than a simple re-use of an already existing game engine. It also seems that I decided to go a good deal beyond the usual flashgame timewaster - and it clearly shows that I'm nuts. I don't even know if there is money in this one (either as license or (most likely not) as sponsored game (as I had my share of sponsoring madness so far).

stupid me.

nGFX

Help me with a halfway goofy, funny, catchy headline.

Back.

It's been a while (again) since my last post so this is kind of a catch up of what happend to the game that badly needs to be finished soon.

First let me tell you how much I hate tilebased games.

The current game is my first "real" tilebased game, so this might change after I've finished this one, but for now ... I hate them.

  • Here's a little description of the game.
  • Action and timebased puzzlegame
  • collect keys and items to open doors and avoid obstacles
  • avoid monsters running around
As the game has a built in editor my first (and wrong) idea was to built the map based on the requirements of the editor, which needed to add some additional things:
  • 2 layers, one floor and on "on top" so you could place things below other things
  • connections between certain buttons and their "endpoint"
  • ability to alter the monster order (because monsters can trigger buttons, for instance)
Basically to build the editor was easy (taking into account that it must be easy to use and still allow to edit all aspects of a level), after I did a complete layout in Photoshop I used that as roadmap for coding.

(Did I mention that this is my first AS3 project?), first week

As always the first quite easy project turned into something that's tested my endurance, the switch to AS3 was not as hard as I feared and I found my way around the mass of classes faster than I thought (I think it's because I'm used to .NET which works like this for a lot longer now).

The first few days I spent with converting my toolset to AS3 and setting up (and redefining) my working environment. So it was alot of coding without having something to play with. Then there was a good deal of time "wasted" reading ...

So where is my timeline, week two (or so)

I'm using CS3 and FlashDevelop instead of flex/eclipse, mainly because I can't stand eclipse's behavior and FD looks and feels a lot like Visual Studio, so I feel more at home there.

My first idea was to go with a 1 frame sollution, but this also would mean no pretty preloader, so I got my head around that started with a preloading/main class.
Hunting for a replacement for "this.getBytesLoaded()" I finally came up with this:

        public function Preloader() {
            
            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.showDefaultContextMenu = false;

            [...]

            this.addEventListener(Event.ENTER_FRAME, this.onEnterFrame);
            
            this.loaderInfo.addEventListener(Event.INIT, this.initDisplay);
            this.loaderInfo.addEventListener(Event.COMPLETE, this.initApplication);
            this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, showProgress);

            this.stop();
            
        }
        

        public function showProgress(eProgress:ProgressEvent):void {

            var fPercent:Number = Math.round((eProgress.bytesLoaded / eProgress.bytesTotal )*100 );
            var mcProgressbar:MovieClip = MovieClip(this.getChildByName("mcProgressBar"));
            
            with (mcProgressbar) {
                mcBar_00.width = fPercent * 2;
                
                [...]
                
            }
            
            if (this._iState == STATE_NOP) {
                this._iState = STATE_LOADBG;
            }
            
        }

You may notice my excessive use of "this", I know it's not needed, but I kinda like it, as it helps me to see at a first glance what is coded on class level and what is defined in the current method (and it also triggers autocomplete :) ).

One of the very first problems I encounter was the missing support for Movieclips in AS3, not that it is gone but it's not as straight forwards as it could have been.

"Oh you don't need MCs anymore", week two, Wednesday

Of course I do. Damn.
Sure I could code a complex UI and create and place every button, textbox, bitmap by code, but to be honest: WHY? (when you finally see the UI you understand why, I just say more than 150 elements ...).
Though I learned how to get along with it.

"Yes, that looks good", week three

After the main screen was done, it's time to start with the editor.
The layout was done so I could just dive into coding the UI for it, but yet again the next few days were a pain, because theres was just nothing to see.

The game needed a map structure (internally and for saving and reading xml), so I decided to code a map class that not only was able to hold the level's data, but also a methods for handling serializing xml and the map editing methods.

Also I coded a tile engine, which later was converted into the main game engine class. Why? Well, I decided that I don't want to switch to "real" game mode when testing the currently build map (also game and editor are using different tile sizes). So the tile engine is there (because I need it in the editor) and writting an extra game class would have meant to either create a new instance from withing the game or link it in using a reference.

Now I just switch the state of the tile engine and it runs as game and inside the editor.

To run it as "real" game I now just have to pass over the new tilesheet and the game can be run in a different environment. wow.

Fast forward some weeks now, week ... I stoped counting

A lot of code, more code, even more code without being able to play with the result. To be honest I got utterly pissed and depressed.

While coding this game a lot of different flash projects and some dynamic websites needed to be done too, like this: http://akademie.gira.de/ a database driven web based training site, multi language enabled, but in German only right now, so there was a lot of flash and 3D to do, too.

I now can edit a map, but I still can't play it. Time to wander away from flash and write something to save the map ... and wrote this: FileSave.

It's alive, IT'S ALIVE!, this week

Finally at the game is playble in parts (at least in the editor), "in parts" means: the first level can be played, still there are some features missing that need to be added, but I'll add them when I add the original game's first 150 maps (I mentioned it's an official licensed remake, didn't I?)

To get there I needed to convert the nice thought out editor map format into something that can be used to play the game, yes I could have thought about that earlier but hey, it's my first tile based game (Wintertales and Logimotion seem to be Tilebased, but I used it only for the "background, while all movement is done by math).

Yesterday it finally all fell into place and WORKED, the player is moving, can collect keys, open doors ... and the first level can be solved.

After I moved away from frame based and went over to time based movement (read a great tutorial from Jeff of 8bitrocket here).

Hopefully I'll don't forget to return posting about the progress from now on.

Anyway I planed to post a basic overview of the classes and structure used later. (and to be honest I need get to coding :) )

nGFX


Feedback

Sorry things have been quiet here for a while, I've been busy going to a couple of weddings and making it to 36 without dying ( Quite an achievement considering my lack of doing anything healthy ).

The pinball game still isn't quite gold yet, we're hoping to finally kill it off Thursday. In the mean time whilst it's sitting on FGL we've been included in the new "First Impressions" feature of the site, which I think is a really great idea ( I think it may well still be beta, so I don't want to blab too much about it here as it's not my place to ).

The thing with feedback is culling out the good useful comments from the noise. And by good I don't just mean the "nice work" style comments, but the comments that make you remove the blinkers a little and be objective about the game.

The main concern which has come up is that people really don't like the fact that it scrolls. I find this weird in that I'm used to the 16bit era of pinball games where they all scrolled. It allows for a playfield which is a lot less cluttered and just gives everything a nice sense of scale and scope. I'm just hoping that the slighty broken camera in the version they tested ( Which is fixed now and hopefully always gives you the best view of what's happening and where the ball is going to go ) is the main reason people weren't liking that aspect. If not, then well it's not going to be that popular and that's all there is to it.

grab_lowP.jpg

Yeah, that's a reflection on there.

Another interesting point raised was about the flipper movement, a lot of people felt that there was almost a lag on them, so that was fixed last night to make them more responsive.

Aside from that ( And filtering out the noise like I said earlier, eg "there are not enough features on the pinball board/play area itself (no bumpers/ramps/etc)", aside from those 3 bumpers and 2 ramps you mean ? ) it's just a polarised comments ( "Too complicated", "Not complicated enough", "Instructions too brief", "Instructions too wordy" ) and things we were aware of anyway, such as the animations running too slow ( This was due to developing at 60fps and then having to drop it down to 40fps for the browser version ).

So a bit more love, a couple of bug fixes, a few more assets from Olli, and it's good to go. We just need someone to buy it off us then.

Squize.