Flash math game in less than 2KB

Read all posts about "" game

Sometimes I make some experiments about fitting complete games into a ridiculously small amount of space.

I already published a complete Flash Sokoban game in less than 2KB and a complete Bejeweled game in less than 2KB, this time I want to show you an original math game concept made in less than 2KB (well, actually exactly 2KB).

The game is similar to Globez, you must draw a path with the mouse to select circles. Every circle has a number in it, and the sum of all selected circles must match one of the shrinking circles on the right. Once a circle on the right becomes too small, it’s game over.

I managed to include backtracking, a “not that flat” scoring system and a level progression. Unfortunately the game has no “Play again” button but all in all we are talking about a 2KB game.

Here is the game, I am curious to know your best score:

And here is the script, probably there are still some bytes to save:

package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.text.TextField;
	public class m extends Sprite {
		public var t:Array;
		public var v:Array;
		public var b:Array;
		public var ss:int;
		public var q:TextField;
		public var s:int;
		public var l:int=1;
		public var n:Array;
		public var h:Boolean=false;
		public function m() {
			q=new TextField();
			addChild(q);
			q.x=500;
			q.y=380;
			t=new Array();
			b=new Array();
			n=new Array();
			for (var i:int=0; i<6; i++) {
				t[i]=new Array();
				for (var j:int=0; j<6; j++) {
					w(i,j);
				}
			}
			for (i=0; i<8; i++) {
				k(i);
			}
			stage.addEventListener(MouseEvent.MOUSE_DOWN,dr);
			addEventListener(Event.ENTER_FRAME,u);
		}
		public function sc(g):void {
			q.text=s+"\nLvl: "+l+"\nSum: "+ss;
			if (g) {
				q.appendText("\nGame Over");
				stage.removeEventListener(MouseEvent.MOUSE_DOWN,dr);
				stage.removeEventListener(MouseEvent.MOUSE_MOVE,dw);
				stage.removeEventListener(MouseEvent.MOUSE_UP,ds);
				removeEventListener(Event.ENTER_FRAME,u);
			}
		}
		public function dr(e:MouseEvent):void {
			var i:int=Math.floor(mouseX/80);
			var j:int=Math.floor(mouseY/80);
			if (i<0 || i>5 || j<0 || j>5) {
				return;
			}
			v=new Array();
			v.push({x:i,y:j});
			t[i][j].k=true;
			ss=t[i][j].v;
			stage.removeEventListener(MouseEvent.MOUSE_DOWN,dr);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,dw);
			stage.addEventListener(MouseEvent.MOUSE_UP,ds);
		}
		public function dw(e:MouseEvent):void {
			var i:int=Math.floor(mouseX/80);
			var j:int=Math.floor(mouseY/80);
			if (i<0 || i>5 || j<0 || j>5) {
				return;
			}
			if ((mouseX-(i*80+40))*(mouseX-(i*80+40))+(mouseY-(j*80+40))*(mouseY-(j*80+40))<1296) {
				if (i!=v[v.length-1].x || j!=v[v.length-1].y) {
					if (Math.abs(i-v[v.length-1].x)<=1 && Math.abs(j-v[v.length-1].y)<=1) {
						if (v.length>1&&i==v[v.length-2].x&&j==v[v.length-2].y) {
							var bp:Object=v.pop();
							t[bp.x][bp.y].k=false;
							ss-=t[bp.x][bp.y].v;
						}
						else {
							if (! t[i][j].k) {
								v.push({x:i,y:j});
								t[i][j].k=true;
								ss+=t[i][j].v;
							}
						}
					}
				}
			}
			graphics.clear();
			graphics.lineStyle(4,0x999999);
			graphics.moveTo(v[0].x*80+40,v[0].y*80+40);
			for (i=0; i<v.length; i++) {
				graphics.lineTo(v[i].x*80+40,v[i].y*80+40);
			}
		}
		public function ds(e:MouseEvent):void {
			graphics.clear();
			var removed:int=-1;
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,dw);
			stage.removeEventListener(MouseEvent.MOUSE_UP,ds);
			if (e!=null && v.length>2) {
				for (i=0; i<b.length; i++) {
					if (b[i].v==ss) {
						removeChild(b[i].tl);
						b[i]=null;
						removed=i;
						s+=ss*v.length;
						n.splice(n.indexOf(ss),1);
						l=Math.ceil(s/500);
						break;
					}
				}
			}
			if (removed>=0) {
				for (var i:int=0; i<v.length; i++) {
					removeChild(t[v[i].x][v[i].y].tl);
					t[v[i].x][v[i].y]=null;
				}
				h=true
				k(removed);
			}
			else {
				for (i=0; i<6; i++) {
					for (var j:int=0; j<6; j++) {
						t[i][j].k=false;
					}
				}
				stage.addEventListener(MouseEvent.MOUSE_DOWN,dr);
			}
			ss=0;
		}
		public function k(p1:int):void {
			var o:Object=new Object();
			o.v=Math.ceil(Math.random()*20)+10;
			while (n.indexOf(o.v)>-1) {
				o.v=Math.ceil(Math.random()*20)+10;
			}
			n.push(o.v);
			o.p=0;
			o.tl= new Sprite();
			var tt:TextField=new TextField();
			tt.text=o.v;
			tt.y=30;
			tt.x=30;
			o.tl.addChild(tt);
			o.tl.x=(p1%2+6)*80;
			o.tl.y=Math.floor(p1/2)*80;
			addChild(o.tl);
			b[p1]=o;
		}
		public function w(_x:int,_y:int,_a=1):void {
			var o:Object=new Object();
			o.k=false;
			o.v=Math.ceil(Math.random()*9);
			o.tl=new Sprite();
			o.tl.x=_x*80;
			o.tl.y=_y*80;
			o.tl.graphics.lineStyle(4,0xff0000);
			o.tl.graphics.drawCircle(40,40,35);
			var tt:TextField=new TextField();
			tt.text=o.v;
			tt.y=30;
			tt.x=35;
			o.tl.addChild(tt);
			o.tl.alpha=_a;
			o.trans=0;
			addChild(o.tl);
			t[_x][_y]=o;
		}
		function u(e:Event):void {
			sc(false);
			for (var i:int=0; i<8; i++) {
				b[i].p+=l;
				b[i].tl.graphics.clear();
				b[i].tl.graphics.lineStyle(4,0x888888);
				b[i].tl.graphics.drawCircle(40,40,40-40*b[i].p/10000);
				if (b[i].p>=10000) {
					sc(true);
				}
			}
			if (h) {
				var a:Boolean=false;
				for (i=0; i<6; i++) {
					for (var j:int=0; j<6; j++) {
						if (t[j][i]!=null&&t[j][i].tl.alpha<1) {
							t[j][i].tl.alpha+=0.25;
							a=true;
						}
					}
				}
				for (i=6-2; i>=0; i--) {
					for (j=6-1; j>=0; j--) {
						if (t[j][i+1]==null&&t[j][i]!=null) {
							a=true;
							t[j][i].tl.y+=80/4;
							if (t[j][i].trans==3) {
								t[j][i].trans=0;
								t[j][i+1]=t[j][i];
								t[j][i]=null;
							}
							else {
								t[j][i].trans++;
							}
						}
						else {
							if (i==0 && t[j][i]==null) {
								w(j,i,0);
								a=true;
							}
						}
					}
				}
				if (! a) {
					stage.addEventListener(MouseEvent.MOUSE_DOWN,dr);
					h=false;
				}
			}
		}
	}
}

I was able to save some space by replacing Point type with an Object with x and y variables.

A full version of the game with some more features is due in some days.

Download the source code.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

214 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers