/**** 
* Classes
****/
var DropEffect = Container.expand(function (x, y, player) {
	var self = Container.call(this);
	var angle = player.angle + Math.random() * DROP_ANGLE_VARIANCE;
	var speed = 10 + Math.random() * 5;
	var speedX = Math.cos(angle) * speed;
	var speedY = Math.sin(angle) * speed;
	var spinSpeed = Math.random() * 0.2 - 0.1;
	var scale = 1;
	var scaleDecrement = 1 / 60;
	var graphics = self.createAsset('pickupProjectile', 'Drop graphics', 0.5, 0.95);
	graphics.rotation = Math.random() * MATH_PI_BY_2;
	;
	self.x = x;
	self.y = y;
	self.update = update;
	;
	function update(velocityX, velocityY) {
		self.x += speedX - velocityX;
		self.y += speedY - velocityY;
		scale -= scaleDecrement;
		graphics.rotation += spinSpeed;
		graphics.scale.set(scale);
		return scale <= 0;
	}
});
var BloodsplatterEffect = Container.expand(function (x, y) {
	var self = Container.call(this);
	var duration = 15;
	var remaining = duration;
	var maxScale = 2.0;
	var startAlpha = 0.5;
	var graphics = self.createAsset('bloodsplatter', 'Bloodsplatter graphics', 0.5, 0.5);
	graphics.alpha = startAlpha;
	graphics.y = -graphics.height / 2;
	;
	self.x = x;
	self.y = y;
	self.update = update;
	;
	function update(velocityX, velocityY) {
		var progress = 1 - remaining-- / duration;
		if (remaining <= 0) {
			return true;
		}
		graphics.scale.set(1 + (maxScale - 1) * progress);
		graphics.alpha = startAlpha * (1 - progress);
		self.x -= velocityX;
		self.y -= velocityY;
	}
});
var Monster = Container.expand(function (x, y) {
	var self = Container.call(this);
	var active = false;
	var updateTick = 0;
	var updatePeriod = 30;
	var jumpSpeedMax = 30;
	var jumpHeight = 100;
	var jumpVelocityX = 0;
	var jumpVelocityY = 0;
	var jumpDuration = updatePeriod * 2 / 3;
	var invulnerabilityBoost = 1.8;
	var jumpDistMax = jumpSpeedMax * jumpDuration;
	var jumpDistMaxSqr = jumpDistMax * jumpDistMax;
	var activationDist = 1000;
	var activationDistSqr = activationDist * activationDist;
	var despawnY = -2500;
	var shadowReduction = 0.1;
	var shadow = self.createAsset('shadow', 'Monster shadow', 0.45, 1);
	var graphics = self.createAsset('monster', 'Monster graphics', 0.5, 1);
	graphics.scale.x = Math.random() < 0.5 ? 1 : -1;
	shadow.width = graphics.width * 0.9;
	shadow.height = graphics.width * 0.45;
	shadow.alpha = SHADOW_BASE_ALPHA;
	;
	self.x = x;
	self.y = y;
	self.jumping = false;
	self.hitbox = shadow;
	self.update = update;
	;
	function update(velocityX, velocityY, player) {
		if (!active) {
			var dx = player.x - self.x;
			var dy = player.y - self.y;
			var distSqr = dx * dx + dy * dy;
			if (distSqr <= activationDistSqr) {
				active = true;
			}
		}
		if (active) {
			var updateCurve = (-Math.cos(++updateTick * Math.PI / (updatePeriod / 2)) + 0.5) / 1.5;
			if (self.jumping) {
				if (updateCurve <= 0) {
					self.jumping = false;
					jumpVelocityX = 0;
					jumpVelocityY = 0;
				}
			} else {
				if (updateCurve > 0) {
					var boost = player.invulnerable ? invulnerabilityBoost : 1;
					var targetPosX = player.x + velocityX * jumpDuration * boost;
					var targetPosY = player.y + velocityY * jumpDuration * boost;
					var ddx = targetPosX - self.x;
					var ddy = targetPosY - self.y;
					var angle = Math.atan2(ddy, ddx);
					var targetDistSqr = ddx * ddx + ddy * ddy;
					var jumpSpeed = jumpSpeedMax * (targetDistSqr >= jumpDistMaxSqr ? 1 : Math.sqrt(targetDistSqr) / jumpDistMax);
					jumpVelocityX = Math.cos(angle) * jumpSpeed;
					jumpVelocityY = Math.sin(angle) * jumpSpeed;
					self.jumping = true;
				}
			}
			var height = -Math.max(0, updateCurve) * jumpHeight;
			graphics.y = height;
			graphics.scale.x = player.x < self.x ? -1 : 1;
			graphics.scale.y = 1 + Math.min(0, updateCurve);
			var shadowScale = (SHADOW_CRITICAL_HEIGHT + height) / SHADOW_CRITICAL_HEIGHT;
			shadow.alpha = 0.5 * shadowScale;
			shadow.scale.set(shadowScale);
		}
		self.x += jumpVelocityX - velocityX;
		self.y += jumpVelocityY - velocityY;
		return self.y < despawnY;
	}
});
var Pickup = Container.expand(function (x, y) {
	var self = Container.call(this);
	var active = false;
	var tilted = false;
	var flipScaling = 1;
	var decorOffset = -0.68;
	var flipTickCounter = randomizeFlipTicks();
	var graphics = self.createAsset('pickup', 'Pickup graphics', 0.5, 1);
	var base = self.createAsset('pickupBase', 'Pickup base', 0.5, 0.5);
	var decor = self.createAsset('pickupDecor', 'Pickup decor', 0, 0.45);
	decor.x = 6;
	decor.y = decorOffset * graphics.height;
	;
	self.x = x;
	self.y = y;
	self.update = update;
	;
	function update(velocityX, velocityY, args) {
		var player = args.player;
		self.x -= velocityX;
		self.y -= velocityY;
		var dx = player.x - self.x;
		var dy = player.y - self.y;
		var distSqr = dx * dx + dy * dy;
		if (!active) {
			if (distSqr <= PICKUP_COLLECT_SQRDIST) {
				activate(args);
			} else if (--flipTickCounter <= 0) {
				flipScaling *= -1;
				decor.scale.set(PICKUP_FLIP_SCALE + Math.random() * (1 - PICKUP_FLIP_SCALE), flipScaling);
				flipTickCounter = randomizeFlipTicks();
			}
		}
		if (!tilted && !player.airborne && distSqr <= PICKUP_TILT_SQRDIST) {
			tilted = true;
			graphics.scale.y = PICKUP_TILT_SCALE + Math.random() * (1 - PICKUP_TILT_SCALE);
			graphics.rotation = (PICKUP_TILT_BASE + Math.random() * PICKUP_TILT_VARIANCE) * (Math.sign(velocityX) || 1);
		}
		return self.y < 0;
	}
	function randomizeFlipTicks() {
		var value = PICKUP_FLIP_BASE + Math.random() * PICKUP_FLIP_VARIANCE;
		if (flipScaling < 0) {
			value = 2 * Math.sqrt(value);
		}
		return Math.floor(value);
	}
	function activate(args) {
		var pickupProjectileList = args.pickupProjectileList,
			player = args.player,
			layers = args.layers;
		var projectileX = self.x + decor.x + decor.width / 2;
		var projectileY = self.y + decor.y;
		pickupProjectileList.push(layers[LAYER_FOREGROUND].addChild(new PickupProjectile(projectileX, projectileY, player)));
		decor.destroy();
		active = true;
	}
});
var PickupProjectile = Container.expand(function (x, y, target) {
	var self = Container.call(this);
	var graphics = self.createAsset('pickupProjectile', 'Pickup Projectile graphics', 0.5, 0.5);
	;
	self.x = x;
	self.y = y;
	self.update = update;
	;
	function update() {
		var targetY = target.y + PLAYER_COLLECTION_HEIGHT - target.rampHeight;
		var dx = target.x - self.x;
		var dy = targetY - self.y;
		var distance = Math.sqrt(dx * dx + dy * dy);
		var velocityX = dx / distance * PICKUP_SPEED;
		var velocityY = dy / distance * PICKUP_SPEED;
		self.x += velocityX;
		self.y += velocityY;
		return distance <= PICKUP_COLLIDE_DIST;
	}
});
var LandscapeTile = Container.expand(function (x, y, _ref) {
	var self = Container.call(this);
	var lookup = _ref.lookup,
		xIndex = _ref.xIndex,
		yIndex = _ref.yIndex,
		density = _ref.density,
		pickups = _ref.pickups,
		monsters = _ref.monsters,
		player = _ref.player,
		key = _ref.key,
		landscapeTiles = _ref.landscapeTiles,
		layers = _ref.layers,
		rampList = _ref.rampList;
	var obstructions = [];
	var background = self.createAsset('landscapeBackground', 'Landscape background', 0.5, 0.5);
	background.width = TILE_SIZE;
	background.height = TILE_SIZE;
	background.alpha = 0.03;
	background.x = yIndex % 2 === 0 ? TILE_BACKGROUND_OFFSET : 0;
	;
	self.x = x;
	self.y = y;
	self.activate = activate;
	self.active = false;
	self.key = key;
	self.checkCollision = checkCollision;
	;
	function checkCollision(player) {
		if (!player.airborne) {
			var reach = 200;
			var dx = Math.abs(player.x - self.x);
			var dy = Math.abs(player.y - self.y);
			if (dx < TILE_SIZE / 2 + reach && dy < TILE_SIZE / 2 + reach) {
				for (var i = 0; i < obstructions.length; i++) {
					var obstruction = obstructions[i];
					if (obstruction.active && player.hitbox.intersects(obstruction.hitbox)) {
						obstruction.deactivate();
						return true;
					}
				}
			}
		}
		return false;
	}
	function activate() {
		if (!self.active) {
			self.active = true;
			var densityChance = density * Math.random();
			var obstructionTypes = ['largeTree', 'smallTree', 'smallTree', 'deadTree', 'smallRock', 'smallRock', 'largeRock', 'stump'];
			var clearanceDist = 300;
			var clearanceDistSqr = clearanceDist * clearanceDist;
			var spawnBorder = 25;
			var cellSize = 150;
			var cols = Math.ceil(TILE_SIZE / cellSize);
			var rows = Math.ceil(TILE_SIZE / cellSize);
			var cellWidth = TILE_SIZE / cols;
			var cellHeight = TILE_SIZE / rows;
			var landmark;
			if (Math.random() <= SPAWN_PICKUP_CHANCE) {
				var _randomPointInRect = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist),
					pointX = _randomPointInRect.pointX,
					pointY = _randomPointInRect.pointY;
				pickups.push(landmark = self.parent.addChild(new Pickup(pointX, pointY)));
			} else if (Math.random() <= SPAWN_RAMP_CHANCE) {
				var _randomPointInRect2 = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist),
					pointX = _randomPointInRect2.pointX,
					pointY = _randomPointInRect2.pointY;
				rampList.push(landmark = layers[LAYER_BACKGROUND].addChild(new Ramp(pointX, pointY)));
			}
			if (player.distanceTravelled > MONSTER_SPAWN_DIST && Math.random() <= SPAWN_MONSTER_CHANCE) {
				var _randomPointInRect3 = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist),
					pointX = _randomPointInRect3.pointX,
					pointY = _randomPointInRect3.pointY;
				monsters.push(self.parent.addChild(new Monster(self.x, self.y)));
			}
			for (i = 0; i < cols; i++) {
				for (j = 0; j < rows; j++) {
					if (Math.random() <= densityChance) {
						var canPlace = true;
						var _randomPointInRect4 = randomPointInRect(cellWidth * i, cellHeight * j, cellWidth, cellHeight, spawnBorder),
							pointX = _randomPointInRect4.pointX,
							pointY = _randomPointInRect4.pointY;
						if (landmark) {
							var dx = landmark.x - pointX;
							var dy = landmark.y - pointY;
							var distSqr = dx * dx + dy * dy;
							if (distSqr <= clearanceDistSqr) {
								canPlace = false;
							}
						}
						if (canPlace) {
							var type = obstructionTypes[Math.floor(Math.random() * obstructionTypes.length)];
							obstructions.push(self.addChild(new Obstruction(pointX, pointY, type)));
						}
					}
				}
			}
		}
		var leftKey = xIndex - 1 + ':' + yIndex;
		var rightKey = xIndex + 1 + ':' + yIndex;
		var downKey = xIndex + ':' + (yIndex + 1);
		var newDensity = (1 + Math.pow(Math.log(player.distanceTravelled / DIFFICULTY_FACTOR_DIST + 2), 2)) / 100;
		if (!lookup[leftKey]) {
			landscapeTiles.push(lookup[leftKey] = self.parent.addChild(new LandscapeTile(self.x - TILE_SIZE, self.y, {
				key: leftKey,
				density: newDensity,
				xIndex: xIndex - 1,
				yIndex: yIndex,
				landscapeTiles: landscapeTiles,
				rampList: rampList,
				lookup: lookup,
				pickups: pickups,
				monsters: monsters,
				layers: layers,
				player: player
			})));
		}
		if (!lookup[rightKey]) {
			landscapeTiles.push(lookup[rightKey] = self.parent.addChild(new LandscapeTile(self.x + TILE_SIZE, self.y, {
				key: rightKey,
				density: newDensity,
				xIndex: xIndex + 1,
				yIndex: yIndex,
				landscapeTiles: landscapeTiles,
				rampList: rampList,
				lookup: lookup,
				pickups: pickups,
				monsters: monsters,
				layers: layers,
				player: player
			})));
		}
		if (!lookup[downKey]) {
			landscapeTiles.push(lookup[downKey] = self.parent.addChild(new LandscapeTile(self.x, self.y + TILE_SIZE, {
				key: downKey,
				density: newDensity,
				yIndex: yIndex + 1,
				xIndex: xIndex,
				landscapeTiles: landscapeTiles,
				rampList: rampList,
				lookup: lookup,
				pickups: pickups,
				monsters: monsters,
				layers: layers,
				player: player
			})));
		}
		function randomPointInRect(centerX, centerY, width, height) {
			var border = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
			var startX = centerX - width / 2 + border;
			var startY = centerY - height / 2 + border;
			var innerWidth = width - border * 2;
			var innerHeight = height - border * 2;
			var pointX = startX + Math.random() * innerWidth;
			var pointY = startY + Math.random() * innerHeight;
			return {
				pointX: pointX,
				pointY: pointY
			};
		}
	}
});
var Ramp = Container.expand(function (x, y) {
	var self = Container.call(this);
	var rampPillar = self.createAsset('rampPillar', 'Ramp pillar graphics', 0.5, 0.5);
	var rampShadow = self.createAsset('rampShadow', 'Ramp shadow graphics', 0.5, -0.2);
	var rampGraphics = self.createAsset('ramp', 'Ramp graphics', 0.5, 0);
	var rampArrow = self.createAsset('rampArrow', 'Ramp direction arrow', 0.5, 0.5);
	var hitbox = self.createAsset('hitbox', 'Ramp hitbox', 0.5, 0);
	rampShadow.rotation = 0.1;
	rampShadow.alpha = SHADOW_BASE_ALPHA;
	rampPillar.y = rampGraphics.height;
	rampArrow.y = rampGraphics.height / 2;
	rampArrow.alpha = 0.85;
	hitbox.width = rampGraphics.width;
	hitbox.height = 50;
	hitbox.alpha = 0;
	;
	self.x = x;
	self.y = y;
	self.hitbox = hitbox;
	self.update = update;
	;
	function update(velocityX, velocityY, player) {
		self.x -= velocityX;
		self.y -= velocityY;
		if (self.y < -200) {
			return true;
		}
		if (!player.airborne && player.hitbox.intersects(self.hitbox)) {
			player.ramp();
		}
	}
});
var Obstruction = Container.expand(function (x, y, type) {
	var self = Container.call(this);
	var graphics = self.createAsset(type, 'Obstruction graphics', 0.5, 1);
	var hitbox = self.createAsset('hitbox', 'Obstruction hitbox', 0.5, 0.5);
	var randomScale = 0.9 + Math.random() * 0.2;
	hitbox.y = -25;
	hitbox.alpha = 0;
	hitbox.width = graphics.width * 0.8;
	hitbox.height = graphics.width * 0.45;
	;
	self.x = x;
	self.y = y;
	self.active = true;
	self.hitbox = hitbox;
	self.deactivate = deactivate;
	self.scale.set(randomScale, randomScale);
	;
	function deactivate() {
		self.active = false;
		graphics.alpha = 0.5;
	}
});
var Player = Container.expand(function (x, y) {
	var self = Container.call(this);
	var speed = 0;
	var reduction = 0;
	var travelDistX = 0;
	var travelDistY = 0;
	var rampRemaining = 0;
	var rampDuration = 0;
	var rampHeightMax = 0;
	var playerShadow = self.createAsset('shadow', 'Player shadow', 0.5, 0.5);
	var platformGraphics = self.createAsset('platform', 'Platform image', 0.4, 0.5);
	var playerFront = self.createAsset('playerFront', 'Player front graphic', 0.5, 1);
	var playerSide = self.createAsset('playerSide', 'Player side graphic', 0.5, 1);
	var hitbox = self.createAsset('hitbox', 'Player Hitbox', 0.5, 0.5);
	playerShadow.alpha = SHADOW_BASE_ALPHA;
	playerShadow.width = playerFront.width * 0.6;
	playerShadow.height = playerShadow.width * 0.6;
	hitbox.width = 25;
	hitbox.height = 25;
	hitbox.alpha = 0;
	;
	self.x = x;
	self.y = y;
	self.angle = 0;
	self.netSpeed = 0;
	self.airborne = false;
	self.rampHeight = 0;
	self.invulnerable = false;
	self.invulnerableTime = 3 * 60;
	self.invulnerableTimer = 0;
	self.distanceTravelled = 0;
	self.hitbox = hitbox;
	self.update = update;
	self.ramp = ramp;
	;
	function update(targetPosition) {
		if (self.invulnerable) {
			if (--self.invulnerableTimer <= 0) {
				self.invulnerable = false;
			}
			self.alpha = self.invulnerableTimer % 60 < 30 ? 1 : 0.5;
		}
		if (self.airborne) {
			if (--rampRemaining <= 0) {
				self.airborne = false;
			}
			self.rampHeight = rampHeightMax * Math.sin(Math.PI * rampRemaining / rampDuration);
			platformGraphics.y = playerFront.y = playerSide.y = -self.rampHeight;
			var shadowScale = (SHADOW_CRITICAL_HEIGHT - self.rampHeight) / SHADOW_CRITICAL_HEIGHT;
			playerShadow.alpha = SHADOW_BASE_ALPHA * shadowScale;
			playerShadow.scale.set(shadowScale);
		}
		if (!self.airborne) {
			var dx = targetPosition.x - self.x;
			var dy = targetPosition.y - self.y;
			self.angle = angleClamp(Math.atan2(dy, dx));
		}
		var acceleration = (Math.sin(self.angle) - PLAYER_ACCELERATION_ANGLE) * PLAYER_ACCELERATION_MAGNITUDE;
		var boost = self.airborne ? RAMP_SPEED_BOOST : 1;
		reduction = self.invulnerable ? 1 - self.invulnerableTimer / self.invulnerableTime : 1;
		speed = Math.max(0, speed * PLAYER_DECELERATION_FACTOR + acceleration);
		self.netSpeed = speed * reduction * boost;
		var velocityX = Math.cos(self.angle) * self.netSpeed;
		var velocityY = Math.sin(self.angle) * self.netSpeed;
		travelDistX += velocityX;
		travelDistY += velocityY;
		self.distanceTravelled = Math.sqrt(travelDistX * travelDistX + travelDistY * travelDistY);
		if (!self.airborne) {
			var facingSide = targetPosition.x < self.x ? -1 : 1;
			var criticalAngle = (MATH_PI_BY_2 - self.angle) / MATH_PI_BY_2;
			var imageAlpha = speed === 0 || Math.abs(criticalAngle) < PLAYER_FRONTFACE_FACTOR ? 1 : 0;
			var tiltAngle = self.netSpeed * criticalAngle / PLAYER_TILT_SPEED_FACTOR;
			platformGraphics.rotation = self.angle;
			playerFront.rotation = playerSide.rotation = tiltAngle;
			playerFront.scale.x = playerSide.scale.x = facingSide;
			playerFront.alpha = imageAlpha;
			playerSide.alpha = 1 - imageAlpha;
		}
		return {
			velocityX: velocityX,
			velocityY: velocityY
		};
	}
	function angleClamp(angle) {
		return angle >= 0 ? angle : angle < -MATH_PI_BY_2 ? Math.PI : 0;
	}
	function ramp() {
		if (!self.airborne && speed * reduction > RAMP_CRITICAL_SPEED) {
			var rampFactor = speed * reduction - RAMP_CRITICAL_REDUX;
			self.airborne = true;
			rampHeightMax = rampFactor * RAMP_SPEED_HEIGHT;
			rampDuration = Math.round(rampFactor * RAMP_SPEED_DURATION);
			rampRemaining = rampDuration;
		}
	}
});
var Trail = Container.expand(function (x, y) {
	var self = Container.call(this);
	var trailLength = 60;
	var trailAlpha = 0.4;
	var trailElements = [];
	;
	self.x = x;
	self.y = y;
	self.update = update;
	;
	function update(velocityX, velocityY, active) {
		var trailElement = null;
		if (active && (velocityX !== 0 || velocityY !== 0)) {
			trailElement = self.createAsset('trail', 'Trail element', 0, 0.5);
			var angle = Math.atan2(velocityY, velocityX);
			var speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
			trailElement.rotation = angle;
			trailElement.scale.x = speed / 100;
		}
		trailElements.push(trailElement);
		if (trailElements.length > trailLength) {
			var removedElement = trailElements.shift();
			if (removedElement) {
				removedElement.destroy();
			}
		}
		for (var i = trailElements.length - 1; i >= 0; i--) {
			var element = trailElements[i];
			if (element) {
				var alpha = trailAlpha * (i / trailLength);
				element.x -= velocityX;
				element.y -= velocityY;
				element.alpha = alpha;
			}
		}
	}
});
var Interface = Container.expand(function (x, y) {
	var self = Container.call(this);
	var lives = 3;
	var lifeIcons = [];
	var banner = self.createAsset('banner', 'Interface banner', 0.5, 0.5);
	var scoreIcon = self.createAsset('scoreIcon', 'Score icon', 1, 0.5);
	var dividor = self.createAsset('scoreDividor', 'Score dividor', 0.5, 0.5);
	var scoreText = self.addChild(new Text2(LK.getScore(), {
		size: 70,
		fill: "#000000",
		align: 'left'
	}));
	var distanceText = self.addChild(new Text2('0 m', {
		size: 70,
		fill: "#000000",
		align: 'right'
	}));
	var speedText = self.addChild(new Text2('0 m/s', {
		size: 70,
		fill: "#000000",
		align: 'right'
	}));
	for (var i = 0; i < lives; i++) {
		var lifeIcon = self.createAsset('lifeIcon', 'Life icon', 0, 0.5);
		lifeIcon.x = dividor.width / 2 + INTERFACE_DIVIDOR_BORDER + i * (lifeIcon.width + INTERFACE_SPACING);
		lifeIcons.push(lifeIcon);
	}
	scoreIcon.x = -(dividor.width / 2 + INTERFACE_DIVIDOR_BORDER);
	scoreText.x = scoreIcon.x - (scoreIcon.width + INTERFACE_SPACING);
	scoreText.anchor.set(1, 0.5);
	speedText.x = STAGE_WIDTH / 2 - 350;
	speedText.anchor.set(1, 0.5);
	distanceText.x = STAGE_WIDTH / 2 - 350;
	distanceText.y = speedText.y + speedText.height + INTERFACE_SPACING;
	distanceText.anchor.set(1, 0.5);
	;
	self.x = x;
	self.y = y;
	self.update = update;
	self.changeScore = changeScore;
	self.changeLives = changeLives;
	;
	function update(distance, netSpeed) {
		distanceText.setText(Math.round(distance * SCREEN_METERAGE) + ' m');
		speedText.setText((netSpeed * 60 * SCREEN_METERAGE).toFixed(1) + ' m/s');
	}
	function changeLives(amount) {
		lives += amount;
		for (var i = 0; i < lifeIcons.length; i++) {
			if (i < lives) {
				lifeIcons[i].alpha = 1;
				lifeIcons[i].tint = 0xFFFFFF;
			} else {
				lifeIcons[i].alpha = 0.5;
				lifeIcons[i].tint = 0x000000;
			}
		}
		if (amount < 0) {
			LK.effects.flashScreen(0xaa0000, 300);
			if (lives <= 0) {
				return true;
			}
		}
		return false;
	}
	function changeScore(amount) {
		var returnValue = amount < 0 && LK.getScore() > 0;
		LK.setScore(Math.max(0, LK.getScore() + amount));
		scoreText.setText(LK.getScore());
		return returnValue;
	}
});
var Instructions = Container.expand(function (x, y) {
	var self = Container.call(this);
	var instructionsText = 'Tap, click or drag to change direction';
	var warningText = 'Warning: Monsters ahead';
	var Distance;
	var fadeDistance = 1000;
	var fullDistance = 3000;
	var distanceRemaining = fullDistance;
	var instructionsShown = false;
	var warningShown = false;
	var warningOffset = 2000;
	var distanceY = 0;
	var displayText = self.addChild(new Text2('', {
		size: 70,
		fill: "#000000",
		align: 'center'
	}));
	displayText.anchor.set(0.5, 0.5);
	;
	self.x = x;
	self.y = y;
	self.update = update;
	;
	function update(velocityX, velocityY) {
		distanceY += velocityY;
		if (instructionsShown === false || warningShown === false && distanceY >= MONSTER_SPAWN_DIST - warningOffset) {
			if (instructionsShown === false) {
				instructionsShown = true;
				displayText.setText(instructionsText);
			} else {
				warningShown = true;
				displayText.setText(warningText);
			}
			distanceRemaining = fullDistance;
		}
		if (fadeDistance > 0) {
			distanceRemaining -= velocityY * INTERFACE_SIZE_FACTOR;
			displayText.alpha = Math.min(1, distanceRemaining / fadeDistance);
		}
	}
});
/**** 
* Initialize Game
****/
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/
;
var MATH_PI_BY_2 = Math.PI / 2;
var MATH_PI_BY_180 = Math.PI / 180;
var STAGE_WIDTH = 2048;
var STAGE_HEIGHT = 2732;
var SCREEN_METERAGE = 1 / 150;
var MONSTER_SPAWN_DIST = 100 / SCREEN_METERAGE;
var DIFFICULTY_FACTOR_DIST = 150 / SCREEN_METERAGE;
var TILE_SIZE = 512;
var TILE_MARGIN = TILE_SIZE;
var TILE_BACKGROUND_OFFSET = 100;
var PLAYER_ACCELERATION_ANGLE = 0.1;
var PLAYER_ACCELERATION_MAGNITUDE = 2.0;
var PLAYER_DECELERATION_FACTOR = 0.95;
var PLAYER_TILT_SPEED_FACTOR = 25 * MATH_PI_BY_2;
var PLAYER_COLLECTION_HEIGHT = -100;
var PLAYER_FRONTFACE_FACTOR = 0.2;
var PICKUP_FLIP_BASE = 10;
var PICKUP_FLIP_VARIANCE = 60;
var PICKUP_FLIP_SCALE = 0.8;
var PICKUP_COLLECT_DIST = 300;
var PICKUP_COLLECT_SQRDIST = PICKUP_COLLECT_DIST * PICKUP_COLLECT_DIST;
var PICKUP_TILT_DIST = 50;
var PICKUP_TILT_SQRDIST = PICKUP_TILT_DIST * PICKUP_TILT_DIST;
var PICKUP_TILT_BASE = 5 * MATH_PI_BY_180;
var PICKUP_TILT_VARIANCE = 60 * MATH_PI_BY_180;
var PICKUP_TILT_SCALE = 0.6;
var PICKUP_SPEED = 20;
var PICKUP_COLLIDE_DIST = 50;
var PICKUP_COLLIDE_SQRDIST = PICKUP_COLLIDE_DIST * PICKUP_COLLIDE_DIST;
var SPAWN_PICKUP_CHANCE = 0.05;
var SPAWN_MONSTER_CHANCE = 0.01;
var SPAWN_RAMP_CHANCE = 0.025;
var RAMP_CRITICAL_SPEED = 15.0;
var RAMP_CRITICAL_REDUX = 10;
var RAMP_SPEED_BOOST = 1.25;
var RAMP_SPEED_DURATION = 3.0;
var RAMP_SPEED_HEIGHT = 20.0;
var DROP_ANGLE_VARIANCE = 10 * MATH_PI_BY_180;
var SHADOW_BASE_ALPHA = 0.5;
var SHADOW_CRITICAL_HEIGHT = 1000;
var INTERFACE_HEIGHT_OFFSET = 40;
var INTERFACE_DIVIDOR_BORDER = -80;
var INTERFACE_SPACING = 10;
var INTERFACE_SIZE_FACTOR = 0.6;
var LAYER_BACKGROUND = 0;
var LAYER_MIDGROUND = 1;
var LAYER_FOREGROUND = 2;
;
var playerPosX = Math.round(STAGE_WIDTH / 2);
var playerPosY = Math.round(STAGE_WIDTH / 3);
var isMouseDown = false;
var targetPosition = {
	x: playerPosX,
	y: playerPosY
};
var landscapeLookup = {};
var landscapeTiles = [];
var pickups = [];
var pickupProjectileList = [];
var monsters = [];
var effects = [];
var rampList = [];
;
var layers = [game.addChild(new Container()), game.addChild(new Container()), game.addChild(new Container())];
var uiContainer = LK.gui.topCenter.addChild(new Interface(0, INTERFACE_HEIGHT_OFFSET));
var instructions = LK.gui.bottom.addChild(new Instructions(0, -2 * INTERFACE_HEIGHT_OFFSET));
var trail = layers[LAYER_BACKGROUND].addChild(new Trail(playerPosX, playerPosY));
var player = layers[LAYER_MIDGROUND].addChild(new Player(playerPosX, playerPosY));
landscapeTiles.push(landscapeLookup['0:0'] = layers[LAYER_FOREGROUND].addChild(new LandscapeTile(STAGE_WIDTH / 2, TILE_SIZE / 2, {
	density: -1,
	lookup: landscapeLookup,
	xIndex: 0,
	yIndex: 0,
	key: '0:0',
	landscapeTiles: landscapeTiles,
	rampList: rampList,
	monsters: monsters,
	pickups: pickups,
	layers: layers,
	player: player
})));
game.setBackgroundColor(0xFFFFFF);
;
game.on('down', function (obj) {
	isMouseDown = true;
	updatePosition(obj.event);
});
game.on('up', function (obj) {
	isMouseDown = false;
});
game.on('move', function (obj) {
	if (isMouseDown) {
		updatePosition(obj.event);
	}
});
LK.on('tick', function () {
	var _player$update = player.update(targetPosition),
		velocityX = _player$update.velocityX,
		velocityY = _player$update.velocityY;
	trail.update(velocityX, velocityY, !player.airborne);
	instructions.update(velocityX, velocityY);
	uiContainer.update(player.distanceTravelled, player.netSpeed);
	for (var i = landscapeTiles.length - 1; i >= 0; i--) {
		var landscapeTile = landscapeTiles[i];
		landscapeTile.x -= velocityX;
		landscapeTile.y -= velocityY;
		if (landscapeTile.y < -(TILE_SIZE / 2 + TILE_MARGIN)) {
			landscapeTile.destroy();
			landscapeTiles.splice(i, 1);
			landscapeLookup[landscapeTile.key] = undefined;
		} else if (!landscapeTile.active && landscapeTile.x > -TILE_MARGIN && landscapeTile.x < STAGE_WIDTH + TILE_MARGIN && landscapeTile.y < STAGE_HEIGHT + TILE_MARGIN) {
			landscapeTile.activate();
		} else if (landscapeTile.checkCollision(player)) {
			if (uiContainer.changeScore(-1)) {
				effects.push(layers[LAYER_FOREGROUND].addChild(new DropEffect(player.x, player.y + PLAYER_COLLECTION_HEIGHT, player)));
			}
			if (!player.invulnerable) {
				player.invulnerable = true;
				player.invulnerableTimer = player.invulnerableTime;
			}
		}
	}
	;
	var pickupArgs = {
		pickupProjectileList: pickupProjectileList,
		layers: layers,
		player: player
	};
	for (var i = pickups.length - 1; i >= 0; i--) {
		var pickup = pickups[i];
		if (pickup.update(velocityX, velocityY, pickupArgs)) {
			pickup.destroy();
			pickups.splice(i, 1);
		}
	}
	for (var i = effects.length - 1; i >= 0; i--) {
		var effect = effects[i];
		if (effect.update(velocityX, velocityY)) {
			effect.destroy();
			effects.splice(i, 1);
		}
	}
	for (var i = rampList.length - 1; i >= 0; i--) {
		var ramp = rampList[i];
		if (ramp.update(velocityX, velocityY, player)) {
			rampList.splice(i, 1);
		}
	}
	for (var i = monsters.length - 1; i >= 0; i--) {
		var monster = monsters[i];
		if (monster.update(velocityX, velocityY, player)) {
			monster.destroy();
			monsters.splice(i, 1);
		} else if (!monster.jumping && !player.airborne && monster.hitbox.intersects(player.hitbox)) {
			effects.push(layers[LAYER_FOREGROUND].addChild(new BloodsplatterEffect(monster.x, monster.y)));
			monster.destroy();
			monsters.splice(i, 1);
			if (uiContainer.changeLives(-1)) {
				LK.showGameOver();
			}
		}
	}
	for (var i = pickupProjectileList.length - 1; i >= 0; i--) {
		var pickupProjectile = pickupProjectileList[i];
		if (pickupProjectile.update()) {
			pickupProjectile.destroy();
			pickupProjectileList.splice(i, 1);
			uiContainer.changeScore(1);
		}
	}
});
;
function updatePosition(event) {
	var pos = event.getLocalPosition(game);
	targetPosition.x = pos.x;
	targetPosition.y = pos.y;
} ===================================================================
--- original.js
+++ change.js
@@ -1,4 +1,7 @@
+/**** 
+* Classes
+****/
 var DropEffect = Container.expand(function (x, y, player) {
 	var self = Container.call(this);
 	var angle = player.angle + Math.random() * DROP_ANGLE_VARIANCE;
 	var speed = 10 + Math.random() * 5;
@@ -140,9 +143,9 @@
 	self.y = y;
 	self.update = update;
 	;
 	function update(velocityX, velocityY, args) {
-		var {player} = args;
+		var player = args.player;
 		self.x -= velocityX;
 		self.y -= velocityY;
 		var dx = player.x - self.x;
 		var dy = player.y - self.y;
@@ -170,9 +173,11 @@
 		}
 		return Math.floor(value);
 	}
 	function activate(args) {
-		var {pickupProjectileList, player, layers} = args;
+		var pickupProjectileList = args.pickupProjectileList,
+			player = args.player,
+			layers = args.layers;
 		var projectileX = self.x + decor.x + decor.width / 2;
 		var projectileY = self.y + decor.y;
 		pickupProjectileList.push(layers[LAYER_FOREGROUND].addChild(new PickupProjectile(projectileX, projectileY, player)));
 		decor.destroy();
@@ -198,10 +203,21 @@
 		self.y += velocityY;
 		return distance <= PICKUP_COLLIDE_DIST;
 	}
 });
