Another simple game. This one is more of an original.
You have limited time and limited number of shots.
Shoot a target to gain extra shots.
Shoot a toy to gain extra time.


<html>
<head>
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">

	<title>FairGround Shoot</title>
	<style>
Body
{
	background-color: #181818;
	color: #ffffff;
	margin: 0px;
}

Canvas
{
	position:fixed;
}

#counter
{
	position:absolute;
	bottom:0;
	right:0;
	color:#ffffff;
/*	display:none;*/

}
	</style>
</head>
<body>
	<canvas id="myCanvas">Sorry... your browser does not support the canvas element.</canvas>
	<br/>
	<img id="screengrab" />
	<p id="counter">counter</p>
</body>
<script>

// Global variables
// used for calculating and showing the frames per second
var dwFrames=0;
var dwCurrentTime=0;
var dwLastUpdateTime=0;
var dwElapsedTime=0;
var fpsText;
// The game engine needs to persist
var GE;

var currentStage;
init = function()
{
	var canvas = document.getElementById('myCanvas');
	if (canvas.getContext)
	{
		// got to have the game engine
		GE = GameEngine16Colour(canvas,update,draw);
		GE.PortraitMode();
		currentStage = StageGame().Init();
//		currentStage = StageGame().MainMenu();

		var bm = Bitmap(4,16);
		bm.DrawRect(0,0,4,16,13);
		var sp = Sprite(GE.CanvasWidth/2-2,GE.CanvasHeight-16,bm);
		GE.SpriteAdd("player",sp,0);

		// when the window resizes we want to resize the canvas
		window.onresize = function() { doResize(); };
		doResize();
	}
}

// This gets called every time the engine redraws the canvas
// For slow machines this may be less that the actual fps
draw = function()
{
	GE.SpriteGet("player").pos.x = GE.mousePos.x - 1;

	currentStage.draw();

	// calculate and show the fps
	dwFrames++;
	dwCurrentTime = (new Date).getTime();
	dwElapsedTime = dwCurrentTime - dwLastUpdateTime;
	if(dwElapsedTime >= 1000)
	{
		fpsText = "FPS " + dwFrames;
		dwLastUpdateTime = dwCurrentTime;
		dwFrames = 0;
	}
	var l = document.getElementById('counter');
	l.textContent = fpsText;
}

// This gets called every game update frame
update = function()
{
	currentStage.update();
	if ( currentStage.finished )
		currentStage = currentStage.nextStage();
}

// This just makes sure the canvas is as big as possible
// given the window size.
function doResize()
{
	var canvas = document.getElementById('myCanvas');
	var screenHeight = window.innerHeight;
	var screenWidth = window.innerWidth;
	if ( GE.CanvasWidth > GE.CanvasHeight)
	{
		if (screenWidth*3/4 < screenHeight)
		{
			screenHeight = Math.floor(screenWidth*3/4);
		}
		else
		{
			screenWidth = Math.floor(screenHeight*4/3);
		}
	}
	else
	{
		if (screenHeight*3/4 < screenWidth)
		{
			screenWidth = Math.floor(screenHeight*3/4);
		}
		else
		{
			screenHeight = Math.floor(screenWidth*4/3);
		}
	}
	canvas.style.height = screenHeight+"px";
	canvas.style.width = screenWidth+"px";
	canvas.style.marginLeft = (window.innerWidth-screenWidth)/2;
	canvas.style.marginTop = Math.floor((window.innerHeight-screenHeight)/2)+1;

	// fudge to remove adddress bar on mobile browsers
	window.scrollTo(0, 0);
	window.scrollTo(0, 1);
}

var soundBounce;

