/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Pillar = Container.expand(function (gap, gapSize) {
	var self = Container.call(this);
	var gapY = gap || Math.random() * 1500 + 500;
	var pillarGap = gapSize || 500;
	var topPillar = self.attachAsset('pillarTop', {
		anchorX: 0.5,
		anchorY: 1.0,
		y: gapY - pillarGap / 2
	});
	var bottomPillar = self.attachAsset('pillarBottom', {
		anchorX: 0.5,
		anchorY: 0.0,
		y: gapY + pillarGap / 2
	});
	self.speed = 5;
	self.passed = false;
	self.width = topPillar.width;
	self.update = function () {
		self.x -= self.speed;
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var cube = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocity = 0;
	self.gravity = 0.5;
	self.flapStrength = -12;
	self.rotation = 0;
	self.isDead = false;
	self.flap = function () {
		if (self.isDead) {
			return;
		}
		self.velocity = self.flapStrength;
		LK.getSound('flap').play();
		// Visual feedback for flap
		tween(cube, {
			rotation: -0.4
		}, {
			duration: 100,
			onFinish: function onFinish() {
				tween(cube, {
					rotation: 0
				}, {
					duration: 200
				});
			}
		});
	};
	self.die = function () {
		if (self.isDead) {
			return;
		}
		self.isDead = true;
		LK.getSound('hit').play();
		LK.effects.flashObject(self, 0xff0000, 500);
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Apply gravity
		self.velocity += self.gravity;
		self.y += self.velocity;
		// Rotate based on velocity
		if (self.velocity > 10) {
			cube.rotation = Math.min(cube.rotation + 0.05, 0.7);
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87CEEB
});
/**** 
* Game Code
****/ 
var player;
var pillars = [];
var ground;
var isGameStarted = false;
var spawnTimer;
var score = 0;
var highScore = storage.highScore || 0;
var baseGapSize = 500;
var difficultyFactor = 1;
var timeElapsed = 0;
// Create score display
var scoreTxt = new Text2('0', {
	size: 150,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create high score display
var highScoreTxt = new Text2('Best: 0', {
	size: 80,
	fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0.5, 0);
highScoreTxt.y = 160;
LK.gui.top.addChild(highScoreTxt);
highScoreTxt.setText('Best: ' + highScore);
// Create tap to start text
var startTxt = new Text2('Tap to Start', {
	size: 100,
	fill: 0xFFFFFF
});
startTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startTxt);
// Create ground
ground = game.addChild(LK.getAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	y: 2732 - 100
}));
// Create player
player = game.addChild(new Player());
player.x = 500;
player.y = 2732 / 2;
function startGame() {
	if (isGameStarted) {
		return;
	}
	isGameStarted = true;
	score = 0;
	scoreTxt.setText(score.toString());
	startTxt.visible = false;
	timeElapsed = 0;
	difficultyFactor = 1;
	// Create initial pillars
	createPillar();
	// Start pillar spawning
	spawnTimer = LK.setInterval(createPillar, 2000);
	// Play music
	LK.playMusic('gameMusic');
}
function createPillar() {
	// Calculate gap size (decreases with difficulty)
	var currentGapSize = Math.max(300, baseGapSize - (difficultyFactor - 1) * 100);
	var pillar = new Pillar(undefined, currentGapSize);
	pillar.x = 2048 + 200; // Start off-screen
	game.addChild(pillar);
	pillars.push(pillar);
}
function resetGame() {
	// Clear all pillars
	for (var i = pillars.length - 1; i >= 0; i--) {
		pillars[i].destroy();
		pillars.splice(i, 1);
	}
	// Clear timer
	if (spawnTimer) {
		LK.clearInterval(spawnTimer);
		spawnTimer = null;
	}
	// Reset player
	player.destroy();
	player = game.addChild(new Player());
	player.x = 500;
	player.y = 2732 / 2;
	// Reset game state
	isGameStarted = false;
	startTxt.visible = true;
	// Update high score
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
		highScoreTxt.setText('Best: ' + highScore);
	}
	// Stop music
	LK.stopMusic();
}
function checkCollisions() {
	if (player.isDead) {
		return;
	}
	// Check ground collision
	if (player.y + 60 >= ground.y) {
		player.die();
		LK.setTimeout(function () {
			LK.showGameOver();
		}, 1000);
		return;
	}
	// Check ceiling collision
	if (player.y - 60 <= 0) {
		player.die();
		LK.setTimeout(function () {
			LK.showGameOver();
		}, 1000);
		return;
	}
	// Check pillar collisions
	for (var i = 0; i < pillars.length; i++) {
		var pillar = pillars[i];
		if (player.intersects(pillar) && !player.isDead) {
			player.die();
			LK.setTimeout(function () {
				LK.showGameOver();
			}, 1000);
			return;
		}
		// Check if player has passed pillar
		if (!pillar.passed && pillar.x + pillar.width / 2 < player.x - 60) {
			pillar.passed = true;
			score++;
			scoreTxt.setText(score.toString());
			LK.setScore(score);
			LK.getSound('score').play();
		}
	}
}
// Handle input
game.down = function (x, y, obj) {
	if (!isGameStarted) {
		startGame();
	}
	player.flap();
};
// Main update loop
game.update = function () {
	if (isGameStarted) {
		timeElapsed++;
		// Increase difficulty every 10 seconds
		if (timeElapsed % 600 === 0) {
			difficultyFactor += 0.2;
			// Increase pillar speed
			for (var j = 0; j < pillars.length; j++) {
				pillars[j].speed = 5 + (difficultyFactor - 1) * 2;
			}
		}
		// Update pillars
		for (var i = pillars.length - 1; i >= 0; i--) {
			pillars[i].update();
			// Remove pillars that are off-screen
			if (pillars[i].x < -250) {
				pillars[i].destroy();
				pillars.splice(i, 1);
			}
		}
		// Update player
		player.update();
		// Check collisions
		checkCollisions();
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Pillar = Container.expand(function (gap, gapSize) {
	var self = Container.call(this);
	var gapY = gap || Math.random() * 1500 + 500;
	var pillarGap = gapSize || 500;
	var topPillar = self.attachAsset('pillarTop', {
		anchorX: 0.5,
		anchorY: 1.0,
		y: gapY - pillarGap / 2
	});
	var bottomPillar = self.attachAsset('pillarBottom', {
		anchorX: 0.5,
		anchorY: 0.0,
		y: gapY + pillarGap / 2
	});
	self.speed = 5;
	self.passed = false;
	self.width = topPillar.width;
	self.update = function () {
		self.x -= self.speed;
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var cube = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocity = 0;
	self.gravity = 0.5;
	self.flapStrength = -12;
	self.rotation = 0;
	self.isDead = false;
	self.flap = function () {
		if (self.isDead) {
			return;
		}
		self.velocity = self.flapStrength;
		LK.getSound('flap').play();
		// Visual feedback for flap
		tween(cube, {
			rotation: -0.4
		}, {
			duration: 100,
			onFinish: function onFinish() {
				tween(cube, {
					rotation: 0
				}, {
					duration: 200
				});
			}
		});
	};
	self.die = function () {
		if (self.isDead) {
			return;
		}
		self.isDead = true;
		LK.getSound('hit').play();
		LK.effects.flashObject(self, 0xff0000, 500);
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Apply gravity
		self.velocity += self.gravity;
		self.y += self.velocity;
		// Rotate based on velocity
		if (self.velocity > 10) {
			cube.rotation = Math.min(cube.rotation + 0.05, 0.7);
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87CEEB
});
/**** 
* Game Code
****/ 
var player;
var pillars = [];
var ground;
var isGameStarted = false;
var spawnTimer;
var score = 0;
var highScore = storage.highScore || 0;
var baseGapSize = 500;
var difficultyFactor = 1;
var timeElapsed = 0;
// Create score display
var scoreTxt = new Text2('0', {
	size: 150,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create high score display
var highScoreTxt = new Text2('Best: 0', {
	size: 80,
	fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0.5, 0);
highScoreTxt.y = 160;
LK.gui.top.addChild(highScoreTxt);
highScoreTxt.setText('Best: ' + highScore);
// Create tap to start text
var startTxt = new Text2('Tap to Start', {
	size: 100,
	fill: 0xFFFFFF
});
startTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(startTxt);
// Create ground
ground = game.addChild(LK.getAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	y: 2732 - 100
}));
// Create player
player = game.addChild(new Player());
player.x = 500;
player.y = 2732 / 2;
function startGame() {
	if (isGameStarted) {
		return;
	}
	isGameStarted = true;
	score = 0;
	scoreTxt.setText(score.toString());
	startTxt.visible = false;
	timeElapsed = 0;
	difficultyFactor = 1;
	// Create initial pillars
	createPillar();
	// Start pillar spawning
	spawnTimer = LK.setInterval(createPillar, 2000);
	// Play music
	LK.playMusic('gameMusic');
}
function createPillar() {
	// Calculate gap size (decreases with difficulty)
	var currentGapSize = Math.max(300, baseGapSize - (difficultyFactor - 1) * 100);
	var pillar = new Pillar(undefined, currentGapSize);
	pillar.x = 2048 + 200; // Start off-screen
	game.addChild(pillar);
	pillars.push(pillar);
}
function resetGame() {
	// Clear all pillars
	for (var i = pillars.length - 1; i >= 0; i--) {
		pillars[i].destroy();
		pillars.splice(i, 1);
	}
	// Clear timer
	if (spawnTimer) {
		LK.clearInterval(spawnTimer);
		spawnTimer = null;
	}
	// Reset player
	player.destroy();
	player = game.addChild(new Player());
	player.x = 500;
	player.y = 2732 / 2;
	// Reset game state
	isGameStarted = false;
	startTxt.visible = true;
	// Update high score
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
		highScoreTxt.setText('Best: ' + highScore);
	}
	// Stop music
	LK.stopMusic();
}
function checkCollisions() {
	if (player.isDead) {
		return;
	}
	// Check ground collision
	if (player.y + 60 >= ground.y) {
		player.die();
		LK.setTimeout(function () {
			LK.showGameOver();
		}, 1000);
		return;
	}
	// Check ceiling collision
	if (player.y - 60 <= 0) {
		player.die();
		LK.setTimeout(function () {
			LK.showGameOver();
		}, 1000);
		return;
	}
	// Check pillar collisions
	for (var i = 0; i < pillars.length; i++) {
		var pillar = pillars[i];
		if (player.intersects(pillar) && !player.isDead) {
			player.die();
			LK.setTimeout(function () {
				LK.showGameOver();
			}, 1000);
			return;
		}
		// Check if player has passed pillar
		if (!pillar.passed && pillar.x + pillar.width / 2 < player.x - 60) {
			pillar.passed = true;
			score++;
			scoreTxt.setText(score.toString());
			LK.setScore(score);
			LK.getSound('score').play();
		}
	}
}
// Handle input
game.down = function (x, y, obj) {
	if (!isGameStarted) {
		startGame();
	}
	player.flap();
};
// Main update loop
game.update = function () {
	if (isGameStarted) {
		timeElapsed++;
		// Increase difficulty every 10 seconds
		if (timeElapsed % 600 === 0) {
			difficultyFactor += 0.2;
			// Increase pillar speed
			for (var j = 0; j < pillars.length; j++) {
				pillars[j].speed = 5 + (difficultyFactor - 1) * 2;
			}
		}
		// Update pillars
		for (var i = pillars.length - 1; i >= 0; i--) {
			pillars[i].update();
			// Remove pillars that are off-screen
			if (pillars[i].x < -250) {
				pillars[i].destroy();
				pillars.splice(i, 1);
			}
		}
		// Update player
		player.update();
		// Check collisions
		checkCollisions();
	}
};
 pillarbottom mg. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 ground mg. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 pillartop mg. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 MG FlappyCube. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows