/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0
});
/**** 
* Classes
****/ 
// Dino (player) class
var Dino = Container.expand(function () {
	var self = Container.call(this);
	var dinoSprite = self.attachAsset('dino', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = dinoSprite.width;
	self.height = dinoSprite.height;
	self.isJumping = false;
	self.isDucking = false;
	self.velocityY = 0;
	self.gravity = 2.2;
	self.jumpStrength = -48;
	self.groundY = 0; // Will be set after creation
	// Jump method
	self.jump = function () {
		if (!self.isJumping && !self.isDucking) {
			self.velocityY = self.jumpStrength;
			self.isJumping = true;
		}
	};
	// Duck method
	self.duck = function () {
		if (!self.isJumping && !self.isDucking) {
			self.isDucking = true;
			// Animate duck (shrink height, move down)
			tween(self, {
				scaleY: 0.55,
				y: self.y + self.height * 0.45
			}, {
				duration: 120,
				easing: tween.cubicIn
			});
		}
	};
	// Stand up from duck
	self.stand = function () {
		if (self.isDucking) {
			self.isDucking = false;
			tween(self, {
				scaleY: 1,
				y: self.groundY
			}, {
				duration: 120,
				easing: tween.cubicOut
			});
		}
	};
	// Update method
	self.update = function () {
		// Jumping physics
		if (self.isJumping) {
			self.y += self.velocityY;
			self.velocityY += self.gravity;
			if (self.y >= self.groundY) {
				self.y = self.groundY;
				self.velocityY = 0;
				self.isJumping = false;
			}
		}
	};
	return self;
});
// Obstacle base class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0; // Will be set on spawn
	self.type = 'cactus'; // cactus, rock, bird
	self.passed = false; // For scoring
	self.update = function () {
		self.x -= self.speed;
	};
	return self;
});
// Rock
var Rock = Obstacle.expand(function () {
	var self = Obstacle.call(this);
	var rockSprite = self.attachAsset('rock', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = rockSprite.width;
	self.height = rockSprite.height;
	self.type = 'rock';
	return self;
});
// Cactus
var Cactus = Obstacle.expand(function () {
	var self = Obstacle.call(this);
	var cactusSprite = self.attachAsset('cactus', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = cactusSprite.width;
	self.height = cactusSprite.height;
	self.type = 'cactus';
	return self;
});
// Bird
var Bird = Obstacle.expand(function () {
	var self = Obstacle.call(this);
	var birdSprite = self.attachAsset('bird', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = birdSprite.width;
	self.height = birdSprite.height;
	self.type = 'bird';
	// Bird flies at random heights
	self.flyY = 0;
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xffffff
});
/**** 
* Game Code
****/ 
// Add background image (fills the game area)
var background = LK.getAsset('background', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0,
	width: 2048,
	height: 2732
});
game.addChild(background);
// Ground
// Bird obstacle
// Rock obstacle
// Cactus obstacle
// Dino (player)
// Game constants
var GROUND_Y = 2300;
var DINO_START_X = 400;
var OBSTACLE_MIN_GAP = 600;
var OBSTACLE_MAX_GAP = 1100;
var OBSTACLE_TYPES = ['cactus', 'rock', 'bird'];
var GAME_SPEED_START = 12;
var GAME_SPEED_MAX = 28;
var GAME_SPEED_INC = 0.00022; // Per tick
var BIRD_HEIGHTS = [GROUND_Y - 120, GROUND_Y - 320, GROUND_Y - 520];
// Game state
var dino;
var ground;
var obstacles = [];
var score = 0;
var highScore = storage.highScore || 0;
var distance = 0;
var gameSpeed = GAME_SPEED_START;
var lastObstacleX = 0;
var isGameOver = false;
var scoreTxt, highScoreTxt;
// Add ground
// Make the ground a perfect square and fit it to the bottom of the screen
var groundSize = Math.min(2048, 2732 - GROUND_Y);
// Tile the ground square horizontally to fill the screen width
var groundTiles = [];
var numTiles = Math.ceil(2048 / groundSize);
for (var i = 0; i < numTiles; i++) {
	var groundTile = LK.getAsset('ground', {
		anchorX: 0,
		anchorY: 0,
		x: i * groundSize,
		y: 2732 - groundSize,
		width: groundSize,
		height: groundSize
	});
	game.addChild(groundTile);
	groundTiles.push(groundTile);
}
// For compatibility, keep a reference to the first ground tile as 'ground'
ground = groundTiles[0];
// Add dino
dino = new Dino();
dino.x = DINO_START_X;
dino.groundY = GROUND_Y;
dino.y = GROUND_Y;
game.addChild(dino);
// Score text
scoreTxt = new Text2('0', {
	size: 110,
	fill: "#222"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// High score text
highScoreTxt = new Text2('En Yüksek: ' + highScore, {
	size: 60,
	fill: "#888"
});
highScoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(highScoreTxt);
highScoreTxt.y = 120;
// Helper: spawn obstacle
function spawnObstacle() {
	var typeIdx = Math.floor(Math.random() * OBSTACLE_TYPES.length);
	var type = OBSTACLE_TYPES[typeIdx];
	var obs;
	if (type === 'cactus') {
		obs = new Cactus();
		obs.y = GROUND_Y;
	} else if (type === 'rock') {
		obs = new Rock();
		obs.y = GROUND_Y;
	} else if (type === 'bird') {
		obs = new Bird();
		var hIdx = Math.floor(Math.random() * BIRD_HEIGHTS.length);
		obs.y = BIRD_HEIGHTS[hIdx];
		obs.flyY = obs.y;
	}
	obs.x = 2048 + obs.width;
	obs.speed = gameSpeed;
	// Defensive: initialize lastX and lastY for event/collision best practices
	obs.lastX = obs.x;
	obs.lastY = obs.y;
	obstacles.push(obs);
	game.addChild(obs);
	lastObstacleX = obs.x;
}
// Helper: reset game
function resetGame() {
	// Remove obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].destroy();
	}
	obstacles = [];
	score = 0;
	distance = 0;
	gameSpeed = GAME_SPEED_START;
	lastObstacleX = 0;
	isGameOver = false;
	dino.x = DINO_START_X;
	dino.y = GROUND_Y;
	dino.groundY = GROUND_Y;
	dino.velocityY = 0;
	dino.isJumping = false;
	dino.isDucking = false;
	dino.scaleY = 1;
	dino.lastX = dino.x;
	dino.lastY = dino.y;
	scoreTxt.setText('0');
	highScoreTxt.setText('En Yüksek: ' + highScore);
}
// Touch/press: jump or duck
var touchStartY = null;
var touchActive = false;
game.down = function (x, y, obj) {
	if (isGameOver) return;
	touchStartY = y;
	touchActive = true;
};
game.move = function (x, y, obj) {
	if (isGameOver) return;
	if (!touchActive) return;
	// If swipe up, jump
	if (touchStartY !== null && y < touchStartY - 80) {
		dino.jump();
		touchActive = false;
	}
	// If swipe down, duck
	if (touchStartY !== null && y > touchStartY + 80) {
		dino.duck();
		touchActive = false;
	}
};
game.up = function (x, y, obj) {
	if (isGameOver) return;
	dino.stand();
	touchStartY = null;
	touchActive = false;
};
// Main update loop
game.update = function () {
	if (isGameOver) return;
	// Defensive: track dino's lastX and lastY for event/collision best practices
	if (dino.lastX === undefined) dino.lastX = dino.x;
	if (dino.lastY === undefined) dino.lastY = dino.y;
	// Update dino
	dino.update();
	// Ground tiles remain static; no movement
	for (var g = 0; g < groundTiles.length; g++) {
		var tile = groundTiles[g];
		tile.x = g * groundSize;
	}
	// Update obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obs = obstacles[i];
		// Defensive: track lastX and lastY for event/collision best practices
		if (obs.lastX === undefined) obs.lastX = obs.x;
		if (obs.lastY === undefined) obs.lastY = obs.y;
		obs.speed = gameSpeed;
		obs.update();
		// Bird: simple up-down movement
		if (obs.type === 'bird') {
			obs.y = obs.flyY + Math.sin(LK.ticks / 12 + i) * 18;
		}
		// Remove if off screen
		if (obs.x < -obs.width) {
			obs.destroy();
			obstacles.splice(i, 1);
			continue;
		}
		// Scoring: passed dino
		if (!obs.passed && obs.x + obs.width / 2 < dino.x - dino.width / 2) {
			obs.passed = true;
			score += 1;
			scoreTxt.setText('' + score);
		}
		// Collision
		if (dino.intersects(obs)) {
			// If ducking and bird, allow pass
			if (obs.type === 'bird' && dino.isDucking && obs.y > dino.y - dino.height * 0.7) {
				continue;
			}
			// Game over
			isGameOver = true;
			LK.effects.flashScreen(0xff0000, 800);
			if (score > highScore) {
				highScore = score;
				storage.highScore = highScore;
			}
			LK.setTimeout(function () {
				LK.showGameOver();
			}, 900);
			return;
		}
	}
	// After all movement, update lastX and lastY for obstacles
	for (var j = 0; j < obstacles.length; j++) {
		obstacles[j].lastX = obstacles[j].x;
		obstacles[j].lastY = obstacles[j].y;
	}
	// Update dino's lastX and lastY
	dino.lastX = dino.x;
	dino.lastY = dino.y;
	// Increase game speed
	if (gameSpeed < GAME_SPEED_MAX) {
		gameSpeed += GAME_SPEED_INC * (1 + score * 0.04);
		if (gameSpeed > GAME_SPEED_MAX) gameSpeed = GAME_SPEED_MAX;
	}
	// Distance for score
	distance += gameSpeed;
	// Spawn new obstacle
	if (obstacles.length === 0 || 2048 - lastObstacleX > OBSTACLE_MIN_GAP + Math.random() * (OBSTACLE_MAX_GAP - OBSTACLE_MIN_GAP)) {
		spawnObstacle();
	}
};
// Listen for game over to reset
LK.on('gameover', function () {
	resetGame();
});
// Listen for you win (not used, but for completeness)
LK.on('youwin', function () {
	resetGame();
}); /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0
});
/**** 
* Classes
****/ 
// Dino (player) class
var Dino = Container.expand(function () {
	var self = Container.call(this);
	var dinoSprite = self.attachAsset('dino', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = dinoSprite.width;
	self.height = dinoSprite.height;
	self.isJumping = false;
	self.isDucking = false;
	self.velocityY = 0;
	self.gravity = 2.2;
	self.jumpStrength = -48;
	self.groundY = 0; // Will be set after creation
	// Jump method
	self.jump = function () {
		if (!self.isJumping && !self.isDucking) {
			self.velocityY = self.jumpStrength;
			self.isJumping = true;
		}
	};
	// Duck method
	self.duck = function () {
		if (!self.isJumping && !self.isDucking) {
			self.isDucking = true;
			// Animate duck (shrink height, move down)
			tween(self, {
				scaleY: 0.55,
				y: self.y + self.height * 0.45
			}, {
				duration: 120,
				easing: tween.cubicIn
			});
		}
	};
	// Stand up from duck
	self.stand = function () {
		if (self.isDucking) {
			self.isDucking = false;
			tween(self, {
				scaleY: 1,
				y: self.groundY
			}, {
				duration: 120,
				easing: tween.cubicOut
			});
		}
	};
	// Update method
	self.update = function () {
		// Jumping physics
		if (self.isJumping) {
			self.y += self.velocityY;
			self.velocityY += self.gravity;
			if (self.y >= self.groundY) {
				self.y = self.groundY;
				self.velocityY = 0;
				self.isJumping = false;
			}
		}
	};
	return self;
});
// Obstacle base class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	self.speed = 0; // Will be set on spawn
	self.type = 'cactus'; // cactus, rock, bird
	self.passed = false; // For scoring
	self.update = function () {
		self.x -= self.speed;
	};
	return self;
});
// Rock
var Rock = Obstacle.expand(function () {
	var self = Obstacle.call(this);
	var rockSprite = self.attachAsset('rock', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = rockSprite.width;
	self.height = rockSprite.height;
	self.type = 'rock';
	return self;
});
// Cactus
var Cactus = Obstacle.expand(function () {
	var self = Obstacle.call(this);
	var cactusSprite = self.attachAsset('cactus', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = cactusSprite.width;
	self.height = cactusSprite.height;
	self.type = 'cactus';
	return self;
});
// Bird
var Bird = Obstacle.expand(function () {
	var self = Obstacle.call(this);
	var birdSprite = self.attachAsset('bird', {
		anchorX: 0.5,
		anchorY: 1
	});
	self.width = birdSprite.width;
	self.height = birdSprite.height;
	self.type = 'bird';
	// Bird flies at random heights
	self.flyY = 0;
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0xffffff
});
/**** 
* Game Code
****/ 
// Add background image (fills the game area)
var background = LK.getAsset('background', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 0,
	width: 2048,
	height: 2732
});
game.addChild(background);
// Ground
// Bird obstacle
// Rock obstacle
// Cactus obstacle
// Dino (player)
// Game constants
var GROUND_Y = 2300;
var DINO_START_X = 400;
var OBSTACLE_MIN_GAP = 600;
var OBSTACLE_MAX_GAP = 1100;
var OBSTACLE_TYPES = ['cactus', 'rock', 'bird'];
var GAME_SPEED_START = 12;
var GAME_SPEED_MAX = 28;
var GAME_SPEED_INC = 0.00022; // Per tick
var BIRD_HEIGHTS = [GROUND_Y - 120, GROUND_Y - 320, GROUND_Y - 520];
// Game state
var dino;
var ground;
var obstacles = [];
var score = 0;
var highScore = storage.highScore || 0;
var distance = 0;
var gameSpeed = GAME_SPEED_START;
var lastObstacleX = 0;
var isGameOver = false;
var scoreTxt, highScoreTxt;
// Add ground
// Make the ground a perfect square and fit it to the bottom of the screen
var groundSize = Math.min(2048, 2732 - GROUND_Y);
// Tile the ground square horizontally to fill the screen width
var groundTiles = [];
var numTiles = Math.ceil(2048 / groundSize);
for (var i = 0; i < numTiles; i++) {
	var groundTile = LK.getAsset('ground', {
		anchorX: 0,
		anchorY: 0,
		x: i * groundSize,
		y: 2732 - groundSize,
		width: groundSize,
		height: groundSize
	});
	game.addChild(groundTile);
	groundTiles.push(groundTile);
}
// For compatibility, keep a reference to the first ground tile as 'ground'
ground = groundTiles[0];
// Add dino
dino = new Dino();
dino.x = DINO_START_X;
dino.groundY = GROUND_Y;
dino.y = GROUND_Y;
game.addChild(dino);
// Score text
scoreTxt = new Text2('0', {
	size: 110,
	fill: "#222"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// High score text
highScoreTxt = new Text2('En Yüksek: ' + highScore, {
	size: 60,
	fill: "#888"
});
highScoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(highScoreTxt);
highScoreTxt.y = 120;
// Helper: spawn obstacle
function spawnObstacle() {
	var typeIdx = Math.floor(Math.random() * OBSTACLE_TYPES.length);
	var type = OBSTACLE_TYPES[typeIdx];
	var obs;
	if (type === 'cactus') {
		obs = new Cactus();
		obs.y = GROUND_Y;
	} else if (type === 'rock') {
		obs = new Rock();
		obs.y = GROUND_Y;
	} else if (type === 'bird') {
		obs = new Bird();
		var hIdx = Math.floor(Math.random() * BIRD_HEIGHTS.length);
		obs.y = BIRD_HEIGHTS[hIdx];
		obs.flyY = obs.y;
	}
	obs.x = 2048 + obs.width;
	obs.speed = gameSpeed;
	// Defensive: initialize lastX and lastY for event/collision best practices
	obs.lastX = obs.x;
	obs.lastY = obs.y;
	obstacles.push(obs);
	game.addChild(obs);
	lastObstacleX = obs.x;
}
// Helper: reset game
function resetGame() {
	// Remove obstacles
	for (var i = 0; i < obstacles.length; i++) {
		obstacles[i].destroy();
	}
	obstacles = [];
	score = 0;
	distance = 0;
	gameSpeed = GAME_SPEED_START;
	lastObstacleX = 0;
	isGameOver = false;
	dino.x = DINO_START_X;
	dino.y = GROUND_Y;
	dino.groundY = GROUND_Y;
	dino.velocityY = 0;
	dino.isJumping = false;
	dino.isDucking = false;
	dino.scaleY = 1;
	dino.lastX = dino.x;
	dino.lastY = dino.y;
	scoreTxt.setText('0');
	highScoreTxt.setText('En Yüksek: ' + highScore);
}
// Touch/press: jump or duck
var touchStartY = null;
var touchActive = false;
game.down = function (x, y, obj) {
	if (isGameOver) return;
	touchStartY = y;
	touchActive = true;
};
game.move = function (x, y, obj) {
	if (isGameOver) return;
	if (!touchActive) return;
	// If swipe up, jump
	if (touchStartY !== null && y < touchStartY - 80) {
		dino.jump();
		touchActive = false;
	}
	// If swipe down, duck
	if (touchStartY !== null && y > touchStartY + 80) {
		dino.duck();
		touchActive = false;
	}
};
game.up = function (x, y, obj) {
	if (isGameOver) return;
	dino.stand();
	touchStartY = null;
	touchActive = false;
};
// Main update loop
game.update = function () {
	if (isGameOver) return;
	// Defensive: track dino's lastX and lastY for event/collision best practices
	if (dino.lastX === undefined) dino.lastX = dino.x;
	if (dino.lastY === undefined) dino.lastY = dino.y;
	// Update dino
	dino.update();
	// Ground tiles remain static; no movement
	for (var g = 0; g < groundTiles.length; g++) {
		var tile = groundTiles[g];
		tile.x = g * groundSize;
	}
	// Update obstacles
	for (var i = obstacles.length - 1; i >= 0; i--) {
		var obs = obstacles[i];
		// Defensive: track lastX and lastY for event/collision best practices
		if (obs.lastX === undefined) obs.lastX = obs.x;
		if (obs.lastY === undefined) obs.lastY = obs.y;
		obs.speed = gameSpeed;
		obs.update();
		// Bird: simple up-down movement
		if (obs.type === 'bird') {
			obs.y = obs.flyY + Math.sin(LK.ticks / 12 + i) * 18;
		}
		// Remove if off screen
		if (obs.x < -obs.width) {
			obs.destroy();
			obstacles.splice(i, 1);
			continue;
		}
		// Scoring: passed dino
		if (!obs.passed && obs.x + obs.width / 2 < dino.x - dino.width / 2) {
			obs.passed = true;
			score += 1;
			scoreTxt.setText('' + score);
		}
		// Collision
		if (dino.intersects(obs)) {
			// If ducking and bird, allow pass
			if (obs.type === 'bird' && dino.isDucking && obs.y > dino.y - dino.height * 0.7) {
				continue;
			}
			// Game over
			isGameOver = true;
			LK.effects.flashScreen(0xff0000, 800);
			if (score > highScore) {
				highScore = score;
				storage.highScore = highScore;
			}
			LK.setTimeout(function () {
				LK.showGameOver();
			}, 900);
			return;
		}
	}
	// After all movement, update lastX and lastY for obstacles
	for (var j = 0; j < obstacles.length; j++) {
		obstacles[j].lastX = obstacles[j].x;
		obstacles[j].lastY = obstacles[j].y;
	}
	// Update dino's lastX and lastY
	dino.lastX = dino.x;
	dino.lastY = dino.y;
	// Increase game speed
	if (gameSpeed < GAME_SPEED_MAX) {
		gameSpeed += GAME_SPEED_INC * (1 + score * 0.04);
		if (gameSpeed > GAME_SPEED_MAX) gameSpeed = GAME_SPEED_MAX;
	}
	// Distance for score
	distance += gameSpeed;
	// Spawn new obstacle
	if (obstacles.length === 0 || 2048 - lastObstacleX > OBSTACLE_MIN_GAP + Math.random() * (OBSTACLE_MAX_GAP - OBSTACLE_MIN_GAP)) {
		spawnObstacle();
	}
};
// Listen for game over to reset
LK.on('gameover', function () {
	resetGame();
});
// Listen for you win (not used, but for completeness)
LK.on('youwin', function () {
	resetGame();
});
:quality(85)/https://cdn.frvr.ai/6830ddfed9786b640a7bfe40.png%3F3) 
 3d pixar tarzı kanat çırpan kuş yandan. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6830de50d9786b640a7bfe4d.png%3F3) 
 3d pixar tarzı kirpi yandan bakış. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6830e385d9786b640a7bfeec.png%3F3) 
 :quality(85)/https://cdn.frvr.ai/6831c105a25fd3027fdde51d.png%3F3) 
 Oyun arka planı gökyüzü 3d pixar. In-Game asset. 2d. High contrast. No shadows
:quality(85)/https://cdn.frvr.ai/6831c151a25fd3027fdde52f.png%3F3) 
 Garip bir oyun karakteri 3d pixar tarzı. In-Game asset. 2d. High contrast. No shadows