• Stick Nodes - 100% Complete Go animate some stickfigures. Google Play links: [free] or [pro]. App Store links: [free] or [pro].
Weapons on Wheels
Stick Nodes

Get it from: App Store | Google Play | SlideMe | Amazon | Opera

“Weapons on Wheels 2” Completed

0comments

Barring any unforeseen circumstances or potential bugs / required fixes, the game is pretty much done.  Isn’t that nifty?

Weapons on Wheels 2Now, it’s not up for bidding on FGL.com yet, mainly because it took too long for me to get everything 100% ready.  At first, I couldn’t get the encryption software I typically use (secureSWF) to function properly, it kept producing a blank SWF file.  Then, after getting by that by using the online encryption service FGL provides, I noticed the game undergoes a minimal amount of lag only when hosted on FGL.com (the game would bounce around 50 – 55fps but never reach 60fps like it does when played locally or hosted elsewhere).

I eventually narrowed the problem down to the online encryption service mentioned earlier.  I’m actually currently in the process of tweaking the encryption levels and re-uploading the game over and over to determine what exactly causes the lag.  Once I’m done here, I think I’ll be good to go.

However, I won’t click “enable bidding” until Sunday.  Thing is, with it being Thursday, the game won’t be approved and sent out in emails until Friday afternoon at the earliest.  In my opinion, I’d rather wait until Sunday and have the game approved Monday, you know, fresh work week, new monthly budgets, etc…  I don’t want to screw this up and give myself a disadvantage with that initial rush of views games get when they first get approved.

Anyway, here are some of the promotional material I’ve created over the weekend:

Trailer

Screenshots

ScreenshotScreenshotScreenshot
ScreenshotScreenshotScreenshot

Tomorrow I begin work on my next project, more details soon, of course.

“Weapons on Wheels 2” – Update 8

1comment

So, another two weeks just gone like that.  Last week was actually my birthday, and keeping up with the usual tradition, I was as sick as I’ve ever been in quite a while.  Seems about right.

Anyway, as a result, this post was delayed a week to today.  First off, there’s not much to report – at least not much in terms of pictures or video.

A few days ago I implemented the preloader, splash screens, and the pause menu for the game and, to be honest, it was all pretty simple.  I guess I’m finally getting the hang of this programming thing.  That’s about as far as I went with actual coding, though (there’s not much more to do other than implement the remaining levels and bug-test).

Game Levels

Over this past weekend, I spent a good portion of my time creating the basic foundation (read: the bland, uncolored roads and walls, no design elements yet) of each of the remaining eight levels.  This will result in a final total of twelve levels, which I think is a perfect amount for the game.  Eight levels just didn’t feel right and ten levels wouldn’t make sense (since, in the game, I’m bunching levels in groups of four).

Weapons on Wheels 2 LevelsThis decision comes with a price, though.  No matter what I do at this point, even with all of my past optimizations still in place, the game will be over 10MB.  Oh well, I tried my best.

I tried to avoid going over 10MB because I feel anything bigger than that will inhibit viral distribution.  On the other hand, every “big” Flash game I know of has a file size of over 10MB, so there’s that, right?  (Note: I know big file does not instantly equal great game, I’m just saying.)  Plus, like I said, I needed more levels, there’s nothing I can do.

I plan to spend this week (into and including next weekend) designing and “building” the remaining levels (drawing the visual aspects you’ll see in-game, placing trees, building the walls, etc).  This is kind of a tedious process, so doing it for a batch of eight levels doesn’t sound like too much fun, but I’ll do my best to get it done as soon as I can.  If everything goes well, the game should be near 95-100% complete by Monday.  My goal right now is to get all the levels implemented, balancing the game and bug-testing as I go along, and have it uploaded to FlashGameLicense.com for sponsorship on Tuesday of next week.

