Complete Bejeweled game in less than 2KB
You should know Bejeweled from PopCap Games.
It’s a game which have been played millions, if not billions, of times. Now PopCap just released the 3rd version of his blockbuster.
To celebrate this event, just like I made when I coded a complete Flash Sokoban game in less than 2KB, I made a Bejeweled version in less than 2KB. The swf file is 2035 bytes, less than the 2048 need to make 2KB.
Do you think it does not have any feature? Take a look:
* colorful representation of all 7 kinds of jewel
* select a jewel clicking on it
* swap jewels only if they make a chain
* combo chains recognizing
* falling jewels animation
* complex (let’s say “not that basic”) score system
* hint on a possible move when clicking outside the game area
Everything in less than 2KB. The code was mode with the only purpose of making the game fit in less than 2KB, there’s not readability nor optimization.
Here it is the source:
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 228 229 230 231 232 233 234 235 236 237 238 239 240 | package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.Event; import flash.text.TextField; public class n extends Sprite { private var jw:Array=new Array(); private var g:Sprite; private var s:Sprite=new Sprite(); private var pr:int=-10; private var pc:int=-10; private var cl:Array=new Array(0xFF0000,0xFF00,0xFF,0XFFFF00,0xFF00FF,0xFFFF,0xFFFFFF); private var cp:Boolean=false; private var ts:TextField=new TextField(); private var th:TextField=new TextField(); private var sc:uint=0; private var m:uint=0; public function n() { addChild(ts); ts.textColor=0xFFFFFF; ts.x=500; addChild(th); th.textColor=0xFFFFFF; th.x=550; for (var i:uint=0; i<8; i++) { jw[i]=new Array(); for (var j:uint=0; j<8; j++) { do { jw[i][j]=Math.floor(Math.random()*7); } while (rk(i,j)>2||ck(i,j)>2); g=new Sprite(); g.graphics.beginFill(cl[jw[i][j]]); g.graphics.drawCircle(30,30,29); g.graphics.endFill(); g.name=i+"_"+j; g.x=j*60; g.y=i*60; addChild(g); } } addChild(s); s.graphics.lineStyle(2,0xff0000,1); s.graphics.drawRect(0,0,60,60); s.visible=false; stage.addEventListener(MouseEvent.CLICK,ci); addEventListener(Event.ENTER_FRAME,ef); } private function ef(e:Event):void { var f:Boolean=false; for (var i:int=6; i>=0; i--) { for (var j:uint=0; j<8; j++) { if (jw[i][j]!=-1&&jw[i+1][j]==-1) { f=true; jw[i+1][j]=jw[i][j]; jw[i][j]=-1; getChildByName(i+"_"+j).y+=60; getChildByName(i+"_"+j).name=(i+1)+"_"+j; break; } } if (f) { break; } } if (! f) { var h:Boolean=false; for (i=7; i>=0; i--) { for (j=0; j<8; j++) { if (jw[i][j]==-1) { h=true; jw[0][j]=Math.floor(Math.random()*7); g=new Sprite(); g.graphics.beginFill(cl[jw[0][j]]); g.graphics.drawCircle(30,30,29); g.graphics.endFill(); g.name="0_"+j; g.x=j*60; g.y=0; addChild(g); break; } } if (h) { break; } } if (! h) { var r:Boolean=false; for (i=7; i>=0; i--) { for (j=0; j<8; j++) { if (rk(i,j)>2||ck(i,j)>2) { r=true; var tr:Array=[i+"_"+j]; var u:uint=jw[i][j]; var t:int; if (rk(i,j)>2) { t=j; while (chk(u,i,t-1)) { t--; tr.push(i+"_"+t); } t=j; while (chk(u,i,t+1)) { t++; tr.push(i+"_"+t); } } if (ck(i,j)>2) { t=i; while (chk(u,t-1,j)) { t--; tr.push(t+"_"+j); } t=i; while (chk(u,t+1,j)) { t++; tr.push(t+"_"+j); } } for (i=0; i<tr.length; i++) { removeChild(getChildByName(tr[i])); var cd:Array=tr[i].split("_"); jw[cd[0]][cd[1]]=-1; sc+=m; m++; } break; } } if (r) { break; } } if (! r) { cp=true; m=0; } } } ts.text=sc.toString(); } private function ci(e:MouseEvent):void { if (cp) { if (mouseX<480&&mouseX>0&&mouseY<480&&mouseY>0) { var sr:uint=Math.floor(mouseY/60); var sc:uint=Math.floor(mouseX/60); if (!(((sr==pr+1||sr==pr-1)&&sc==pc)||((sc==pc+1||sc==pc-1)&&sr==pr))) { pr=sr; pc=sc; s.x=60*pc; s.y=60*pr; s.visible=true; } else { swp(pr,pc,sr,sc); if (rk(pr,pc)>2||ck(pr,pc)>2||rk(sr,sc)>2||ck(sr,sc)>2) { th.text=""; cp=false; getChildByName(pr+"_"+pc).x=sc*60; getChildByName(pr+"_"+pc).y=sr*60; getChildByName(pr+"_"+pc).name="t"; getChildByName(sr+"_"+sc).x=pc*60; getChildByName(sr+"_"+sc).y=pr*60; getChildByName(sr+"_"+sc).name=pr+"_"+pc; getChildByName("t").name=sr+"_"+sc; } else { swp(pr,pc,sr,sc); } pr=-10; pc=-10; s.visible=false; } } else { for (var i:uint=0; i<8; i++) { for (var j:uint=0; j<8; j++) { if (i<7) { swp(i,j,i+1,j); if ((rk(i,j)>2||ck(i,j)>2||rk(i+1,j)>2||ck(i+1,j)>2)) { th.text = i.toString()+","+j.toString()+"->"+(i+1).toString()+","+j.toString(); } swp(i,j,i+1,j); } if (j<7) { swp(i,j,i,j+1); if ((rk(i,j)>2||ck(i,j)>2||rk(i,j+1)>2||ck(i,j+1)>2) ) { th.text = i.toString()+","+j.toString()+"->"+(i).toString()+","+(j+1).toString(); } swp(i,j,i,j+1); } } } } } } private function swp(r1:uint,c1:uint,r2:uint,c2:uint):void { var t:uint=jw[r1][c1]; jw[r1][c1]=jw[r2][c2]; jw[r2][c2]=t; } private function rk(r:uint,c:uint):uint { var u:uint=jw[r][c]; var stk:uint=1; var t:int=c; while (chk(u,r,t-1)) { t--; stk++; } t=c; while (chk(u,r,t+1)) { t++; stk++; } return (stk); } private function ck(r:uint,c:uint):uint { var u:uint=jw[r][c]; var stk:uint=1; var t:int=r; while (chk(u,t-1,c)) { t--; stk++; } t=r; while (chk(u,t+1,c)) { t++; stk++; } return (stk); } private function chk(g:uint,r:int,c:int):Boolean { if (jw[r]==null) { return false; } if (jw[r][c]==null) { return false; } return g==jw[r][c]; } } } |
This class was compiled with “Compress movie” checked and “Include XMP metadata” unchecked. There’s still room to save some bytes, but not enough to develop power jewels I am afraid… anyway you are free to try to reduce the code some more.
Download the source code. What’s your best score?
They can be easily customized to meet the unique requirements of your project.
















