My code tricks #1: All around consistent data
Sorry about not having posted too much, but deadlines have this strange habit of having a higher priority. Vlad is here trying to stay awake in this awkward coding night and to celebrate this fine hour of coding I decided to take a small break and create a new ’series’ in the blog. I’ll call it “My code tricks” and #1 is dedicated to the neat little trick I use to have a lot of standardization across my code.
Not my original idea at all, actually it’s so simple I’m amazed that I haven’t found any blog post or article that talks about it. But here goes!
Finite State Machines
Once upon a time I had the need to start using state machines. Like pretty much all code I write and as noted by a fellow coder, my code is OOP enough to make coding easier but not a by the book approach, far from it. So my state machines are quite simple:
1 2 3 4 5 6 7 8 9 10 11 12 | package { public class PlayerController { // Vars --------------------------------------------------------------- private const NONE:int = 0; private const IDLE:int = 1; private const WALK:int = 2; private const HURT:int = 3; } } |
Yes, those constants there are the heart of my state machines. They offer two great features: they are extremely simple to use and they are very intuitive and readable, making my coding life easier. As time passed and projects grew bigger and more complex, I started to have issues with controlling all the states and all the constants, especially when I had to get information across objects and classes.
Moreover, some constants had to be public in order to be checked or I’d have to put getters or some other coding artifact to do it.
Objective: reusable and consistent
The way I found to address this was to create one class that would hold static constants for everyone! This way I know that a TOKEN_RUNNING is a game entity that is running and that this data is consistent all around the game. It does not matter who needs to know that value. What I know is that I have a very easy lightweight way to address states. Check it out:
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 | /* Author: Ricardo Vladimiro * ------------------------------------------------------------------------------------------------ * Description: Constant placeholder for common states. */ package bpe.data { public class State { // Common states -------------------------------------------------------------------------- public static const IDLE:int = 1001; public static const NONE:int = 1002; // Game states ---------------------------------------------------------------------------- public static const GAME_PRELOADING:int = 2001; public static const GAME_PRELOADING_FINISHED:int = 2002; public static const GAME_LOADING:int = 2003; public static const GAME_LOADING_FINISHED:int = 2004; public static const GAME_RUNNING:int = 2005; // Level states --------------------------------------------------------------------------- public static const LEVEL_RUNNING:int = 3001; public static const LEVEL_FINISHED:int = 3002; public static const LEVEL_FAILED:int = 3003; public static const LEVEL_COUNTDOWN:int = 3004; // Token states --------------------------------------------------------------------------- public static const TOKEN_MOVING:int = 4001; // Directional states --------------------------------------------------------------------- public static const DIRECTION_UP:int = 5001; public static const DIRECTION_DOWN:int = 5002; public static const DIRECTION_LEFT:int = 5003; public static const DIRECTION_RIGHT:int = 5004; public static const DIRECTION_HORIZONTAL:int = 5005; public static const DIRECTION_VERTICAL:int = 5006; } } |
But by all means, don’t assume this serves states only. As you might have noticed by reading the package, this class is part of the Bold Pixel Engine. The package holds several classes with static constants. The type of entities the blit engine uses, easing codes for the (future) tweening class and color tables. Everything in that package is a constant int that allows data to be consistent and readable.
Consistency means two things: no constant has the same value EVER! and I can add whatever other states I need and data will be backward compatible.
Here’s another example, a class that holds key codes and that uses the key code to feed a name array with key names. We use it to get key states from an input manager. It was migrated some days ago, to be honest I know the input manager is working but I don’t know if the name array has any use as a static member, still, feel free to use it, the keycodes are REALLY handy!
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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | /* Author: Ricardo Vladimiro * ------------------------------------------------------------------------------------------------ * Description: Holds keyName data. */ package bpe.data { public class Keycode { // Key Names ------------------------------------------------------------------------------- public static const keyName:Array = new Array(); keyName[A] = "A"; keyName[B] = "B"; keyName[C] = "C"; keyName[D] = "D"; keyName[E] = "E"; keyName[F] = "F"; keyName[G] = "G"; keyName[H] = "H"; keyName[I] = "I"; keyName[J] = "J"; keyName[K] = "K"; keyName[L] = "L"; keyName[M] = "M"; keyName[N] = "N"; keyName[O] = "O"; keyName[P] = "P"; keyName[Q] = "Q"; keyName[R] = "R"; keyName[S] = "S"; keyName[T] = "T"; keyName[U] = "U"; keyName[V] = "V"; keyName[W] = "W"; keyName[X] = "X"; keyName[Y] = "Y"; keyName[Z] = "Z"; keyName[Keyb0] = "0"; keyName[Keyb1] = "1"; keyName[Keyb2] = "2"; keyName[Keyb3] = "3"; keyName[Keyb4] = "4"; keyName[Keyb5] = "5"; keyName[Keyb6] = "6"; keyName[Keyb7] = "7"; keyName[Keyb8] = "8"; keyName[Keyb9] = "9"; keyName[Numpad0] = "Numpad 0"; keyName[Numpad1] = "Numpad 1"; keyName[Numpad2] = "Numpad 2"; keyName[Numpad3] = "Numpad 3"; keyName[Numpad4] = "Numpad 4"; keyName[Numpad5] = "Numpad 5"; keyName[Numpad6] = "Numpad 6"; keyName[Numpad7] = "Numpad 7"; keyName[Numpad8] = "Numpad 8"; keyName[Numpad9] = "Numpad 9"; keyName[NumpadStar] = "Numpad *"; keyName[NumpadPlus] = "Numpad +"; keyName[NumpadMinus] = "Numpad -"; keyName[NumpadPeriod] = "Numpad ."; keyName[NumpadSlash] = "Numpad /"; keyName[F1] = "F1"; keyName[F2] = "F2"; keyName[F3] = "F3"; keyName[F4] = "F4"; keyName[F5] = "F5"; keyName[F6] = "F6"; keyName[F7] = "F7"; keyName[F8] = "F8"; keyName[F9] = "F9"; keyName[F11] = "F11"; keyName[F12] = "F12"; keyName[F13] = "F13"; keyName[F14] = "F14"; keyName[F15] = "F15"; keyName[Backspace] = "Backspace"; keyName[Tab] = "Tab"; keyName[Enter] = "Enter"; keyName[Shift] = "Shift"; keyName[Control] = "Control"; keyName[PauseBreak] = "Pause/Break"; keyName[CapsLock] = "Caps Lock"; keyName[Esc] = "Esc"; keyName[Spacebar] = "Spacebar"; keyName[PageUp] = "Page Up"; keyName[PageDown] = "Page Down"; keyName[End] = "End"; keyName[Home] = "Home"; keyName[Left] = "Left Arrow"; keyName[Up] = "Up Arrow"; keyName[Right] = "Right Arrow"; keyName[Down] = "Down Arrow"; keyName[Insert] = "Insert"; keyName[Delete] = "Delete"; keyName[NumLck] = "NumLck"; keyName[ScrLck] = "ScrLck"; keyName[SemiColon] = ";"; keyName[Equal] = "="; keyName[Comma] = ","; keyName[Minus] = "-"; keyName[Period] = "."; keyName[Question] = "?"; keyName[BackQuote] = "`"; keyName[LeftBrace] = "["; keyName[Pipe] = "|"; keyName[RightBrace] = "]"; keyName[SingleQuote] = "'"; // Key Codes ------------------------------------------------------------------------------- public static const A = 65; public static const B = 66; public static const C = 67; public static const D = 68; public static const E = 69; public static const F = 70; public static const G = 71; public static const H = 72; public static const I = 73; public static const J = 74; public static const K = 75; public static const L = 76; public static const M = 77; public static const N = 78; public static const O = 79; public static const P = 80; public static const Q = 81; public static const R = 82; public static const S = 83; public static const T = 84; public static const U = 85; public static const V = 86; public static const W = 87; public static const X = 88; public static const Y = 89; public static const Z = 90; public static const Keyb0 = 48; public static const Keyb1 = 49; public static const Keyb2 = 50; public static const Keyb3 = 51; public static const Keyb4 = 52; public static const Keyb5 = 53; public static const Keyb6 = 54; public static const Keyb7 = 55; public static const Keyb8 = 56; public static const Keyb9 = 57; public static const Numpad0 = 96; public static const Numpad1 = 97; public static const Numpad2 = 98; public static const Numpad3 = 99; public static const Numpad4 = 100; public static const Numpad5 = 101; public static const Numpad6 = 102; public static const Numpad7 = 103; public static const Numpad8 = 104; public static const Numpad9 = 105; public static const NumpadStar = 106; public static const NumpadPlus = 107; public static const NumpadMinus = 109; public static const NumpadPeriod = 110; public static const NumpadSlash = 111; public static const F1 = 112; public static const F2 = 113; public static const F3 = 114; public static const F4 = 115; public static const F5 = 116; public static const F6 = 117; public static const F7 = 118; public static const F8 = 119; public static const F9 = 120; public static const F11 = 122; public static const F12 = 123; public static const F13 = 124; public static const F14 = 125; public static const F15 = 126; public static const Backspace = 8; public static const Tab = 9; public static const Enter = 13; public static const Shift = 16; public static const Control = 17; public static const PauseBreak = 19; public static const CapsLock = 20; public static const Esc = 27; public static const Spacebar = 32; public static const PageUp = 33; public static const PageDown = 34; public static const End = 35; public static const Home = 36; public static const Left = 37; public static const Up = 38; public static const Right = 39; public static const Down = 40; public static const Insert = 45; public static const Delete = 46; public static const NumLck = 144; public static const ScrLck = 145; public static const SemiColon = 186; public static const Equal = 187; public static const Comma = 188; public static const Minus = 189; public static const Period = 190; public static const Question = 191; public static const BackQuote = 192; public static const LeftBrace = 219; public static const Pipe = 220; public static const RightBrace = 221; public static const SingleQuote = 222; /* Changelog ------------------------------------------------------------------------------ * 2009.08.18 Changed namespace and name to blit.data.Keycode * --------------------------------------------------------------------------------------*/ } } |
Posted: September 1st, 2009
at 2:59am by Vlad
Tagged with Code Tricks, FlashGameBlogs
Categories: The code of VGS
Comments: 4 comments
