Gaming Your Way

May contain nuts.

Flash FullScreenInteractive and Chrome

Look at that for a SEO type subject title, I hate using them and would rather revert to something stupid / flippant, but this is meant to be an actual useful post, so I guess I shouldn't obscure it too much.

We've been having problems with FullScreenInteractive in Chrome since first adding the feature to Outpost 2, it just scaled up wrongly and was basically broken ( You can't even seen the accept / cancel requestor properly ). Damn you PepperPot player and your added weirdness. So here's a couple of gotcha's for you to hopefully save some pain.

Firstly stage.allowsFullScreenInteractive isn't what you'd think. My idea was I'd hit that value up and if it was false then don't bother displaying a full screen button as an option. That would be too simple. Apparently that only returns true if you're already in full screen interactive mode which makes it totally useless as far as I can see ( You could either read stage.displayState or just set a flag in your own code as you kinda know when you've gone full screen ).

Ok, that wasn't really the bug, just a crushing disappointment connected with the whole mechanic. Here's the actual money shot,

"The fullScreenSourceRect property can only be set when Flash Player or AIR is not in full-screen mode. To use this property correctly, set this property first, then set the displayState property to full-screen mode."

source: http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7e31.html

When working in either full screen mode you really need to use the fullScreenSourceRect property to enable hardware acceleration. This is just a rect you set to the size of your normal stage, once done your content flies along ( O2 runs the same full screen as it does normally ).

Turns out this was the problem, when I removed the rect call it scaled up correctly in Chrome, but ran like a dog. Let's try adding the rect setting after going into full screen interactive, yeah we're ignoring Adobe's rules, fuck the man.

Hey presto, it all works. The requestor dialog isn't quite central, but it's the same on Safari and to be honest well down the list of things I care about, as I'm sure that's a Flash quirk that I can do nothing about.

There you go, hope that's some help,

Squize.

Dungeons: Explained better

A bit of a repeat post. Nothing from us for ages, and then when it arrives it's just a rehash. Ages back I did try and explain how we make the dungeons in Knight'sQuest ( FB link ), but using test data images along with poor writing didn't explain it too well I don't think.

Ok, so we have at the basis Olli's dungeon generator code. This creates an array of objects describing a room / corridor. Each room is made up of blocks and blocks are made up of 4x4 tiles. The rooms are made up of a variable number of blocks, so we can have small tight rooms or bigger expansive areas.

When plotting a dungeon ( A generic term, it covers the caves and the new forest ) we look through each room which starts its life as just a collection of 4 digit numbers which are stored in a clock wise fashion ( North, East, South and West ) and each tell us if there's a wall / door / nothing.
For example, if we get the code 0111 that means there are walls to the north, and nothing in any of the other directions ( Little weird 1 meaning an empty space, to be honest I couldn't face refactoring Olli's code ).

Due to the large number of combinations, using a switch / if statement was a non starter, I'd still be typing it now, so we used this cheeky bit of code,

            var directionsAsString:String;             if(location=="caves"){                 directionsAsString="caves_"+northWallValue+eastWallValue+
southWallValue+westWallValue;             } else {                 if(location=="dungeon"){                     directionsAsString="dung_"+northWallValue+eastWallValue+
southWallValue+westWallValue;                 } else {                     if(location=="forest"){                         directionsAsString="forest_"+northWallValue+eastWallValue
+southWallValue+westWallValue;                     }                 }                     }                          try {                 var functionCall:Function=this[directionsAsString];                 functionCall();             }             catch (e:Error){ Debug.trace(directionsAsString,2);                 if(location=="caves"){                     caves_1111();                 } else {                     if(location=="dungeon"){                         dung_1111();                     } else {                         if(location=="forest"){                             forest_1111();                         }                     }                 }             }

Basically we just turn the value into a function call. The try / catch is there in case I've missed one of the possible combinations ( And the trace is so I can find out which and fix it ). Using our current example value from above, and we're in the forest this time, we'd call the function

private function forest_0111():void{

Which is a million times easier than any sort of conditional.

Right we now know what block we need to plot ( Take it as read we know the x/y position of it, this isn't the most fun post in the world as it is without me going into that depth ), how do we store the blocks themselves ?

KQ_darkForest.jpg


In the IDE we have block movieclips, like you can see above. Inside those blocks we have a floorMC and then the tiles. For the floor we just use bitmap draw() to grab it and turn it into a bitmap, and then burn that into the master ground bitmap ( All the floors in the game are just one huge bitmap, so no depth sorting or messing around, it's just a flat bitmap we scroll ).
The beauty of this approach is that the floors are in effect art style, we can drop any image on any pixel position, use blendmodes / alpha / scaling / anything really and because we're just burning it into the ground bitmap all this extra stuff is basically free.

That's the floor covered, next the tiles. Each tile in a block is just a movieclip, with an instance name. See that campfire on the top left block ? That's got the instance name "forest_088", and we just store that in an array with a reference to the bitmap of that image ( We're using the blitter for everything, which means bitmaps ). When plotting a block we loop through all the tile mc's in the block, find out the reference to it's bitmap and create a Bob ( Blitter OBject, ie a sprite ) for it.
In terms of layout, we don't have to be really anal, none of these tiles are pixel perfect aligned, that would be soul destroying, so the plotter rounds things down and most of the time gets it right.
One other slight bit of weirdness before we move on, each instance of a certain tile has to have the same name. Going back to the top left block, notice all the trees are the same ? They are all called "forest_008". Normally we'd never use the same instance name, as that's mental and wrong, but all we're doing is looping through each mc in the block, getting it's x,y position relative to the blocks origin, and then it's .name so we can look up the bitmap reference.

Not easy going I know, sorry. We're nearly there.

Notice we've got 4 blocks all with a north facing wall. To try and make the dungeons look as good as possible we make as many variations of each block as we can face. Before we actually plot them, we pick one at random ( Again, another array, just listing each possible block for each possible combination ).

If you've got this far then well done. Hopefully it explains things better than before.

Squize.