(28 votes, average: 4.46 out of 5)










This post has 31 comments
Thomas
550, there’s an entry score for people to beat.
I’d do better if it were on timed mode, where you can’t have an impossible board. See, my 550 might not be good, but you can bet it was fast ;)
Davide
I think I found a missing thing :)
If you make a double combination (3 horizontal and 3 vertical) it considers only one.
Impressive anyway! Oh and my best score actually is only 328 :(
jarofed
1070
and have quite a little combinations to continue. Just have no time for it
Emanuele Feronato
wow, it would be interesting to see the source code… it could be a 1kb game or a 2kb game featuring power jewels
R!ch!3
I think he means that he reached 1070 points.
Really great work as always btw. :)
Emanuele Feronato
I hope you’re right, otherwise my code would suck… from 2035 to 1070 bytes… :(
theDude
2031 and very bored. Kudos on the coding though!
zandy
Muy bueno el ejemplo! :-) gracias por compartir.
kutay gursoy
well i dont know if it is a “bug” but when i play that kind of games the game clears both lines like the example matrix i ll give below.this game just clears if the line is 4 or more.
xyza
axzy
zzzx
xazy
as u see above there is a 4 “z” and a 3 “z” line. but game just clears 4 “z” and then left a 2″z” line.
btw:plz have a look at your e mail some newbies may need help:)
kutay gursoy
well i guess its second bug :S sample matrix is;
bcbcbc
yzxxaa
zxxaay
if i change 2nd line 4th colomn “x” with 3rd line 4th colomn “a” that would be
bcbcbc
yzxaaa
zxxxay
but game calculates just “xxx” line and doesnt calculate “aaa” line.after clearing “xxx” new matrix is like;
ydyzdc
ycbcaa
zzxaay
actually both lines should be cleared and that must be a “combo” :)
Damian Orlandi
If you make an “L” of the same colour, it will only take a line, not the whole L.
mc
Now it would be nice to see the commented version :)
Angell
1622 – i thought it was endless
I’d just like to say that I’m just taking my babysteps in flash and I find your site really helpful, it’s in speed dial in my Opera :D.
shaman4d
Interesting but where is smooth animation of drop downing pieces? And hypercube and flame crystal?
cs
I keep getting this message: Scene 1, Layer ‘Layer 1′, Frame 1, Line 1 1037: Packages cannot be nested.
Do anyone knows that can be fixed?
cs
Never mind, I got it. That is some great work. Thanks a lot! 5/5
Nameless
For the past year, I’ve been struggling to advance my studies into flash and AS3 but couldn’t come up with a project that uses more complex method. I’ve always been hesitant into starting array-based games, but thanks to this tutorial I feel more conformable about it. It took a a few hours for me to decipher the code (mainly the method for adding new jewels once the player create chains), but now I am having a much better understanding of the game’s functionality and array-based games.
Once I am finished with my concept of Bejeweled, I plan on exploring more possibilities with the knowledge I just learned.
Thanks again!
Az
First try, 736
Luis Epifanio
Great. Quit at 606 point. Congrats
FuzzDog
It’s really hard to reduce the code when I can’t even understand it because the variables you have used are not descriptive at all.
Brook Jordan
Would it be out of line to post my version of the code, with properly named variables and comments for people to look at?
Obviously the swf now compiles bigger than yours, but I’m sure some people would appreciate seeing the code.
Emanuele Feronato
@Jordan: it would be great, send your work at info[at]emanueleferonato.com
DutchBoy
Very nice, but it have a bad, BAD B-A-D skin.
And you are so genious why don’t you make a better guestbook? This one sucks, really…
Simon Gleizes
Final score: 1951.
The key is to play at the top of the board and to clear those pieces first, before going downwards.
Anyway, thanks a bunch for posting this Emanuele. I’m an avid reader of your blog and I found this script very nice!
Xtrude
Question,
Has anyone tried to run this in Flash Builder? It comes up blank. What am I doing wrong?
B.Jordan
Hi
@Xtrude:
You can run this code in all IDE:
Adobe Flash (I tried CS5)
FlashDevelop (with Flash to Release)
Flex works too (a few things are different but you should know them or you would not understand the game code of course)
Perhabs there are some debug information/errors fired in Flash Builder??
I also have read the code from “Game Development by Example” to write my own Bejeweled Version. It works nice but there is much to do for getting a real commercial working game :)!
Have you tried secureSWF or something else to reduce your Code again Emanuele?
Have a nice day!
Bejeweled for Flash, in under 2KB « White Labs
[...] impressive find demonstrates how to fit a game in under 2KB. As the author says: “The code was mode(sic) with [...]
Honey
hello sir Emanuele.. what part in the source code will the circles fall after a match? i am creating a matching game wherein the tiles will fall after there is a match in the middle..you’re tutorial is very helpful..thank you so much sir! Godbless!:D
[Flash CS5] - Flash Spiel design - Flashforum
[...] das macht man ziemlich genau so: Complete Bejeweled game in less than 2KB – Emanuele Feronato mfg sx __________________ [...]
Supanida
I got 3248!! It’s nice. I’m trying to do the same thing in html5/javascript. I got the game work so far but I want to add on some dropping animation which I don’t know how to do it yet.
The White Agency Blog » Bejeweled for Flash, in under 2KB » The White Agency Blog
[...] impressive find demonstrates how to fit a game in under 2KB. The author says “The code was mode(sic) with the [...]