/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Obstacle = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'spike';
	var graphics = self.attachAsset(self.type, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.8,
		// Reduce width by 20%
		scaleY: 0.8 // Reduce height by 20%
	});
	// Removed spike rotation to make it point upward
	self.speed = 10;
	self.active = true;
	self.update = function () {
		if (!self.active) {
			return;
		}
		self.x -= self.speed;
		// Remove when offscreen
		if (self.x < -graphics.width) {
			self.active = false;
			self.destroy();
		}
	};
	return self;
});
var Platform = Obstacle.expand(function () {
	var self = Obstacle.call(this, 'platform');
	self.yOffset = 0;
	self.moving = Math.random() > 0.7;
	self.moveDirection = 1;
	self.moveSpeed = 2;
	self.moveRange = 100;
	self.initialY = 0;
	var superUpdate = self.update;
	self.update = function () {
		superUpdate.call(self);
		if (self.moving && self.active) {
			self.yOffset += self.moveDirection * self.moveSpeed;
			if (Math.abs(self.yOffset) > self.moveRange) {
				self.moveDirection *= -1;
			}
			self.y = self.initialY + self.yOffset;
		}
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocity = 0;
	self.gravity = 0.8;
	self.jumpForce = -18;
	self.onGround = false;
	self.isDead = false;
	self.rotation = 0;
	self.jump = function () {
		if (self.onGround && !self.isDead) {
			self.velocity = self.jumpForce;
			self.onGround = false;
			LK.getSound('jump').play();
			// Rotate the player
			tween.stop(self, {
				rotation: true
			});
			tween(self, {
				rotation: self.rotation + Math.PI * 2
			}, {
				duration: 500,
				easing: tween.linear
			});
		}
	};
	self.die = function () {
		if (!self.isDead) {
			self.isDead = true;
			LK.getSound('death').play();
			LK.effects.flashObject(self, 0xff0000, 500);
			// Show death animation
			tween(self, {
				alpha: 0,
				scaleX: 2,
				scaleY: 2
			}, {
				duration: 800,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					LK.showGameOver();
				}
			});
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Apply gravity
		self.velocity += self.gravity;
		self.y += self.velocity;
		// Check ground collision
		if (self.y > groundLevel - playerGraphics.height / 2) {
			self.y = groundLevel - playerGraphics.height / 2;
			self.velocity = 0;
			self.onGround = true;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x121212
});
/**** 
* Game Code
****/ 
// Game variables
var gameSpeed = 10;
var groundLevel = 2500;
var obstacleSpawnRate = 90;
var score = 0;
var highScore = storage.highScore || 0;
var obstacles = [];
var backgroundTiles = [];
var groundTiles = [];
var platformHeight = 350;
var lastObstacleType = '';
var player;
var groundTileWidth = 300;
var dragNode = null;
// Set up background
var background = LK.getAsset('background', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0
});
game.addChild(background);
// Create ground
function createGround() {
	var numTiles = Math.ceil(2048 / groundTileWidth) + 2;
	for (var i = 0; i < numTiles; i++) {
		var groundTile = LK.getAsset('ground', {
			anchorX: 0,
			anchorY: 0,
			x: i * groundTileWidth,
			y: groundLevel + 10
		});
		game.addChild(groundTile);
		groundTiles.push(groundTile);
	}
}
// Create the player
function createPlayer() {
	player = new Player();
	player.x = 300;
	player.y = groundLevel - 200;
	game.addChild(player);
	player.down = function () {
		player.jump();
	};
}
// Create scoring UI
var scoreText = new Text2('Score: 0', {
	size: 70,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var highScoreText = new Text2('Best: ' + highScore, {
	size: 50,
	fill: 0xCCCCCC
});
highScoreText.anchor.set(0.5, 0);
highScoreText.y = 80;
LK.gui.top.addChild(highScoreText);
// Update score
function updateScore() {
	score++;
	scoreText.setText('Score: ' + score);
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
		highScoreText.setText('Best: ' + highScore);
	}
}
// Create obstacles
function createObstacle() {
	var type;
	// Avoid consecutive same obstacles
	do {
		var rand = Math.random();
		type = rand < 0.6 ? 'spike' : 'platform';
	} while (type === lastObstacleType);
	lastObstacleType = type;
	if (type === 'spike') {
		var obstacle = new Obstacle('spike');
		obstacle.x = 2048 + 50;
		obstacle.y = groundLevel - obstacle.height / 2;
		game.addChild(obstacle);
		obstacles.push(obstacle);
	} else {
		var platform = new Platform();
		platform.x = 2048 + 50;
		// Random height for platforms
		var platformY = groundLevel - platformHeight - Math.random() * 250;
		platform.y = platformY;
		platform.initialY = platformY;
		game.addChild(platform);
		obstacles.push(platform);
	}
}
// Check for collisions
function checkCollisions() {
	if (player.isDead) {
		return;
	}
	for (var i = 0; i < obstacles.length; i++) {
		var obstacle = obstacles[i];
		if (player.intersects(obstacle)) {
			if (obstacle.type === 'spike') {
				player.die();
				return;
			} else if (obstacle.type === 'platform') {
				// Only consider standing on top of platforms
				var playerBottom = player.y + player.height / 2;
				var platformTop = obstacle.y - obstacle.height / 2;
				// Check if player is above platform and falling down
				if (player.velocity > 0 && playerBottom >= platformTop && playerBottom <= platformTop + Math.abs(player.velocity) + 5) {
					player.y = platformTop - player.height / 2;
					player.velocity = 0;
					player.onGround = true;
				} else {
					// Side collision with platform
					player.die();
					return;
				}
			}
		}
	}
}
// Move ground tiles
function moveGround() {
	for (var i = 0; i < groundTiles.length; i++) {
		var tile = groundTiles[i];
		tile.x -= gameSpeed;
		// If the tile is completely off-screen, move it to the right
		if (tile.x <= -groundTileWidth) {
			var lastTileX = -Infinity;
			// Find the rightmost tile
			for (var j = 0; j < groundTiles.length; j++) {
				if (groundTiles[j].x > lastTileX) {
					lastTileX = groundTiles[j].x;
				}
			}
			// Place this tile after the rightmost one
			tile.x = lastTileX + groundTileWidth;
		}
	}
}
// Clear game state
function resetGame() {
	// Clear obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].destroy();
	}
	obstacles = [];
	// Reset score
	score = 0;
	scoreText.setText('Score: 0');
	// Reset player
	if (player) {
		player.destroy();
	}
	createPlayer();
}
// Start the game
function startGame() {
	createGround();
	createPlayer();
	// Start game music
	LK.playMusic('gameMusic', {
		fade: {
			start: 0,
			end: 0.5,
			duration: 1000
		}
	});
}
// Main update loop
game.update = function () {
	// Move ground
	moveGround();
	// Spawn obstacles
	if (LK.ticks % obstacleSpawnRate === 0) {
		createObstacle();
	}
	// Update obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obstacle = obstacles[i];
		if (!obstacle.active) {
			obstacles.splice(i, 1);
		}
	}
	// Check collisions
	checkCollisions();
	// Update score periodically
	if (LK.ticks % 30 === 0 && !player.isDead) {
		updateScore();
	}
	// Gradually increase game difficulty
	if (LK.ticks % 600 === 0 && gameSpeed < 18) {
		gameSpeed += 0.5;
		// Update obstacle speed
		for (var i = 0; i < obstacles.length; i++) {
			obstacles[i].speed = gameSpeed;
		}
		// Reduce spawn rate to increase difficulty
		if (obstacleSpawnRate > 45) {
			obstacleSpawnRate -= 5;
		}
	}
};
// Handle input
game.down = function (x, y, obj) {
	player.jump();
};
// Initialize the game
startGame(); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/**** 
* Classes
****/ 
var Obstacle = Container.expand(function (type) {
	var self = Container.call(this);
	self.type = type || 'spike';
	var graphics = self.attachAsset(self.type, {
		anchorX: 0.5,
		anchorY: 0.5,
		scaleX: 0.8,
		// Reduce width by 20%
		scaleY: 0.8 // Reduce height by 20%
	});
	// Removed spike rotation to make it point upward
	self.speed = 10;
	self.active = true;
	self.update = function () {
		if (!self.active) {
			return;
		}
		self.x -= self.speed;
		// Remove when offscreen
		if (self.x < -graphics.width) {
			self.active = false;
			self.destroy();
		}
	};
	return self;
});
var Platform = Obstacle.expand(function () {
	var self = Obstacle.call(this, 'platform');
	self.yOffset = 0;
	self.moving = Math.random() > 0.7;
	self.moveDirection = 1;
	self.moveSpeed = 2;
	self.moveRange = 100;
	self.initialY = 0;
	var superUpdate = self.update;
	self.update = function () {
		superUpdate.call(self);
		if (self.moving && self.active) {
			self.yOffset += self.moveDirection * self.moveSpeed;
			if (Math.abs(self.yOffset) > self.moveRange) {
				self.moveDirection *= -1;
			}
			self.y = self.initialY + self.yOffset;
		}
	};
	return self;
});
var Player = Container.expand(function () {
	var self = Container.call(this);
	var playerGraphics = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocity = 0;
	self.gravity = 0.8;
	self.jumpForce = -18;
	self.onGround = false;
	self.isDead = false;
	self.rotation = 0;
	self.jump = function () {
		if (self.onGround && !self.isDead) {
			self.velocity = self.jumpForce;
			self.onGround = false;
			LK.getSound('jump').play();
			// Rotate the player
			tween.stop(self, {
				rotation: true
			});
			tween(self, {
				rotation: self.rotation + Math.PI * 2
			}, {
				duration: 500,
				easing: tween.linear
			});
		}
	};
	self.die = function () {
		if (!self.isDead) {
			self.isDead = true;
			LK.getSound('death').play();
			LK.effects.flashObject(self, 0xff0000, 500);
			// Show death animation
			tween(self, {
				alpha: 0,
				scaleX: 2,
				scaleY: 2
			}, {
				duration: 800,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					LK.showGameOver();
				}
			});
		}
	};
	self.update = function () {
		if (self.isDead) {
			return;
		}
		// Apply gravity
		self.velocity += self.gravity;
		self.y += self.velocity;
		// Check ground collision
		if (self.y > groundLevel - playerGraphics.height / 2) {
			self.y = groundLevel - playerGraphics.height / 2;
			self.velocity = 0;
			self.onGround = true;
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x121212
});
/**** 
* Game Code
****/ 
// Game variables
var gameSpeed = 10;
var groundLevel = 2500;
var obstacleSpawnRate = 90;
var score = 0;
var highScore = storage.highScore || 0;
var obstacles = [];
var backgroundTiles = [];
var groundTiles = [];
var platformHeight = 350;
var lastObstacleType = '';
var player;
var groundTileWidth = 300;
var dragNode = null;
// Set up background
var background = LK.getAsset('background', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0
});
game.addChild(background);
// Create ground
function createGround() {
	var numTiles = Math.ceil(2048 / groundTileWidth) + 2;
	for (var i = 0; i < numTiles; i++) {
		var groundTile = LK.getAsset('ground', {
			anchorX: 0,
			anchorY: 0,
			x: i * groundTileWidth,
			y: groundLevel + 10
		});
		game.addChild(groundTile);
		groundTiles.push(groundTile);
	}
}
// Create the player
function createPlayer() {
	player = new Player();
	player.x = 300;
	player.y = groundLevel - 200;
	game.addChild(player);
	player.down = function () {
		player.jump();
	};
}
// Create scoring UI
var scoreText = new Text2('Score: 0', {
	size: 70,
	fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var highScoreText = new Text2('Best: ' + highScore, {
	size: 50,
	fill: 0xCCCCCC
});
highScoreText.anchor.set(0.5, 0);
highScoreText.y = 80;
LK.gui.top.addChild(highScoreText);
// Update score
function updateScore() {
	score++;
	scoreText.setText('Score: ' + score);
	if (score > highScore) {
		highScore = score;
		storage.highScore = highScore;
		highScoreText.setText('Best: ' + highScore);
	}
}
// Create obstacles
function createObstacle() {
	var type;
	// Avoid consecutive same obstacles
	do {
		var rand = Math.random();
		type = rand < 0.6 ? 'spike' : 'platform';
	} while (type === lastObstacleType);
	lastObstacleType = type;
	if (type === 'spike') {
		var obstacle = new Obstacle('spike');
		obstacle.x = 2048 + 50;
		obstacle.y = groundLevel - obstacle.height / 2;
		game.addChild(obstacle);
		obstacles.push(obstacle);
	} else {
		var platform = new Platform();
		platform.x = 2048 + 50;
		// Random height for platforms
		var platformY = groundLevel - platformHeight - Math.random() * 250;
		platform.y = platformY;
		platform.initialY = platformY;
		game.addChild(platform);
		obstacles.push(platform);
	}
}
// Check for collisions
function checkCollisions() {
	if (player.isDead) {
		return;
	}
	for (var i = 0; i < obstacles.length; i++) {
		var obstacle = obstacles[i];
		if (player.intersects(obstacle)) {
			if (obstacle.type === 'spike') {
				player.die();
				return;
			} else if (obstacle.type === 'platform') {
				// Only consider standing on top of platforms
				var playerBottom = player.y + player.height / 2;
				var platformTop = obstacle.y - obstacle.height / 2;
				// Check if player is above platform and falling down
				if (player.velocity > 0 && playerBottom >= platformTop && playerBottom <= platformTop + Math.abs(player.velocity) + 5) {
					player.y = platformTop - player.height / 2;
					player.velocity = 0;
					player.onGround = true;
				} else {
					// Side collision with platform
					player.die();
					return;
				}
			}
		}
	}
}
// Move ground tiles
function moveGround() {
	for (var i = 0; i < groundTiles.length; i++) {
		var tile = groundTiles[i];
		tile.x -= gameSpeed;
		// If the tile is completely off-screen, move it to the right
		if (tile.x <= -groundTileWidth) {
			var lastTileX = -Infinity;
			// Find the rightmost tile
			for (var j = 0; j < groundTiles.length; j++) {
				if (groundTiles[j].x > lastTileX) {
					lastTileX = groundTiles[j].x;
				}
			}
			// Place this tile after the rightmost one
			tile.x = lastTileX + groundTileWidth;
		}
	}
}
// Clear game state
function resetGame() {
	// Clear obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].destroy();
	}
	obstacles = [];
	// Reset score
	score = 0;
	scoreText.setText('Score: 0');
	// Reset player
	if (player) {
		player.destroy();
	}
	createPlayer();
}
// Start the game
function startGame() {
	createGround();
	createPlayer();
	// Start game music
	LK.playMusic('gameMusic', {
		fade: {
			start: 0,
			end: 0.5,
			duration: 1000
		}
	});
}
// Main update loop
game.update = function () {
	// Move ground
	moveGround();
	// Spawn obstacles
	if (LK.ticks % obstacleSpawnRate === 0) {
		createObstacle();
	}
	// Update obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obstacle = obstacles[i];
		if (!obstacle.active) {
			obstacles.splice(i, 1);
		}
	}
	// Check collisions
	checkCollisions();
	// Update score periodically
	if (LK.ticks % 30 === 0 && !player.isDead) {
		updateScore();
	}
	// Gradually increase game difficulty
	if (LK.ticks % 600 === 0 && gameSpeed < 18) {
		gameSpeed += 0.5;
		// Update obstacle speed
		for (var i = 0; i < obstacles.length; i++) {
			obstacles[i].speed = gameSpeed;
		}
		// Reduce spawn rate to increase difficulty
		if (obstacleSpawnRate > 45) {
			obstacleSpawnRate -= 5;
		}
	}
};
// Handle input
game.down = function (x, y, obj) {
	player.jump();
};
// Initialize the game
startGame();
:quality(85)/https://cdn.frvr.ai/67f8e212c552b72b62b051c1.png%3F3) 
 Geometry dash ground. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/67faa2881463d815c0f63fbb.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/67faa35b1463d815c0f63fdd.png%3F3) 
 Background with lots of squares. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/67faa3ac1463d815c0f63fec.png%3F3) 
 Platform. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows