/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = 0;
	self.velocityY = 0;
	self.gravity = 0.5;
	self.isFlying = false;
	self.startX = 0;
	self.startY = 0;
	self.reset = function () {
		self.x = 1024;
		self.y = 2500;
		self.velocityX = 0;
		self.velocityY = 0;
		self.isFlying = false;
		self.startX = self.x;
		self.startY = self.y;
		self.lastY = self.y;
	};
	self.flick = function (targetX, targetY, power) {
		var deltaX = targetX - self.x;
		var deltaY = targetY - self.y;
		var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
		self.velocityX = deltaX / distance * power * 0.1;
		self.velocityY = deltaY / distance * power * 0.1;
		// Apply wind effect
		self.velocityX += windStrength * 0.01;
		self.isFlying = true;
		LK.getSound('kick').play();
	};
	self.update = function () {
		if (self.isFlying) {
			self.lastY = self.y;
			self.x += self.velocityX;
			self.y += self.velocityY;
			// Calculate rotation based on velocity for spinning effect
			var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
			ballGraphics.rotation += speed * 0.02;
			// Apply air resistance
			self.velocityX *= 0.998;
			self.velocityY *= 0.998;
			// Ground collision
			if (self.y >= 2500) {
				self.y = 2500;
				self.velocityY = -self.velocityY * 0.6;
				self.velocityX *= 0.8;
				if (Math.abs(self.velocityY) < 2 && Math.abs(self.velocityX) < 1) {
					self.isFlying = false;
				}
			}
			// Side boundaries
			if (self.x <= 30 || self.x >= 2018) {
				self.velocityX = -self.velocityX * 0.7;
				self.x = Math.max(30, Math.min(2018, self.x));
			}
			// Top boundary
			if (self.y <= 30) {
				self.y = 30;
				self.velocityY = Math.abs(self.velocityY);
			}
		}
	};
	return self;
});
var Goal = Container.expand(function () {
	var self = Container.call(this);
	var crossbar = self.attachAsset('crossbar', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.goalWidth = 200;
	self.goalHeight = 200;
	self.setup = function (x, y) {
		self.x = x;
		self.y = y;
		crossbar.x = 0;
		crossbar.y = -self.goalHeight;
	};
	self.checkGoal = function (ballX, ballY, ballLastY) {
		var leftPostX = self.x - self.goalWidth / 2;
		var rightPostX = self.x + self.goalWidth / 2;
		var crossbarY = self.y - self.goalHeight;
		// Check if ball is within goal area horizontally
		var inGoalAreaHorizontally = ballX > leftPostX && ballX < rightPostX;
		// Check if ball is currently above crossbar (inside goal vertically)
		var aboveCrossbar = ballY < crossbarY;
		// Check if ball entered from below the crossbar (was below crossbar and now above it)
		var enteredFromBelow = ballLastY >= crossbarY && ballY < crossbarY;
		return inGoalAreaHorizontally && aboveCrossbar && enteredFromBelow;
	};
	return self;
});
var Goalkeeper = Container.expand(function () {
	var self = Container.call(this);
	var keeperGraphics = self.attachAsset('goalkeeper', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.moveSpeed = 2;
	self.direction = 1;
	self.goalX = 0;
	self.goalWidth = 200;
	self.setup = function (goalX, goalWidth) {
		self.goalX = goalX;
		self.goalWidth = goalWidth;
		self.x = goalX;
		self.y = 800; // Position at ground level in front of goal
	};
	self.update = function () {
		// Move horizontally within goal area
		self.x += self.moveSpeed * self.direction;
		// Bounce between goal posts
		var leftBound = self.goalX - self.goalWidth / 2;
		var rightBound = self.goalX + self.goalWidth / 2;
		if (self.x <= leftBound || self.x >= rightBound) {
			self.direction *= -1;
			// Use tween for smooth direction change
			tween(self, {
				scaleX: self.direction
			}, {
				duration: 200,
				easing: tween.easeOut
			});
		}
	};
	return self;
});
var WindIndicator = Container.expand(function () {
	var self = Container.call(this);
	var arrow = self.attachAsset('windArrow', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		arrow.rotation = windDirection;
		arrow.scaleX = Math.abs(windStrength) * 0.5 + 0.5;
		arrow.alpha = Math.abs(windStrength) * 0.3 + 0.7;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x4a90e2
});
/**** 
* Game Code
****/ 
var ball = new Ball();
var goal = new Goal();
var goalkeeper = new Goalkeeper();
var windIndicator = new WindIndicator();
// Game state variables
var gameState = 'aiming'; // 'aiming', 'flying', 'resetting'
var shots = 0;
var maxShots = 10;
var windStrength = 0;
var windDirection = 0;
var difficulty = 1;
var goalMoveSpeed = 0;
var goalDirection = 1;
// Hold-to-power variables
var isHolding = false;
var holdStartTime = 0;
var holdTargetX = 0;
var holdTargetY = 0;
var maxHoldTime = 2000; // 2 seconds for maximum power
// Double tap variables
var lastTapTime = 0;
var doubleTapDelay = 300; // 300ms window for double tap
// Initialize ground
var ground = game.attachAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 2632
});
// Initialize game objects
ball.reset();
goal.setup(1024, 800);
goalkeeper.setup(1024, 200);
windIndicator.x = 200;
windIndicator.y = 200;
game.addChild(ball);
game.addChild(goal);
game.addChild(goalkeeper);
game.addChild(windIndicator);
// Goals display
var goalsScoredCount = 0;
var scoreTxt = new Text2('Goals: 0', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Shots remaining display
var shotsTxt = new Text2('Shots: 10', {
	size: 60,
	fill: 0xFFFFFF
});
shotsTxt.anchor.set(1, 0);
shotsTxt.x = -50;
shotsTxt.y = 100;
LK.gui.topRight.addChild(shotsTxt);
// Wind display
var windTxt = new Text2('Wind: None', {
	size: 50,
	fill: 0xFFFFFF
});
windTxt.anchor.set(0, 0);
windTxt.x = 50;
windTxt.y = 100;
LK.gui.topLeft.addChild(windTxt);
// Power display
var powerTxt = new Text2('Power: 0%', {
	size: 60,
	fill: 0xFFFF00
});
powerTxt.anchor.set(0.5, 0);
powerTxt.x = 0;
powerTxt.y = 150;
LK.gui.top.addChild(powerTxt);
function updateWind() {
	windDirection = (Math.random() - 0.5) * Math.PI;
	windStrength = (Math.random() - 0.5) * 2;
	var windText = 'Wind: ';
	if (Math.abs(windStrength) < 0.3) {
		windText += 'Light';
	} else if (Math.abs(windStrength) < 0.7) {
		windText += 'Moderate';
	} else {
		windText += 'Strong';
	}
	if (windStrength > 0) {
		windText += ' →';
	} else {
		windText += ' ←';
	}
	windTxt.setText(windText);
}
function resetRound() {
	ball.reset();
	gameState = 'aiming';
	shots++;
	// Update shots display
	shotsTxt.setText('Shots: ' + (maxShots - shots));
	// Check game over
	if (shots >= maxShots) {
		LK.showGameOver();
		return;
	}
	// Increase difficulty
	difficulty = Math.floor(shots / 3) + 1;
	goalMoveSpeed = Math.min(difficulty * 0.5, 3);
	// Update wind
	updateWind();
	// Move goal to new position
	var newGoalX = 500 + Math.random() * 1048;
	var newGoalY = 300 + Math.random() * 500;
	goal.setup(newGoalX, newGoalY);
	goalkeeper.setup(newGoalX, goal.goalWidth);
}
function calculatePower(startX, startY, endX, endY) {
	var deltaX = endX - startX;
	var deltaY = endY - startY;
	return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
}
// Initialize first round
updateWind();
game.down = function (x, y, obj) {
	var currentTime = Date.now();
	// Check for double tap
	if (currentTime - lastTapTime < doubleTapDelay) {
		// Double tap detected - skip to next shot
		if (gameState === 'flying' || gameState === 'aiming') {
			resetRound();
			return;
		}
	}
	lastTapTime = currentTime;
	if (gameState === 'aiming' && !ball.isFlying) {
		// Start holding for power calculation
		isHolding = true;
		holdStartTime = Date.now();
		holdTargetX = x;
		holdTargetY = y;
	}
};
game.up = function (x, y, obj) {
	if (gameState === 'aiming' && !ball.isFlying && isHolding) {
		// Calculate hold time and convert to power
		var holdTime = Date.now() - holdStartTime;
		var power = Math.min(holdTime / maxHoldTime * 400, 400); // Scale to max 400 power
		power = Math.max(power, 50); // Ensure minimum power
		// Shoot toward the target point
		ball.flick(holdTargetX, holdTargetY, power);
		gameState = 'flying';
		isHolding = false;
	}
};
game.update = function () {
	// Update wind indicator
	windIndicator.update();
	// Update goalkeeper movement
	goalkeeper.update();
	// Update power display during hold
	if (isHolding) {
		var holdTime = Date.now() - holdStartTime;
		var powerPercent = Math.min(holdTime / maxHoldTime * 100, 100);
		powerTxt.setText('Power: ' + Math.floor(powerPercent) + '%');
		powerTxt.visible = true;
	} else {
		powerTxt.visible = false;
	}
	// Move goal based on difficulty
	if (difficulty > 2) {
		goal.x += goalMoveSpeed * goalDirection;
		if (goal.x <= 300 || goal.x >= 1748) {
			goalDirection *= -1;
		}
	}
	// Check for collision with goalkeeper
	if (ball.isFlying && ball.intersects(goalkeeper)) {
		// Calculate reflection angle based on where ball hits goalkeeper
		var relativeHitX = ball.x - goalkeeper.x;
		var reflectionAngle = relativeHitX * 0.02; // Increased reflection sensitivity
		// Reflect velocity with energy loss - ensure ball goes back towards player
		ball.velocityX = -Math.abs(ball.velocityX) * 0.9 + reflectionAngle; // Force negative X (back towards player)
		ball.velocityY = -Math.abs(ball.velocityY) * 0.8; // Always bounce upward with more energy
		// Add goalkeeper movement influence
		ball.velocityX += goalkeeper.direction * goalkeeper.moveSpeed * 0.5;
		// Add some spin effect
		tween(ball, {
			rotation: ball.rotation + Math.PI * 2
		}, {
			duration: 500,
			easing: tween.easeOut
		});
		// Move ball away from goalkeeper to prevent multiple collisions
		ball.x = goalkeeper.x - 60; // Position ball in front of goalkeeper
		ball.y -= 10; // Lift ball slightly
	}
	// Check for goal
	if (ball.isFlying && goal.checkGoal(ball.x, ball.y, ball.lastY)) {
		goalsScoredCount++;
		scoreTxt.setText('Goals: ' + goalsScoredCount);
		LK.getSound('goal').play();
		LK.effects.flashScreen(0x00ff00, 500);
		resetRound();
	}
	// Check if ball has stopped and missed
	if (gameState === 'flying' && !ball.isFlying) {
		resetRound();
	}
	// Victory condition
	if (goalsScoredCount >= 5) {
		LK.showYouWin();
	}
}; /**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.velocityX = 0;
	self.velocityY = 0;
	self.gravity = 0.5;
	self.isFlying = false;
	self.startX = 0;
	self.startY = 0;
	self.reset = function () {
		self.x = 1024;
		self.y = 2500;
		self.velocityX = 0;
		self.velocityY = 0;
		self.isFlying = false;
		self.startX = self.x;
		self.startY = self.y;
		self.lastY = self.y;
	};
	self.flick = function (targetX, targetY, power) {
		var deltaX = targetX - self.x;
		var deltaY = targetY - self.y;
		var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
		self.velocityX = deltaX / distance * power * 0.1;
		self.velocityY = deltaY / distance * power * 0.1;
		// Apply wind effect
		self.velocityX += windStrength * 0.01;
		self.isFlying = true;
		LK.getSound('kick').play();
	};
	self.update = function () {
		if (self.isFlying) {
			self.lastY = self.y;
			self.x += self.velocityX;
			self.y += self.velocityY;
			// Calculate rotation based on velocity for spinning effect
			var speed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
			ballGraphics.rotation += speed * 0.02;
			// Apply air resistance
			self.velocityX *= 0.998;
			self.velocityY *= 0.998;
			// Ground collision
			if (self.y >= 2500) {
				self.y = 2500;
				self.velocityY = -self.velocityY * 0.6;
				self.velocityX *= 0.8;
				if (Math.abs(self.velocityY) < 2 && Math.abs(self.velocityX) < 1) {
					self.isFlying = false;
				}
			}
			// Side boundaries
			if (self.x <= 30 || self.x >= 2018) {
				self.velocityX = -self.velocityX * 0.7;
				self.x = Math.max(30, Math.min(2018, self.x));
			}
			// Top boundary
			if (self.y <= 30) {
				self.y = 30;
				self.velocityY = Math.abs(self.velocityY);
			}
		}
	};
	return self;
});
var Goal = Container.expand(function () {
	var self = Container.call(this);
	var crossbar = self.attachAsset('crossbar', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.goalWidth = 200;
	self.goalHeight = 200;
	self.setup = function (x, y) {
		self.x = x;
		self.y = y;
		crossbar.x = 0;
		crossbar.y = -self.goalHeight;
	};
	self.checkGoal = function (ballX, ballY, ballLastY) {
		var leftPostX = self.x - self.goalWidth / 2;
		var rightPostX = self.x + self.goalWidth / 2;
		var crossbarY = self.y - self.goalHeight;
		// Check if ball is within goal area horizontally
		var inGoalAreaHorizontally = ballX > leftPostX && ballX < rightPostX;
		// Check if ball is currently above crossbar (inside goal vertically)
		var aboveCrossbar = ballY < crossbarY;
		// Check if ball entered from below the crossbar (was below crossbar and now above it)
		var enteredFromBelow = ballLastY >= crossbarY && ballY < crossbarY;
		return inGoalAreaHorizontally && aboveCrossbar && enteredFromBelow;
	};
	return self;
});
var Goalkeeper = Container.expand(function () {
	var self = Container.call(this);
	var keeperGraphics = self.attachAsset('goalkeeper', {
		anchorX: 0.5,
		anchorY: 1.0
	});
	self.moveSpeed = 2;
	self.direction = 1;
	self.goalX = 0;
	self.goalWidth = 200;
	self.setup = function (goalX, goalWidth) {
		self.goalX = goalX;
		self.goalWidth = goalWidth;
		self.x = goalX;
		self.y = 800; // Position at ground level in front of goal
	};
	self.update = function () {
		// Move horizontally within goal area
		self.x += self.moveSpeed * self.direction;
		// Bounce between goal posts
		var leftBound = self.goalX - self.goalWidth / 2;
		var rightBound = self.goalX + self.goalWidth / 2;
		if (self.x <= leftBound || self.x >= rightBound) {
			self.direction *= -1;
			// Use tween for smooth direction change
			tween(self, {
				scaleX: self.direction
			}, {
				duration: 200,
				easing: tween.easeOut
			});
		}
	};
	return self;
});
var WindIndicator = Container.expand(function () {
	var self = Container.call(this);
	var arrow = self.attachAsset('windArrow', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		arrow.rotation = windDirection;
		arrow.scaleX = Math.abs(windStrength) * 0.5 + 0.5;
		arrow.alpha = Math.abs(windStrength) * 0.3 + 0.7;
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x4a90e2
});
/**** 
* Game Code
****/ 
var ball = new Ball();
var goal = new Goal();
var goalkeeper = new Goalkeeper();
var windIndicator = new WindIndicator();
// Game state variables
var gameState = 'aiming'; // 'aiming', 'flying', 'resetting'
var shots = 0;
var maxShots = 10;
var windStrength = 0;
var windDirection = 0;
var difficulty = 1;
var goalMoveSpeed = 0;
var goalDirection = 1;
// Hold-to-power variables
var isHolding = false;
var holdStartTime = 0;
var holdTargetX = 0;
var holdTargetY = 0;
var maxHoldTime = 2000; // 2 seconds for maximum power
// Double tap variables
var lastTapTime = 0;
var doubleTapDelay = 300; // 300ms window for double tap
// Initialize ground
var ground = game.attachAsset('ground', {
	anchorX: 0,
	anchorY: 0,
	x: 0,
	y: 2632
});
// Initialize game objects
ball.reset();
goal.setup(1024, 800);
goalkeeper.setup(1024, 200);
windIndicator.x = 200;
windIndicator.y = 200;
game.addChild(ball);
game.addChild(goal);
game.addChild(goalkeeper);
game.addChild(windIndicator);
// Goals display
var goalsScoredCount = 0;
var scoreTxt = new Text2('Goals: 0', {
	size: 80,
	fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Shots remaining display
var shotsTxt = new Text2('Shots: 10', {
	size: 60,
	fill: 0xFFFFFF
});
shotsTxt.anchor.set(1, 0);
shotsTxt.x = -50;
shotsTxt.y = 100;
LK.gui.topRight.addChild(shotsTxt);
// Wind display
var windTxt = new Text2('Wind: None', {
	size: 50,
	fill: 0xFFFFFF
});
windTxt.anchor.set(0, 0);
windTxt.x = 50;
windTxt.y = 100;
LK.gui.topLeft.addChild(windTxt);
// Power display
var powerTxt = new Text2('Power: 0%', {
	size: 60,
	fill: 0xFFFF00
});
powerTxt.anchor.set(0.5, 0);
powerTxt.x = 0;
powerTxt.y = 150;
LK.gui.top.addChild(powerTxt);
function updateWind() {
	windDirection = (Math.random() - 0.5) * Math.PI;
	windStrength = (Math.random() - 0.5) * 2;
	var windText = 'Wind: ';
	if (Math.abs(windStrength) < 0.3) {
		windText += 'Light';
	} else if (Math.abs(windStrength) < 0.7) {
		windText += 'Moderate';
	} else {
		windText += 'Strong';
	}
	if (windStrength > 0) {
		windText += ' →';
	} else {
		windText += ' ←';
	}
	windTxt.setText(windText);
}
function resetRound() {
	ball.reset();
	gameState = 'aiming';
	shots++;
	// Update shots display
	shotsTxt.setText('Shots: ' + (maxShots - shots));
	// Check game over
	if (shots >= maxShots) {
		LK.showGameOver();
		return;
	}
	// Increase difficulty
	difficulty = Math.floor(shots / 3) + 1;
	goalMoveSpeed = Math.min(difficulty * 0.5, 3);
	// Update wind
	updateWind();
	// Move goal to new position
	var newGoalX = 500 + Math.random() * 1048;
	var newGoalY = 300 + Math.random() * 500;
	goal.setup(newGoalX, newGoalY);
	goalkeeper.setup(newGoalX, goal.goalWidth);
}
function calculatePower(startX, startY, endX, endY) {
	var deltaX = endX - startX;
	var deltaY = endY - startY;
	return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
}
// Initialize first round
updateWind();
game.down = function (x, y, obj) {
	var currentTime = Date.now();
	// Check for double tap
	if (currentTime - lastTapTime < doubleTapDelay) {
		// Double tap detected - skip to next shot
		if (gameState === 'flying' || gameState === 'aiming') {
			resetRound();
			return;
		}
	}
	lastTapTime = currentTime;
	if (gameState === 'aiming' && !ball.isFlying) {
		// Start holding for power calculation
		isHolding = true;
		holdStartTime = Date.now();
		holdTargetX = x;
		holdTargetY = y;
	}
};
game.up = function (x, y, obj) {
	if (gameState === 'aiming' && !ball.isFlying && isHolding) {
		// Calculate hold time and convert to power
		var holdTime = Date.now() - holdStartTime;
		var power = Math.min(holdTime / maxHoldTime * 400, 400); // Scale to max 400 power
		power = Math.max(power, 50); // Ensure minimum power
		// Shoot toward the target point
		ball.flick(holdTargetX, holdTargetY, power);
		gameState = 'flying';
		isHolding = false;
	}
};
game.update = function () {
	// Update wind indicator
	windIndicator.update();
	// Update goalkeeper movement
	goalkeeper.update();
	// Update power display during hold
	if (isHolding) {
		var holdTime = Date.now() - holdStartTime;
		var powerPercent = Math.min(holdTime / maxHoldTime * 100, 100);
		powerTxt.setText('Power: ' + Math.floor(powerPercent) + '%');
		powerTxt.visible = true;
	} else {
		powerTxt.visible = false;
	}
	// Move goal based on difficulty
	if (difficulty > 2) {
		goal.x += goalMoveSpeed * goalDirection;
		if (goal.x <= 300 || goal.x >= 1748) {
			goalDirection *= -1;
		}
	}
	// Check for collision with goalkeeper
	if (ball.isFlying && ball.intersects(goalkeeper)) {
		// Calculate reflection angle based on where ball hits goalkeeper
		var relativeHitX = ball.x - goalkeeper.x;
		var reflectionAngle = relativeHitX * 0.02; // Increased reflection sensitivity
		// Reflect velocity with energy loss - ensure ball goes back towards player
		ball.velocityX = -Math.abs(ball.velocityX) * 0.9 + reflectionAngle; // Force negative X (back towards player)
		ball.velocityY = -Math.abs(ball.velocityY) * 0.8; // Always bounce upward with more energy
		// Add goalkeeper movement influence
		ball.velocityX += goalkeeper.direction * goalkeeper.moveSpeed * 0.5;
		// Add some spin effect
		tween(ball, {
			rotation: ball.rotation + Math.PI * 2
		}, {
			duration: 500,
			easing: tween.easeOut
		});
		// Move ball away from goalkeeper to prevent multiple collisions
		ball.x = goalkeeper.x - 60; // Position ball in front of goalkeeper
		ball.y -= 10; // Lift ball slightly
	}
	// Check for goal
	if (ball.isFlying && goal.checkGoal(ball.x, ball.y, ball.lastY)) {
		goalsScoredCount++;
		scoreTxt.setText('Goals: ' + goalsScoredCount);
		LK.getSound('goal').play();
		LK.effects.flashScreen(0x00ff00, 500);
		resetRound();
	}
	// Check if ball has stopped and missed
	if (gameState === 'flying' && !ball.isFlying) {
		resetRound();
	}
	// Victory condition
	if (goalsScoredCount >= 5) {
		LK.showYouWin();
	}
};