StageGame = function ()
{
	var obj = {};
	obj.finished = false;
	var data;

	var firePressed = false;
	var spacekeyDown = false;

	function FirePressed ()
	{
		if (GE.mouseClicked )
			return true;

		if ( GE.GetKeyState(GE.KEY_SPACE))
		{
			if ( !spacekeyDown )
			{
				spacekeyDown = true;
				return true;
			}
		}
		else
		{
			spacekeyDown = false;
		}
		return false;
	}

	obj.Data = function()
	{
		var obj = {};
		obj.score = 0;
		obj.hiscore = 0;
		obj.useKeyboard = false;
		obj.lastTarget = 9;
		obj.targetDirection = -1;

		obj.lastTarget2 = 9;
		obj.targetDirection2 = -1;

		obj.Timer = 0;
		obj.nextShotNumber=0;
		obj.Shots=10;

		return obj;
	}

	obj.Init = function (dataIn)
	{
		var obj = {};
		var data;

		if ( dataIn == undefined )
			data = new Array();
		else
			data = dataIn;

		data["game"] = StageGame().Data();

		obj.finished = false;

		obj.init = function()
		{
			data["game"].score = 0;
			data["game"].hiscore = 0;

			data["game"].lastTarget = 9;
			data["game"].targetDirection = -1;

			data["game"].lastTarget2 = 9;
			data["game"].targetDirection2 = -1;

			data["game"].Timer = 0;
			data["game"].nextShotNumber=0;
			data["game"].Shots=10;
		}

		obj.update = function()
		{
			obj.finished = true;
		}
		obj.draw = function()
		{
		}

		obj.nextStage = function()
		{
			return StageSplash(data);
		}

		obj.init();

		return obj;
	}

	function StageSplash (dataIn)
	{
		var obj = {};
		obj.finished = false;
		var currentStage;
		var data = dataIn;

		obj.init=function()
		{
			data = dataIn;
			if ( dataIn == undefined )
				data = new Array();
			currentStage = Static(data);
			currentStage.init();
		}

		obj.draw = function()
		{
			currentStage.draw();
		}

		obj.update = function()
		{
			currentStage.update();
			if ( currentStage.finished )
			{
				if ( currentStage.nextStage() == null )
					obj.finished = true;
				else
					currentStage = currentStage.nextStage();
			}
		}

		obj.nextStage = function()
		{
			return PlayGame(data);
		}

		// Splash Stages

		function Static(data)
		{
			var obj = {};

			var startTime;
			obj.finished = false;
			var soundStatic = null;
			var soundBeep = null;
			var started = false;

			obj.init=function()
			{
				startTime = new Date().getTime();
				soundStatic = new customSound(8000);
				soundStatic.add(2.5, 4000, 4000, 80, 80, 1, 1 );
				soundStatic.createSound().play();

				soundBeep = new customSound(8000);
				soundBeep.add(.3, 550,550,127,127,0,0);
				started = false;
			}

			obj.update=function()
			{
				if ( new Date().getTime() - startTime > 2750 )
				{
					if ( started == false )
					{
						soundBeep.createSound().play();
						started = true;
					}
					GE.DrawRect(0,0,GE.CanvasWidth, GE.CanvasHeight,15);
				}
				else
				{
					for ( var y = 0; y < GE.CanvasHeight; y++)
					{
						for ( var x = 0; x < GE.CanvasWidth; x++ )
						{
							GE.DrawPixel(x,y,Math.floor(Math.random()*16));
						}
					}
				}
				if ( new Date().getTime() - startTime > 3000 )
					obj.finished = true;
			}

			obj.draw=function()
			{
			}

			obj.nextStage = function()
			{
				return LoadScreen(data);
			}

			obj.init();

			return obj;
		}

		function LoadScreen(data)
		{
			var obj = {};

			obj.finished = false;
			var currentStage;
			var soundClick;

			var loadData = [
				["QB 8bit Game Engine V1.0",0,0,false],
				["",0,0],
				["Ready",0,0],
				["",0,0],
				["load \"FairGrndShoot\"",30,6],
				["Ready",100,0],
				["",0,0],
				["run",30,6],
				["",50,0]];
			var MSG_TEXT=0;
			var MSG_LINE_PAUSE=1;
			var MSG_CHAR_PAUSE=2;

			var msgNum = 0;
			var msgPos = 0;
			var keyboardtimer = 0;
			var xpos = 0;
			var ypos = 0;
			var cursorstate = 0;

			obj.init=function()
			{
				GE.DrawRect ( 0,0,GE.CanvasWidth, GE.CanvasHeight, 0);
				startTime = new Date().getTime();
				soundClick = new customSound(8000);
				soundClick.add(.005, 1000,2000,127,127,0,0);
			}

			obj.update=function()
			{
				keyboardtimer--;
				if ( keyboardtimer <= 0 )
				{
					GE.DrawRect(xpos,ypos,8,8,0);
					if ( msgPos < loadData[msgNum][MSG_TEXT].length )
					{
						if ( loadData[msgNum][MSG_CHAR_PAUSE] > 0 )
							soundClick.createSound().play();
						GE.WriteString(loadData[msgNum][MSG_TEXT][msgPos],xpos,ypos,15);
						msgPos+=1;
						xpos+=8;
						keyboardtimer = loadData[msgNum][MSG_CHAR_PAUSE]+Math.floor(Math.random()*(loadData[msgNum][MSG_CHAR_PAUSE]));
					}
					else
					{
						msgNum++;
						msgPos=0;
						xpos=0;
						ypos+=8;
						if ( msgNum >= loadData.length )
						{
							obj.finished = true;
							return;
						}
						if ( loadData[msgNum][MSG_CHAR_PAUSE] != 0 )
						{
							GE.WriteString(">",xpos,ypos,15);
							xpos+=8;
						}
						keyboardtimer = loadData[msgNum][MSG_LINE_PAUSE];
					}
				}
				if ( loadData[msgNum][MSG_CHAR_PAUSE] != 0 )
					cursorstate = (cursorstate + 1) % 2;
				else
					cursorSate = 0;
			}

			obj.draw=function()
			{
				GE.DrawRect(xpos,ypos,8,8,cursorstate * 15);
			}

			obj.nextStage = function()
			{
				return Logo(data);
			}

			obj.init();

			return obj;
		}

		function Logo (data)
		{
			var obj = {};

			var startTime;
			obj.finished = false;
			var currentStage;

			obj.init=function()
			{
				startTime = new Date().getTime();
				GE.DrawRect(0,0,GE.CanvasWidth, GE.CanvasHeight,0);
				GE.WriteStringCentered("QuietBloke Productions",GE.CanvasHeight/2-32-8,15,false,true);
				GE.WriteStringCentered("Presents",GE.CanvasHeight/2,15);
				GE.WriteStringCentered("Fairground Shoot",GE.CanvasHeight/2+32,15,false,true);
			}

			obj.update=function()
			{
				if ( new Date().getTime() - startTime > 3000 )
					obj.finished = true;
			}

			obj.draw=function()
			{
			}

			obj.nextStage = function()
			{
				return null;
			}

			obj.init();

			return obj;
		}

		obj.init();

		return obj;
	}

	function PlayGame (data)
	{
		var obj = {};
		obj.finished = false;
		var currentStage;

		var LAYER_SHOT = 3
		var LAYER_TARGET1 = 4;
		var LAYER_TARGET2 = 5;

		var soundShoot;

		obj.init=function()
		{
			if ( data == undefined )
				data = new Array();
			currentStage = InitGame(data);

			soundStatic = new customSound(8000);
			soundStatic.add(2.5, 4000, 2000, 120, 80, 1, 1 );
//			soundStatic.createSound().play();

		}

		obj.draw = function()
		{
			currentStage.draw();
		}

		obj.update = function()
		{
			currentStage.update();
			if ( currentStage.finished )
			{
				if ( currentStage.nextStage() == null )
					obj.finished = true;
				else
					currentStage = currentStage.nextStage();
			}
		}

		obj.nextStage = function()
		{
			return InitGame(data);
		}

		function CreateTargetSet()
		{
			var targetCostumes = CreateTargetCostumes();
			GE.DeleteSpritesInLayer(LAYER_TARGET1);
			data["game"].targetDirection = Math.random()*2+1.5;
			if ( Math.random() < .5 )
				data["game"].targetDirection *= -1;

			if (data["game"].targetDirection < 0 )
				data["game"].targetDirection-=1;
			if (data["game"].targetDirection >= 0 )
				data["game"].targetDirection+=1;

			var offset = 0;

			if ( data["game"].targetDirection < 0 )
			{
				for ( var t = 0; t < 10; t++ )
				{
					var gap = Math.floor(Math.random()*3)+1;
					offset += gap*32;
					var targetType = Math.floor(Math.random()*3);
					var sp = Sprite(GE.CanvasWidth+offset, 16+30, targetCostumes[targetType]);
					sp.vel.x = data["game"].targetDirection;
					sp.SetAnimatorLoop();
					sp.costumeAnimator.Stop();
					sp.SetAnimatorFrame(0);
					if (targetType == 0 )
						GE.SpriteAdd("target1."+t,sp,LAYER_TARGET1);
					else
						GE.SpriteAdd("toy1."+t,sp,LAYER_TARGET1);
				}
			}
			else
			{
				for ( var t = 0; t < 10; t++ )
				{
					var gap = Math.floor(Math.random()*3)+1;
					offset += gap*32;
					var targetType = Math.floor(Math.random()*3);
					var sp = Sprite(-offset, 16+30, targetCostumes[targetType]);
					sp.vel.x = data["game"].targetDirection;
					sp.SetAnimatorLoop();
					sp.costumeAnimator.Stop();
					sp.SetAnimatorFrame(0);
					if (targetType == 0 )
						GE.SpriteAdd("target1."+t,sp,LAYER_TARGET1);
					else
						GE.SpriteAdd("toy1."+t,sp,LAYER_TARGET1);
				}
			}
			data["game"].lastTarget = 9;
		}

		function CheckTargetSet()
		{
			var sp = GE.SpriteGet("target1." + data["game"].lastTarget);
			if (sp == null )
				sp = GE.SpriteGet("toy1." + data["game"].lastTarget);
			if ( data["game"].targetDirection < 0 )
			{
				if ( sp.pos.x + sp.bitmap.width < 0 )
					CreateTargetSet();
			}
			else
			{
				if ( sp.pos.x > GE.CanvasWidth )
					CreateTargetSet();
			}
		}

		function CreateTargetSet2()
		{
			targetCostumes = CreateTargetCostumes();
			GE.DeleteSpritesInLayer(LAYER_TARGET2);

			data["game"].targetDirection2 = Math.random()*2+1.5;
			if ( Math.random() < .5 )
				data["game"].targetDirection2 *= -1;

			data["game"].targetDirection2 = Math.random()*2-1;
			if (data["game"].targetDirection2 < 0 )
				data["game"].targetDirection2-=1;
			if (data["game"].targetDirection2 >= 0 )
				data["game"].targetDirection2+=1;

			var offset = 0;

			if ( data["game"].targetDirection2 < 0 )
			{
				for ( var t = 0; t < 10; t++ )
				{
					var gap = Math.floor(Math.random()*3)+1;
					offset += gap*32;
					var targetType = Math.floor(Math.random()*3);
					var sp = Sprite(GE.CanvasWidth+offset, 48+30, targetCostumes[targetType]);
					sp.vel.x = data["game"].targetDirection2;
					sp.SetAnimatorLoop();
					sp.costumeAnimator.Stop();
					sp.SetAnimatorFrame(0);
					if (targetType == 0 )
						GE.SpriteAdd("target2."+t,sp,LAYER_TARGET2);
					else
						GE.SpriteAdd("toy2."+t,sp,LAYER_TARGET2);
				}
			}
			else
			{
				for ( var t = 0; t < 10; t++ )
				{
					var gap = Math.floor(Math.random()*3)+1;
					offset += gap*32;
					var targetType = Math.floor(Math.random()*3);
					var sp = Sprite(-offset, 48+30, targetCostumes[targetType]);
					sp.vel.x = data["game"].targetDirection2;
					sp.SetAnimatorLoop();
					sp.costumeAnimator.Stop();
					sp.SetAnimatorFrame(0);
					if (targetType == 0 )
						GE.SpriteAdd("target2."+t,sp,LAYER_TARGET2);
					else
						GE.SpriteAdd("toy2."+t,sp,LAYER_TARGET2);
				}
			}
			data["game"].lastTarget2 = 9;
		}

		function CheckTargetSet2()
		{
			var sp = GE.SpriteGet("target2." + data["game"].lastTarget2);
			if (sp == null )
				sp = GE.SpriteGet("toy2." + data["game"].lastTarget);
			if ( data["game"].targetDirection2 < 0 )
			{
				if ( sp.pos.x + sp.bitmap.width < 0 )
					CreateTargetSet2();
			}
			else
			{
				if ( sp.pos.x > GE.CanvasWidth )
					CreateTargetSet2();
			}
		}

		function DrawScore ( timer, shots, score,hiscore )
		{
			GE.DrawRect(0,00,3*16,30,0);
			GE.DrawRect(GE.CanvasWidth-3*16,0,3*16,30,0);
			GE.DrawRect(GE.CanvasWidth/2-7*8,0,3*16,30,0);
			GE.DrawRect(GE.CanvasWidth/2+1*8,0,3*16,30,0);

			var colour = 7;
			if (timer < 6 )
				colour = 9;

			var tmpStr = "000" + timer;
			tmpStr = tmpStr.substring(tmpStr.length-3);

			GE.WriteString("Time",0,4,7);
			GE.WriteString(tmpStr,0,16,colour,true,true);

			colour = 7;
			if (shots < 4 )
				colour = 9;

			tmpStr = "000" + shots;
			tmpStr = tmpStr.substring(tmpStr.length-3);

			GE.WriteString("Shots",GE.CanvasWidth-3*16,4,7);
			GE.WriteString(tmpStr,GE.CanvasWidth-3*16,16,colour,true,true);

			tmpStr = "000" + score;
			tmpStr = tmpStr.substring(tmpStr.length-3);

			GE.WriteString("Score",GE.CanvasWidth/2-7*8,4,7);
			GE.WriteString(tmpStr,GE.CanvasWidth/2-7*8,16,7,true,true);

			tmpStr = "000" + hiscore;
			tmpStr = tmpStr.substring(tmpStr.length-3);

			GE.WriteString("HiScore",GE.CanvasWidth/2+1*8,4,7);
			GE.WriteString(tmpStr,GE.CanvasWidth/2+1*8,16,7,true,true);
		}

		function InitGame(data)
		{
			var obj = {}

			obj.finished = false;

			var shotVectors = new Array();
			GE.CollisionRuleAdd(LAYER_SHOT,LAYER_TARGET1);
			GE.CollisionRuleAdd(LAYER_SHOT,LAYER_TARGET2);

			obj.init=function()
			{
				if ( data == undefined )
					data = new Array();

				obj.finished = true;
			}

			obj.update = function()
			{
			}

			obj.draw = function ()
			{
			}

			obj.nextStage = function()
			{
				return MainMenu(data);
			}

			obj.init();

			return obj;
		}

		function MainMenu (data)
		{
			var obj = {};
			obj.finished = false;

			obj.init=function()
			{
				if ( data == undefined )
					data = new Array();

				GE.DrawRect(0,0,GE.CanvasWidth, GE.CanvasHeight,0);
				DrawScore(Math.floor(data["game"].Timer/30),data["game"].Shots, data["game"].score, data["game"].hiscore);
				obj.finished = false;
			}

			obj.update = function()
			{
				if (FirePressed() )
				{
					obj.finished = true;
				}

				if ( obj.finished )
				{
					data["game"].score = 0;
				}
			}

			obj.draw = function ()
			{
				GE.WriteStringCentered("Fire using :       ",80,14);
				GE.WriteStringCentered("  Left Mouse Button",88,14);
				GE.WriteStringCentered("  Touch Screen     ",96,14);
				GE.WriteStringCentered("  Space Key        ",104,14);

				GE.WriteStringCentered("Press Fire to Begin",GE.CanvasHeight/2,10);
			}

			obj.nextStage = function()
			{
				return Play(data);
			}

			obj.init();

			return obj;
		}

		function Play (data)
		{
			var obj = {};
			obj.finished = false;

			obj.init=function()
			{
				GE.DrawRect(0,0,GE.CanvasWidth, GE.CanvasHeight,0);
				data["game"].Timer = 30*30;
				data["game"].nextShotNumber = 0;
				data["game"].Shots = 10;
				CreateTargetSet();
				CreateTargetSet2();
			}

			obj.update = function()
			{
				data["game"].Timer--;
				if ( data["game"].Timer <= 0 )
					obj.finished = true;

				if ( data["game"].Shots == 0 &&  GE.CountSpritesInLayer(LAYER_SHOT) == 0 )
				{
					obj.finished = true;
				}

				CheckTargetSet();
				CheckTargetSet2();

				// check collisions on targets
				for ( var t = 0; t < 20; t++)
				{
					var ts = GE.SpriteGet("target1."+t);
					var isToy = false;
					if ( ts == null )
					{
						ts = GE.SpriteGet("toy1."+t);
						isToy = true;
					}
					if ( ts )
					{
						if ( ts.collided )
						{
							data["game"].score += 1;
							if ( data["game"].score > data["game"].hiscore )
								data["game"].hiscore = data["game"].score
							if ( !isToy )
								data["game"].Shots += 5;
							else
								data["game"].Timer += 5*30;
//							ts.died = true;
							ts.SetAnimatorLoop();
							ts.costumeAnimator.repeat = false;
							ts.costumeAnimator.SetUpdateRate(.5);
							ts.costumeAnimator.Start()
							ts.collided = false;
						}
					}
				}
				// check collisions on targets
				for ( var t = 0; t < 20; t++)
				{
					var ts = GE.SpriteGet("target2."+t);
					var isToy = false;
					if ( ts == null )
					{
						ts = GE.SpriteGet("toy2."+t);
						isToy = true;
					}
					if ( ts )
					{
						if ( ts.collided )
						{
							data["game"].score += 1;
							if ( data["game"].score > data["game"].hiscore )
								data["game"].hiscore = data["game"].score
							if ( !isToy )
								data["game"].Shots += 5;
							else
								data["game"].Timer += 5*30;
							ts.SetAnimatorLoop();
							ts.costumeAnimator.repeat = false;
							ts.costumeAnimator.SetUpdateRate(.5);
							ts.costumeAnimator.Start()
							ts.collided = false;
						}
					}
				}
				// check collisions on shots
				for ( var t = 0; t < 10; t++)
				{
					var ts = GE.SpriteGet("shot"+t);
					if ( ts )
					{
						if ( ts.collided )
						{
							ts.died = true;
						}
					}
				}

				if (FirePressed() && data["game"].Shots > 0 )
				{
					FireShot(GE.mousePos.x, GE.mousePos.y)
				}
				DrawScore(Math.floor(data["game"].Timer/30),data["game"].Shots, data["game"].score, data["game"].hiscore);
			}

			obj.draw = function()
			{
			}

			obj.nextStage = function()
			{
				return GameOver(data);
			}

			obj.init();

			return obj;
		}

		function GameOver (data)
		{
			var obj = {};
			obj.finished = false;

			obj.init=function()
			{
				GE.WriteStringCentered("Game Over",GE.CanvasHeight/2,9,true,true);

				obj.finished = false;
			}

			obj.update = function()
			{
				if ( FirePressed() )
					obj.finished = true;
			}

			obj.draw = function()
			{
			}

			obj.nextStage = function()
			{
				return MainMenu(data);
			}

			obj.init();

			return obj;
		}

		function FireShot(xp, yp )
		{
			var nextShotNumber = data["game"].nextShotNumber;
			if ( GE.SpriteGet("shot"+nextShotNumber) == null)
			{
				var bm = Bitmap(2,16);
				bm.DrawRect(0,0,2,16,12);
				var sp = Sprite(xp,GE.CanvasHeight-16,bm);
				sp.SetLifeSpan(Math.floor((GE.CanvasHeight-46)/5));
				sp.vel.y = -5;
				GE.SpriteAdd("shot"+data["game"].nextShotNumber,sp,LAYER_SHOT);
				nextShotNumber++;
				if ( nextShotNumber > 0 )
					nextShotNumber = 0;
				data["game"].nextShotNumber = nextShotNumber;
				data["game"].Shots--;
			}
		}

		function CreateTargetCostumes()
		{
			var targetCostumes = new Array();
			targetCostumes.push(CreateTarget());
			targetCostumes.push(CreateBear());
			targetCostumes.push(CreateDuck());

			return targetCostumes;

			function CreateTarget()
			{
				var cs=Costume();
				cs.SetItem(0,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,15,15,15,15,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,15,15,15,15,15,15,15,15,-1,-1,-1,-1
				,-1,-1,-1,15,15,15,15,15,15,15,15,15,15,-1,-1,-1
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
				,-1,15,15,15,15,15,15,9,9,15,15,15,15,15,15,-1
				,15,15,15,15,15,15,9,9,9,9,15,15,15,15,15,15
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,15,15,15,15,15,15,9,9,9,9,15,15,15,15,15,15
				,-1,15,15,15,15,15,15,9,9,15,15,15,15,15,15,15
				,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
				,-1,-1,-1,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				,-1,-1,-1,-1,15,15,15,15,15,15,15,15,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,15,15,15,15,-1,-1,-1,-1,-1,-1
				]));
				cs.SetItem(1,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,15,15,15,15,15,15,-1,-1,-1,-1,-1
				,-1,-1,-1,15,15,15,15,15,15,15,15,15,15,-1,-1,-1
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
				,15,15,15,15,15,15,9,9,9,9,15,15,15,15,15,15
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,15,15,15,15,15,15,9,9,9,9,15,15,15,15,15,15
				,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				,-1,-1,-1,15,15,15,15,15,15,15,15,15,15,-1,-1,-1
				,-1,-1,-1,-1,-1,15,15,15,15,15,15,-1,-1,-1,-1,-1
				]));
				cs.SetItem(2,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,15,15,15,15,15,15,15,15,-1,-1,-1,-1
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				,15,15,15,15,15,15,15,9,9,15,15,15,15,15,15,15
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,15,15,15,15,15,15,15,9,9,15,15,15,15,15,15,15
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				,-1,-1,-1,-1,15,15,15,15,15,15,15,15,-1,-1,-1,-1
				]));
				cs.SetItem(3,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
				,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
				]));
				cs.SetItem(4,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				]));

				return cs;
			}

			function CreateBear()
			{
				var cs=Costume();
				cs.SetItem(0,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,13,13,-1,-1,-1,-1,13,13,-1,-1,-1,-1
				,-1,-1,-1,-1,13,13,13,13,13,13,13,13,-1,-1,-1,-1
				,-1,-1,-1,-1,13,13,15,13,13,15,13,13,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,13,11,13,13,11,13,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,13,13,0,0,13,13,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,13,13,13,13,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,13,13,13,13,13,13,13,13,-1,-1,-1,-1
				,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,-1,-1,-1
				,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1
				,-1,-1,13,13,-1,13,13,13,13,13,13,-1,13,13,-1,-1
				,-1,-1,5,5,-1,13,13,13,13,13,13,-1,5,5,-1,-1
				,-1,-1,-1,-1,-1,13,13,13,13,13,13,-1,-1,-1,-1,-1
				,-1,-1,-1,13,5,5,13,13,13,13,5,5,13,-1,-1,-1
				,-1,-1,13,13,5,5,13,13,13,13,5,5,13,13,-1,-1
				,-1,-1,13,13,5,5,13,13,13,13,5,5,13,13,-1,-1
				,-1,-1,13,13,13,-1,13,13,13,13,-1,13,13,13,-1,-1
				]));
				cs.SetItem(1,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,13,13,13,0,0,13,13,13,-1,-1,-1,-1
				,-1,-1,-1,-1,13,13,13,13,13,13,13,13,-1,-1,-1,-1
				,-1,-1,-1,-1,13,13,13,0,0,13,13,13,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,13,13,13,13,13,13,-1,-1,-1,-1,-1
				,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,-1,-1,-1
				,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1
				,-1,-1,5,5,13,13,13,13,13,13,13,13,5,5,-1,-1
				,-1,-1,5,5,5,5,13,13,13,13,5,5,5,5,-1,-1
				,-1,-1,13,13,5,5,13,13,13,13,5,5,13,13,-1,-1
				,-1,-1,13,13,5,5,13,13,13,13,5,5,13,13,-1,-1
				,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,-1,-1,-1
				,-1,-1,-1,-1,13,-1,13,13,13,13,-1,13,-1,-1,-1,-1
				]));
				cs.SetItem(2,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,0,0,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,13,13,13,13,13,13,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,5,5,13,0,0,13,5,5,-1,-1,-1,-1
				,-1,-1,13,5,5,5,13,13,13,13,5,5,5,13,-1,-1
				,-1,-1,13,5,5,5,13,13,13,13,5,5,5,13,-1,-1
				,-1,-1,13,13,5,5,13,13,13,13,5,5,13,13,-1,-1
				,-1,-1,13,13,5,5,13,13,13,13,5,5,13,13,-1,-1
				,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,-1,-1,-1
				,-1,-1,-1,-1,13,-1,13,13,13,13,-1,13,-1,-1,-1,-1
				]));
				cs.SetItem(3,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,0,0,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,5,5,-1,-1,-1,-1,5,5,-1,-1,-1,-1
				,-1,-1,-1,13,5,5,13,13,13,13,5,5,13,-1,-1,-1
				,-1,-1,13,13,5,5,13,13,13,13,5,5,13,13,-1,-1
				,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1
				,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,-1,-1,-1
				]));
				cs.SetItem(4,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				]));

				return cs;
			}

			function CreateDuck()
			{
				var cs=Costume();
				cs.SetItem(0,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,0,0,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
				,12,12,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,12,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,-1,-1,-1
				,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,-1
				,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,-1
				,-1,-1,-1,-1,-1,12,12,12,12,12,12,12,12,12,-1,-1
				]));
				cs.SetItem(1,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,12,12,0,0,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
				,12,12,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,12,12,12,12,12,12,12,-1,-1,-1
				,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12,-1
				,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,-1
				,-1,-1,-1,-1,-1,12,12,12,12,12,12,12,12,-1,-1,-1
				]));
				cs.SetItem(2,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,12,12,12,0,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,-1,-1
				,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,-1,-1,-1,-1,12,12,12,12,12,12,12,12,12,-1,-1
				]));
				cs.SetItem(3,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,12,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,-1,-1
				,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12
				,-1,-1,-1,-1,-1,12,12,12,12,12,12,12,12,12,-1,-1
				]));
				cs.SetItem(4,
				Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
				]));

				return cs;
			}
		}

		function CreateTargetCostume()
		{
			var cs=Costume();
			cs.SetItem(0,
			Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,15,15,15,15,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,15,15,15,15,15,15,15,15,-1,-1,-1,-1
			,-1,-1,-1,15,15,15,15,15,15,15,15,15,15,-1,-1,-1
			,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,-1,-1
			,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
			,-1,15,15,15,15,15,15,9,9,15,15,15,15,15,15,-1
			,15,15,15,15,15,15,9,9,9,9,15,15,15,15,15,15
			,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
			,15,15,15,15,15,9,9,9,9,9,9,15,15,15,15,15
			,15,15,15,15,15,15,9,9,9,9,15,15,15,15,15,15
			,-1,15,15,15,15,15,15,9,9,15,15,15,15,15,15,15
			,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
			,-1,-1,15,15,15,15,15,15,15,15,15,15,15,15,15,-1
			,-1,-1,-1,15,15,15,15,15,15,15,15,15,15,15,-1,-1
			,-1,-1,-1,-1,15,15,15,15,15,15,15,15,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,15,15,15,15,-1,-1,-1,-1,-1,-1
			]));
			cs.SetItem(1,
			Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,13,13,-1,-1,-1,-1,13,13,-1,-1,-1,-1
			,-1,-1,-1,-1,13,13,13,13,13,13,13,13,-1,-1,-1,-1
			,-1,-1,-1,-1,13,13,13,13,13,13,13,13,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,13,13,13,13,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,13,13,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,13,13,13,13,13,13,13,13,-1,-1,-1,-1
			,-1,-1,-1,13,13,13,13,13,13,13,13,13,13,13,-1,-1
			,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1
			,-1,-1,13,13,-1,13,13,13,13,13,13,-1,13,13,-1,-1
			,-1,-1,13,13,-1,13,13,13,13,13,13,-1,13,13,-1,-1
			,-1,-1,-1,-1,-1,13,13,13,13,13,13,-1,-1,-1,-1,-1
			,-1,-1,13,13,-1,13,13,13,13,13,13,-1,13,13,-1,-1
			,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1
			,-1,-1,13,13,13,13,13,13,13,13,13,13,13,13,-1,-1
			,-1,-1,13,13,13,-1,-1,-1,-1,-1,-1,13,13,13,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			]));
			cs.SetItem(2,
			Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,12,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
			,12,12,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,12,12,12,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,12,12,12,12,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,12,12,12,12,12,12,12,-1,-1,-1,-1,-1
			,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,-1,-1
			,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,-1
			,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12
			,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12
			,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12,12
			,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,12
			,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,12,12,-1
			,-1,-1,-1,-1,12,12,12,12,12,12,12,12,12,12,-1,-1
			]));

			cs.SetItem(3,
			Bitmap(16,16).PixelsFromArray([-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
			]));
			return cs;
		}

		obj.init();

		return obj;
	}
	return obj;
}

