<!--
// game variables
// timer for game ticks, measured in milliseconds
// many other vars are based on game ticks so they are declared first
var gameInterval;
var gameTick = 40;

// define the map boundaries to match the size & position of the mmap div
var leftEdge = 0;
var rightEdge = 368;
var topEdge = 0;
var bottomEdge = 380;
var gravityLine = 50; // above this line balls are not affected by gravity

// various gameplay variables
var timeElapsed = 0;
var gameTime = 0;
var ballsToCatch = 0;
var gameScore = 0;
var scoreRed = 40;
var scoreBlue = 20;
var scoreYellow = 20;
var scoreYellowExp = 30;
var scoreRedExp = 40;
var scoreBlueExp = 20;
var scoreBucketExplosion = 50;
var scorePowerup_block = 0;
var scorePowerup_points = 200;
var scorePowerup_catchyellows = 100;
var scorePowerup_antigravity = 100;
var scorePowerup_freefall = 100;
var scorePowerup_fly = 100;
var scorePowerup_balls = 100;
var numberExplosions = 0;
var cascadeBonus = 10;

// how long a score is displayed for
var scoreCardTime = 2.5 * (1000 / gameTick);

// level variables
var gameStatusTime = 3000;
var gameStatusCounter;
var currentLevel = 1;
var levelOver = false;
var gameOver = false;
var defaultNumberLives = 3;
var currentNumberLives;

// arrays for object graphics
var balls = [];
var scoreCards = [];
var buckets = [];
var sources = [];
var powerups = [];

// bucket parameters
var bucketsNumber = 1;
var bucketWidth = 32;
var bucketHeight = 32;
var bucketStartX = ((rightEdge - leftEdge) / 2) - (bucketWidth / 2);
var bucketStartY = bottomEdge - bucketHeight;
var bucketMinY = 50; // prevents bucket from entering top of map - may need to replace this with gravityLine for consistency
var bucketEdge = 5; // width of area on bucket top that gives edge effects to collision - but thickness (below) takes priority
var bucketThickness = 1; // thickness of the bucket walls
var bucketDefaultFly = "nofly"; // bucket starts not flying
var bucketDefaultCatchYellows = "nocatch"; // bucket starts not catching yellows

// controls duration of yellow catch status and countdown to status end (flash start)
var catchYellowDuration = 15000 / gameTick; // about 15 seconds
var flashStart = 3000 / gameTick;
var flashInterval = 500 / gameTick;
var numberFlashes = 0;

// controls duration of bucket shake (when ball explodes in bucket)
var shakeDuration = 1200 / gameTick; //  around 2 seconds?
var shakeInterval = 40 / gameTick;
var numberShakes = 0;

var shakeOffset = 0;
var maxOffset = 4;
var shakeShift = 2;

// vars for moving the bucket
var moveLeft = false;
var moveRight = false;
var moveUp = false;
var moveDown = false;
var maxBucketSpeed = 3 * gameTick;
var bucketAcceleration = gameTick/2;
var ballMaxSpeed = 3.2 * gameTick;
var powerupMaxSpeed = 3 * gameTick;


// define the control keys
var leftKey = 90;
var rightKey = 88;
var upKey = 75;
var downKey = 77;
var altLeftKey = 37;
var altRightKey = 39;
var altUpKey = 38;
var altDownKey = 40;

// properties of the ball explosion animated gif
var explosionNoFrames = 16; // number of frames
var explosionFrameDelay = 40; // frame duration in thousandths of a second
var explodingBallWidth = 64; // animation width
var explodingBallHeight = 64; // animation height
var powerupTriggeredNoFrames = 8;

// speed of ball after capture
var longFuseSpeed = -20;

// delay between releasing new balls
// var ballReleaseDelay = 1 * (1000 / gameTick);

// width and height of balls icons by rank
// there is no rank 0, they go 1 to 10, so rank 0 will be a dummy entry
 var ball_width = new Array (16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16);
 var ball_height = new Array (16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16);
  var ball_radius = new Array (8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8);
 var originalBallWidth = 16; // for explosions, need to know initial ball width
 var sourceHeight = 16;
 var sourceWidth = 16;
 var powerupHeight = 32;
 var powerupWidth = 64;

// root names for icons
var ballsIconRoot = "ball";
var sourcesIconRoot = "source";
var powerupsIconRoot = "powerup";

// falling parameters
var defaultGravityAcceleration = 25 * (gameTick / 1000);
var GravityAcceleration;
var terminalVelocity = 700;


var settingsDialogX = "112px";
var settingsDialogY = "60px";

// is the game running or paused?
var isPaused = 1;

// is a modal dialog open?
var modalDialogOpen = 0;

// was the game paused or running when the modal dialog was opened?
var previousPauseStatus = 0;

// initial values for Settings dialog
var defaultSetSeed=false;
var setSeed;

var defaultStartSeed = 123456;
var startSeed;
var randomSeed;
var minSeed = 1;
var seed_string = "Seed must be a positive whole number"

var defaultStartLevel = 1;
var startLevel;
var minStartLevel = 1;
var maxStartLevel = numberOfLevels;
var level_number_string = "Start level must be a whole number between " + minStartLevel + " and " + maxStartLevel;

// each ball or source will be given a permanent unique ID
// this will be incremented for each new ball
var nextID=0;
var defaultStrategy = "wait";
var defaultLeader = 1;

// distance within which a ball can perceive objects
var sightDistance = 80;

// nearest a ball wants to get to their leader
var leaderClosestDistance = 30;

// max angle by which a ball can turn (radians per second)
var maxTurnAngle = 0.01;

// info text
var defaultHelpInfo = "<b>Controls:</b><br />Use arrow keys to move bucket<br /><br /><b>Scores:</b><br /><img src=\"icons/game/ball_yellow.gif\" alt=\"\" />avoid!<br /><img src=\"icons/game/ball_blue.gif\" alt=\"\" />20 points<br /><img src=\"icons/game/ball_red.gif\" alt=\"\" />40 points<br />";
 
var catchYellowsHelpInfo = "<b>Controls:</b><br />Use arrow keys to move bucket<br /><br /><b>Scores:</b><br /><img src=\"icons/game/ball_yellow.gif\" alt=\"\" />20 points!<br /><img src=\"icons/game/ball_blue.gif\" alt=\"\" />20 points<br /><img src=\"icons/game/ball_red.gif\" alt=\"\" />40 points<br />";

