/**** 
* Classes
****/ 
// Assets will be automatically created based on usage in the code.
// Ball class
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = (Math.random() < 0.5 ? -1 : 1) * (10 + Math.random() * 10);
	self.speedY = (Math.random() < 0.5 ? -1 : 1) * (10 + Math.random() * 10);
	self._move_migrated = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		// Bounce off top and bottom walls
		if (self.y <= 0 || self.y >= 2732) {
			self.speedY *= -1;
		}
	};
});
// DashedLine class
var DashedLine = Container.expand(function () {
	var self = Container.call(this);
	var lineGraphics = self.attachAsset('dashedLine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
});
// Paddle class
var Paddle = Container.expand(function () {
	var self = Container.call(this);
	var paddleGraphics = self.attachAsset('paddle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.score = 0; // Initialize score counter
	self._move_migrated = function (y) {
		self.y = y;
		// Prevent paddle from moving out of bounds
		if (self.y < 0) {
			self.y = 0;
		} else if (self.y > 2732) {
			self.y = 2732;
		}
	};
});
var SmallBall = Container.expand(function () {
	var self = Container.call(this);
	var smallBallGraphics = self.attachAsset('smallBall', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = (Math.random() < 0.5 ? -1 : 1) * (5 + Math.random() * 5);
	self.speedY = (Math.random() < 0.5 ? -1 : 1) * (5 + Math.random() * 5);
	self._move_migrated = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		// Bounce off top and bottom walls
		if (self.y <= 0 || self.y >= 2732) {
			self.speedY *= -1;
		}
		// Bounce off left and right walls
		if (self.x <= 0 || self.x >= 2048) {
			self.speedX *= -1;
		}
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000 // Init game with black background 
});
/**** 
* Game Code
****/ 
// Initialize ball and paddles
var ball = game.addChild(new Ball());
ball.x = 1024; // Center horizontally
ball.y = 1366; // Center vertically
var playerPaddle = game.addChild(new Paddle());
playerPaddle.x = 100; // Position player paddle on the left
var aiPaddle = game.addChild(new Paddle());
aiPaddle.x = 1948; // Position AI paddle on the right
// Initialize score text
var playerScoreTxt = new Text2('0', {
	size: 150,
	fill: "#ffffff" //Optional (this is the default string)
});
playerScoreTxt.anchor.set(0, 0); // Sets anchor to the left of the top edge of the text.
playerScoreTxt.x = 500; // Move the player score 500 pixels to the right
LK.gui.topLeft.addChild(playerScoreTxt); // Add the player's score text to the GUI overlay
var aiScoreTxt = new Text2('0', {
	size: 150,
	fill: "#ffffff"
});
aiScoreTxt.anchor.set(1, 0);
aiScoreTxt.x = -500; // Move the computer score 500 pixels to the left
LK.gui.topRight.addChild(aiScoreTxt);
// Initialize and position the dashed line
for (var i = 0; i < 2732; i += 200) {
	var dashedLine = game.addChild(new DashedLine());
	dashedLine.x = 1024; // Center horizontally
	dashedLine.y = i;
}
// Handle touch movement for player paddle
game.on('move', function (x, y, obj) {
	var pos = game.toLocal(obj.global);
	playerPaddle._move_migrated(pos.y);
});
// AI movement
function aiMove() {
	var speed = 20; // Increase the speed of AI paddle
	var inaccuracy = Math.random() < 0.5 ? 200 : 0; // 50% chance to move inaccurately
	var targetY = ball.y + inaccuracy;
	var diff = targetY - aiPaddle.y;
	if (Math.abs(diff) < speed) {
		aiPaddle.y = targetY;
	} else {
		aiPaddle.y += Math.sign(diff) * speed;
	}
}
// Check for ball collisions with paddles
function checkCollisions() {
	if (ball.intersects(playerPaddle)) {
		// Calculate the difference between the center of the ball and the center of the paddle
		var diffY = ball.y - playerPaddle.y;
		// Normalize the difference to get a value between -1 and 1
		var normalizedDiffY = diffY / (playerPaddle.height / 2);
		// Multiply the normalized difference by the maximum angle of deflection (in radians)
		var angle = normalizedDiffY * (5 * Math.PI / 12);
		// Ensure the angle is at least 30 degrees
		angle = Math.max(angle, Math.PI / 6);
		// Set the new speeds based on the angle and increase it by 3 times
		ball.speedX = Math.cos(angle) * 5 * 3;
		ball.speedY = Math.sin(angle) * 5 * 3;
		// Create 5 new balls
		for (var i = 0; i < 5; i++) {
			var newBall = new SmallBall();
			newBall.x = ball.x;
			newBall.y = ball.y;
			var randomAngle = angle + (Math.random() - 0.5) * (Math.PI / 6); // Randomize angle slightly
			var randomSpeed = 5 + Math.random() * 5; // Randomize speed
			newBall.speedX = Math.cos(randomAngle) * randomSpeed;
			newBall.speedY = Math.sin(randomAngle) * randomSpeed;
			game.addChild(newBall);
			// Calculate the difference between the center of the ball and the center of the paddle
			var diffY = ball.y - playerPaddle.y;
			// Normalize the difference to get a value between -1 and 1
			var normalizedDiffY = diffY / (playerPaddle.height / 2);
			// Multiply the normalized difference by the maximum angle of deflection (in radians)
			var angle = normalizedDiffY * (5 * Math.PI / 12);
			// Ensure the angle is at least 30 degrees
			angle = Math.max(angle, Math.PI / 6);
			// Set the new speeds based on the angle and increase it by 3 times
			ball.speedX = Math.cos(angle) * 5 * 3;
			ball.speedY = Math.sin(angle) * 5 * 3;
		}
	}
	if (ball.intersects(aiPaddle)) {
		// Create 20 new balls
		for (var i = 0; i < 20; i++) {
			var newBall = new SmallBall();
			newBall.x = ball.x;
			newBall.y = ball.y;
			var randomAngle = (Math.random() - 0.5) * (Math.PI / 3); // Randomize angle
			var randomSpeed = 5 + Math.random() * 5; // Randomize speed
			newBall.speedX = -Math.cos(randomAngle) * randomSpeed;
			newBall.speedY = Math.sin(randomAngle) * randomSpeed;
			game.addChild(newBall);
		}
		// Calculate the difference between the center of the ball and the center of the paddle
		var diffY = ball.y - aiPaddle.y;
		// Normalize the difference to get a value between -1 and 1
		var normalizedDiffY = diffY / (aiPaddle.height / 2);
		// Multiply the normalized difference by the maximum angle of deflection (in radians)
		var angle = normalizedDiffY * (5 * Math.PI / 12);
		// Ensure the angle is at least 30 degrees
		angle = Math.max(angle, Math.PI / 6);
		// Set the new speeds based on the angle and increase it by 3 times
		ball.speedX = -Math.cos(angle) * 5 * 3;
		ball.speedY = Math.sin(angle) * 5 * 3;
		// Calculate the difference between the center of the ball and the center of the paddle
		var diffY = ball.y - aiPaddle.y;
		// Normalize the difference to get a value between -1 and 1
		var normalizedDiffY = diffY / (aiPaddle.height / 2);
		// Multiply the normalized difference by the maximum angle of deflection (in radians)
		var angle = normalizedDiffY * (5 * Math.PI / 12);
		// Ensure the angle is at least 30 degrees
		angle = Math.max(angle, Math.PI / 6);
		// Set the new speeds based on the angle and increase it by 3 times
		ball.speedX = -Math.cos(angle) * 5 * 3;
		ball.speedY = Math.sin(angle) * 5 * 3;
	}
	// Check for scoring
	if (ball.x <= 0) {
		// Reset ball position
		ball.x = 1024;
		ball.y = 1366;
		ball.speedX *= -1;
		aiPaddle.score++; // Increase AI's score
		aiScoreTxt.setText(aiPaddle.score); // Update AI's score display
		// Add blood splatter effect
		LK.effects.flashScreen(0xff0000, 100);
	}
	if (ball.x >= 2048) {
		// Reset ball position
		ball.x = 1024;
		ball.y = 1366;
		ball.speedX *= -1;
		playerPaddle.score++; // Increase player's score
		playerScoreTxt.setText(playerPaddle.score); // Update player's score display
		// Add blood splatter effect
		LK.effects.flashScreen(0xff0000, 100);
	}
	// Check if the player or the AI has won
	if (playerPaddle.score >= 10 || aiPaddle.score >= 10) {
		// Flash screen red for 1 second (1000ms) to show game over.
		LK.effects.flashScreen(0xff0000, 1000);
		// Show game over. The game will be automatically paused while game over is showing.
		LK.showGameOver(); // Calling this will destroy the 'Game' and reset entire game state.
	}
}
// Game tick
LK.on('tick', function () {
	ball._move_migrated();
	aiMove();
	checkCollisions();
	playerScoreTxt.setText(playerPaddle.score); // Update score display
	// Move the new balls
	game.children.forEach(function (child) {
		if (child instanceof SmallBall) {
			child._move_migrated();
		}
	});
}); /**** 
* Classes
****/ 
// Assets will be automatically created based on usage in the code.
// Ball class
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = (Math.random() < 0.5 ? -1 : 1) * (10 + Math.random() * 10);
	self.speedY = (Math.random() < 0.5 ? -1 : 1) * (10 + Math.random() * 10);
	self._move_migrated = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		// Bounce off top and bottom walls
		if (self.y <= 0 || self.y >= 2732) {
			self.speedY *= -1;
		}
	};
});
// DashedLine class
var DashedLine = Container.expand(function () {
	var self = Container.call(this);
	var lineGraphics = self.attachAsset('dashedLine', {
		anchorX: 0.5,
		anchorY: 0.5
	});
});
// Paddle class
var Paddle = Container.expand(function () {
	var self = Container.call(this);
	var paddleGraphics = self.attachAsset('paddle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.score = 0; // Initialize score counter
	self._move_migrated = function (y) {
		self.y = y;
		// Prevent paddle from moving out of bounds
		if (self.y < 0) {
			self.y = 0;
		} else if (self.y > 2732) {
			self.y = 2732;
		}
	};
});
var SmallBall = Container.expand(function () {
	var self = Container.call(this);
	var smallBallGraphics = self.attachAsset('smallBall', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speedX = (Math.random() < 0.5 ? -1 : 1) * (5 + Math.random() * 5);
	self.speedY = (Math.random() < 0.5 ? -1 : 1) * (5 + Math.random() * 5);
	self._move_migrated = function () {
		self.x += self.speedX;
		self.y += self.speedY;
		// Bounce off top and bottom walls
		if (self.y <= 0 || self.y >= 2732) {
			self.speedY *= -1;
		}
		// Bounce off left and right walls
		if (self.x <= 0 || self.x >= 2048) {
			self.speedX *= -1;
		}
	};
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000 // Init game with black background 
});
/**** 
* Game Code
****/ 
// Initialize ball and paddles
var ball = game.addChild(new Ball());
ball.x = 1024; // Center horizontally
ball.y = 1366; // Center vertically
var playerPaddle = game.addChild(new Paddle());
playerPaddle.x = 100; // Position player paddle on the left
var aiPaddle = game.addChild(new Paddle());
aiPaddle.x = 1948; // Position AI paddle on the right
// Initialize score text
var playerScoreTxt = new Text2('0', {
	size: 150,
	fill: "#ffffff" //Optional (this is the default string)
});
playerScoreTxt.anchor.set(0, 0); // Sets anchor to the left of the top edge of the text.
playerScoreTxt.x = 500; // Move the player score 500 pixels to the right
LK.gui.topLeft.addChild(playerScoreTxt); // Add the player's score text to the GUI overlay
var aiScoreTxt = new Text2('0', {
	size: 150,
	fill: "#ffffff"
});
aiScoreTxt.anchor.set(1, 0);
aiScoreTxt.x = -500; // Move the computer score 500 pixels to the left
LK.gui.topRight.addChild(aiScoreTxt);
// Initialize and position the dashed line
for (var i = 0; i < 2732; i += 200) {
	var dashedLine = game.addChild(new DashedLine());
	dashedLine.x = 1024; // Center horizontally
	dashedLine.y = i;
}
// Handle touch movement for player paddle
game.on('move', function (x, y, obj) {
	var pos = game.toLocal(obj.global);
	playerPaddle._move_migrated(pos.y);
});
// AI movement
function aiMove() {
	var speed = 20; // Increase the speed of AI paddle
	var inaccuracy = Math.random() < 0.5 ? 200 : 0; // 50% chance to move inaccurately
	var targetY = ball.y + inaccuracy;
	var diff = targetY - aiPaddle.y;
	if (Math.abs(diff) < speed) {
		aiPaddle.y = targetY;
	} else {
		aiPaddle.y += Math.sign(diff) * speed;
	}
}
// Check for ball collisions with paddles
function checkCollisions() {
	if (ball.intersects(playerPaddle)) {
		// Calculate the difference between the center of the ball and the center of the paddle
		var diffY = ball.y - playerPaddle.y;
		// Normalize the difference to get a value between -1 and 1
		var normalizedDiffY = diffY / (playerPaddle.height / 2);
		// Multiply the normalized difference by the maximum angle of deflection (in radians)
		var angle = normalizedDiffY * (5 * Math.PI / 12);
		// Ensure the angle is at least 30 degrees
		angle = Math.max(angle, Math.PI / 6);
		// Set the new speeds based on the angle and increase it by 3 times
		ball.speedX = Math.cos(angle) * 5 * 3;
		ball.speedY = Math.sin(angle) * 5 * 3;
		// Create 5 new balls
		for (var i = 0; i < 5; i++) {
			var newBall = new SmallBall();
			newBall.x = ball.x;
			newBall.y = ball.y;
			var randomAngle = angle + (Math.random() - 0.5) * (Math.PI / 6); // Randomize angle slightly
			var randomSpeed = 5 + Math.random() * 5; // Randomize speed
			newBall.speedX = Math.cos(randomAngle) * randomSpeed;
			newBall.speedY = Math.sin(randomAngle) * randomSpeed;
			game.addChild(newBall);
			// Calculate the difference between the center of the ball and the center of the paddle
			var diffY = ball.y - playerPaddle.y;
			// Normalize the difference to get a value between -1 and 1
			var normalizedDiffY = diffY / (playerPaddle.height / 2);
			// Multiply the normalized difference by the maximum angle of deflection (in radians)
			var angle = normalizedDiffY * (5 * Math.PI / 12);
			// Ensure the angle is at least 30 degrees
			angle = Math.max(angle, Math.PI / 6);
			// Set the new speeds based on the angle and increase it by 3 times
			ball.speedX = Math.cos(angle) * 5 * 3;
			ball.speedY = Math.sin(angle) * 5 * 3;
		}
	}
	if (ball.intersects(aiPaddle)) {
		// Create 20 new balls
		for (var i = 0; i < 20; i++) {
			var newBall = new SmallBall();
			newBall.x = ball.x;
			newBall.y = ball.y;
			var randomAngle = (Math.random() - 0.5) * (Math.PI / 3); // Randomize angle
			var randomSpeed = 5 + Math.random() * 5; // Randomize speed
			newBall.speedX = -Math.cos(randomAngle) * randomSpeed;
			newBall.speedY = Math.sin(randomAngle) * randomSpeed;
			game.addChild(newBall);
		}
		// Calculate the difference between the center of the ball and the center of the paddle
		var diffY = ball.y - aiPaddle.y;
		// Normalize the difference to get a value between -1 and 1
		var normalizedDiffY = diffY / (aiPaddle.height / 2);
		// Multiply the normalized difference by the maximum angle of deflection (in radians)
		var angle = normalizedDiffY * (5 * Math.PI / 12);
		// Ensure the angle is at least 30 degrees
		angle = Math.max(angle, Math.PI / 6);
		// Set the new speeds based on the angle and increase it by 3 times
		ball.speedX = -Math.cos(angle) * 5 * 3;
		ball.speedY = Math.sin(angle) * 5 * 3;
		// Calculate the difference between the center of the ball and the center of the paddle
		var diffY = ball.y - aiPaddle.y;
		// Normalize the difference to get a value between -1 and 1
		var normalizedDiffY = diffY / (aiPaddle.height / 2);
		// Multiply the normalized difference by the maximum angle of deflection (in radians)
		var angle = normalizedDiffY * (5 * Math.PI / 12);
		// Ensure the angle is at least 30 degrees
		angle = Math.max(angle, Math.PI / 6);
		// Set the new speeds based on the angle and increase it by 3 times
		ball.speedX = -Math.cos(angle) * 5 * 3;
		ball.speedY = Math.sin(angle) * 5 * 3;
	}
	// Check for scoring
	if (ball.x <= 0) {
		// Reset ball position
		ball.x = 1024;
		ball.y = 1366;
		ball.speedX *= -1;
		aiPaddle.score++; // Increase AI's score
		aiScoreTxt.setText(aiPaddle.score); // Update AI's score display
		// Add blood splatter effect
		LK.effects.flashScreen(0xff0000, 100);
	}
	if (ball.x >= 2048) {
		// Reset ball position
		ball.x = 1024;
		ball.y = 1366;
		ball.speedX *= -1;
		playerPaddle.score++; // Increase player's score
		playerScoreTxt.setText(playerPaddle.score); // Update player's score display
		// Add blood splatter effect
		LK.effects.flashScreen(0xff0000, 100);
	}
	// Check if the player or the AI has won
	if (playerPaddle.score >= 10 || aiPaddle.score >= 10) {
		// Flash screen red for 1 second (1000ms) to show game over.
		LK.effects.flashScreen(0xff0000, 1000);
		// Show game over. The game will be automatically paused while game over is showing.
		LK.showGameOver(); // Calling this will destroy the 'Game' and reset entire game state.
	}
}
// Game tick
LK.on('tick', function () {
	ball._move_migrated();
	aiMove();
	checkCollisions();
	playerScoreTxt.setText(playerPaddle.score); // Update score display
	// Move the new balls
	game.children.forEach(function (child) {
		if (child instanceof SmallBall) {
			child._move_migrated();
		}
	});
});