Nexus 10So yeah, that’s about all of that.  In other news, I got a Nexus 10 tablet for my birthday.  Didn’t expect that, I’ve never been one to want a tablet, I don’t know, I never got into that craze.  However, after playing around with it, I have to admit, it is pretty awesome.  I’m already planning my next game project and it’s definitely going to be an Android game (for tablets) using Adobe Air and the Starling framework.

Alright, that’s that.  Time to get to work on these levels.

“Weapons on Wheels 2” – Update 7

2comments

So, guys, crazy story – I totally forgot my password to log into the site here and post an update for the past two months.  Crazy, right?

I’ll make up for it with a new video showcasing the first two levels (there are currently four) and some of the weapons:

I just recently got finished implementing sounds and, wow, do they make such a difference.  It sounds like a war-zone at times and it really brings the game alive.

I’m now at a point where I can really see the finish line (sorry) coming into view.  As a quick overview, the meat of all that’s really left to do is to tweak the enemy AI and allow them to “buy” and use weapons.  Oh, and create the remaining levels, which is causing me an issue.

Weapons on Wheels 1 vs 2I’d really love 12 levels, 10 levels minimum, but at the rate I’m going (in terms of file-size) I’ll be lucky to get 8.  Right now, the file-size of a release build is about 9.0MB.  From what I understand about Flash games, 10MB is pretty much the understood limit for most games, with some notable exceptions, of course (large RPGs, huge tower-defense games, etc).  This is because a smaller file-size equals easier and wider distribution (bandwidth, portal upload restrictions, etc).

This leaves me with two options.  I’m going to either going to down the quality of the sounds / music / graphics and try to squeeze 8 or 10 levels into the game, or I’m going to just bite the bullet and end up with a 12MB game.  (I believe Weapons on Wheels 1 was actually 10.6MB, and that’s still my most popular game ever, still being played today!)

Anyway, it won’t be so long until my next update.  To be completely honest, this one took so long because I wanted to wait until I implemented some sounds.  As it turns out, I kept pushing it off later and later because of other things I was working on.  Eventually, two months later, I finally dedicated a day or two and added sounds to the game.

Okay bye, go play Weapons on Wheels 1 (why do the cars move so slow in that game?).

AS3 – Get Actual Keyboard Key From KeyCode

Comments Off on AS3 – Get Actual Keyboard Key From KeyCode

This is a little something I was having trouble with just now.  I thought there was some built-in functionality for this somewhere, but apparently there is not.  Also Google searches trying to find an existing solution turned up nothing, so I’m putting it here for anyone who may need this in their projects.

This simply returns the actual key value given a certain keyCode.  (For example, pass in 32 and get “Spacebar” in return.)  There is a built-in function, String.fromCharCode(), but I found this only works with the letter / number keys and not “special” keys like escape, shift, control, and most importantly – the arrow keys.

Create the Dictionary object:

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
var _keyCodeDictionary:Dictionary = new Dictionary();
_keyCodeDictionary[8] = "Backspace";
_keyCodeDictionary[9] = "Tab";
_keyCodeDictionary[13] = "Enter";
_keyCodeDictionary[16] = "Shift";
_keyCodeDictionary[17] = "Control";
_keyCodeDictionary[20] = "Caps Lock";
_keyCodeDictionary[27] = "Esc";
_keyCodeDictionary[32] = "Spacebar";
_keyCodeDictionary[33] = "Page Up";
_keyCodeDictionary[34] = "Page Down";
_keyCodeDictionary[35] = "End";
_keyCodeDictionary[36] = "Home";
_keyCodeDictionary[37] = "Left Arrow";
_keyCodeDictionary[38] = "Up Arrow";
_keyCodeDictionary[39] = "Right Arrow";
_keyCodeDictionary[40] = "Down Arrow";
_keyCodeDictionary[45] = "Insert";
_keyCodeDictionary[46] = "Delete";
_keyCodeDictionary[144] = "Num Lock";
_keyCodeDictionary[145] = "Scroll Lock";
_keyCodeDictionary[19] = "Pause/Break";
_keyCodeDictionary[65] = "A";
_keyCodeDictionary[66] = "B";
_keyCodeDictionary[67] = "C";
_keyCodeDictionary[68] = "D";
_keyCodeDictionary[69] = "E";
_keyCodeDictionary[70] = "F";
_keyCodeDictionary[71] = "G";
_keyCodeDictionary[72] = "H";
_keyCodeDictionary[73] = "I";
_keyCodeDictionary[74] = "J";
_keyCodeDictionary[75] = "K";
_keyCodeDictionary[76] = "L";
_keyCodeDictionary[77] = "M";
_keyCodeDictionary[78] = "N";
_keyCodeDictionary[79] = "O";
_keyCodeDictionary[80] = "P";
_keyCodeDictionary[81] = "Q";
_keyCodeDictionary[82] = "R";
_keyCodeDictionary[83] = "S";
_keyCodeDictionary[84] = "T";
_keyCodeDictionary[85] = "U";
_keyCodeDictionary[86] = "V";
_keyCodeDictionary[87] = "W";
_keyCodeDictionary[88] = "X";
_keyCodeDictionary[89] = "Y";
_keyCodeDictionary[90] = "Z";
_keyCodeDictionary[48] = "0";
_keyCodeDictionary[49] = "1";
_keyCodeDictionary[50] = "2";
_keyCodeDictionary[51] = "3";
_keyCodeDictionary[52] = "4";
_keyCodeDictionary[53] = "5";
_keyCodeDictionary[54] = "6";
_keyCodeDictionary[55] = "7";
_keyCodeDictionary[56] = "8";
_keyCodeDictionary[57] = "9";
_keyCodeDictionary[186] = ";";
_keyCodeDictionary[187] = "=";
_keyCodeDictionary[189] = "-";
_keyCodeDictionary[191] = "/";
_keyCodeDictionary[192] = "`";
_keyCodeDictionary[219] = "[";
_keyCodeDictionary[220] = "\\";
_keyCodeDictionary[221] = "]";
_keyCodeDictionary[222] = "'";
_keyCodeDictionary[188] = ",";
_keyCodeDictionary[190] = ".";
_keyCodeDictionary[96] = "Numpad 0";
_keyCodeDictionary[97] = "Numpad 1";
_keyCodeDictionary[98] = "Numpad 2";
_keyCodeDictionary[99] = "Numpad 3";
_keyCodeDictionary[100] = "Numpad 4";
_keyCodeDictionary[101] = "Numpad 5";
_keyCodeDictionary[102] = "Numpad 6";
_keyCodeDictionary[103] = "Numpad 7";
_keyCodeDictionary[104] = "Numpad 8";
_keyCodeDictionary[105] = "Numpad 9";
_keyCodeDictionary[106] = "Numpad Multiply";
_keyCodeDictionary[107] = "Numpad Add";
_keyCodeDictionary[109] = "Numpad Subtract";
_keyCodeDictionary[110] = "Numpad Decimal";
_keyCodeDictionary[111] = "Numpad Divide";
_keyCodeDictionary[112] = "F1";
_keyCodeDictionary[113] = "F2";
_keyCodeDictionary[114] = "F3";
_keyCodeDictionary[115] = "F4";
_keyCodeDictionary[116] = "F5";
_keyCodeDictionary[117] = "F6";
_keyCodeDictionary[118] = "F7";
_keyCodeDictionary[119] = "F8";
_keyCodeDictionary[120] = "F9";
_keyCodeDictionary[122] = "F11";
_keyCodeDictionary[123] = "F12";
_keyCodeDictionary[124] = "F13";
_keyCodeDictionary[125] = "F14";
_keyCodeDictionary[126] = "F15";

Function to retrieve from the Dictionary object:

1
2
3
4
5
6
7
8
9
public function getKeyboardFromKeyCode(keyCode:int):String
{
var string:String = null;

if (_keyCodeDictionary[keyCode])
string = (_keyCodeDictionary[keyCode] as String);

return string;
}

