Gaming Your Way

May contain nuts.

BitmapData.copyChannel(), you're a sexy minx aren't you

There's a very minor update of X on the X Dev page.

Aside from adding some credits ( I have no sense of priority do I ? Credits done before the game, what the hell is wrong with me ) and finally getting the in-game skybox pretty much how I want it ( Although using a placeholder, which I know I'll come to love and hate having to remove come the time ) quite a bit of time ( Read: Far too much ) was spent on the transition.

Keeping with the TV screen theme, which I think I may have done to death now, I wanted the transition to be a nice distortion / break up effect ( I've been heavily inspired by this After Effects plug-in ).
Part of that, aside from the more obvious static and ghosting / blurring, was splitting up the red / green / blue channels so I could offset them.

With that in mind, copyChannel() got some F1 treatment to see how it works. It's all pretty straight forward, to the point that I'm not going to repeat the syntax here.

What isn't straight forward, is how to overlay the images again to get the original image back. Perhaps it's just me, but I couldn't find one example of how to do that ( Well, I found something using papervision which overlaid planes for a similar sort of effect ).
3 bitmaps, 1 red channel, 1 green and 1 blue. I want to shove those all into a sprite on top of each other to get the same image that I started with. To be honest, I can't think of another reason to use copyChannel() off the top of my head, so I thought I'd be tripping over examples.

But no, one PV3D example like I said, and nothing more.

Cosmic.

The solution ? BlendMode.DIFFERENCE. By applying that to each of the 3 bitmaps it works a treat. Hopefully this will help someone out one day when faced with the same problem.
It amazes me at times how some things are still so tricky to find out about in actionscript.

Squize.

Xtreme Coding [ Hardly ]

I'm starting a little experiment today. It could either prove to be something quite cool, or I'll really fall flat on my face with it. Lucky that I don't mind either way really.

Rather than doing a diary style collection of posts about a specific game's development, I'm going to post daily builds. Every day I work on it, even if it's just to tweak a sprites position quickly 'cause it's bugging me, I'll upload that new build.

Now this doesn't mean I'm going to be working on it every day. There aren't going to be a nice collection of sequential posts here until it's done. This is a personal project + Christmas is coming up, and life just isn't so smooth as to allow that.
If I get an urgent job come in then this is on the back burner straight away.

Also if you stick with this ( Never mind me sticking with it ) you're going to see versions which crash, versions which are buggy, versions with no preloader so you're looking at a blank screen for a while. It's a true game in development. I'm not going to fluff it up for you guys, or put some spin on it and work 8 days on it and then pretend that's just 1 day. It's going to be the same as that game you've got in development on your hd, with all the traces that say "Sprite collision failed, wtf?" and all the nasty things that you'd have to hide from the clients build.

That's the caveat out of the way. What are the good parts to this project after all the negative ? I guess that's down to you guys. If you find it interesting then the blog is doing it's job.

X. That's the game. It's an old asteroids clone that I did years ago ( It was my 2nd ever complete game, 2003 some time ? It was part of the "Majestic Trilogy" of games. I'll dig out a link for a future post ).
I've already done a reskin of it, X+, but for some reason that has never seen the light of day. I was looking at it recently and realised it's just a bit too dated now to use, it's as1 so publishing it for F8 so I can use the blendModes in there is really a lot of trouble, so it's either release something that's not as good as it should be, or re-writing it in as3. X++ it is then.

I'm weird when it comes to coding. I know a lot of developers just like to get in there and get the engine working, and then work back from that. I'm very linear, like a bad fps. I need to start from the beginning, the title screen. It's important to get that look & feel in place to set the tone for the rest of the game.
So that's what we've got, a title screen. There are buttons that rollOver, but don't lead anywhere. The background image is a place holder as we're going to have a flv running there instead ( I did have a flv to test in place, borrowed from here ( Click the video button ) but it bumped the file to 9meg, so it's been reduced to a static image until we get the final render done ).

Enough words, here's the front-page for the xtreme coding experiment

More soon, although I'm going to try avoid saying what's coming, 'cause it usually falls through and I go off and do something else.

Squize.

GameBall Maize Maze is finally live

Our first project with Brandissimo is finally live, and sitting on the NFLRush site.

Just to caveat the excitement a little, the NFL site requires a sign up, and I'm sure it may be a subscription service ( Read: You've got to pay ) [ EDIT: Nope, its free, just needs a sign up. Sorry about that, and thanks to Andy for pointing that out ]

To compensate for this, I'm just going to post some screen shots, a couple from the intro movie, and one in-game one. Then in conjunction with the development posts ( For some joyous reason I can't look back at old posts and be logged in at the same time, which means I can't just simply give all the dev. posts a GMM category and then just refer you to the tag cloud. Cosmic. So instead, the development ran from the start of Sept '08, to the 1st Oct. Cutting edge blog technology in all it's glory ) you can use your imagination to play the game.
That's got to be better than actually playing it hasn't it ? I mean you can imagine any old mental things. For example, I'm imagining that I had the time to scroll the screen rather than just making it flick...

gmm_grab1.jpg

gmm_grab2.jpg

And a little something in-game...

gmm_inGameGrab.jpg


A really enjoyable project, some great assets to work with ( I'd never have opted for that art style in a million years ), some great people to work with at Brandissimo and quite a nice little game at the end of it. All good.

Squize.

States machines in actionscript, nice and easy

December already, it really does fly.

I was chatting with our mate Jeff @ 8bitRocket the other week about function pointers / state machines and I thought it may be useful to quickly write something up about it here, as so much of my code relies on them and they do make life easier.

private var mainFunc:Function;

That's pretty much it.

I'm guessing all your routines have some sort of mainloop. Either you're old school and that's running on an enterFrame on each mc you're moving about or it's a public method in an object which you loop through and call every frame.

Let's take a space invaders mainloop as an example ( Psuedo-code ahead )

function mainloop():void{
  if(thisInvaderIsDeadFlag==true){
    return;
  }
  if(areWeDyingFlag==true){
    if(sprite.currentframe==endOfExplosionsFrame){
      thisInvaderIsDeadFlag=true;
    }
    return;
  }

  moveInvader();
  testForShootingAtPlayer();
  testForBeingHitByPlayersBullet();
}


That should hopefully be straight forward enough. In real life we wouldn't want to be testing for thisInvaderIsDeadFlag every time, we'd just remove this invader from our array of active ones, but this is just an example.

Now check this out,

mainFunc=mainloop_normal;

function mainloop():void{
    mainFunc();
}

function mainloop_normal():void{
    moveInvader();
    testForShootingAtPlayer();
    testForBeingHitByPlayersBullet();
}

Here we've set up our function pointer to point to mainloop_normal, and then we just call that one method in our mainloop() method. Cool so far ?

Now we're not checking to see if the invader is dead, or if it's exploding. That's good, because by default the vast majority of the time neither of those are going to be true, so it's a waste to check ( It's like waking up every morning and seeing if it's your birthday ).

At the moment it's more of a function pointer than a state machine as such, so next up is why doing it this way is so sexy...

function testForBeingHitByPlayersBullet():void{
    if(playerBullet.hitTest(thisInvaderSprite)){
       thisInvaderSprite.gotoAndPlay("firstExplodingFrame");
       mainFunc=mainloop_waitingToDie;
    }
}

Here's our testForBeingHitByPlayerBullet method from the main loop. Imagine that's just doing a hitTest, the invader to the player bullet. Bang, it's a collision, but instead of having to set our areWeDyingFlag from the original example, we just change the state machine.

function mainloop_waitingToDie():void{
  if(sprite.currentframe==endOfExplosionsFrame){
//Kill this invader totally, ie remove the mc
      mainFunc=null;
  }
}

In effect, no extra checks are needed every frame, we're only running what we need. We've got the advantage of a slight performance boost, but far more useful than that is the flexibility this gives us.

Say for example you want your invader to teleport in now, at the start instead of:

mainFunc=mainloop_normal;

we can now alter it to,

mainFunc=mainloop_waitingForInvaderToTeleportIn;

And run the code there waiting for your cool teleport effect to finish, and then just alter the mainFunc to carry on with our flow.

Running your code this way means you can chop and change states without having to have lots of extra conditionals in your code ( If the player is teleporting in, but that teleport tween isn't at frame 10 yet, then don't test for collisions with the player bullet etc. etc. ).

Any questions just hit that comment button,

Squize.

The sound of silience ...

Back again!

After a good deal of time I finally have something to post about - or let's face it moan about.

As the headling slightly might suggest I'm dealing with sound today.
I think that sound handling in AS3 is a nightmare compared to the ease of it in AS1/2 and I'm not the only one asking WTF?

So in order to play your sound you have to instanciate it, if it's exported CS3 kindly creates a class for you so you can easily use it ... (loading it from an external source is another story)

This is what the CS3 help gives us for embeded sounds ("working with embeded sounds"):

var drum:DrumSound = new DrumSound();
var channel:SoundChannel = drum.play();

My first question was: what do I need the SoundChannel for if I just want to play the sound?

Well, the rocket scientists at Adobe thought that it would be a good idea to add a play() command to the Sound, but not a stop(), so in order to stop our sound playing we *need* the SoundChannel - so we better store it for later use.

Anyway, to make my life easier I converted my SoundUtil class from AS2, basically it deals with the sounds so I don't have to think about it, it has a few usefull commands like playSFX (plays a sound effect, once), playMusic (which allows fading), crossfade ...
I usually used attached sounds (or from an external swf, but the SoundUtil dealt with it ...)
So in order to play music for the menu I'd just do:

SoundUtil.getInstance().playMusic("musicName", 2); // 2 would do a 2 sec. fade in

The AS3 version should work the same, although it uses static functions which then call the singleton's method.

Oh wait. We need to have a class to start the embeded sound ...

To get over that I wrote the add method, which basically takes the name of the sound (or the classname) and then does it's magic.

        public function add (strSound:String, bIsMusic:Boolean):void {
            
            var refClass:Class = getDefinitionByName(strSound) as Class;
            var sndTmp:Sound = new refClass();
                        
            var iTmp:int = this._aSound.length;
            
            this._aSound.push(sndTmp);
            this._objSound[strSound] = { id:iTmp, bIsMusic: bIsMusic };
            
            if (bIsMusic) {
                this._objSound[strSound].spDummy = new Sprite();
            }
            
        }

Ha! that was easy ...

As you see the sounds name gets stored in an object (I just use it as dictionairy), I store an Object with some more values along with the name. And you surely might ask WHY on earth I did create a Sprite for music files ...
Well I'm a lamer, I use the Sprite to attach an onEnterFrameTo it for things like fading :)

Fast forward ...

k. Let's say we play some music, and only wont it to play 2 times, after that the sound should be removed from memory. Luckily we have the onSoundComplete Event, it should return (CS3 help): "The Sound object on which a sound has finished playing."

For me it reads like it returns the Sound that is playing. FAIL!

It does however return a SoundChannel, which of course HAS no information (prove me wrong) about the Sound it belongs to ...
So how can I unload/cleanup a Sound when an onSoundComplete occurs, if I don't know which Sound is playing (and don't want to write a seperate Listner for each sound)?

Oh lucky me...

Thank fuck I store a lot of things in my information object (not only what is shown in the add method), for instance I store the SoundChannel I got from Sound's play() command and I store if a Sound is playing ...

After a few hours of using our favorite search engine I came up with something so stupid it might even be brilliant ...

private function onSoundComplete (e:Event):void {
            
      var strKey:String;
            
      for (strKey in this._objSound) {
           if (this._objSound[strKey].bIsMusic) {
               if (this._objSound[strKey].chChannel == e.target) {
                   this._objSound[strKey].chChannel.removeEventListener(Event.SOUND_COMPLETE, this.onSoundComplete);
                   this._objSound[strKey].bIsPlaying = false;
                   // do some cleanup
               }
           }
       }
            
}

Basically I loop over all music "files" that are playing and *compare* their SoundChannel with the one returned by the Event.
That's so insanely stupid! But it works. Sweet.

Maybe it helps some of you ...

nGFX

Another 48 hours

Every now and again there's a 48hr game comp on FlashKit games. I've not entered since the 2nd one ( Which I was really pleased to have won, so I wanted to keep my 100% record ) so I felt it was time again, to see if I can still turn it on.

It works by everyone offering up a couple of words and then at kick off two are chosen at random and that's the games theme. This time it was "human brain" and "micro-organisms".

The theme was announced at 1am ( Saturday ) and the obvious thing for me was a shoot'em up over the brain, zapping the invading baddies, so I went to bed. It's what us coders do best.
Saturday afternoon I was mulling it over, an arena shooter would be cool but I'm meant to be finishing Orbs off as it is without trying to do another, plus I knew realistically that I'd have about 16 hours to do this. Ok, a Galaga style shooter. But that means lots of attack waves, plus a scrolling background ( Without the scrolling background it would feel really really old school ). Scratch that then.

I've never written a mouse avoider as I've always found them trite and throwaway. Perfect!

Saturday I didn't get much done, the England match got in the way, mainly the front-end and the overall structure was nailed. The power-crystals ( Or "geoms" as they're actually called in the code 'cause I just couldn't think of a better term ) were in and running which was good 'cause I knew a lot of those routines would be used by the baddies.

Sunday, erm, well I finished it off. I managed to be the first person to post up a final game, as I was sick to death of working to be honest ( It only took around 12 hours in total, but by the end I was glad to see the back of it ).
The sounds were the last thing to be added, I found an old tune from a game I'm not going to finish so re-cycled that and the sfx are also from various old games. I'm not a 100% happy with them, and I wanted to add another baddie type that would explode when killed which would have caused a cool chain reaction with combo's etc. but I felt it was better to have a complete ok-ish game done on time rather than try for more but post a game with a lot of loose ends in there.
For me the comp is as much about finishing by the deadline as the game itself.

If you'd like to see the fruits of my labours, click me

Also I've posted the source, in two flavours:
Just the code ( 16k )
Code with fla's ( 2.5 meg )

It was written in Flex and I very much doubt it'll run out of the box straight away, but it includes the preloader code which may be handy.

Also all the comp entries are here. I can really recommend giving them all a play as there's some great work there in such a short space of time.

Squize.

74 hours, 33 minutes and 40 seconds

I'm currently touching wood ( tehehe ) that GMM is gold.

Guess how long it's taken ?

This is going to be a two pronged post, I'm going to both wow you with visuals and bore you with stats. Stats first I guess, here's the breakdown of how long the game took blow by blow

Attract Mode: 1hr 9mins
Bots: 13hr 33mins ( I had such a mare with these )
Class Structure: 10mins
Corn Power-Up: 5hr 20mins ( This was re-used for the other power-ups, hence it taking so long )
Display Map: 32mins
Dummy Trap: 2hr 34mins
Game Complete: 58mins
Game Over: 24mins
Golden Ball Power-Up: 49mins
Health Power-Up: 1hr 37mins
Hidden Baddie: 2hr 47mins
HUD: 1hr 38mins
Instructions: 2hr 33mins
Level Complete: 40mins
Level Design: 7hr 38mins
Level Plotter: 7hr 39mins ( What are the odds ? )
Level Structure: 1hr 22min
MiniMap Layout: 1hr 31mins
Mud Power-Up: 1hr 8mins
Pause Mode: 30mins
Player: 7hr 37mins
Points anim: 24mins
Preloader: 34mins
Score: 7mins
Sounds: 3hr 22mins
Tiles: 2h 54mins
Transition: 25mins
TrapDoors: 3hr
WaterTraps: 1hr 23mins

Now this may seem incredibly anal, perhaps to some degree it is, but when working for yourself it's important to keep track of where your time is going. It helps budget for the next game, as you'll see a pattern ( So for example a preloader won't take long, but you know the player and baddie routines will ). A lot of common sense I know, but seeing how long things actually take can be a useful eye opener.

Want to see the map for level 1 ? Go on then seeing how I promised

gmmMap.png

So from here the clients need to give it the once over, make sure I've fixed what I was meant to, tweaked where things should have been tweaked and sign this bad boy off.

K, time to work on the arkanoid game again...

Squize.

...Thursday i don't care about you...

I worked 'til gone 3am last night, and I'm beyond tired, so rather than a blog entry covering how I knocked a lot of things off the to do list for GMM and designed level 2, here's a link to a viral clip that Chris at errorWare sent me today that made me laugh.

This, in it's own bizarre way is totally safe for work.

A less tired and lazy post tomorrow, if for no other reason than I've got to use the last lyric as a title.

Squize.

...Tuesday's grey and Wednesday too...

Well my days being split in two carries on.

During the day I'm working on the Arkanoid game for gimme5, evenings it's back to GMM. I can only say thank God both of these are coming to a close at roughly the same time 'cause it's so nasty working on two projects at once ( I equate it to writing two different novels at once ), not just in terms of swapping and changing ( as2 to as3 to as2 ) but the sheer number of hours a day I'm working on them.

Most of yesterday was spent on the g5 game. Myself and Ronnie the tech. lead at g5 spent hours nailing down the server side intergration for the level saving / swapping. That's nearly done, and I'm really hoping with one final push tomorrow it'll be done for good.

Between that I was adding all the speech to the game, and it works really well in place. Today was more of the same and clearing off some of the really obscure bugs. The To Do list for that is finally going down.

Last night on GMM was spent adding sounds too. Thankfully the client sent me a zip with pretty much all of them in there, and they're all pretty spot on, which is great.
It was also nice using my as2 SoundHandler class again, the one in as3 is very make shift at best, the as2 has been built up over the years and is so easy to use and does everything I want ( For example, sound.setPanDistance() calculates the mc's position in relation to the center of the screen and sets the pan accordingly ).

Pretty much a whole day doing sounds for both games then. This morning ( Before starting back on Arkanoid ) I managed to finish off the instructions for GMM. Not hard work, but lots of fiddly aligning and just boring really.

I think tonight I'm going to try and knock up a couple more levels for GMM. Only level 1 is done so far, so getting a couple more done will be good, and it's a break from actual coding. I'll be able to test it a lot whilst making sure the level plays well so the to do list will grow ( It's always the way, when a project is coming to the end you find you'll delete one thing off your list but find at least another 2 to add to it ).

I'm just going to be a bit self indulgent, not for the first time I know. I hope I'm not the only person who's wanky enough to google themselves. Well I googled "Gaming your way" and was wrapped to see we've "made" it on google.

gywGoogle.png

Check us out all indexed. Ok it's only the blog, the site itself seems to be as popular as the plague, but it's just a place for us to whore ourselves in a grown up way ( "In terms of traffic it has more than met their expectations" all nice and nu-media friendly )

After that, I thought sod it, let's see what "Squize" brings up. I came second, the top entry being

"I masturbate weirdly. I squize my hips with my hand in the middle. Even with my panties on... Weird?
Anyone else does that? I'm 13..."

I ( For once ) just couldn't make it up. That's my sails deflated, 2nd to a 13 year not knowing how to frig.

I guess there will be more of the same crap, just worded differently, tomorrow.

Squize.

I don't care if Mondays blue...

Back to Flash after Fridays rant.

Today was a bit of this and a bit of that.

I'm having to finish of an arkanoid clone for gimme5, a hang over from when I worked there. Improved the collisions ( Again ) and finally finished the baddies off.
Still a lot of things to do, it's becoming a long drawn out project that I can't wait to see the back of to be honest.

Back to the lot more fun GMM. I started the player shooting routines Friday and they're nearly finished after starting it up again today. Doing a game in ISO just adds that layer of complication to it, but I've got projectiles flying around quite nicely now, and in the past 30mins got it so the baddie bots know they've been hit and power-down for a couple of seconds allowing you to run past.

Right now my to do list stands at:

* Instructions
* Golden Ball - shoot / test for hitting bot
* Mud - shoot / test for hitting bot
* Bots
* Sounds
* Score
* Design levels
* Test right hand exit
* Remove traps from fore/background mcs

The Bots are nearly done, I'm just removing the final kinks with animation frames going a bit mental and stopping them just sitting on your head when they've hit you until they drain all your energy.
The two remaining power-ups ( Golden Ball / Mud ) shouldn't be too much work now the first power-up is in there and working ( It's really just the end result when a bot is hit by one which differs ).
Everything else is just bits and bobs, with the sound looking like it'll take the most time out of all that.

So it's slipped, but it's still on-track (  ie there's nothing left that fills me with fear ). In terms of actual time spent on it, 50 hours 48mins, which shows that I must spend an awful lot of the day just day dreaming instead of coding. It's something I really need to tighten up, if I was doing proper 7 hour days then we'd be looking at just starting day 6 now ( In my defence a decent chunk of the day seems to be taken up with admin stuff ).

Anyway until tomorrow that's it from me.

Squize.

PS. Just as a sidenote, we've got a great guest article coming up this week, which we're really proud to be presenting here.