GameEngine16Colour = function(canvasIn,updateFunction,drawFunction)
{
	"use strict";
	var obj = {};

	if ( typeof(updateFunction) != "function" )
		updateFunction = function(){};

	if ( typeof(drawFunction) != "function" )
		drawFunction = function(){};

	var CANVAS_WIDTH = 320; //320;
	var CANVAS_HEIGHT = 240; // 240;

	var FPS = 30;
	var updateRate = Math.floor(1000 / FPS);

	var canvas = canvasIn;

	var colours = new Array();

	var charSet = {};

	obj.mousePos = new Vector();
	obj.mouseClicked = false;
	obj.mouseTouchFire = false;
	obj.mouseUnclicked = false;
	obj.mouseDown = false;

	obj.CanvasWidth = CANVAS_WIDTH;
	obj.CanvasHeight = CANVAS_HEIGHT;

	canvas.width = CANVAS_WIDTH;
	canvas.height = CANVAS_HEIGHT;

	obj.sprites = new Array(); 	// key = spritename, value = layer
	obj.layers = new Array();	// key = spritename, value = sprite

	obj.collisionRules = new Array();

	var ctx = null;
	if(canvas.getContext )
	{
		ctx = canvas.getContext('2d');
	}

	if (ctx === null )
	{
		return null;
	}

	var screenImageData = ctx.getImageData(0,0,CANVAS_WIDTH,CANVAS_HEIGHT);

	for ( var pixel = 0; pixel < CANVAS_WIDTH*CANVAS_HEIGHT; pixel+=1)
	{
		screenImageData.data[pixel*4+3] = 255;
	}

	var screenBitmap = Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);
	screenBitmap.DrawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT,0);

	var tempScreenBitmap= Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);
	var prevScreenBitmap= Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);

	function InitColours()
	{
		colours[0] = Colour(0,0,0);
		colours[1] = Colour(128,0,0);
		colours[2] = Colour(0,128,0);
		colours[3] = Colour(0,0,128);
		colours[4] = Colour(128,128,0);
		colours[5] = Colour(128,0,128);
		colours[6] = Colour(0,128,128);
		colours[7] = Colour(128,128,128);

		colours[8] = Colour(64,64,64);
		colours[9] = Colour(255,0,0);
		colours[10] = Colour(0,255,0);
		colours[11] = Colour(0,0,255);
		colours[12] = Colour(255,255,0);
		colours[13] = Colour(255,0,255);
		colours[14] = Colour(0,255,255);
		colours[15] = Colour(255,255,255);

		// experimental colours
		// mid black and dark primary
		colours[16] = TertiaryMix(colours[7],colours[7],32);
		colours[17] = TertiaryMix(colours[1],colours[1],64);
		colours[18] = TertiaryMix(colours[2],colours[2],64);
		colours[19] = TertiaryMix(colours[3],colours[3],64);
		// secondary
		colours[20] = TertiaryMix(colours[4],colours[4],64);
		colours[21] = TertiaryMix(colours[5],colours[5],64);
		colours[22] = TertiaryMix(colours[6],colours[6],64);

		// tertiary colours
		colours[23] = TertiaryMix(colours[1],colours[4],128);
		colours[24] = TertiaryMix(colours[1],colours[5],128);
//		colours[18] = TertiaryMix(colours[1],colours[6],128);

		colours[25] = TertiaryMix(colours[2],colours[4],128);
//		colours[20] = TertiaryMix(colours[2],colours[5],128);
		colours[26] = TertiaryMix(colours[2],colours[6],128);

//		colours[22] = TertiaryMix(colours[3],colours[4],128);
		colours[27] = TertiaryMix(colours[3],colours[5],128);
		colours[28] = TertiaryMix(colours[3],colours[6],128);

		colours[29] = TertiaryMix(colours[4],colours[5],128);
		colours[30] = TertiaryMix(colours[4],colours[6],128);

//		colours[28] = TertiaryMix(colours[5],colours[4],128);
//		colours[29] = TertiaryMix(colours[5],colours[6],128);

//		colours[30] = TertiaryMix(colours[6],colours[4],128);
		colours[31] = TertiaryMix(colours[6],colours[5],128);

		// bright
		colours[32] = TertiaryMix(colours[15],colours[15],192);
		colours[33] = TertiaryMix(colours[9],colours[9],192);
		colours[34] = TertiaryMix(colours[10],colours[10],192);
		colours[35] = TertiaryMix(colours[11],colours[11],192);
		// secondary
		colours[36] = TertiaryMix(colours[12],colours[12],192);
		colours[37] = TertiaryMix(colours[13],colours[13],192);
		colours[38] = TertiaryMix(colours[14],colours[14],192);

//		colours[31] = TertiaryMix(colours[7],colours[7],96);

		colours[39] = TertiaryMix(colours[9],colours[12],255);
		colours[40] = TertiaryMix(colours[9],colours[13],255);
//		colours[34] = TertiaryMix(colours[9],colours[14],255);

		colours[41] = TertiaryMix(colours[10],colours[12],255);
//		colours[36] = TertiaryMix(colours[10],colours[13],255);
		colours[42] = TertiaryMix(colours[10],colours[14],255);

//		colours[38] = TertiaryMix(colours[11],colours[12],255);
		colours[43] = TertiaryMix(colours[11],colours[13],255);
		colours[44] = TertiaryMix(colours[11],colours[14],255);

		colours[45] = TertiaryMix(colours[12],colours[13],255);
		colours[46] = TertiaryMix(colours[12],colours[14],255);

//		colours[44] = TertiaryMix(colours[13],colours[12],255);
//		colours[45] = TertiaryMix(colours[13],colours[14],255);

//		colours[46] = TertiaryMix(colours[14],colours[12],255);
		colours[47] = TertiaryMix(colours[14],colours[13],255);

//		colours[47] = TertiaryMix(colours[15],colours[15],192);

		function TertiaryMix (col1,col2,maxValue)
		{
			var red = col1.red + col2.red;
			var green = col1.green + col2.green;
			var blue = col1.blue + col2.blue;

			var br = red;
			if(green > br) br = green;
			if(blue > br) br = blue;

			red = Math.floor(red / br * maxValue);
			green = Math.floor(green / br * maxValue);
			blue = Math.floor(blue / br * maxValue);

			return Colour(red,green,blue);
		}
	}	

	InitColours();

	function InitCharSet()
	{
		charSet = CharSet(8,8);

		charSet.SetChar("!",[
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"        ",
			"   *    ",
			"        "]);

		charSet.SetChar("?",[
			" *****  ",
			"*     * ",
			"    **  ",
			"   *    ",
			"   *    ",
			"        ",
			"   *    ",
			"        "]);

		charSet.SetChar("\\",[
			"*       ",
			" *      ",
			"  *     ",
			"   *    ",
			"    *   ",
			"     *  ",
			"      * ",
			"        "]);

		charSet.SetChar("\"",[
			"  * *   ",
			"  * *   ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        "]);

		charSet.SetChar("#",[
			" *   *  ",
			"******* ",
			" *   *  ",
			" *   *  ",
			" *   *  ",
			"******* ",
			" *   *  ",
			"        "]);

		charSet.SetChar("$",[
			"   *    ",
			" *****  ",
			"*  *    ",
			" *****  ",
			"   *  * ",
			" *****  ",
			"   *    ",
			"        "]);

		charSet.SetChar("%",[
			" *    * ",
			"* *  *  ",
			" *  *   ",
			"   *    ",
			"  *  *  ",
			" *  * * ",
			"*    *  ",
			"        "]);

		charSet.SetChar("&",[
			"  ***   ",
			" *   *  ",
			"  * *   ",
			"  **    ",
			" *  *   ",
			"*    *  ",
			" **** * ",
			"        "]);

		charSet.SetChar("'",[
			"   *    ",
			"   *    ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        "]);

		charSet.SetChar("(",[
			"   *    ",
			"  *     ",
			" *      ",
			" *      ",
			" *      ",
			"  *     ",
			"   *    ",
			"        "]);

		charSet.SetChar(")",[
			"   *    ",
			"    *   ",
			"     *  ",
			"     *  ",
			"     *  ",
			"    *   ",
			"   *    ",
			"        "]);

		charSet.SetChar("*",[
			"        ",
			"*   *   ",
			" * *    ",
			"  *     ",
			" * *    ",
			"*   *   ",
			"        ",
			"        "]);

		charSet.SetChar("+",[
			"        ",
			"   *    ",
			"   *    ",
			" *****  ",
			"   *    ",
			"   *    ",
			"        ",
			"        "]);

		charSet.SetChar(",",[
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"   *    ",
			"   *    ",
			"  *     "]);

		charSet.SetChar("-",[
			"        ",
			"        ",
			"        ",
			" *****  ",
			"        ",
			"        ",
			"        ",
			"        "]);

		charSet.SetChar(".",[
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"   *    ",
			"        "]);

		charSet.SetChar("/",[
			"      * ",
			"     *  ",
			"    *   ",
			"   *    ",
			"  *     ",
			" *      ",
			"*       ",
			"        "]);

		charSet.SetChar("0",[
			" *****  ",
			"*     * ",
			"*   * * ",
			"*  *  *",
			"* *   * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("1",[
			"   *    ",
			"  **    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"  ***   ",
			"        "]);

		charSet.SetChar("2",[
			" *****  ",
			"*     * ",
			"     *  ",
			"    *   ",
			"  **    ",
			" *      ",
			"******* ",
			"        "]);

		charSet.SetChar("3",[
			" *****  ",
			"*     * ",
			"      * ",
			"  ****  ",
			"      * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("4",[
			" *      ",
			" *      ",
			" *      ",
			" *  *   ",
			" ****** ",
			"    *   ",
			"    *   ",
			"        "]);

		charSet.SetChar("5",[
			"******* ",
			"*       ",
			"*       ",
			"******  ",
			"      * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("6",[
			" *****  ",
			"*     * ",
			"*       ",
			"******  ",
			"*     * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("7",[
			"******* ",
			"      * ",
			"     *  ",
			"     *  ",
			"    *   ",
			"    *   ",
			"    *   ",
			"        "]);

		charSet.SetChar("8",[
			" *****  ",
			"*     * ",
			"*     * ",
			" *****  ",
			"*     * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("9",[
			" *****  ",
			"*     * ",
			"*     * ",
			" ****** ",
			"      * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar(":",[
			"        ",
			"        ",
			"   *    ",
			"        ",
			"   *    ",
			"        ",
			"        ",
			"        "]);

		charSet.SetChar(";",[
			"        ",
			"        ",
			"   *    ",
			"        ",
			"   *    ",
			"  *     ",
			"        ",
			"        "]);

		charSet.SetChar("<",[
			"        ",
			"    **  ",
			"  **    ",
			" *      ",
			"  **    ",
			"    **  ",
			"        ",
			"        "]);

		charSet.SetChar("=",[
			"        ",
			"        ",
			" *****  ",
			"        ",
			" *****  ",
			"        ",
			"        ",
			"        "]);

		charSet.SetChar(">",[
			"        ",
			" **     ",
			"   **   ",
			"     *  ",
			"   **   ",
			" **     ",
			"        ",
			"        "]);

		charSet.SetChar("A",[
			" *****  ",
			"*     * ",
			"*     * ",
			"******* ",
			"*     * ",
			"*     * ",
			"*     * ",
			"        "]);

		charSet.SetChar("B",[
			"******  ",
			"*     * ",
			"*     * ",
			"******* ",
			"*     * ",
			"*     * ",
			"******  ",
			"        "]);

		charSet.SetChar("C",[
			" *****  ",
			"*     * ",
			"*       ",
			"*       ",
			"*       ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("D",[
			"******  ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"******  ",
			"        "]);

		charSet.SetChar("E",[
			"******* ",
			"*       ",
			"*       ",
			"*****   ",
			"*       ",
			"*       ",
			"******* ",
			"        "]);

		charSet.SetChar("F",[
			"******* ",
			"*       ",
			"*       ",
			"*****   ",
			"*       ",
			"*       ",
			"*       ",
			"        "]);

		charSet.SetChar("G",[
			" *****  ",
			"*     * ",
			"*       ",
			"*  **** ",
			"*     * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("H",[
			"*     * ",
			"*     * ",
			"*     * ",
			"******* ",
			"*     * ",
			"*     * ",
			"*     * ",
			"        "]);

		charSet.SetChar("I",[
			"  ***   ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"  ***   ",
			"        "]);

		charSet.SetChar("J",[
			"******* ",
			"      * ",
			"      * ",
			"      * ",
			"*     * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("K",[
			"*     * ",
			"*   **  ",
			"* **    ",
			"**      ",
			"* **    ",
			"*   **  ",
			"*     * ",
			"        "]);

		charSet.SetChar("L",[
			"*       ",
			"*       ",
			"*       ",
			"*       ",
			"*       ",
			"*       ",
			"******* ",
			"        "]);

		charSet.SetChar("M",[
			"*     * ",
			"**   ** ",
			"* * * * ",
			"*  *  * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"        "]);

		charSet.SetChar("N",[
			"*     * ",
			"**    * ",
			"* *   * ",
			"*  *  * ",
			"*   * * ",
			"*    ** ",
			"*     * ",
			"        "]);

		charSet.SetChar("O",[
			" *****  ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("P",[
			" *****  ",
			"*     * ",
			"*     * ",
			"******  ",
			"*       ",
			"*       ",
			"*       ",
			"        "]);

		charSet.SetChar("Q",[
			" *****  ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*   * * ",
			"**   *  ",
			" **** * ",
			"        "]);

		charSet.SetChar("R",[
			"******  ",
			"*     * ",
			"*     * ",
			"******  ",
			"*     * ",
			"*     * ",
			"*     * ",
			"        "]);

		charSet.SetChar("S",[
			" *****  ",
			"*     * ",
			"*       ",
			" *****  ",
			"      * ",
			"*     * ",
			" *****  ",
			"        "]);

		charSet.SetChar("T",[
			"******* ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"        "]);

		charSet.SetChar("U",[
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			" ****** "]);

		charSet.SetChar("V",[
			"*     * ",
			"*     * ",
			" *   *  ",
			" *   *  ",
			"  * *   ",
			"  * *   ",
			"   *    ",
			"        "]);

		charSet.SetChar("W",[
			"*     * ",
			"*     * ",
			"*     * ",
			"*     * ",
			"*  *  * ",
			"* * * * ",
			"**   ** ",
			"        "]);

		charSet.SetChar("X",[
			"*     * ",
			" *   *  ",
			"  * *   ",
			"   *    ",
			"  * *   ",
			" *   *  ",
			"*     * ",
			"        "]);

		charSet.SetChar("Y",[
			"*     * ",
			" *   *  ",
			"  * *   ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"        "]);

		charSet.SetChar("Z",[
			"******* ",
			"     *  ",
			"    *   ",
			"   *    ",
			"  *     ",
			" *      ",
			"******* ",
			"        "]);

	// [\]^_`abcdefg.....z{|}~
		charSet.SetChar("[",[
			"  ***   ",
			"  *     ",
			"  *     ",
			"  *     ",
			"  *     ",
			"  *     ",
			"  ***   ",
			"        "]);

		charSet.SetChar("\\",[
			"*       ",
			" *      ",
			"  *     ",
			"   *    ",
			"    *   ",
			"     *  ",
			"      * ",
			"        "]);

		charSet.SetChar("]",[
			"  ***   ",
			"    *   ",
			"    *   ",
			"    *   ",
			"    *   ",
			"    *   ",
			"  ***   ",
			"        "]);

		charSet.SetChar("^",[
			"   *    ",
			"  * *   ",
			" *   *  ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        "]);

		charSet.SetChar("_",[
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"********"]);

		charSet.SetChar("`",[
			"  *     ",
			"   *    ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        ",
			"        "]);

		charSet.SetChar("a",[
			"        ",
			"        ",
			" ****   ",
			"     *  ",
			" *****  ",
			"*    *  ",
			" **** * ",
			"        "]);

		charSet.SetChar("b",[
			"*       ",
			"*       ",
			"*****   ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			"*****   ",
			"        "]);

		charSet.SetChar("c",[
			"        ",
			"        ",
			" ****   ",
			"*       ",
			"*       ",
			"*       ",
			" ****   ",
			"        "]);

		charSet.SetChar("d",[
			"     *  ",
			"     *  ",
			" *****  ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			" *****  ",
			"        "]);

		charSet.SetChar("e",[
			"        ",
			"        ",
			" ****   ",
			"*    *  ",
			"******  ",
			"*       ",
			" ****   ",
			"        "]);

		charSet.SetChar("f",[
			"  ***   ",
			" *      ",
			" *      ",
			"****    ",
			" *      ",
			" *      ",
			" *      ",
			"        "]);

		charSet.SetChar("g",[
			"        ",
			"        ",
			" ****   ",
			"*    *  ",
			"*    *  ",
			" *****  ",
			"     *  ",
			" ****   "]);

		charSet.SetChar("h",[
			"*       ",
			"*       ",
			"*       ",
			"*****   ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			"        "]);

		charSet.SetChar("i",[
			"        ",
			"  *     ",
			"        ",
			"  *     ",
			"  *     ",
			"  *     ",
			"  *     ",
			"        "]);

		charSet.SetChar("j",[
			"        ",
			"     *  ",
			"        ",
			"    **  ",
			"     *  ",
			"     *  ",
			"     *  ",
			" ****   "]);

		charSet.SetChar("k",[
			"*       ",
			"*       ",
			"*  *    ",
			"* *     ",
			"***     ",
			"*  *    ",
			"*   *   ",
			"        "]);

		charSet.SetChar("l",[
			"*       ",
			"*       ",
			"*       ",
			"*       ",
			"*       ",
			"*       ",
			" ***    ",
			"        "]);

		charSet.SetChar("m",[
			"        ",
			"        ",
			"*** **  ",
			"*  *  * ",
			"*  *  * ",
			"*  *  * ",
			"*  *  * ",
			"        "]);

		charSet.SetChar("n",[
			"        ",
			"        ",
			"*****   ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			"        "]);

		charSet.SetChar("o",[
			"        ",
			"        ",
			" ****   ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			" ****   ",
			"        "]);

		charSet.SetChar("p",[
			"        ",
			"        ",
			"*****   ",
			"*    *  ",
			"*    *  ",
			"*****   ",
			"*       ",
			"*       "]);

		charSet.SetChar("q",[
			"        ",
			"        ",
			" *****  ",
			"*    *  ",
			"*    *  ",
			" *****  ",
			"     *  ",
			"     *  "]);

		charSet.SetChar("r",[
			"        ",
			"        ",
			" ****   ",
			"*       ",
			"*       ",
			"*       ",
			"*       ",
			"        "]);

		charSet.SetChar("s",[
			"        ",
			"        ",
			" ****   ",
			"*       ",
			" ****   ",
			"*    *  ",
			" ****   ",
			"        "]);

		charSet.SetChar("t",[
			"        ",
			" *      ",
			"***     ",
			" *      ",
			" *      ",
			" *      ",
			"  ***   ",
			"        "]);

		charSet.SetChar("u",[
			"        ",
			"        ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			" *****  ",
			"        "]);

		charSet.SetChar("v",[
			"        ",
			"        ",
			"*    *  ",
			"*    *  ",
			" *  *   ",
			" *  *   ",
			"  **    ",
			"        "]);

		charSet.SetChar("w",[
			"        ",
			"        ",
			"*  *  * ",
			"*  *  * ",
			"*  *  * ",
			"*  *  * ",
			" ** **  ",
			"        "]);

		charSet.SetChar("x",[
			"        ",
			"        ",
			"*    *  ",
			" *  *   ",
			"  **    ",
			" *  *   ",
			"*    *  ",
			"        "]);

		charSet.SetChar("y",[
			"        ",
			"        ",
			"*    *  ",
			"*    *  ",
			"*    *  ",
			" *****  ",
			"     *  ",
			" ****   "]);

		charSet.SetChar("z",[
			"        ",
			"        ",
			"*****   ",
			"   *    ",
			"  *     ",
			" *      ",
			"*****   ",
			"        "]);

		charSet.SetChar("{",[
			"    *   ",
			"   *    ",
			"   *    ",
			"  *     ",
			"   *    ",
			"   *    ",
			"    *   ",
			"        "]);

		charSet.SetChar("|",[
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"   *    ",
			"        "]);

		charSet.SetChar("}",[
			"  *     ",
			"   *    ",
			"   *    ",
			"    *   ",
			"   *    ",
			"   *    ",
			"  *     ",
			"        "]);

		charSet.SetChar("~",[
			"        ",
			"        ",
			"      * ",
			" *****  ",
			"*       ",
			"        ",
			"        ",
			"        "]);
	}

	obj.CharSet = function()
	{
		return charSet;
	}

	InitCharSet();

	var dwCurrentTime=0;
	var dwLastUpdateTime=(new Date).getTime();
	var dwTimeCarriedOver = 0;
	var dwElapsedTime=0;

	obj.Main = function()
	{
		dwCurrentTime = (new Date).getTime();
		dwElapsedTime = dwCurrentTime - dwLastUpdateTime + dwTimeCarriedOver;
		if(dwElapsedTime >= updateRate)
		{
			drawFunction();
			obj.Draw();

			var frames = Math.floor(dwElapsedTime / updateRate );
			dwTimeCarriedOver = dwElapsedTime % updateRate;
			dwLastUpdateTime = dwCurrentTime;
			for ( var f = 0; f < frames; f++)
			{
				updateFunction();
				obj.Update();
				obj.mouseClicked = false;
				obj.mouseUnclicked = false;
				obj.mouseTouchFire = false;
				obj.CheckCollisions();
			}
		}
	}

	var timer = Timer(FPS, obj.Main);

	obj.Stop = function()
	{
		timer.Stop();
	}

	obj.writeToCanvas = function(bitmap)
	{
		var sourceArray = bitmap.GetPixelArray();
		var prevArray = prevScreenBitmap.GetPixelArray();
		var offset = 0;

		for ( var p = 0; p < sourceArray.length; p++ )
		{
			if ( sourceArray[p] != prevArray[p])
			{
				prevArray[p] = sourceArray[p];
				var colour = colours[sourceArray[p]];
				screenImageData.data[offset] = colour.red;
				screenImageData.data[offset+1] = colour.green;
				screenImageData.data[offset+2] = colour.blue;
			}
//			else
//			{
//				screenImageData.data[offset] = 0;
//				screenImageData.data[offset+1] = 0;
//				screenImageData.data[offset+2] = 0;
//			}
			offset+=4;
		}
		ctx.putImageData(screenImageData,0,0);
	}

	obj.Update = function()
	{
		for ( var l in obj.layers )
		{
			var currentLayer = obj.layers[l];
			for ( var i in currentLayer )
			{
				var s = currentLayer[i];
				if ( s )
				{
					s.Update(tempScreenBitmap.width, tempScreenBitmap.height);
					if( s.died )
						SpriteDeleteForReal(s.name);
				}
			}
		}
	}

	obj.CustomResolution=function(width, height)
	{
		CANVAS_WIDTH = width;
		CANVAS_HEIGHT = height;

		obj.CanvasWidth = CANVAS_WIDTH;
		obj.CanvasHeight = CANVAS_HEIGHT;

		canvas.width = CANVAS_WIDTH;
		canvas.height = CANVAS_HEIGHT;

		screenImageData = ctx.getImageData(0,0,CANVAS_WIDTH,CANVAS_HEIGHT);

		for ( var pixel = 0; pixel < CANVAS_WIDTH*CANVAS_HEIGHT; pixel+=1)
		{
			screenImageData.data[pixel*4+3] = 255;
		}

		screenBitmap = Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);
		screenBitmap.DrawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT,0);

		tempScreenBitmap= Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);
		prevScreenBitmap= Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);

	}

	obj.PortraitMode = function()
	{
		if (CANVAS_WIDTH > CANVAS_HEIGHT )
		{
			var tmp = CANVAS_WIDTH;
			CANVAS_WIDTH = CANVAS_HEIGHT;
			CANVAS_HEIGHT = tmp;

			obj.CanvasWidth = CANVAS_WIDTH;
			obj.CanvasHeight = CANVAS_HEIGHT;

			canvas.width = CANVAS_WIDTH;
			canvas.height = CANVAS_HEIGHT;

			screenImageData = ctx.getImageData(0,0,CANVAS_WIDTH,CANVAS_HEIGHT);

			for ( var pixel = 0; pixel < CANVAS_WIDTH*CANVAS_HEIGHT; pixel+=1)
			{
				screenImageData.data[pixel*4+3] = 255;
			}

			screenBitmap = Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);
			screenBitmap.DrawRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT,0);

			tempScreenBitmap= Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);
			prevScreenBitmap= Bitmap(CANVAS_WIDTH,CANVAS_HEIGHT);

		}
	}

	obj.CheckCollisions = function()
	{
		for ( var r in obj.collisionRules )
		{
			var currentLayer = obj.layers[r];
			CheckCollisionsForLayer(currentLayer, obj.collisionRules[r]);
		}
	}

	function CheckCollisionsForLayer(layer, collisionRule)
	{
		for ( var spritePos in layer )
		{
			var sprite = layer[spritePos];
			if ( sprite )
			{
				sprite.collided = false;
				for ( var targetLayer in collisionRule)
				{
					CheckSpriteCollisionWithLayer(sprite, obj.layers[targetLayer]);
				}
			}
		}
	}

	function CheckSpriteCollisionWithLayer(sprite, layer)
	{
		if ( layer )
		{
			for ( var spritePos in layer )
			{
				var targetSprite = layer[spritePos];
				if( sprite.IsCollidedWith(targetSprite.name))
				{
					sprite.collided = true;
					targetSprite.collided = true;
				}
			}
		}
	}

	obj.CountSpritesInLayer=function(layerName)
	{
		var count = 0;

		var layer = obj.layers[layerName];

		for ( var spritePos in layer )
		{
			var sprite = layer[spritePos];
			if ( sprite )
			{
				count++;
			}
		}
		return count;
	}

	obj.Draw = function()
	{
		// copy the screenBitmap and place all the sprites on it

		// Cloning has been replaced with a permanent temp bitmap and
		// contents just copied over. This seems to yield significant
		// speed improvement in chrome.
//		var bitmap = screenBitmap.Clone();
		var size = screenBitmap.width * screenBitmap.height;
		var targetArray = tempScreenBitmap.GetPixelArray();
		var sourceArray = screenBitmap.GetPixelArray();
		for (  var p = 0; p < size; p++)
		{
			targetArray[p] = sourceArray[p];
		}

		for ( var l in obj.layers )
		{
			var currentLayer = obj.layers[l];
			for ( var i in currentLayer )
			{
				var spr = currentLayer[i];
				if ( spr )
					tempScreenBitmap.Paste(spr.pos.x,spr.pos.y, spr.bitmap )
//				bitmap.Paste(s.pos.x,s.pos.y, s.bitmap )
			}
		}
		obj.writeToCanvas(tempScreenBitmap);
//		obj.writeToCanvas(bitmap);
	}

	obj.DrawPixel = function(pixelX, pixelY,colour)
	{
		screenBitmap.SetPixel(Math.floor(pixelX),Math.floor(pixelY),colour);
	}

	obj.Clear = function(colour)
	{
		screenBitmap.Clear(colour);
	}

	obj.DrawLine = function(startX, startY, endX, endY, colour)
	{
		screenBitmap.DrawLine(startX, startY, endX, endY, colour)
	}

	obj.DrawRect = function(xPos,yPos,width,height,colour)
	{
		screenBitmap.DrawRect(xPos, yPos, width, height, colour)
	}

	obj.DrawCircle = function(xPos,yPos,radius,colour)
	{
		screenBitmap.DrawCircle(xPos,yPos,radius,colour)
	}

	obj.Scroll = function(xMovement,yMovement)
	{
		screenBitmap.Scroll(xMovement,yMovement);
	}

	obj.FlipX = function()
	{
		screenBitmap = screenBitmap.FlipX();
	}

	obj.FlipY = function()
	{
		screenBitmap = screenBitmap.FlipY();
	}

	obj.Paste = function(xPos,yPos,bitmap)
	{
		screenBitmap.Paste(xPos,yPos,bitmap);
	}

	obj.DefineColour = function(colour,r,g,b)
	{
		colours[colour] = Colour(r,g,b);
	}

	function CleanUpArray(arrayObj)
	{
		var returnArray = new Array();

		for ( var i in arrayObj)
		{
			if ( arrayObj[i] != null )
			{
				returnArray[i] = arrayObj[i];
			}
		}
		return returnArray;
	}

	function CountItemsInArray(arrayObj)
	{
		var count = 0;
		for ( var i in arrayObj )
		{
			count++;
		}

		return count;
	}

	obj.SpriteAdd = function(name,sprite, layer)
	{
		obj.SpriteDelete(name);

		obj.sprites[name] = layer;

		if (obj.layers[layer] == null )
		{
			obj.layers[layer] = new Array();
		}

		var newLayer = obj.layers[layer];
		newLayer[name] = sprite;
		sprite.name = name;
	}

	function SpriteDeleteForReal(name)
	{
		var spriteLayer = obj.sprites[name];
		if ( spriteLayer )
		{
			obj.layers[spriteLayer][name] = null;
			obj.layers[spriteLayer] = CleanUpArray(obj.layers[spriteLayer]);
			if ( CountItemsInArray(obj.layers[spriteLayer]) == 0 )
			{
				obj.layers[spriteLayer] = null;
				obj.layers = CleanUpArray(obj.layers);
			}
			obj.sprites[name] = null;
			obj.sprites = CleanUpArray(obj.sprites);
		}
	}

	obj.SpriteDelete=function(name)
	{
		var spriteLayer = obj.sprites[name];
		if ( spriteLayer )
		{
			if ( obj.layers[spriteLayer] )
				obj.layers[spriteLayer][name].died = true;
		}
	}

	obj.DeleteSpritesInLayer=function(spriteLayer)
	{
		if ( spriteLayer )
		{
			if ( obj.layers[spriteLayer] )
			{
				for ( var i in obj.layers[spriteLayer] )
				{
					obj.layers[spriteLayer][i].died = true;
				}
			}
		}
	}

//	obj.GetSpritesInLayer = function(spriteLayer)
//	{
//		if ( spriteLayer )
//		{
//			if ( obj.layers[spriteLayer] )
//			{
//				return obj.layers[spriteLayer]
//			}
//		}
//		return null;
//	}

/*
	obj.WriteChar = function(char, charset, xPos,yPos,colour)
	{
		screenBitmap.WriteChar(char, charset, xPos,yPos,colour);
	}

	obj.WriteString = function(text,charset, xPos,yPos,colour)
	{
		screenBitmap.WriteString(text,charset, xPos,yPos,colour);
	}
*/
	obj.SpriteGet = function(name)
	{
		var spriteLayer = obj.layers[obj.sprites[name]];
		if ( spriteLayer )
			return spriteLayer[name];
		return null;
	}

	obj.CollisionRuleAdd = function(sourceLayer, targetLayer)
	{
		if ( obj.collisionRules[sourceLayer] == null )
		{
			obj.collisionRules[sourceLayer] = new Array();
		}

		if (obj.collisionRules[sourceLayer][targetLayer] == null )
		{
			obj.collisionRules[sourceLayer][targetLayer] = targetLayer;
		}
	}

	obj.CollisionRuleDelete = function(sourceLayer, targetLayer)
	{
		if ( obj.collisionRules[sourceLayer] )
		{
			if ( obj.collisionRules[sourceLayer][targetLayer] )
			{
				obj.collisionRules[sourceLayer][targetLayer] = null;
				obj.collisionRules[sourceLayer] = CleanUpArray(obj.collisionRules[sourceLayer]);
			}
			if ( CountItemsInArray(obj.collisionRules[sourceLayer]) == 0 )
			{
				obj.collisionRules[sourceLayer] = null;
				obj.collisionRules = CleanUpArray(obj.collisionRules);
			}
		}
	}

	obj.WriteChar = function(char,xPos,yPos,colour,xbig,ybig)
	{
		charSet.WriteChar(char,screenBitmap,xPos,yPos,colour,xbig,ybig)
	}

	obj.WriteString = function(text,xPos,yPos,colour,xbig,ybig)
	{
		charSet.WriteString(text,screenBitmap,xPos,yPos,colour,xbig,ybig)
	}

	obj.WriteStringCentered=function(text,yPos,colour,xbig,ybig)
	{
		screenBitmap.WriteStringCentered(text,charSet, yPos,colour,xbig,ybig);
	}

	var mouseDownPos = Vector(0,0);
	var mouseUpPos = Vector(0,0);
	obj.mouseSwipe = Vector(0,0);

	function SetMousePos(xp,yp)
	{
		var bbox = canvas.getBoundingClientRect();
		obj.mousePos.x = (xp - bbox.left) * ( canvas.width / bbox.width);
		obj.mousePos.y = (yp - bbox.top) * ( canvas.height / bbox.height);
	}

	canvas.addEventListener("mousemove", function(evt){
		SetMousePos(evt.clientX,evt.clientY);
		evt.preventDefault();
	});

	canvas.addEventListener("touchmove", function(evt){
		SetMousePos(evt.targetTouches[0].pageX,evt.targetTouches[0].pageY);
		evt.preventDefault();
	});

	canvas.addEventListener("mousedown", function(evt){
		obj.mouseClicked = true;
		obj.mouseDown = true;
		mouseDownPos.x = obj.mousePos.x;
		mouseDownPos.y = obj.mousePos.y;
		evt.preventDefault();
	});

	canvas.addEventListener("touchstart", function(evt){
		SetMousePos(evt.targetTouches[0].pageX,evt.targetTouches[0].pageY);
		obj.mouseClicked = true;
		obj.mouseDown = true;
		mouseDownPos.x = obj.mousePos.x;
		mouseDownPos.y = obj.mousePos.y;
		if ( evt.targetTouches > 1 )
			obj.mouseTouchFire = true;
		evt.preventDefault();
	});

	canvas.addEventListener("mouseup", function(evt){
		obj.mouseDown = false;
		obj.mouseUnclicked = true;
		mouseUpPos.x = obj.mousePos.x;
		mouseUpPos.y = obj.mousePos.y;
		obj.mouseSwipe.x = mouseUpPos.x - mouseDownPos.x;
		obj.mouseSwipe.y = mouseUpPos.y - mouseDownPos.y;
		evt.preventDefault();
	});

	canvas.addEventListener("touchend", function(evt){
		obj.mouseDown = false;
		obj.mouseUnclicked = true;
		mouseUpPos.x = obj.mousePos.x;
		mouseUpPos.y = obj.mousePos.y;
		obj.mouseSwipe.x = mouseUpPos.x - mouseDownPos.x;
		obj.mouseSwipe.y = mouseUpPos.y - mouseDownPos.y;
		evt.preventDefault();
	});

	var tiltable = false;
	obj.tiltX = null;
	obj.tiltY = null;
	obj.tiltZ = null;

	var tiltXBase = 0;
	var tiltYBase = 0;
	var tiltZBase = 0;

	obj.Tilt=function(values)
	{
		obj.tiltX = values[0];
		obj.tiltY = values[1];
		obj.tiltZ = values[2];
		if ( tiltable == false && obj.tiltX != null )
		{
			tiltable = true;
			obj.TiltCalibrate();
		}
	}

	obj.TiltCalibrate = function()
	{
		tiltXBase = obj.tiltX;
		tiltYBase = obj.tiltY;
		tiltZBase = obj.tiltZ;
	}

	obj.Tiltable = function()
	{
		return tiltable;
	}

	obj.GetTiltX=function()
	{
		 var upsidedown = 1;
		 if(obj.tiltZ > 0 )
			upsidedown = -1;
		if ( window.innerWidth < window.innerHeight )
			return (obj.tiltX-tiltXBase);
		else
			return ( obj.tiltY - tiltYBase )*upsidedown;
	}

	// Tilt events
	if (window.DeviceOrientationEvent)
	{
		window.addEventListener("deviceorientation", function () {
        obj.Tilt([event.gamma,event.beta, event.gamma]);
		}, true);
	}

	// keyboard handler
	var keycodes = [];

	obj.GetKeyState=function(keycode)
	{
		return keycodes[keycode];
	}

	document.addEventListener("keydown", function(evt){
		keycodes[evt.keyCode] = true;
	});

	document.addEventListener("keyup", function(evt){
		keycodes[evt.keyCode] = false;
	});

	obj.KEY_ENTER = 13;

	obj.KEY_ESCAPE = 27;

	obj.KEY_SPACE = 32;

	obj.KEY_LEFT = 37;
	obj.KEY_UP = 38;
	obj.KEY_RIGHT = 39;
	obj.KEY_DOWN = 40;

	obj.KEY_0 = 48;
	obj.KEY_1 = 49;
	obj.KEY_2 = 50;
	obj.KEY_3 = 51;
	obj.KEY_4 = 52;
	obj.KEY_5 = 53;
	obj.KEY_6 = 54;
	obj.KEY_7 = 55;
	obj.KEY_8 = 56;
	obj.KEY_9 = 57;

	obj.KEY_A = 65;
	obj.KEY_B = 66;
	obj.KEY_C = 67;
	obj.KEY_D = 68;
	obj.KEY_E = 69;
	obj.KEY_F = 70;
	obj.KEY_G = 71;
	obj.KEY_H = 72;
	obj.KEY_I = 73;
	obj.KEY_J = 74;
	obj.KEY_K = 75;
	obj.KEY_L = 76;
	obj.KEY_M = 77;
	obj.KEY_N = 78;
	obj.KEY_O = 79;
	obj.KEY_P = 80;
	obj.KEY_Q = 81;
	obj.KEY_R = 82;
	obj.KEY_S = 83;
	obj.KEY_T = 84;
	obj.KEY_U = 85;
	obj.KEY_V = 86;
	obj.KEY_W = 87;
	obj.KEY_X = 88;
	obj.KEY_Y = 89;
	obj.KEY_Z = 90;

	return obj;
}

Timer = function(fps,callFunction)
{
	var obj = {}

	var fps = fps;
	var callFunction = callFunction

	var timerId = setInterval ( callFunction, Math.floor(1000/fps));

	obj.Stop = function()
	{
		clearInterval(timerId);
	}

	return obj;
}

Colour = function(red,green,blue)
{
	obj = {}
	obj.red = red;
	obj.green = green;
	obj.blue = blue;

	return obj;
}

var BaseBitmap = {};

Bitmap = function(width,height)
{
	var obj = Object.create(BaseBitmap);
	obj.width = width;
	obj.height = height;

	var pixels = new Array()
	var scrollXFraction = 0.0;
	var scrollYFraction = 0.0;

	obj.GetPixelArray = function ()
	{
		return pixels;
	}

	obj.SetPixelArray = function (newArray)
	{
		pixels = newArray;
	}

	obj.GetPixel = function (xpos, ypos)
	{
		if (xpos >= 0 && xpos < obj.width && ypos >= 0 && ypos < obj.height)
		{
			return pixels[ypos*width+xpos];
		}
		return 0;
	}

	obj.SetPixel = function (xpos,ypos,colour)
	{
		if (xpos >= 0 && xpos < obj.width && ypos >= 0 && ypos < obj.height)
		{
			pixels[Math.floor(ypos)*width+Math.floor(xpos)] = colour;
		}
	}

	obj.Clear = function (colour)
	{
		for ( var ypos = 0; ypos < obj.height; ypos++)
		{
			for ( var xpos = 0; xpos < obj.width; xpos++)
			{
				obj.SetPixel(xpos,ypos,colour);
			}
		}
	}

	obj.PixelsFromArray = function(pixelsIn)
	{
		var minPixels = Math.min(obj.width*obj.height,pixelsIn.length);

		for(var p = 0; p < minPixels; p++)
		{
			pixels[p] = pixelsIn[p];
		}
		return obj;
	}

	obj.DrawLine = function(startX, startY, endX, endY, colour)
	{
		var xLen = endX - startX;
		var yLen = endY - startY;
		var maxPoints = Math.max(Math.abs(xLen), Math.abs(yLen))

		var xDisp = xLen / maxPoints;
		var yDisp = yLen / maxPoints;

		for ( var p = 0; p <= maxPoints; p++)
		{
			obj.SetPixel(startX + p*xDisp+0.5, startY + p*yDisp+0.5, colour)
		}
	}

	obj.DrawRect = function(xPos,yPos,width,height,colour)
	{
		for(var yDisp = 0; yDisp < height; yDisp++ )
		{
			obj.DrawLine(xPos, yPos+yDisp, xPos+width-1, yPos+yDisp,colour)
		}
	}

	obj.DrawCircle = function(xPos,yPos,radius,colour)
	{
		var radiusSquared = radius * radius;
		var xOff;

		for( var yOff = 0.0; yOff < radius; yOff+= 0.5)
		{
			xOff = Math.sqrt(radiusSquared-(yOff*yOff));
			obj.DrawLine(xPos-xOff+.5,yPos+yOff+.5,xPos+xOff+.5,yPos+yOff,colour)
			obj.DrawLine(xPos-xOff+.5,yPos-yOff+.5,xPos+xOff+.5,yPos-yOff,colour)
		}
	}

	obj.Scroll = function(xMovement,yMovement)
	{
		scrollXFraction += xMovement;
		scrollYFraction += yMovement;

		var xMove = Math.round(scrollXFraction);
		var yMove = Math.round(scrollYFraction);

		if(xMove == 0 && yMove == 0)
		{
			return;
		}

		scrollXFraction -= xMove;
		scrollYFraction -= yMove;

		var newPixels = new Array();

		var targetXPos = xMove;
		if(targetXPos < 0)
		{
			targetXPos += obj.width;
		}

		var targetYPos = yMove
		if(targetYPos < 0)
		{
			targetYPos += obj.height;
		}

		for(var yPos = 0; yPos < obj.height; yPos++)
		{
			for(var xPos = 0; xPos < obj.width; xPos++)
			{
				newPixels[yPos*obj.width+xPos] = pixels[targetYPos*obj.width+targetXPos];
				targetXPos += 1
				if(targetXPos >= obj.width)
				{
					targetXPos -= obj.width;
				}
			}
			targetYPos += 1
			if(targetYPos >= obj.height)
			{
				targetYPos -= obj.height;
			}
		}

		pixels = newPixels;
	}

	// Not ready for relacing scroll function yet. Does not wrap pixels.
	obj.ScrollNew = function(xMovement,yMovement)
	{
		scrollXFraction -= xMovement;
		scrollYFraction -= yMovement;

		var xMove = Math.round(scrollXFraction);
		var yMove = Math.round(scrollYFraction);

		if(xMove == 0 && yMove == 0)
		{
			return;
		}

		scrollXFraction -= xMove;
		scrollYFraction -= yMove;

		var newBitmap = obj.Clone();

		obj.Clear(-1);

		var targetXPos = xMove;
		if(targetXPos < 0)
		{
			targetXPos += obj.width;
		}

		var targetYPos = yMove
		if(targetYPos < 0)
		{
			targetYPos += obj.height;
		}

		obj.Paste(xMove,yMove,newBitmap);
		if(targetYPos > 0 )
			obj.Paste(xMove,yMove-obj.height,newBitmap);
		if(targetYPos < 0 )
		obj.Paste(xMove,yMove+obj.height,newBitmap);

//		obj.Paste(0,0,newBitmap);
	}

	obj.FlipX = function ()
	{
		var newBitmap = Bitmap(obj.width,obj.height);

		for(var yPos = 0; yPos < obj.height; yPos++)
		{
			for(var xPos = 0; xPos < obj.width; xPos++)
			{
				newBitmap.SetPixel(xPos,yPos,obj.GetPixel(obj.width-1-xPos,yPos));
			}
		}
		return newBitmap;
	}

	obj.FlipY = function()
	{
		var newBitmap = Bitmap(obj.width,obj.height);

		for(var yPos = 0; yPos < obj.height; yPos++)
		{
			for(var xPos = 0; xPos < obj.width; xPos++)
			{
				newBitmap.SetPixel(xPos,yPos,obj.GetPixel(xPos,obj.height-1-yPos));
			}
		}
		return newBitmap;
	}

	obj.RotateRight = function()
	{
		var newBitmap = Bitmap(obj.width,obj.height);

		for(var yPos = 0; yPos < obj.height; yPos++)
		{
			for(var xPos = 0; xPos < obj.width; xPos++)
			{
				newBitmap.SetPixel(yPos,xPos,obj.GetPixel(xPos,obj.height-1-yPos));
			}
		}
		return newBitmap;
	}

	obj.RotateLeft = function()
	{
		var newBitmap = Bitmap(obj.width,obj.height);

		for(var yPos = 0; yPos < obj.height; yPos++)
		{
			for(var xPos = 0; xPos < obj.width; xPos++)
			{
				newBitmap.SetPixel(yPos,xPos,obj.GetPixel(obj.width-1-xPos,yPos));
			}
		}
		return newBitmap;
	}

	obj.Clone = function()
	{
		var newBitmap = Bitmap(obj.width,obj.height);

		newBitmap.SetPixelArray([].concat(pixels));

//	for(var yPos = 0; yPos < obj.height; yPos++)
//	{
//		for(var xPos = 0; xPos < obj.width; xPos++)
//		{
//			newBitmap.SetPixel(xPos,yPos,obj.GetPixel(xPos,yPos));
//		}
//	}
		return newBitmap;
	}

	obj.Paste = function(xp,yp,bitmap)
	{
		var xdisp = Math.round(xp);
		var ydisp = Math.round(yp);

		// find the area of overlap
		// calculate the start y pixel in source and target
		var srcY = 0;
		var destY = 0;
		if (ydisp>0) destY = ydisp;
		if (ydisp<0) srcY = -ydisp;

		// calculate the start x pixel in source and target
		var srcX = 0;
		var destX = 0;
		if (xdisp>0) destX = xdisp;
		if (xdisp<0) srcX = -xdisp;

		// calculate the height of the overlap
		var ydist = obj.height-destY;
		if(bitmap.height-srcY < ydist)
			ydist = bitmap.height-srcY;

		// calculate the width of the overlap
		var xdist = obj.width-destX;
		if(bitmap.width-srcX < xdist)
			xdist = bitmap.width-srcX;

		if ( ydist > 0 && xdist > 0)
		{
			for ( var y = 0; y < ydist; y++)
			{
				for(var xPos = 0; xPos < bitmap.width; xPos++)
				{
					if ( bitmap.GetPixel(xPos,srcY) >= 0 )
					{
						obj.SetPixel(xPos+xdisp,destY,bitmap.GetPixel(xPos,srcY));
					}
				}
				srcY++;
				destY++;
			}
		}

/*
		for(var yPos = 0; yPos < bitmap.height; yPos++)
		{
			if ( yPos +ydisp >= 0 && yPos+ydisp < obj.height)
			for(var xPos = 0; xPos < bitmap.width; xPos++)
			{
				if ( bitmap.GetPixel(xPos,yPos) >= 0 )
				obj.SetPixel(xPos+xdisp,yPos+ydisp,bitmap.GetPixel(xPos,yPos));
			}
		}
*/
	}

	obj.WriteChar = function(char, charset, xPos,yPos,colour,xbig,ybig)
	{
		charSet.WriteChar(char,obj,xPos,yPos,colour,xbig,ybig);
	}

	obj.WriteString = function(text,charSet, xPos,yPos,colour,xbig,ybig)
	{
		charSet.WriteString(text,obj,xPos,yPos,colour,xbig,ybig);
	}

	obj.WriteStringCentered = function(text, charset, yPos,colour,xbig,ybig)
	{
		if (xbig == undefined) xbig = false;
		if ( xbig )
			charset.WriteString(text,obj,width/2-charset.GetWidth()/2*text.length*2,yPos, colour,xbig,ybig);
		else
			charset.WriteString(text,obj,width/2-charset.GetWidth()/2*text.length,yPos, colour,xbig,ybig);
	}

	obj.Clear(-1);

	return obj;
}

CharSet = function (width, height)
{
	if (width == undefined)
		width = 8;

	if (height == undefined)
		height = 8;

	var obj = {};
	var charData = {};

	obj.GetWidth = function ()
	{
		return width;
	}

	obj.GetHeight = function ()
	{
		return height;
	}
	obj.SetChar = function(char, chardata )
	{
		charData[char] = chardata;
	}

	obj.WriteChar = function(char,bitmap,xPos,yPos,colour,xbig,ybig)
	{
		if(typeof(xbig)==='undefined') xbig = false;
		if(typeof(ybig)==='undefined') ybig = false;
		var rowData = charData[char];
		if ( rowData != undefined )
		{
			for ( var row = 0; row < rowData.length; row++)
			{
				var line = rowData[row];
				for ( var charPos = 0; charPos < line.length; charPos++)
				{
					var chr = line.charAt(charPos);
					if ( chr != " " )
					{
						if ( !xbig && !ybig)
							bitmap.SetPixel(charPos+xPos, row+yPos, colour );

						if ( xbig && !ybig)
						{
							bitmap.SetPixel(charPos*2+xPos, row+yPos, colour );
							bitmap.SetPixel(charPos*2+xPos+1, row+yPos, colour );
						}
						if ( !xbig && ybig)
						{
							bitmap.SetPixel(charPos+xPos, row*2+yPos, colour );
							bitmap.SetPixel(charPos+xPos, row*2+yPos+1, colour );
						}
						if ( xbig && ybig)
						{
							bitmap.SetPixel(charPos*2+xPos, row*2+yPos, colour );
							bitmap.SetPixel(charPos*2+xPos+1, row*2+yPos, colour );
							bitmap.SetPixel(charPos*2+xPos, row*2+yPos+1, colour );
							bitmap.SetPixel(charPos*2+xPos+1, row*2+yPos+1, colour );
						}
					}
				}
			}
		}
	}

	obj.WriteString = function(text,bitmap,xPos,yPos,colour,xbig,ybig)
	{
		if(typeof(xbig)==='undefined') xbig = false;
		for ( var charPos = 0; charPos < text.length; charPos++)
		{
			var chr = text.charAt(charPos);
			if ( xbig)
				obj.WriteChar(chr,bitmap,xPos+charPos*2*width, yPos, colour,xbig,ybig );
			else
				obj.WriteChar(chr,bitmap,xPos+charPos*width, yPos, colour,xbig,ybig );
		}
	}

	return obj;
}

Sprite = function (xp,yp,costumeOrBitmap)
{
	if (costumeOrBitmap === null ) return null;
	var costume = costumeOrBitmap;
	if ( BaseBitmap.isPrototypeOf(costumeOrBitmap))
	{
		costume = Costume();
		costume.SetItem(0,costumeOrBitmap);
	}
	else
	{
		if ( !BaseCostume.isPrototypeOf(costumeOrBitmap)) return null;
	}
	var obj = {};

	var lifeSpan = -1;
	obj.died = false;
	obj.name = "";

	obj.pos = Vector(xp,yp);
	obj.vel = Vector(0,0);
	obj.costume = costume;
	obj.costumeAnimator = Animator([0]);
	obj.bitmap = costume.GetItem(0);
	obj.wrap = false;
	obj.collided = false;
	obj.collidedList = new Array();

	obj.SetLifeSpan = function(newLifeSpan)
	{
		lifeSpan = newLifeSpan;
	}

	obj.SetCostume = function(costume)
	{
		obj.costume = costume;
	}

	obj.SetWrapOn = function()
	{
		obj.wrap = true;
	}

	obj.SetWrapOff = function()
	{
		obj.wrap = false;
	}

	obj.SetAnimator = function(frameList)
	{
		obj.costumeAnimator = Animator(frameList);
	}

	obj.SetAnimatorBounce = function ()
	{
		obj.costumeAnimator.Bounce(obj.costume.Length());
	}

	obj.SetAnimatorLoop = function ()
	{
		obj.costumeAnimator.Loop(obj.costume.Length());
	}

	obj.SetAnimatorFrame = function(frame)
	{
		obj.costumeAnimator.Set(frame);
		obj.bitmap = obj.costume.GetItem(obj.costumeAnimator.Get());
	}

	obj.GetAnimatorFrame = function(frame)
	{
		return obj.costumeAnimator.Get();
	}

	obj.SetCostumeAnimator = function(animator)
	{
		obj.costumeAnimator = animator;
	}

	obj.SetAnimatorUpdateRate = function (updateRate)
	{
		obj.costumeAnimator.SetUpdateRate(updateRate);
	}

	obj.SetAnimatorStop = function ()
	{
		obj.costumeAnimator.Stop();
	}

	obj.SetMovement = function(xm,ym)
	{
		obj.vel.x = xm;
		obj.vel.y = ym;
		return obj;
	}

	obj.IsCollidedWith = function(targetSpriteName)
	{
		var target = GE.SpriteGet(targetSpriteName);

		if ( target == undefined )
			return false;

		// simple bounding box check will do for now
		if ( obj.pos.x < target.pos.x + target.bitmap.width
			&& obj.pos.x + obj.bitmap.width > target.pos.x
			&& obj.pos.y < target.pos.y + target.bitmap.height
			&& obj.pos.y + obj.bitmap.height > target.pos.y )
		{
//			return true;
			var collided = false;
			// now lets do a pixel perfect collision check
			// get the biggest left
			var boxLeftPos = obj.pos.x;
			if ( boxLeftPos < target.pos.x )
				boxLeftPos = target.pos.x;
			// get the smallest right
			var boxRightPos = obj.pos.x + obj.bitmap.width;
			if ( boxRightPos > target.pos.x + target.bitmap.width)
				boxRightPos = target.pos.x + target.bitmap.width;
			// get the biggest top
			var boxTopPos = obj.pos.y;
			if ( boxTopPos < target.pos.y )
				boxTopPos = target.pos.y;
			// get the smallest bottom
			var boxBottomPos = obj.pos.y + obj.bitmap.height;
			if ( boxBottomPos > target.pos.y + target.bitmap.height)
				boxBottomPos = target.pos.y + target.bitmap.height;

			var overlapWidth = boxRightPos - boxLeftPos;
			var overlapHeight = boxBottomPos - boxTopPos;

			var sx = Math.floor(boxLeftPos - obj.pos.x);
			var sy = Math.floor(boxTopPos - obj.pos.y);
			var tx = Math.floor(boxLeftPos - target.pos.x);
			var ty = Math.floor(boxTopPos - target.pos.y);
			for ( var y = 0; y < overlapHeight; y++)
			{
				for ( var x = 0; x < overlapWidth; x++ )
				{
					var p1 = obj.bitmap.GetPixel(sx+x,sy+y);
					var p2 = target.bitmap.GetPixel(tx+x,ty+y);
					if (p1 != -1 && p2 != -1 )
						collided = true;
				}
			}

			return collided;
		}

		return false;
	}

	obj.Update = function (scrWidth, scrHeight)
	{
		obj.pos.x += obj.vel.x;
		obj.pos.y += obj.vel.y;
		if ( obj.wrap )
		{
			if ( obj.pos.x < 0 )
				obj.pos.x += scrWidth;
			if ( obj.pos.y < 0 )
				obj.pos.y += scrHeight;
			if ( obj.pos.x >= scrWidth )
				obj.pos.x -= scrWidth;
			if ( obj.pos.y >= scrHeight )
				obj.pos.y -= scrHeight;
		}

		obj.costumeAnimator.Update();
		obj.bitmap = obj.costume.GetItem(obj.costumeAnimator.Get());
		obj.layerChanged = false;

		if ( lifeSpan != -1 )
		{
			lifeSpan--;
			if (lifeSpan == 0 )
				obj.died = true;
		}
	}

//	obj.Draw = function ()
//	{
//
//	}

	return obj;
}

Vector = function(x,y)
{
	var obj = {};

	obj.x = x;
	obj.y = y;

	obj.Add = function(v1)
	{
		return Vector(obj.x+v1.x, obj.y+v1.y);
	}

	obj.Subtract = function(v1)
	{
		return Vector(obj.x-v1.x, obj.y-v1.y);
	}

	obj.Multiply = function(v1)
	{
		return Vector(obj.x*v1.x, obj.y*v1.y);
	}

	obj.Magnitude = function()
	{
		return Math.sqrt(obj.x*obj.x + obj.y*obj.y);
	}

	obj.Normalise = function()
	{
		var mag = obj.Magnitude();
		obj.x /= mag;
		obj.y /= mag;
	}

	obj.SetMagnitude = function(newMagnitude)
	{
		obj.Normalise();
		obj.x *= newMagnitude;
		obj.y *= newMagnitude;
	}

	obj.DotProduct = function(v)
	{
		return obj.x * v.x + obj.y * v.y;
	}

	obj.ScalarMultiply = function(scalar)
	{
		obj.x *= scalar;
		obj.y *= scalar;
	}

	return obj;
}

var BaseCostume = {};
Costume = function()
{
	var obj = Object.create(BaseCostume);

	obj.bitmaps = Array();

	obj.SetItem = function (frame, bitmap)
	{
		// try to set a frame to something other than a bitmap will result in nothing happening
		if ( !BaseBitmap.isPrototypeOf(bitmap)) return;
		obj.bitmaps[frame] = bitmap;
	};

	obj.SetItems = function (bitmaps,startFrame)
	{
		var frame = startFrame;
		for(var bitmapPos = 0; bitmapPos < bitmaps.length; bitmapPos++)
		{
			obj.SetItem(frame, bitmaps[bitmapPos]);
			frame++;
		}
	};

	obj.Length = function ()
	{
		return obj.bitmaps.length;
	}

	obj.GetItem = function (frame)
	{
		return obj.bitmaps[frame];
	}

	obj.Update = function()
	{
	}

	return obj;
}

Animator = function (frameList)
{
	var obj = {};
	obj.frame = 0;
	obj.updateRate = 1;
	obj.repeat = true;

	if (frameList == null )
	{
		obj.frameList = new Array();
	}
	else
	{
		obj.frameList = frameList;
	}
	var paused = false;

	obj.Bounce = function (frames)
	{
		var list = new Array();
		var f = 0;
		for ( var i = 0; i < frames; i++)
		{
			list[f] = i;
			f++;
		}
		for ( var i = frames-2; i > 0; i--)
		{
			list[f] = i;
			f++;
		}
		obj.frameList = list;
	}

	obj.Loop = function (frames)
	{
		var list = new Array();
		var f = 0;
		for ( var i = 0; i < frames; i++)
		{
			list[f] = i;
			f++;
		}
		obj.frameList = list;
	}

	obj.Update = function ()
	{
		if ( paused == false )
		{
			var prevFrame = obj.frame;
			obj.frame = (obj.frame + obj.updateRate)  % obj.frameList.length;
			if ( obj.frame < prevFrame )
				if ( !obj.repeat )
				{
					obj.frame = prevFrame;
					obj.Pause();
				}
		}
	}

	obj.Get = function()
	{
		return obj.frameList[Math.floor(obj.frame)];
	}

	obj.Set = function(frame)
	{
		obj.frame = Math.floor(frame % obj.frameList.length);
	}

	obj.SetUpdateRate = function(updateRate)
	{
		obj.updateRate = updateRate;
		obj.waitTime = 0;
	}

	obj.Start = function ()
	{
		frame = 0;
		paused = false;
	}

	obj.Resume = function ()
	{
		paused = false;
	}

	obj.Stop = function ()
	{
		frame = 0;
		paused = true;
	}

	obj.Pause = function ()
	{
		paused = true;
	}

	obj.Resume = function ()
	{
		paused = false;
	}

	return obj;
}

var channels = new Array();
var soundOn = true;

function customSound(bitrate)
{
	this.bitrate = bitrate;
	this.angle = 0;
	this.customSoundData=[];
	this.totalDuration = 0;
	this.dataPos = 0;

	customSound.prototype.add = function(duration, startFreq, endFreq, startVol, endVol, startNoise, endNoise, square )
	{
		var vol = startVol;
		var freq = startFreq;
		var angleInc = (2*Math.PI)/this.bitrate * freq;
		var noise = startNoise;

		for ( var x=0; x < this.bitrate*duration; x++)
		{
			vol = (startVol + (endVol - startVol)*x/(this.bitrate*duration));
			this.customSoundData[this.dataPos] = (Math.sin(this.angle) + (Math.random()*noise)) * vol;
			if (square )
				if ( this.customSoundData[this.dataPos]  < 0)
					this.customSoundData[this.dataPos] = -vol;
				else
					this.customSoundData[this.dataPos] = vol
			freq = startFreq + (endFreq - startFreq)*x/(this.bitrate*duration);
			noise = startNoise + (endNoise - startNoise)*x/(this.bitrate*duration);

			angleInc = (2*Math.PI)/this.bitrate * freq;
			this.angle+=angleInc;
			if ( this.angle > Math.PI * 2 )
			{
				this.angle -= Math.PI * 2;
			}
			this.dataPos++;
		}
	}

	customSound.prototype.createSound = function(channel)
	{
		var n = this.customSoundData.length;
		var header = "RIFF****WAVEfmt \x10\x00\x00\x00\x01\x00\x01\x00********\x01\x00\x08\x00data****";

		// ChunkSize
		var numval = n + 36;
		header=insertLong(header,4,numval);

		numval = this.bitrate; // byterate
		header = insertLong(header,24,numval);

		  // BitRate
		numval = this.bitrate * 8; //44100;
		header = insertLong(header,28,numval);

		  // Subchunk2Size
	//      insertLong(n);
		numval = n;
		header = insertLong(header,40,numval);

		// Output sound data
		for (var i = 0; i < n; ++i)
		{
			var charCode = Math.round(Math.min(127, Math.max(-127, this.customSoundData[i]))+127);
			header += String.fromCharCode(charCode);
		}

//		var o= document.getElementById('output');
		var h = btoa(header);
		h = 'data:audio/wav;base64,' + h;

		var a = new Audio();
		a.src = h;
		if ( channels[channel] )
			channels[channel].pause();
		channels[channel] = a;
		return a;
	}
}

function soundPlay(channel,loop)
{
	if ( !soundOn )
		return;

	if ( loop )
		channels[channel].loop = loop;
	if (channels[channel].readyState < 1 )
		return;
//	channels[channel].pause();
	channels[channel].currentTime=0;
	channels[channel].play();
}

function soundStop(channel)
{
	if (channels[channel].readyState < 1 )
		return;
	channels[channel].pause();
}

function insertLong(inString, index, inValue)
{
	var retString = inString.substr(0,index);
	for (i = 0; i < 4; ++i) {
	  retString += String.fromCharCode(inValue & 255);
	  inValue = inValue >> 8;
	}
	retString += inString.substr(index+4);
	return retString;
}

GameSatePattern = function (data)
{
	var obj = {};
	var innerStates = new Array();
	var finished = false;
	var nextState;
	var doInit = true;

	obj.Draw = function()
	{
		if ( obj.DrawCustom )
			obj.DrawCustom();

		for( var state in innerStates )
			if ( innerStates[state] )
				innerStates[state].Draw();

	}

	obj.Update = function()
	{
		if ( doInit )
		{
			doInit = false;
			if ( obj.Init )
				obj.Init();
		}

		if ( obj.UpdateCustom)
			obj.UpdateCustom();

		if ( finished )
		{
			for( var state in innerStates )
			{
				if ( innerStates[state] )
				{
					innerStates[state].SetFinished();
					innerStates[state] = innerStates[state].Update();
				}
			}

			if ( obj.TearDown )
				obj.TearDown();

			if ( nextState)
				return nextState;

			return undefined;
		}
		else
			for( var state in innerStates )
				if ( innerStates[state] )
					innerStates[state]  = innerStates[state].Update();

		return this;
	}

	obj.AddInnerState=function(state)
	{
		innerStates.push(state);
	}

	obj.SetNextState=function(state)
	{
		nextState = state;
	}

	obj.SetFinished=function()
	{
		finished = true;
	}

	return obj;
}
// last piece of code is to start the game
init();
</script>

</html>

Leave a reply

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> 

required