That’s all there is to it.  Sure it was tedious, but I’m sure this will be useful for displaying what keys are pressed on the screen, etc…

How To: Preloader in Flash Builder 4.7

10comments

So I’ve spent the better part of the past two or three days fumbling around Flash Builder 4.7 because, come on, who wants to use old, outdated Flash Builder 4.6, right?

Anyway, I unknowingly backed myself into a corner when I (stupidly) uninstalled FB 4.6 before installing FB 4.7 because a download link for FB 4.6 is apparently hard to come by these days.  As a result, I was stuck with the task of fixing the monumental wall of errors facing me when I first imported up my old game project.

This has nothing to do with this preloader stuff, but in case anyone out there runs into this problem, this is bad and throws errors:

1
[Embed(source = "../lib/levels/level1.lvl", mimeType = "application/octet-stream")]

This is valid:

1
[Embed(source = "/../lib/levels/level1.lvl", mimeType = "application/octet-stream")]

Spot the difference!  That alone fixed 80+ errors I was facing.  Apparently that leading forward slash is now mandatory.

Alright, onto the preloader.

Custom Preloader in Flash Builder 4.7

From what I can surmise, things have changed in FB 4.7 and I’m not sure if there are plans to “fix” things back to the way they used to work.

To get started, the basic core of my Preloader.as class I got from somewhere else on the internet.  I can’t seem to remember exactly, but shout-out to them.

Edit: I’ve found the original source of the preloader code to be from a post on pixelpaton.com.

Now, this process involves two classes, the Preloader.as class and your document class (here, mine will be Main.as).

Step One – Compiler Settings

  1. Flash Builder 4.7 Preloader Open FB 4.7 and right-click on your project, select Properties.
  2. Click ActionScript Compiler on the left and find the Additional compiler arguments field.
  3. Append this in that field: -frame appFrame Main
    Note: This assumes Main is the name of your document class, make sure you change it appropriately.