-var LandscapeTile = Container.expand(function (x, y, {lookup, xIndex, yIndex, density, pickups, monsters, player, key, landscapeTiles, layers, rampList}) {
+var LandscapeTile = Container.expand(function (x, y, _ref) {
 	var self = Container.call(this);
+	var lookup = _ref.lookup,
+		xIndex = _ref.xIndex,
+		yIndex = _ref.yIndex,
+		density = _ref.density,
+		pickups = _ref.pickups,
+		monsters = _ref.monsters,
+		player = _ref.player,
+		key = _ref.key,
+		landscapeTiles = _ref.landscapeTiles,
+		layers = _ref.layers,
+		rampList = _ref.rampList;
 	var obstructions = [];
 	var background = self.createAsset('landscapeBackground', 'Landscape background', 0.5, 0.5);
 	background.width = TILE_SIZE;
 	background.height = TILE_SIZE;
@@ -246,23 +262,31 @@
 			var cellWidth = TILE_SIZE / cols;
 			var cellHeight = TILE_SIZE / rows;
 			var landmark;
 			if (Math.random() <= SPAWN_PICKUP_CHANCE) {
-				var {pointX, pointY} = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist);
+				var _randomPointInRect = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist),
+					pointX = _randomPointInRect.pointX,
+					pointY = _randomPointInRect.pointY;
 				pickups.push(landmark = self.parent.addChild(new Pickup(pointX, pointY)));
 			} else if (Math.random() <= SPAWN_RAMP_CHANCE) {
-				var {pointX, pointY} = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist);
+				var _randomPointInRect2 = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist),
+					pointX = _randomPointInRect2.pointX,
+					pointY = _randomPointInRect2.pointY;
 				rampList.push(landmark = layers[LAYER_BACKGROUND].addChild(new Ramp(pointX, pointY)));
 			}
 			if (player.distanceTravelled > MONSTER_SPAWN_DIST && Math.random() <= SPAWN_MONSTER_CHANCE) {
-				var {pointX, pointY} = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist);
+				var _randomPointInRect3 = randomPointInRect(self.x, self.y, TILE_SIZE, TILE_SIZE, clearanceDist),
+					pointX = _randomPointInRect3.pointX,
+					pointY = _randomPointInRect3.pointY;
 				monsters.push(self.parent.addChild(new Monster(self.x, self.y)));
 			}
 			for (i = 0; i < cols; i++) {
 				for (j = 0; j < rows; j++) {
 					if (Math.random() <= densityChance) {
 						var canPlace = true;
-						var {pointX, pointY} = randomPointInRect(cellWidth * i, cellHeight * j, cellWidth, cellHeight, spawnBorder);
+						var _randomPointInRect4 = randomPointInRect(cellWidth * i, cellHeight * j, cellWidth, cellHeight, spawnBorder),
+							pointX = _randomPointInRect4.pointX,
+							pointY = _randomPointInRect4.pointY;
 						if (landmark) {
 							var dx = landmark.x - pointX;
 							var dy = landmark.y - pointY;
 							var distSqr = dx * dx + dy * dy;
@@ -286,58 +310,59 @@
 			landscapeTiles.push(lookup[leftKey] = self.parent.addChild(new LandscapeTile(self.x - TILE_SIZE, self.y, {
 				key: leftKey,
 				density: newDensity,
 				xIndex: xIndex - 1,
-				yIndex,
-				landscapeTiles,
-				rampList,
-				lookup,
-				pickups,
-				monsters,
-				layers,
-				player
+				yIndex: yIndex,
+				landscapeTiles: landscapeTiles,
+				rampList: rampList,
+				lookup: lookup,
+				pickups: pickups,
+				monsters: monsters,
+				layers: layers,
+				player: player
 			})));
 		}
 		if (!lookup[rightKey]) {
 			landscapeTiles.push(lookup[rightKey] = self.parent.addChild(new LandscapeTile(self.x + TILE_SIZE, self.y, {
 				key: rightKey,
 				density: newDensity,
 				xIndex: xIndex + 1,
-				yIndex,
-				landscapeTiles,
-				rampList,
-				lookup,
-				pickups,
-				monsters,
-				layers,
-				player
+				yIndex: yIndex,
+				landscapeTiles: landscapeTiles,
+				rampList: rampList,
+				lookup: lookup,
+				pickups: pickups,
+				monsters: monsters,
+				layers: layers,
+				player: player
 			})));
 		}
 		if (!lookup[downKey]) {
 			landscapeTiles.push(lookup[downKey] = self.parent.addChild(new LandscapeTile(self.x, self.y + TILE_SIZE, {
 				key: downKey,
 				density: newDensity,
 				yIndex: yIndex + 1,
-				xIndex,
-				landscapeTiles,
-				rampList,
-				lookup,
-				pickups,
-				monsters,
-				layers,
-				player
+				xIndex: xIndex,
+				landscapeTiles: landscapeTiles,
+				rampList: rampList,
+				lookup: lookup,
+				pickups: pickups,
+				monsters: monsters,
+				layers: layers,
+				player: player
 			})));
 		}
-		function randomPointInRect(centerX, centerY, width, height, border = 0) {
+		function randomPointInRect(centerX, centerY, width, height) {
+			var border = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
 			var startX = centerX - width / 2 + border;
 			var startY = centerY - height / 2 + border;
 			var innerWidth = width - border * 2;
 			var innerHeight = height - border * 2;
 			var pointX = startX + Math.random() * innerWidth;
 			var pointY = startY + Math.random() * innerHeight;
 			return {
-				pointX,
-				pointY
+				pointX: pointX,
+				pointY: pointY
 			};
 		}
 	}
 });
@@ -473,10 +498,10 @@
 			playerFront.alpha = imageAlpha;
 			playerSide.alpha = 1 - imageAlpha;
 		}
 		return {
-			velocityX,
-			velocityY
+			velocityX: velocityX,
+			velocityY: velocityY
 		};
 	}
 	function angleClamp(angle) {
 		return angle >= 0 ? angle : angle < -MATH_PI_BY_2 ? Math.PI : 0;
@@ -529,15 +554,14 @@
 	}
 });
 var Interface = Container.expand(function (x, y) {
 	var self = Container.call(this);
-	var score = 0;
 	var lives = 3;
 	var lifeIcons = [];
 	var banner = self.createAsset('banner', 'Interface banner', 0.5, 0.5);
 	var scoreIcon = self.createAsset('scoreIcon', 'Score icon', 1, 0.5);
 	var dividor = self.createAsset('scoreDividor', 'Score dividor', 0.5, 0.5);
-	var scoreText = self.addChild(new Text2(score, {
+	var scoreText = self.addChild(new Text2(LK.getScore(), {
 		size: 70,
 		fill: "#000000",
 		align: 'left'
 	}));
@@ -594,26 +618,66 @@
 		}
 		return false;
 	}
 	function changeScore(amount) {
-		var returnValue = amount < 0 && score > 0;
-		score = Math.max(0, score + amount);
-		LK.setScore(score);
-		scoreText.setText(score);
+		var returnValue = amount < 0 && LK.getScore() > 0;
+		LK.setScore(Math.max(0, LK.getScore() + amount));
+		scoreText.setText(LK.getScore());
 		return returnValue;
 	}
 });
-var Instructions = Container.expand(function () {
+var Instructions = Container.expand(function (x, y) {
 	var self = Container.call(this);
-	var instructionsText = self.addChild(new Text2('Tap, click or drag to change direction', {
-		size: 50,
+	var instructionsText = 'Tap, click or drag to change direction';
+	var warningText = 'Warning: Monsters ahead';
+	var Distance;
+	var fadeDistance = 1000;
+	var fullDistance = 3000;
+	var distanceRemaining = fullDistance;
+	var instructionsShown = false;
+	var warningShown = false;
+	var warningOffset = 2000;
+	var distanceY = 0;
+	var displayText = self.addChild(new Text2('', {
+		size: 70,
 		fill: "#000000",
 		align: 'center'
 	}));
-	instructionsText.anchor.set(0.5, 1);
-	instructionsText.x = 0;
-	instructionsText.y = 800;
+	displayText.anchor.set(0.5, 0.5);
+	;
+	self.x = x;
+	self.y = y;
+	self.update = update;
+	;
+	function update(velocityX, velocityY) {
+		distanceY += velocityY;
+		if (instructionsShown === false || warningShown === false && distanceY >= MONSTER_SPAWN_DIST - warningOffset) {
+			if (instructionsShown === false) {
+				instructionsShown = true;
+				displayText.setText(instructionsText);
+			} else {
+				warningShown = true;
+				displayText.setText(warningText);
+			}
+			distanceRemaining = fullDistance;
+		}
+		if (fadeDistance > 0) {
+			distanceRemaining -= velocityY * INTERFACE_SIZE_FACTOR;
+			displayText.alpha = Math.min(1, distanceRemaining / fadeDistance);
+		}
+	}
 });
+
+/**** 
+* Initialize Game
+****/
+var game = new LK.Game({
+	backgroundColor: 0x000000
+});
+
+/**** 
+* Game Code
+****/
 ;
 var MATH_PI_BY_2 = Math.PI / 2;
 var MATH_PI_BY_180 = Math.PI / 180;
 var STAGE_WIDTH = 2048;
@@ -656,137 +720,138 @@
 var SHADOW_CRITICAL_HEIGHT = 1000;
 var INTERFACE_HEIGHT_OFFSET = 40;
 var INTERFACE_DIVIDOR_BORDER = -80;
 var INTERFACE_SPACING = 10;
+var INTERFACE_SIZE_FACTOR = 0.6;
 var LAYER_BACKGROUND = 0;
 var LAYER_MIDGROUND = 1;
 var LAYER_FOREGROUND = 2;
 ;
-var Game = Container.expand(function () {
-	var self = Container.call(this);
-	var playerPosX = Math.round(STAGE_WIDTH / 2);
-	var playerPosY = Math.round(STAGE_WIDTH / 3);
-	var landscapeLookup = {};
-	var landscapeTiles = [];
-	var pickups = [];
-	var pickupProjectileList = [];
-	var monsters = [];
-	var effects = [];
-	var rampList = [];
-	;
-	var layers = [self.addChild(new Container()), self.addChild(new Container()), self.addChild(new Container())];
-	var interface = LK.gui.topCenter.addChild(new Interface(0, INTERFACE_HEIGHT_OFFSET));
-	var instructions = LK.gui.center.addChild(new Instructions());
-	var trail = layers[LAYER_BACKGROUND].addChild(new Trail(playerPosX, playerPosY));
-	var player = layers[LAYER_MIDGROUND].addChild(new Player(playerPosX, playerPosY));
-	landscapeTiles.push(landscapeLookup['0:0'] = layers[LAYER_FOREGROUND].addChild(new LandscapeTile(STAGE_WIDTH / 2, TILE_SIZE / 2, {
-		density: -1,
-		lookup: landscapeLookup,
-		xIndex: 0,
-		yIndex: 0,
-		key: '0:0',
-		landscapeTiles,
-		rampList,
-		monsters,
-		pickups,
-		layers,
-		player
-	})));
-	var isMouseDown = false;
-	var targetPosition = {
-		x: playerPosX,
-		y: playerPosY
-	};
-	LK.stageContainer.setBackgroundColor(0xFFFFFF);
-	;
-	stage.on('down', function (obj) {
-		isMouseDown = true;
+var playerPosX = Math.round(STAGE_WIDTH / 2);
+var playerPosY = Math.round(STAGE_WIDTH / 3);
+var isMouseDown = false;
+var targetPosition = {
+	x: playerPosX,
+	y: playerPosY
+};
+var landscapeLookup = {};
+var landscapeTiles = [];
+var pickups = [];
+var pickupProjectileList = [];
+var monsters = [];
+var effects = [];
+var rampList = [];
+;
+var layers = [game.addChild(new Container()), game.addChild(new Container()), game.addChild(new Container())];
+var uiContainer = LK.gui.topCenter.addChild(new Interface(0, INTERFACE_HEIGHT_OFFSET));
+var instructions = LK.gui.bottom.addChild(new Instructions(0, -2 * INTERFACE_HEIGHT_OFFSET));
+var trail = layers[LAYER_BACKGROUND].addChild(new Trail(playerPosX, playerPosY));
+var player = layers[LAYER_MIDGROUND].addChild(new Player(playerPosX, playerPosY));
+landscapeTiles.push(landscapeLookup['0:0'] = layers[LAYER_FOREGROUND].addChild(new LandscapeTile(STAGE_WIDTH / 2, TILE_SIZE / 2, {
+	density: -1,
+	lookup: landscapeLookup,
+	xIndex: 0,
+	yIndex: 0,
+	key: '0:0',
+	landscapeTiles: landscapeTiles,
+	rampList: rampList,
+	monsters: monsters,
+	pickups: pickups,
+	layers: layers,
+	player: player
+})));
+game.setBackgroundColor(0xFFFFFF);
+;
+game.on('down', function (obj) {
+	isMouseDown = true;
+	updatePosition(obj.event);
+});
+game.on('up', function (obj) {
+	isMouseDown = false;
+});
+game.on('move', function (obj) {
+	if (isMouseDown) {
 		updatePosition(obj.event);
-	});
-	stage.on('up', function (obj) {
-		isMouseDown = false;
-	});
-	stage.on('move', function (obj) {
-		if (isMouseDown) {
-			updatePosition(obj.event);
-		}
-	});
-	LK.on('tick', function () {
-		var {velocityX, velocityY} = player.update(targetPosition);
-		trail.update(velocityX, velocityY, !player.airborne);
-		interface.update(player.distanceTravelled, player.netSpeed);
-		for (var i = landscapeTiles.length - 1; i >= 0; i--) {
-			var landscapeTile = landscapeTiles[i];
-			landscapeTile.x -= velocityX;
-			landscapeTile.y -= velocityY;
-			if (landscapeTile.y < -(TILE_SIZE / 2 + TILE_MARGIN)) {
-				landscapeTile.destroy();
-				landscapeTiles.splice(i, 1);
-				landscapeLookup[landscapeTile.key] = undefined;
-			} else if (!landscapeTile.active && landscapeTile.x > -TILE_MARGIN && landscapeTile.x < STAGE_WIDTH + TILE_MARGIN && landscapeTile.y < STAGE_HEIGHT + TILE_MARGIN) {
-				landscapeTile.activate();
-			} else if (landscapeTile.checkCollision(player)) {
-				if (interface.changeScore(-1)) {
-					effects.push(layers[LAYER_FOREGROUND].addChild(new DropEffect(player.x, player.y + PLAYER_COLLECTION_HEIGHT, player)));
-				}
-				if (!player.invulnerable) {
-					player.invulnerable = true;
-					player.invulnerableTimer = player.invulnerableTime;
-				}
+	}
+});
+LK.on('tick', function () {
+	var _player$update = player.update(targetPosition),
+		velocityX = _player$update.velocityX,
+		velocityY = _player$update.velocityY;
+	trail.update(velocityX, velocityY, !player.airborne);
+	instructions.update(velocityX, velocityY);
+	uiContainer.update(player.distanceTravelled, player.netSpeed);
+	for (var i = landscapeTiles.length - 1; i >= 0; i--) {
+		var landscapeTile = landscapeTiles[i];
+		landscapeTile.x -= velocityX;
+		landscapeTile.y -= velocityY;
+		if (landscapeTile.y < -(TILE_SIZE / 2 + TILE_MARGIN)) {
+			landscapeTile.destroy();
+			landscapeTiles.splice(i, 1);
+			landscapeLookup[landscapeTile.key] = undefined;
+		} else if (!landscapeTile.active && landscapeTile.x > -TILE_MARGIN && landscapeTile.x < STAGE_WIDTH + TILE_MARGIN && landscapeTile.y < STAGE_HEIGHT + TILE_MARGIN) {
+			landscapeTile.activate();
+		} else if (landscapeTile.checkCollision(player)) {
+			if (uiContainer.changeScore(-1)) {
+				effects.push(layers[LAYER_FOREGROUND].addChild(new DropEffect(player.x, player.y + PLAYER_COLLECTION_HEIGHT, player)));
 			}
-		}
-		;
-		var pickupArgs = {
-			pickupProjectileList,
-			layers,
-			player
-		};
-		for (var i = pickups.length - 1; i >= 0; i--) {
-			var pickup = pickups[i];
-			if (pickup.update(velocityX, velocityY, pickupArgs)) {
-				pickup.destroy();
-				pickups.splice(i, 1);
+			if (!player.invulnerable) {
+				player.invulnerable = true;
+				player.invulnerableTimer = player.invulnerableTime;
 			}
 		}
-		for (var i = effects.length - 1; i >= 0; i--) {
-			var effect = effects[i];
-			if (effect.update(velocityX, velocityY)) {
-				effect.destroy();
-				effects.splice(i, 1);
-			}
+	}
+	;
+	var pickupArgs = {
+		pickupProjectileList: pickupProjectileList,
+		layers: layers,
+		player: player
+	};
+	for (var i = pickups.length - 1; i >= 0; i--) {
+		var pickup = pickups[i];
+		if (pickup.update(velocityX, velocityY, pickupArgs)) {
+			pickup.destroy();
+			pickups.splice(i, 1);
 		}
-		for (var i = rampList.length - 1; i >= 0; i--) {
-			var ramp = rampList[i];
-			if (ramp.update(velocityX, velocityY, player)) {
-				rampList.splice(i, 1);
-			}
+	}
+	for (var i = effects.length - 1; i >= 0; i--) {
+		var effect = effects[i];
+		if (effect.update(velocityX, velocityY)) {
+			effect.destroy();
+			effects.splice(i, 1);
 		}
-		for (var i = monsters.length - 1; i >= 0; i--) {
-			var monster = monsters[i];
-			if (monster.update(velocityX, velocityY, player)) {
-				monster.destroy();
-				monsters.splice(i, 1);
-			} else if (!monster.jumping && !player.airborne && monster.hitbox.intersects(player.hitbox)) {
-				effects.push(layers[LAYER_FOREGROUND].addChild(new BloodsplatterEffect(monster.x, monster.y)));
-				monster.destroy();
-				monsters.splice(i, 1);
-				if (interface.changeLives(-1)) {
-					LK.showGameOver();
-				}
-			}
+	}
+	for (var i = rampList.length - 1; i >= 0; i--) {
+		var ramp = rampList[i];
+		if (ramp.update(velocityX, velocityY, player)) {
+			rampList.splice(i, 1);
 		}
-		for (var i = pickupProjectileList.length - 1; i >= 0; i--) {
-			var pickupProjectile = pickupProjectileList[i];
-			if (pickupProjectile.update()) {
-				pickupProjectile.destroy();
-				pickupProjectileList.splice(i, 1);
-				interface.changeScore(1);
+	}
+	for (var i = monsters.length - 1; i >= 0; i--) {
+		var monster = monsters[i];
+		if (monster.update(velocityX, velocityY, player)) {
+			monster.destroy();
+			monsters.splice(i, 1);
+		} else if (!monster.jumping && !player.airborne && monster.hitbox.intersects(player.hitbox)) {
+			effects.push(layers[LAYER_FOREGROUND].addChild(new BloodsplatterEffect(monster.x, monster.y)));
+			monster.destroy();
+			monsters.splice(i, 1);
+			if (uiContainer.changeLives(-1)) {
+				LK.showGameOver();
 			}
 		}
-	});
-	;
-	function updatePosition(event) {
-		var pos = event.getLocalPosition(self);
-		targetPosition.x = pos.x;
-		targetPosition.y = pos.y;
 	}
+	for (var i = pickupProjectileList.length - 1; i >= 0; i--) {
+		var pickupProjectile = pickupProjectileList[i];
+		if (pickupProjectile.update()) {
+			pickupProjectile.destroy();
+			pickupProjectileList.splice(i, 1);
+			uiContainer.changeScore(1);
+		}
+	}
 });
+;
+function updatePosition(event) {
+	var pos = event.getLocalPosition(game);
+	targetPosition.x = pos.x;
+	targetPosition.y = pos.y;
+}
\ No newline at end of file
 pixel art of a tree stump covered in snow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of a dead tree covered in snow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of a spruce tree covered in snow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of a rock covered in snow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 Pixel art heart icon . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 two vertical lines with a blank background.
 pixel art of a large, snow covered rock . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of skiis . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of a floating grinch monster . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 single green firework explosion . Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of a wooden board covered in snow. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 pixel art of a wooden pole with snow at it's base. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 tileable white water texture pixel art.
 pixel art of a red flag. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 pixel art of a red orb. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 white
 white
 pixel art shape of a red arrow pointing downwards. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 
 
 
 pixel art banner of a pair of skis crossed. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
 white