/**** 
* Plugins
****/ 
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
// Ball class to create the bouncing ball
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Set initial position and velocity
	self.x = game.width / 2 + 100;
	self.y = game.height / 4;
	self.velocity = {
		x: 0,
		y: -20
	};
	self.immunity = 0;
	self.followers = 0;
	self.fallingActivated = false;
	self.vely = 1;
	// Function to update ball position
	self._update_migrated = function () {
		if (this.fallingActivated) {
			this.vely *= 1.1;
			this.width *= 1.02;
			this.height *= 1.02;
			this.rotation = -Math.PI / 4;
			this.y += this.vely / 5;
			this.zIndex = 10000;
			if (self.width > 1000) {
				self.destroy();
				LK.showGameOver();
			}
		} else {
			if (self.x > 500 && self.x < 1548) {
				self.x += self.velocity.x;
			}
			self.velocity.y += 1; // simple gravity
			platforms.forEach(function (platform) {
				platform.y -= self.velocity.y;
			});
		}
	};
	// Function to bounce the ball off platforms with a bounce counter
	self.bounceCounter = 0;
	self.bounce = function (platforms) {
		for (var i = platforms.length - 1; i > 0; i--) {
			var platform = platforms[i];
			if (platform && platform.collidable && platform.alpha == 1) {
				if (self.intersects(platform) && self.velocity.y > 0) {
					if (self.immunity > 0) {
						self.immunity--;
						platform.alpha = 0;
						// If immunity is spent, player jumps up, so he has time to dodge a possibly toxic platform below.
						if (self.immunity == 0) {
							self.velocity.y = -30;
						}
						break;
					}
					if (platform.toxic) {
						self.removeChild(self.getChildAt(0));
						self.attachAsset('newDeathSpriteId', {
							anchorX: 0.5,
							anchorY: 0.5
						});
						LK.getSound('GameOver').play();
						self.fallingActivated = true;
						gameEnding = true;
						break;
					}
					self.velocity.y *= -1;
					if (self.velocity.y < -40) {
						self.velocity.y = -40;
					}
					if (platform.powerupType == "Multiply") {
						multiplier++;
						LK.getSound('peanutCrunch').play();
					}
					platform.alpha = 0;
					if (platform.powerup == false) {
						var scoreIncrement = multiplier - 1;
						LK.setScore(LK.getScore() + scoreIncrement);
						// Create and display score label
						var scoreLabel = new ScoreLabel(scoreIncrement, self.x, self.y);
						scoreLabel.updateScore(scoreIncrement);
						scoreLabels.push(scoreLabel);
						game.addChild(scoreLabel);
						// play bounce sound effect
						if (soundFlip) {
							LK.getSound('bounce').play();
						} else {
							LK.getSound('bounce2').play();
						}
						soundFlip = !soundFlip;
					}
					if (platform.powerup == true) {
						self.velocity.y = platform.velocityBoost;
						self.immunity = platform.immunityBoost;
						var scoreIncrement = (multiplier - 1) * platform.scoreBoost;
						LK.setScore(LK.getScore() + scoreIncrement);
						// Create and display score label
						var scoreLabel = new ScoreLabel(scoreIncrement, self.x, self.y);
						scoreLabel.updateScore(scoreIncrement);
						scoreLabels.push(scoreLabel);
						game.addChild(scoreLabel);
						if (platform.powerupType != "Follow") {
							if (platform.powerupType == "Score") {
								LK.getSound('bonus').play();
							} else if (platform.powerupType == "Burst") {
								LK.getSound('burst').play();
							}
							platform.destroy();
						} else {
							self.followers += 1;
							platform.removeChild(platform.getChildAt(0));
							platform.attachAsset(platform.freeGraphicName, {
								anchorX: 0.5,
								anchorY: 0.5
							});
							LK.getSound(platform.freeSoundName).play();
							platform.followActivated = true;
							platform.alpha = 1;
							platform.collidable = false;
						}
					}
					playerScoreLabel.updateScore(LK.getScore());
					if (LK.getScore() > storage.bestScore) {
						storage.bestScore = LK.getScore();
						bestScoreTxt.setText('Best Score\n' + storage.bestScore);
					}
					if (platform.row > maxDepth) {
						maxDepth = platform.row;
					}
				}
			}
		}
	};
});
// Platform class to create movable platforms
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platformGraphics = self.attachAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = 200;
	self.height = 60;
	self.toxic = false;
	self.row = 0;
	self.col = 0;
	self.powerup = false;
	self.collidable = true;
	// Set platform tint based on toxicity
	self.setTint = function () {
		if (platformGraphics) {
			if (this.toxic) {
				self.removeChild(platformGraphics);
				platformGraphics = self.attachAsset('spikyPlatform', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.width = 220;
				self.height = 90;
			} else {
				platformGraphics.tint = 0xffffff;
				self.removeChild(platformGraphics);
				platformGraphics = self.attachAsset('platform', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.width = 200;
				self.height = 60;
			}
		}
	};
	self.setTint();
});
var PlayerScoreLabel = Container.expand(function () {
	var self = Container.call(this);
	var scoreText = new Text2('0', {
		size: 150,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(0.5, 0);
	self.addChild(scoreText);
	self.updateScore = function (newScore) {
		scoreText.setText(newScore.toString());
	};
	self.updateScore(0); // Initialize with 0 score
});
var PowerupBluebird = Container.expand(function () {
	var self = Container.call(this);
	var powerupBluebirdGraphics = self.attachAsset('powerupBluebird', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Follow";
	self.freeGraphicName = "bluebirdFreeGraphic";
	self.freeSoundName = "bird3";
	self.followActivated = false;
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 20;
	self.vely = 1;
	self._update_migrated = function () {
		if (this.followActivated) {
			if (self.x > 1024) {
				this.x += 4;
			} else {
				this.x -= 4;
			}
			this.vely *= 1.1;
			this.width *= 1.01;
			this.height *= 1.01;
			this.y -= this.vely;
			if (self.x < -self.width / 2 || self.x > 2048 + self.width / 2) {
				self.destroy();
			}
		}
	};
});
var PowerupBurst = Container.expand(function () {
	var self = Container.call(this);
	var powerupBurstGraphics = self.attachAsset('powerupBurst', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Burst";
	self.collidable = true;
	self.velocityBoost = 50;
	self.immunityBoost = 10;
	self.scoreBoost = 10;
});
var PowerupFollow = Container.expand(function () {
	var self = Container.call(this);
	var powerupFollowGraphics = self.attachAsset('powerupFollow', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Follow";
	self.followActivated = false;
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 10;
	self.vely = 1;
	self.freeGraphicName = 'powerupFollowFree';
	self.freeSoundName = "bird1";
	self._update_migrated = function () {
		if (this.followActivated) {
			if (self.x > 1024) {
				this.x += 4;
			} else {
				this.x -= 4;
			}
			this.vely *= 1.1;
			this.width *= 1.01;
			this.height *= 1.01;
			this.y -= this.vely;
			if (self.x < -self.width / 2 || self.x > 2048 + self.width / 2) {
				self.destroy();
			}
		}
	};
});
var PowerupGreenbird = Container.expand(function () {
	var self = Container.call(this);
	var powerupGreenbirdGraphics = self.attachAsset('powerupGreenbird', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Follow";
	self.freeGraphicName = "greenbirdFreeGraphic";
	self.freeSoundName = "bird2";
	self.followActivated = false;
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 30;
	self.vely = 1;
	self._update_migrated = function () {
		if (this.followActivated) {
			if (self.x > 1024) {
				this.x += 4;
			} else {
				this.x -= 4;
			}
			this.vely *= 1.1;
			this.width *= 1.01;
			this.height *= 1.01;
			this.y -= this.vely;
			if (self.x < -self.width / 2 || self.x > 2048 + self.width / 2) {
				self.destroy();
			}
		}
	};
});
var PowerupMultiply = Container.expand(function () {
	var self = Container.call(this);
	var powerupMultiplyGraphics = self.attachAsset('powerupMultiply', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Multiply";
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 1;
	self.rotation = Math.PI / 4;
});
var PowerupScore = Container.expand(function () {
	var self = Container.call(this);
	var powerupScoreGraphics = self.attachAsset('powerupScore', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Score";
	self.collidable = true;
	self.scoreVal = 0;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 0;
	var valText = new Text2('0', {
		size: 43,
		fill: 0x000000,
		outline: true
	});
	valText.anchor.set(0.5, 0.5);
	self.addChild(valText);
	self.updateLabel = function (newVal) {
		valText.setText('x' + self.scoreVal.toString());
		self.scoreBoost = newVal;
	};
	self.updateLabel(self.scoreVal);
});
/* 
TODO:
--------------------
Bugs:
* Consider shaft method for difficulty ramping.
* Now that player graphic is bigger, it sometimes collides with platforms from below. Either adjust size, spacing
or jump height/logic.
* Maybe player should have three lives - shown as little red hearts in top right corner.
---------------------
Interface/graphics:
* Show instructions on screen at start.
* Maybe elephant should face the last direction it moved.
--------------
Powerup ideas:
* A powerup that removes all nearby platforms and give score for them.
* Maybe make a disco powerup that changes light, colors or visuals somehow.
* Consider platforms that increase or decrease the size/weight of the character.
* Or maybe just a platform with a piece of cake on it, and when player lands there he gets 10 points and swells up
(no gameplay side effects) for 5 seconds. Could actually be all kinds of funny pickups like that.
* Different hats that the player will wear until a new one is picked up?
----------
Gameplay:
* Consider difficulty ramping. More red platforms?
* Make sure red platforms never fully block the way. Platforms have row and column id's to pattern match against.
-----------
Theming:
* Consider possible player character.
* A frog? A kangaroo? A spring? A tennisball? A rabbit? A two-headed squirrel? Something on a pogostick?
* A Rick Dangerous finding treasures on the platforms?
* A Pirate Ship finding bounty on platforms? Maybe beats platforms with less strength than they have?
* A cat eating sushi on each platform?
* A princess saving animals on every tenth platform?
* Maybe all those characters, each triggered by a powerup until a new one is picked up.
* Maybe new mode unlocked per 200 platforms or so?
----------
*/
var ScoreLabel = Container.expand(function (scoreValue, posX, posY) {
	var self = Container.call(this);
	var scoreText = new Text2(scoreValue.toString(), {
		size: 150,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(0.5, 0.5);
	self.addChild(scoreText);
	self.x = posX;
	self.y = posY;
	var angle = Math.random() * Math.PI; // Random angle in radians
	self.dx = Math.cos(angle) * 4; // Horizontal drift
	self.dy = Math.sin(angle) * 8; // Vertical drift
	// Animation for the score label to drift upwards and fade out
	var driftFrames = 60;
	self._update_migrated = function () {
		if (driftFrames > 0) {
			self.x += self.dx;
			self.y -= self.dy;
			scoreText.alpha -= 0.005;
			driftFrames--;
		} else {
			self.destroy();
		}
	};
	self.updateScore = function (newScore) {
		scoreText.setText(newScore.toString());
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x517425 // Init game with black background
});
/**** 
* Game Code
****/ 
//LK.init.shape('sideBarrier', {width:100, height:100, color:0xff0000, shape:'box'})
var blackBgGraphic = game.addChild(LK.getAsset('blackBg', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 1024,
	// Centered on x-axis
	y: 1366 // Centered on y-axis
}));
blackBgGraphic.zIndex = -2;
// Create background graphic and add it to the game
// Initialize background graphic asset
var backgroundGraphic = game.addChild(LK.getAsset('background', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 1024,
	// Centered on x-axis
	y: 1366 // Centered on y-axis
}));
backgroundGraphic.zIndex = -1; // Ensure it's beneath everything
backgroundGraphic.alpha = 0.8;
var platforms = [];
var scoreLabels = [];
var moveLeftFrames = 0;
var moveRightFrames = 0;
var rowAmount = 13;
var maxDepth = 0;
var multiplier = 2;
var gameEnding = false;
var soundFlip = true;
// Create player score label
var playerScoreLabel = new PlayerScoreLabel();
LK.gui.top.addChild(playerScoreLabel);
var bestScoreTxt = new Text2('Best Score\n0', {
	size: 50,
	fill: 0xFFFFFF,
	align: 'center'
});
bestScoreTxt.x = -300; //2048 - 300;
//bestScoreTxt.y = 50;
storage.bestScore = storage.bestScore || 0;
bestScoreTxt.setText('Best Score\n' + storage.bestScore);
//game.addChild(bestScoreTxt);
LK.gui.topRight.addChild(bestScoreTxt);
// Create 14 rows of 5 platforms each at game start
for (var row = 0; row < rowAmount; row++) {
	for (var col = 0; col < 5; col++) {
		var platform = new Platform();
		if (row < rowAmount / 2) {
			platform.alpha = 0;
			platform.toxic = false;
		} else if (row === Math.ceil(rowAmount / 2)) {
			platform.alpha = 1;
			platform.toxic = false;
		} else {
			platform.alpha = Math.random() < 0.5 ? 1 : 0;
			platform.toxic = Math.random() < 0.1 ? true : false;
		}
		platform.setTint();
		platform.y = game.height - 2000 + row * 300;
		platform.x = 2048 / 2 + (2 - col) * (platform.width + 200);
		platform.row = row;
		platform.col = col;
		platforms.push(platform);
		game.addChild(platform);
	}
}
var ball = new Ball();
ball.x = 1024;
game.addChild(ball);
// Handle touch move events to move platforms
function handleMove(obj) {
	var event = obj.event;
	var position = game.toLocal(event.global);
	// Move ball depending on whether click is left or right of it.
	if (position.x > ball.x) {
		// Take previous clicks into account, so ball can't fly off stage.
		if (ball.x < 2048 - (300 + moveRightFrames * 40)) {
			moveRightFrames += 10;
			ball.getChildAt(0).scale.x = -1;
		}
	} else {
		// Take previous clicks into account, so ball can't fly off stage.
		if (ball.x > 300 + moveLeftFrames * 40) {
			moveLeftFrames += 10;
			ball.getChildAt(0).scale.x = 1;
		}
	}
}
// Add event listener for touch down
game.on('down', function (x, y, obj) {
	obj.event = obj;
	handleMove(obj);
});
//console.log(LK.getSound('ambience'));
//console.log(LK);
//LK.getSound('ambience').loop = true;
//LK.getSound('ambience').play();
var bgMusic = LK.getSound('ambience');
bgMusic.play();
LK.setInterval(function () {
	bgMusic.play();
}, 9215);
// Game tick event
LK.on('tick', function () {
	if (gameEnding) {
		ball._update_migrated(platforms);
		platforms.forEach(function (platform) {
			if (platform._update_migrated) {
				platform._update_migrated();
			}
		});
		scoreLabels.forEach(function (scoreLabel) {
			if (scoreLabel._update_migrated) {
				scoreLabel._update_migrated();
			}
		});
	} else {
		/* 
		if (LK.ticks % 120 == 0) {
		console.log('Platforms.length is now: ' + platforms.length);
		}*/
		scoreLabels.forEach(function (scoreLabel) {
			if (scoreLabel._update_migrated) {
				scoreLabel._update_migrated();
			}
		});
		// Update ball position
		ball._update_migrated(platforms);
		// Check for ball bouncing off platforms
		ball.bounce(platforms);
		if (moveLeftFrames > 0) {
			moveLeftFrames--;
			ball.x -= 40;
		}
		if (moveRightFrames > 0) {
			moveRightFrames--;
			ball.x += 40;
		}
		var newPlatforms = [];
		for (var i = platforms.length - 1; i > 0; i--) {
			var platform = platforms[i];
			if (platform._update_migrated) {
				platform._update_migrated();
			}
			if (platform.y < -900) {
				platform.y += rowAmount * 300;
				platform.row += rowAmount;
				// Only randomize normal platforms, not sidebarriers.
				if (platform.height < 100) {
					platform.alpha = Math.random() < 0.55 ? 1 : 0;
					platform.toxic = Math.random() < 0.1 ? true : false;
					// Make a shaft
					var rowRel = platform.row % 100;
					if (platform.col == 0) {
						if (rowRel > 10 && rowRel < 20) {
							platform.alpha = rowRel == 19 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 1) {
						if (rowRel > 70 && rowRel < 80) {
							platform.alpha = rowRel == 79 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 2) {
						if (rowRel > 30 && rowRel < 40) {
							platform.alpha = rowRel == 39 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 3) {
						if (rowRel > 90 && rowRel < 100) {
							platform.alpha = rowRel == 99 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 4) {
						if (rowRel > 50 && rowRel < 60) {
							platform.alpha = rowRel == 59 ? 1 : 0;
							platform.toxic = false;
						}
					}
					platform.setTint();
					// Chance that powerups are spawned on normal platforms
					if (platform.alpha == 1 && platform.powerup == false && !platform.toxic) {
						if (Math.random() < 0.01) {
							var t = new PowerupBurst();
							t.x = platform.x;
							t.y = platform.y - t.height;
							newPlatforms.push(t);
							game.addChild(t);
						} else if (platform.row % 25 == 0 && Math.random() < 0.5) {
							var t = new PowerupScore();
							t.x = platform.x;
							t.y = platform.y - t.height;
							t.scoreVal = platform.row;
							t.updateLabel(t.scoreVal);
							newPlatforms.push(t);
							game.addChild(t);
						} else if (Math.random() < 0.1) {
							var t = new PowerupMultiply();
							t.x = platform.x;
							t.y = platform.y - t.height / 1.7;
							newPlatforms.push(t);
							game.addChild(t);
						} else if (Math.random() < 0.1) {
							if (maxDepth < 50) {
								var t = new PowerupFollow();
							} else if (maxDepth < 100) {
								if (Math.random() < 0.5) {
									var t = new PowerupFollow();
								} else {
									var t = new PowerupBluebird();
								}
							} else {
								var r = Math.random();
								if (r < 0.33) {
									var t = new PowerupFollow();
								} else if (r < 0.66) {
									var t = new PowerupBluebird();
								} else {
									var t = new PowerupGreenbird();
								}
							}
							t.x = platform.x;
							t.y = platform.y - t.height;
							newPlatforms.push(t);
							game.addChild(t);
						}
					}
				}
				// Powerups don't automatically respawn below when they move off screen top edge.
				if (platform.powerup == true) {
					platform.destroy();
					platforms.splice(i, 1);
				}
			}
		}
		platforms.push.apply(platforms, newPlatforms);
	}
}); /**** 
* Plugins
****/ 
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
// Ball class to create the bouncing ball
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	// Set initial position and velocity
	self.x = game.width / 2 + 100;
	self.y = game.height / 4;
	self.velocity = {
		x: 0,
		y: -20
	};
	self.immunity = 0;
	self.followers = 0;
	self.fallingActivated = false;
	self.vely = 1;
	// Function to update ball position
	self._update_migrated = function () {
		if (this.fallingActivated) {
			this.vely *= 1.1;
			this.width *= 1.02;
			this.height *= 1.02;
			this.rotation = -Math.PI / 4;
			this.y += this.vely / 5;
			this.zIndex = 10000;
			if (self.width > 1000) {
				self.destroy();
				LK.showGameOver();
			}
		} else {
			if (self.x > 500 && self.x < 1548) {
				self.x += self.velocity.x;
			}
			self.velocity.y += 1; // simple gravity
			platforms.forEach(function (platform) {
				platform.y -= self.velocity.y;
			});
		}
	};
	// Function to bounce the ball off platforms with a bounce counter
	self.bounceCounter = 0;
	self.bounce = function (platforms) {
		for (var i = platforms.length - 1; i > 0; i--) {
			var platform = platforms[i];
			if (platform && platform.collidable && platform.alpha == 1) {
				if (self.intersects(platform) && self.velocity.y > 0) {
					if (self.immunity > 0) {
						self.immunity--;
						platform.alpha = 0;
						// If immunity is spent, player jumps up, so he has time to dodge a possibly toxic platform below.
						if (self.immunity == 0) {
							self.velocity.y = -30;
						}
						break;
					}
					if (platform.toxic) {
						self.removeChild(self.getChildAt(0));
						self.attachAsset('newDeathSpriteId', {
							anchorX: 0.5,
							anchorY: 0.5
						});
						LK.getSound('GameOver').play();
						self.fallingActivated = true;
						gameEnding = true;
						break;
					}
					self.velocity.y *= -1;
					if (self.velocity.y < -40) {
						self.velocity.y = -40;
					}
					if (platform.powerupType == "Multiply") {
						multiplier++;
						LK.getSound('peanutCrunch').play();
					}
					platform.alpha = 0;
					if (platform.powerup == false) {
						var scoreIncrement = multiplier - 1;
						LK.setScore(LK.getScore() + scoreIncrement);
						// Create and display score label
						var scoreLabel = new ScoreLabel(scoreIncrement, self.x, self.y);
						scoreLabel.updateScore(scoreIncrement);
						scoreLabels.push(scoreLabel);
						game.addChild(scoreLabel);
						// play bounce sound effect
						if (soundFlip) {
							LK.getSound('bounce').play();
						} else {
							LK.getSound('bounce2').play();
						}
						soundFlip = !soundFlip;
					}
					if (platform.powerup == true) {
						self.velocity.y = platform.velocityBoost;
						self.immunity = platform.immunityBoost;
						var scoreIncrement = (multiplier - 1) * platform.scoreBoost;
						LK.setScore(LK.getScore() + scoreIncrement);
						// Create and display score label
						var scoreLabel = new ScoreLabel(scoreIncrement, self.x, self.y);
						scoreLabel.updateScore(scoreIncrement);
						scoreLabels.push(scoreLabel);
						game.addChild(scoreLabel);
						if (platform.powerupType != "Follow") {
							if (platform.powerupType == "Score") {
								LK.getSound('bonus').play();
							} else if (platform.powerupType == "Burst") {
								LK.getSound('burst').play();
							}
							platform.destroy();
						} else {
							self.followers += 1;
							platform.removeChild(platform.getChildAt(0));
							platform.attachAsset(platform.freeGraphicName, {
								anchorX: 0.5,
								anchorY: 0.5
							});
							LK.getSound(platform.freeSoundName).play();
							platform.followActivated = true;
							platform.alpha = 1;
							platform.collidable = false;
						}
					}
					playerScoreLabel.updateScore(LK.getScore());
					if (LK.getScore() > storage.bestScore) {
						storage.bestScore = LK.getScore();
						bestScoreTxt.setText('Best Score\n' + storage.bestScore);
					}
					if (platform.row > maxDepth) {
						maxDepth = platform.row;
					}
				}
			}
		}
	};
});
// Platform class to create movable platforms
var Platform = Container.expand(function () {
	var self = Container.call(this);
	var platformGraphics = self.attachAsset('platform', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = 200;
	self.height = 60;
	self.toxic = false;
	self.row = 0;
	self.col = 0;
	self.powerup = false;
	self.collidable = true;
	// Set platform tint based on toxicity
	self.setTint = function () {
		if (platformGraphics) {
			if (this.toxic) {
				self.removeChild(platformGraphics);
				platformGraphics = self.attachAsset('spikyPlatform', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.width = 220;
				self.height = 90;
			} else {
				platformGraphics.tint = 0xffffff;
				self.removeChild(platformGraphics);
				platformGraphics = self.attachAsset('platform', {
					anchorX: 0.5,
					anchorY: 0.5
				});
				self.width = 200;
				self.height = 60;
			}
		}
	};
	self.setTint();
});
var PlayerScoreLabel = Container.expand(function () {
	var self = Container.call(this);
	var scoreText = new Text2('0', {
		size: 150,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(0.5, 0);
	self.addChild(scoreText);
	self.updateScore = function (newScore) {
		scoreText.setText(newScore.toString());
	};
	self.updateScore(0); // Initialize with 0 score
});
var PowerupBluebird = Container.expand(function () {
	var self = Container.call(this);
	var powerupBluebirdGraphics = self.attachAsset('powerupBluebird', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Follow";
	self.freeGraphicName = "bluebirdFreeGraphic";
	self.freeSoundName = "bird3";
	self.followActivated = false;
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 20;
	self.vely = 1;
	self._update_migrated = function () {
		if (this.followActivated) {
			if (self.x > 1024) {
				this.x += 4;
			} else {
				this.x -= 4;
			}
			this.vely *= 1.1;
			this.width *= 1.01;
			this.height *= 1.01;
			this.y -= this.vely;
			if (self.x < -self.width / 2 || self.x > 2048 + self.width / 2) {
				self.destroy();
			}
		}
	};
});
var PowerupBurst = Container.expand(function () {
	var self = Container.call(this);
	var powerupBurstGraphics = self.attachAsset('powerupBurst', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Burst";
	self.collidable = true;
	self.velocityBoost = 50;
	self.immunityBoost = 10;
	self.scoreBoost = 10;
});
var PowerupFollow = Container.expand(function () {
	var self = Container.call(this);
	var powerupFollowGraphics = self.attachAsset('powerupFollow', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Follow";
	self.followActivated = false;
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 10;
	self.vely = 1;
	self.freeGraphicName = 'powerupFollowFree';
	self.freeSoundName = "bird1";
	self._update_migrated = function () {
		if (this.followActivated) {
			if (self.x > 1024) {
				this.x += 4;
			} else {
				this.x -= 4;
			}
			this.vely *= 1.1;
			this.width *= 1.01;
			this.height *= 1.01;
			this.y -= this.vely;
			if (self.x < -self.width / 2 || self.x > 2048 + self.width / 2) {
				self.destroy();
			}
		}
	};
});
var PowerupGreenbird = Container.expand(function () {
	var self = Container.call(this);
	var powerupGreenbirdGraphics = self.attachAsset('powerupGreenbird', {
		anchorX: 0.5,
		anchorY: 0
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Follow";
	self.freeGraphicName = "greenbirdFreeGraphic";
	self.freeSoundName = "bird2";
	self.followActivated = false;
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 30;
	self.vely = 1;
	self._update_migrated = function () {
		if (this.followActivated) {
			if (self.x > 1024) {
				this.x += 4;
			} else {
				this.x -= 4;
			}
			this.vely *= 1.1;
			this.width *= 1.01;
			this.height *= 1.01;
			this.y -= this.vely;
			if (self.x < -self.width / 2 || self.x > 2048 + self.width / 2) {
				self.destroy();
			}
		}
	};
});
var PowerupMultiply = Container.expand(function () {
	var self = Container.call(this);
	var powerupMultiplyGraphics = self.attachAsset('powerupMultiply', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Multiply";
	self.collidable = true;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 1;
	self.rotation = Math.PI / 4;
});
var PowerupScore = Container.expand(function () {
	var self = Container.call(this);
	var powerupScoreGraphics = self.attachAsset('powerupScore', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.col = 0;
	self.row = 0;
	self.toxic = false;
	self.powerup = true;
	self.powerupType = "Score";
	self.collidable = true;
	self.scoreVal = 0;
	self.velocityBoost = 25;
	self.immunityBoost = 0;
	self.scoreBoost = 0;
	var valText = new Text2('0', {
		size: 43,
		fill: 0x000000,
		outline: true
	});
	valText.anchor.set(0.5, 0.5);
	self.addChild(valText);
	self.updateLabel = function (newVal) {
		valText.setText('x' + self.scoreVal.toString());
		self.scoreBoost = newVal;
	};
	self.updateLabel(self.scoreVal);
});
/* 
TODO:
--------------------
Bugs:
* Consider shaft method for difficulty ramping.
* Now that player graphic is bigger, it sometimes collides with platforms from below. Either adjust size, spacing
or jump height/logic.
* Maybe player should have three lives - shown as little red hearts in top right corner.
---------------------
Interface/graphics:
* Show instructions on screen at start.
* Maybe elephant should face the last direction it moved.
--------------
Powerup ideas:
* A powerup that removes all nearby platforms and give score for them.
* Maybe make a disco powerup that changes light, colors or visuals somehow.
* Consider platforms that increase or decrease the size/weight of the character.
* Or maybe just a platform with a piece of cake on it, and when player lands there he gets 10 points and swells up
(no gameplay side effects) for 5 seconds. Could actually be all kinds of funny pickups like that.
* Different hats that the player will wear until a new one is picked up?
----------
Gameplay:
* Consider difficulty ramping. More red platforms?
* Make sure red platforms never fully block the way. Platforms have row and column id's to pattern match against.
-----------
Theming:
* Consider possible player character.
* A frog? A kangaroo? A spring? A tennisball? A rabbit? A two-headed squirrel? Something on a pogostick?
* A Rick Dangerous finding treasures on the platforms?
* A Pirate Ship finding bounty on platforms? Maybe beats platforms with less strength than they have?
* A cat eating sushi on each platform?
* A princess saving animals on every tenth platform?
* Maybe all those characters, each triggered by a powerup until a new one is picked up.
* Maybe new mode unlocked per 200 platforms or so?
----------
*/
var ScoreLabel = Container.expand(function (scoreValue, posX, posY) {
	var self = Container.call(this);
	var scoreText = new Text2(scoreValue.toString(), {
		size: 150,
		fill: 0xFFFFFF
	});
	scoreText.anchor.set(0.5, 0.5);
	self.addChild(scoreText);
	self.x = posX;
	self.y = posY;
	var angle = Math.random() * Math.PI; // Random angle in radians
	self.dx = Math.cos(angle) * 4; // Horizontal drift
	self.dy = Math.sin(angle) * 8; // Vertical drift
	// Animation for the score label to drift upwards and fade out
	var driftFrames = 60;
	self._update_migrated = function () {
		if (driftFrames > 0) {
			self.x += self.dx;
			self.y -= self.dy;
			scoreText.alpha -= 0.005;
			driftFrames--;
		} else {
			self.destroy();
		}
	};
	self.updateScore = function (newScore) {
		scoreText.setText(newScore.toString());
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x517425 // Init game with black background
});
/**** 
* Game Code
****/ 
//LK.init.shape('sideBarrier', {width:100, height:100, color:0xff0000, shape:'box'})
var blackBgGraphic = game.addChild(LK.getAsset('blackBg', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 1024,
	// Centered on x-axis
	y: 1366 // Centered on y-axis
}));
blackBgGraphic.zIndex = -2;
// Create background graphic and add it to the game
// Initialize background graphic asset
var backgroundGraphic = game.addChild(LK.getAsset('background', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 1024,
	// Centered on x-axis
	y: 1366 // Centered on y-axis
}));
backgroundGraphic.zIndex = -1; // Ensure it's beneath everything
backgroundGraphic.alpha = 0.8;
var platforms = [];
var scoreLabels = [];
var moveLeftFrames = 0;
var moveRightFrames = 0;
var rowAmount = 13;
var maxDepth = 0;
var multiplier = 2;
var gameEnding = false;
var soundFlip = true;
// Create player score label
var playerScoreLabel = new PlayerScoreLabel();
LK.gui.top.addChild(playerScoreLabel);
var bestScoreTxt = new Text2('Best Score\n0', {
	size: 50,
	fill: 0xFFFFFF,
	align: 'center'
});
bestScoreTxt.x = -300; //2048 - 300;
//bestScoreTxt.y = 50;
storage.bestScore = storage.bestScore || 0;
bestScoreTxt.setText('Best Score\n' + storage.bestScore);
//game.addChild(bestScoreTxt);
LK.gui.topRight.addChild(bestScoreTxt);
// Create 14 rows of 5 platforms each at game start
for (var row = 0; row < rowAmount; row++) {
	for (var col = 0; col < 5; col++) {
		var platform = new Platform();
		if (row < rowAmount / 2) {
			platform.alpha = 0;
			platform.toxic = false;
		} else if (row === Math.ceil(rowAmount / 2)) {
			platform.alpha = 1;
			platform.toxic = false;
		} else {
			platform.alpha = Math.random() < 0.5 ? 1 : 0;
			platform.toxic = Math.random() < 0.1 ? true : false;
		}
		platform.setTint();
		platform.y = game.height - 2000 + row * 300;
		platform.x = 2048 / 2 + (2 - col) * (platform.width + 200);
		platform.row = row;
		platform.col = col;
		platforms.push(platform);
		game.addChild(platform);
	}
}
var ball = new Ball();
ball.x = 1024;
game.addChild(ball);
// Handle touch move events to move platforms
function handleMove(obj) {
	var event = obj.event;
	var position = game.toLocal(event.global);
	// Move ball depending on whether click is left or right of it.
	if (position.x > ball.x) {
		// Take previous clicks into account, so ball can't fly off stage.
		if (ball.x < 2048 - (300 + moveRightFrames * 40)) {
			moveRightFrames += 10;
			ball.getChildAt(0).scale.x = -1;
		}
	} else {
		// Take previous clicks into account, so ball can't fly off stage.
		if (ball.x > 300 + moveLeftFrames * 40) {
			moveLeftFrames += 10;
			ball.getChildAt(0).scale.x = 1;
		}
	}
}
// Add event listener for touch down
game.on('down', function (x, y, obj) {
	obj.event = obj;
	handleMove(obj);
});
//console.log(LK.getSound('ambience'));
//console.log(LK);
//LK.getSound('ambience').loop = true;
//LK.getSound('ambience').play();
var bgMusic = LK.getSound('ambience');
bgMusic.play();
LK.setInterval(function () {
	bgMusic.play();
}, 9215);
// Game tick event
LK.on('tick', function () {
	if (gameEnding) {
		ball._update_migrated(platforms);
		platforms.forEach(function (platform) {
			if (platform._update_migrated) {
				platform._update_migrated();
			}
		});
		scoreLabels.forEach(function (scoreLabel) {
			if (scoreLabel._update_migrated) {
				scoreLabel._update_migrated();
			}
		});
	} else {
		/* 
		if (LK.ticks % 120 == 0) {
		console.log('Platforms.length is now: ' + platforms.length);
		}*/
		scoreLabels.forEach(function (scoreLabel) {
			if (scoreLabel._update_migrated) {
				scoreLabel._update_migrated();
			}
		});
		// Update ball position
		ball._update_migrated(platforms);
		// Check for ball bouncing off platforms
		ball.bounce(platforms);
		if (moveLeftFrames > 0) {
			moveLeftFrames--;
			ball.x -= 40;
		}
		if (moveRightFrames > 0) {
			moveRightFrames--;
			ball.x += 40;
		}
		var newPlatforms = [];
		for (var i = platforms.length - 1; i > 0; i--) {
			var platform = platforms[i];
			if (platform._update_migrated) {
				platform._update_migrated();
			}
			if (platform.y < -900) {
				platform.y += rowAmount * 300;
				platform.row += rowAmount;
				// Only randomize normal platforms, not sidebarriers.
				if (platform.height < 100) {
					platform.alpha = Math.random() < 0.55 ? 1 : 0;
					platform.toxic = Math.random() < 0.1 ? true : false;
					// Make a shaft
					var rowRel = platform.row % 100;
					if (platform.col == 0) {
						if (rowRel > 10 && rowRel < 20) {
							platform.alpha = rowRel == 19 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 1) {
						if (rowRel > 70 && rowRel < 80) {
							platform.alpha = rowRel == 79 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 2) {
						if (rowRel > 30 && rowRel < 40) {
							platform.alpha = rowRel == 39 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 3) {
						if (rowRel > 90 && rowRel < 100) {
							platform.alpha = rowRel == 99 ? 1 : 0;
							platform.toxic = false;
						}
					} else if (platform.col == 4) {
						if (rowRel > 50 && rowRel < 60) {
							platform.alpha = rowRel == 59 ? 1 : 0;
							platform.toxic = false;
						}
					}
					platform.setTint();
					// Chance that powerups are spawned on normal platforms
					if (platform.alpha == 1 && platform.powerup == false && !platform.toxic) {
						if (Math.random() < 0.01) {
							var t = new PowerupBurst();
							t.x = platform.x;
							t.y = platform.y - t.height;
							newPlatforms.push(t);
							game.addChild(t);
						} else if (platform.row % 25 == 0 && Math.random() < 0.5) {
							var t = new PowerupScore();
							t.x = platform.x;
							t.y = platform.y - t.height;
							t.scoreVal = platform.row;
							t.updateLabel(t.scoreVal);
							newPlatforms.push(t);
							game.addChild(t);
						} else if (Math.random() < 0.1) {
							var t = new PowerupMultiply();
							t.x = platform.x;
							t.y = platform.y - t.height / 1.7;
							newPlatforms.push(t);
							game.addChild(t);
						} else if (Math.random() < 0.1) {
							if (maxDepth < 50) {
								var t = new PowerupFollow();
							} else if (maxDepth < 100) {
								if (Math.random() < 0.5) {
									var t = new PowerupFollow();
								} else {
									var t = new PowerupBluebird();
								}
							} else {
								var r = Math.random();
								if (r < 0.33) {
									var t = new PowerupFollow();
								} else if (r < 0.66) {
									var t = new PowerupBluebird();
								} else {
									var t = new PowerupGreenbird();
								}
							}
							t.x = platform.x;
							t.y = platform.y - t.height;
							newPlatforms.push(t);
							game.addChild(t);
						}
					}
				}
				// Powerups don't automatically respawn below when they move off screen top edge.
				if (platform.powerup == true) {
					platform.destroy();
					platforms.splice(i, 1);
				}
			}
		}
		platforms.push.apply(platforms, newPlatforms);
	}
});
:quality(85)/https://cdn.frvr.ai/65acdcea140304550d97e46a.png%3F3) 
 A happy blue elephant.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65acdf38140304550d97e4a7.png%3F3) 
 erase.
:quality(85)/https://cdn.frvr.ai/65acef0e140304550d97e4f8.png%3F3) 
 Make the bird sit inside a birdcage.
:quality(85)/https://cdn.frvr.ai/65acf1ea140304550d97e520.png%3F3) 
 Three green arrows pointing down.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65acf58e140304550d97e595.png%3F3) 
 A sad little bluebird sitting down.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65acf6f0140304550d97e5a3.png%3F3) 
 A happy little bluebird flying.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65acf9faeadef7a45ad68b76.png%3F3) 
 A happy little green bird flying.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65acfc02eadef7a45ad68b8c.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/65ad07c7eadef7a45ad68bdb.png%3F3) 
 A lush jungle scenery with huge old trees covered in vines and overwrowth, blue sky and forested mountains in the background.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65ae119fdacd7871e6103320.png%3F3) 
 A dark wooden message board with vines and jungle moss growing on top.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65af65050128a5007814719d.png%3F3) 
 A happy little blue elephant, looking scared, facing the viewer, legs flailing as it falls through the air.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65af74820128a50078147209.png%3F3) 
 A delicious peanut.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
:quality(85)/https://cdn.frvr.ai/65afbea50128a5007814740a.png%3F3) 
 delete