Step Two – Preloader Class

  1. Create a new class, call it Preloader.as.
  2. Paste the following code into this class:
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
package
{
import flash.display.DisplayObject;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.utils.getDefinitionByName;

[SWF(frameRate="60", width="700", height="525", backgroundColor="0x000000")]
public class Preloader extends Sprite
{
// Private
private var _preloaderBackground:Shape
private var _preloaderPercent:Shape;
private var _checkForCacheFlag:Boolean = true;
// Constants
private static const MAIN_CLASS_NAME:String = "Main";

public function Preloader()
{
trace("Preloader: Initialized.")
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}

public function dispose():void
{
trace("Preloader: Disposing.")
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
if (_preloaderBackground)
{
removeChild(_preloaderBackground);
_preloaderBackground = null;
}
if (_preloaderPercent)
{
removeChild(_preloaderPercent);
_preloaderPercent = null;
}
}

// Private functions

private function onAddedToStage(e:Event):void
{
trace("Preloader: Added to stage.");
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
stage.scaleMode = StageScaleMode.SHOW_ALL;
stage.align = StageAlign.TOP_LEFT;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function onEnterFrame(e:Event):void
{
if (_checkForCacheFlag == true)
{
_checkForCacheFlag = false;
if (root.loaderInfo.bytesLoaded >= root.loaderInfo.bytesTotal)
{
trace("Preloader: No need to load, all " + root.loaderInfo.bytesTotal + " bytes are cached.");
finishedLoading();
}
else
beginLoading();
}
else
{
if (root.loaderInfo.bytesLoaded >= root.loaderInfo.bytesTotal)
{
trace("Preloader: Finished loading all " + root.loaderInfo.bytesTotal + " bytes.");
finishedLoading();
}
else
{
var percent:Number = root.loaderInfo.bytesLoaded / root.loaderInfo.bytesTotal;
updateGraphic(percent);
trace("Preloader: " + (percent * 100) + " %");
}
}
}

private function beginLoading():void
{
// Might not be called if cached.
// ------------------------------
trace("Preloader: Beginning loading.")
_preloaderBackground = new Shape()
_preloaderBackground.graphics.beginFill(0x333333)
_preloaderBackground.graphics.lineStyle(2,0x000000)
_preloaderBackground.graphics.drawRect(0,0,200,20)
_preloaderBackground.graphics.endFill()

_preloaderPercent = new Shape()
_preloaderPercent.graphics.beginFill(0xFFFFFFF)
_preloaderPercent.graphics.drawRect(0,0,200,20)
_preloaderPercent.graphics.endFill()

addChild(_preloaderBackground)
addChild(_preloaderPercent)
_preloaderBackground.x = _preloaderBackground.y = 10
_preloaderPercent.x = _preloaderPercent.y = 10
_preloaderPercent.scaleX = 0
}

private function updateGraphic(percent:Number):void
{
// Might not be called if cached.
// ------------------------------
_preloaderPercent.scaleX = percent
}

private function finishedLoading():void
{
var MainClass:Class = getDefinitionByName(MAIN_CLASS_NAME) as Class;

if (MainClass == null)
throw new Error("Preloader: There is no class \"" + MAIN_CLASS_NAME + "\".");

var main:DisplayObject = new MainClass() as DisplayObject;
if (main == null)
throw new Error("Preloader: The class \"" + MAIN_CLASS_NAME + "\" is not a Sprite or MovieClip.");

addChild(main);
dispose();
}
}
}

There are two main components here you need to worry about.

  1. Be sure to change the values in the SWF metadata tag to whatever you want (above the class declaration).
  2. Also be sure to change the value of the constant that holds the name of the document class (again, mine is Main.as):
    private static const MAIN_CLASS_NAME:String = “Main”;

This is the most absolute bare-bones preloader you can have.  It simply uses two rectangle shapes to display a loading bar.  When you need to, you can replace the functionality with graphics or whatever.

Step 3 – Main.as (or whatever your document class is)

There is nothing special about Main.as.  This is simply the “starting point” for your game.  It doesn’t matter what’s in the actual .as file, just as long as the file exists right now.

Step 4 – Default Application

  1. Flash Builder 4.7 PreloaderRight-click on Preloader.as in the Package Explorer window and select Set as Default Application.
  2. In the Package Explorer window, Preloader.as should now have an icon with a small blue circle and Main.as should not.
    (Also, very important. Preloader.as should also have a green triangle on it’s icon while Main.as should not.  If Main.as does have this triangle, read below section, “Having Problems?.”  The image to the right shows a green triangle on both icons – this is bad.)

Step 5 – Profit!

That’s it, you’re done.  The main change here (at least from the method I’ve become accustomed to) is the lack of the [Frame(factoryClass = “Preloader”)] tag typically utilized.

Having Problems?

Depending on when you’re adding a preloader to your project, you may have to do one more thing.  I learned this the hard way after things would only work once, then on the next build it’d be all messed up again.

You only need to worry about this if there is a green triangle on the icon next to Main.as in the Package Explorer window.

  1. Right-click on your project and select Properties.
  2. Select ActionScript Applications on the left.
  3. In the list on the right, select Main.as and click Remove.  All that should be left in the list is Preloader.as (default).
  4. Now select Run/Debug Settings on the left.
  5. In the list on the right, select Main and click Delete.  All that should be left in the list is Preloader.
  6. Click OK.  All done!

From what I’ve seen, there hasn’t been a clear-cut answer to this preloader issue posted anywhere for FB 4.7 yet, so that’s why I wrote this up.

I originally didn’t know the “old” method of creating preloaders was deprecated until FB 4.7 kept throwing a ReferenceError: Error #1065: Variable Main is not defined error as soon as I attempted to build my project.  Big thanks to the topic on the Adobe forums here that led me to this solution.