/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
	highScore: 0,
	aiDifficulty: 0.7
});
/**** 
* Classes
****/ 
var Ball = Container.expand(function () {
	var self = Container.call(this);
	var ballGraphics = self.attachAsset('ball', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.radius = ballGraphics.width / 2;
	self.velocity = {
		x: 0,
		y: 0
	};
	self.baseSpeed = 12;
	self.speedMultiplier = 1.0;
	self.maxSpeedMultiplier = 2.5;
	self.reset = function () {
		self.x = 2048 / 2;
		self.y = 2732 / 2;
		self.speedMultiplier = 1.0;
		// Random initial direction
		var angle = Math.random() * Math.PI / 2 - Math.PI / 4;
		if (Math.random() < 0.5) {
			angle += Math.PI;
		}
		self.velocity.x = Math.cos(angle) * self.baseSpeed;
		self.velocity.y = Math.sin(angle) * self.baseSpeed;
		// Make sure horizontal speed is significant
		if (Math.abs(self.velocity.x) < self.baseSpeed * 0.6) {
			self.velocity.x = (self.velocity.x > 0 ? 1 : -1) * self.baseSpeed * 0.6;
		}
	};
	self.update = function () {
		// Move ball based on velocity
		self.x += self.velocity.x * self.speedMultiplier;
		self.y += self.velocity.y * self.speedMultiplier;
		// Collision with top and bottom walls
		if (self.y < self.radius) {
			self.y = self.radius;
			self.velocity.y *= -1;
			LK.getSound('hit').play();
		} else if (self.y > 2732 - self.radius) {
			self.y = 2732 - self.radius;
			self.velocity.y *= -1;
			LK.getSound('hit').play();
		}
	};
	self.hitPaddle = function (paddle) {
		// Normalize collision point (-1 to 1) from paddle center
		var relativeY = (self.y - paddle.y) / (paddle.height / 2);
		// Adjust angle based on where the ball hit the paddle
		var angle = relativeY * Math.PI / 3; // max ±60 degrees
		// Reverse x direction and apply new angle
		self.velocity.x = -Math.sign(self.velocity.x) * Math.cos(angle) * self.baseSpeed;
		self.velocity.y = Math.sin(angle) * self.baseSpeed;
		// Increase speed with each hit, up to a maximum
		self.speedMultiplier = Math.min(self.maxSpeedMultiplier, self.speedMultiplier + 0.05);
		// Play hit sound
		LK.getSound('hit').play();
	};
	return self;
});
var Paddle = Container.expand(function () {
	var self = Container.call(this);
	var paddleGraphics = self.attachAsset('paddle', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.width = paddleGraphics.width;
	self.height = paddleGraphics.height;
	self.speed = 0;
	self.target = 0;
	self.isAI = false;
	self.aiReactionSpeed = 0.7; // Default AI difficulty level (0.1-0.9)
	// AI paddle movement logic
	self.updateAI = function (ball, dt) {
		if (!self.isAI) {
			return;
		}
		// Only update target if ball is moving toward this paddle
		if (self.x < 1024 && ball.velocity.x < 0 || self.x > 1024 && ball.velocity.x > 0) {
			// Predict where the ball will be
			var distanceX = Math.abs(self.x - ball.x);
			var timeToReach = distanceX / Math.abs(ball.velocity.x);
			var futureY = ball.y + ball.velocity.y * timeToReach;
			// Keep the future position in bounds
			futureY = Math.max(self.height / 2, Math.min(2732 - self.height / 2, futureY));
			// Add some imperfection based on AI difficulty
			var errorFactor = (1 - self.aiReactionSpeed) * 300;
			futureY += Math.random() * errorFactor * 2 - errorFactor;
			// Gradually move toward the predicted position
			self.target = futureY;
		}
	};
	self.update = function (dt) {
		// Gradually move toward target position (whether controlled by player or AI)
		if (self.target !== null) {
			self.speed = (self.target - self.y) * 0.2;
			// Cap movement speed
			var maxSpeed = 40;
			self.speed = Math.max(-maxSpeed, Math.min(maxSpeed, self.speed));
			self.y += self.speed;
			// Keep paddle in bounds
			self.y = Math.max(self.height / 2, Math.min(2732 - self.height / 2, self.y));
		}
	};
	return self;
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000
});
/**** 
* Game Code
****/ 
// Game state
var gameStarted = false;
var gameMode = "single"; // "single" or "multi"
var scoreLeft = 0;
var scoreRight = 0;
var maxScore = 11;
var lastFrameTime = Date.now();
// Create paddles
var leftPaddle = game.addChild(new Paddle());
leftPaddle.x = 100;
leftPaddle.y = 2732 / 2;
var rightPaddle = game.addChild(new Paddle());
rightPaddle.x = 2048 - 100;
rightPaddle.y = 2732 / 2;
rightPaddle.isAI = true;
rightPaddle.aiReactionSpeed = storage.aiDifficulty;
// Create ball
var ball = game.addChild(new Ball());
ball.reset();
// Create center line
var centerLineContainer = game.addChild(new Container());
centerLineContainer.x = 2048 / 2;
for (var y = 15; y < 2732; y += 60) {
	var lineSegment = centerLineContainer.attachAsset('centerLine', {
		anchorX: 0.5,
		anchorY: 0.5,
		y: y
	});
}
// Score text
var scoreLeftText = new Text2(scoreLeft.toString(), {
	size: 150,
	fill: 0xFFFFFF
});
scoreLeftText.anchor.set(1, 0);
scoreLeftText.x = 2048 / 2 - 50;
scoreLeftText.y = 50;
LK.gui.addChild(scoreLeftText);
var scoreRightText = new Text2(scoreRight.toString(), {
	size: 150,
	fill: 0xFFFFFF
});
scoreRightText.anchor.set(0, 0);
scoreRightText.x = 2048 / 2 + 50;
scoreRightText.y = 50;
LK.gui.addChild(scoreRightText);
// Game mode button
var singlePlayerButton = new Text2("1P", {
	size: 80,
	fill: gameMode === "single" ? "#ffffff" : "#888888"
});
singlePlayerButton.anchor.set(1, 0);
singlePlayerButton.x = 2048 / 2 - 20;
singlePlayerButton.y = 220;
LK.gui.addChild(singlePlayerButton);
var multiPlayerButton = new Text2("2P", {
	size: 80,
	fill: gameMode === "multi" ? "#ffffff" : "#888888"
});
multiPlayerButton.anchor.set(0, 0);
multiPlayerButton.x = 2048 / 2 + 20;
multiPlayerButton.y = 220;
LK.gui.addChild(multiPlayerButton);
// Start text
var startText = new Text2("TAP TO START", {
	size: 100,
	fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = 2048 / 2;
startText.y = 2732 / 2;
LK.gui.addChild(startText);
// Store which paddle the user is currently controlling
var activePaddle = null;
// Update scores
function updateScore() {
	scoreLeftText.setText(scoreLeft.toString());
	scoreRightText.setText(scoreRight.toString());
}
// Check for win condition
function checkWinCondition() {
	if (scoreLeft >= maxScore) {
		if (gameMode === "single") {
			// Update high score if playing single player
			if (scoreLeft > storage.highScore) {
				storage.highScore = scoreLeft;
			}
		}
		LK.showYouWin();
	} else if (scoreRight >= maxScore) {
		if (gameMode === "multi") {
			LK.showYouWin(); // In multiplayer, right player winning is still a win
		} else {
			LK.showGameOver();
		}
	}
}
// Handle touch events
game.down = function (x, y, obj) {
	if (!gameStarted) {
		gameStarted = true;
		startText.visible = false;
		LK.playMusic('gameMusic');
		return;
	}
	// Check if game mode buttons were clicked
	if (!gameStarted && y < 300) {
		var centerX = 2048 / 2;
		if (x < centerX) {
			gameMode = "single";
			rightPaddle.isAI = true;
			singlePlayerButton.style.fill = "#ffffff";
			multiPlayerButton.style.fill = "#888888";
		} else {
			gameMode = "multi";
			rightPaddle.isAI = false;
			singlePlayerButton.style.fill = "#888888";
			multiPlayerButton.style.fill = "#ffffff";
		}
		return;
	}
	// Determine which paddle to control based on screen side
	if (gameMode === "multi") {
		if (x < 2048 / 2) {
			activePaddle = leftPaddle;
		} else {
			activePaddle = rightPaddle;
		}
	} else {
		// In single player, only control left paddle
		activePaddle = leftPaddle;
	}
	if (activePaddle) {
		activePaddle.target = y;
	}
};
game.move = function (x, y, obj) {
	if (activePaddle) {
		activePaddle.target = y;
	}
};
game.up = function (x, y, obj) {
	// Keep tracking the paddle's target position
	// This allows for smooth movement even after lifting finger
};
// Main game update loop
game.update = function () {
	// Calculate delta time for smoother animations
	var currentTime = Date.now();
	var dt = (currentTime - lastFrameTime) / 16.67; // Normalize to 60fps
	lastFrameTime = currentTime;
	// Don't update game logic if not started
	if (!gameStarted) {
		return;
	}
	// Update AI
	rightPaddle.updateAI(ball, dt);
	// Update paddles
	leftPaddle.update(dt);
	rightPaddle.update(dt);
	// Update ball
	ball.update();
	// Check for collisions with paddles
	if (ball.velocity.x < 0 && ball.x - ball.radius <= leftPaddle.x + leftPaddle.width / 2 && ball.x - ball.radius > leftPaddle.x - leftPaddle.width / 2 && ball.y >= leftPaddle.y - leftPaddle.height / 2 && ball.y <= leftPaddle.y + leftPaddle.height / 2) {
		// Position ball at paddle edge to prevent sticking
		ball.x = leftPaddle.x + leftPaddle.width / 2 + ball.radius;
		ball.hitPaddle(leftPaddle);
	} else if (ball.velocity.x > 0 && ball.x + ball.radius >= rightPaddle.x - rightPaddle.width / 2 && ball.x + ball.radius < rightPaddle.x + rightPaddle.width / 2 && ball.y >= rightPaddle.y - rightPaddle.height / 2 && ball.y <= rightPaddle.y + rightPaddle.height / 2) {
		// Position ball at paddle edge to prevent sticking
		ball.x = rightPaddle.x - rightPaddle.width / 2 - ball.radius;
		ball.hitPaddle(rightPaddle);
	}
	// Check for scoring
	if (ball.x < -ball.radius) {
		// Right scores
		scoreRight++;
		updateScore();
		LK.getSound('score').play();
		ball.reset();
		checkWinCondition();
	} else if (ball.x > 2048 + ball.radius) {
		// Left scores
		scoreLeft++;
		updateScore();
		LK.getSound('score').play();
		ball.reset();
		checkWinCondition();
	}
	// Flash effect for center line if ball crosses it
	if (ball.x < 1024 && ball.velocity.x > 0 && ball.x + ball.velocity.x >= 1024 || ball.x > 1024 && ball.velocity.x < 0 && ball.x + ball.velocity.x <= 1024) {
		tween(centerLineContainer, {
			alpha: 0.3
		}, {
			duration: 100,
			onFinish: function onFinish() {
				tween(centerLineContainer, {
					alpha: 1
				}, {
					duration: 100
				});
			}
		});
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,333 @@
-/****
+/**** 
+* Plugins
+****/ 
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+	highScore: 0,
+	aiDifficulty: 0.7
+});
+
+/**** 
+* Classes
+****/ 
+var Ball = Container.expand(function () {
+	var self = Container.call(this);
+	var ballGraphics = self.attachAsset('ball', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	self.radius = ballGraphics.width / 2;
+	self.velocity = {
+		x: 0,
+		y: 0
+	};
+	self.baseSpeed = 12;
+	self.speedMultiplier = 1.0;
+	self.maxSpeedMultiplier = 2.5;
+	self.reset = function () {
+		self.x = 2048 / 2;
+		self.y = 2732 / 2;
+		self.speedMultiplier = 1.0;
+		// Random initial direction
+		var angle = Math.random() * Math.PI / 2 - Math.PI / 4;
+		if (Math.random() < 0.5) {
+			angle += Math.PI;
+		}
+		self.velocity.x = Math.cos(angle) * self.baseSpeed;
+		self.velocity.y = Math.sin(angle) * self.baseSpeed;
+		// Make sure horizontal speed is significant
+		if (Math.abs(self.velocity.x) < self.baseSpeed * 0.6) {
+			self.velocity.x = (self.velocity.x > 0 ? 1 : -1) * self.baseSpeed * 0.6;
+		}
+	};
+	self.update = function () {
+		// Move ball based on velocity
+		self.x += self.velocity.x * self.speedMultiplier;
+		self.y += self.velocity.y * self.speedMultiplier;
+		// Collision with top and bottom walls
+		if (self.y < self.radius) {
+			self.y = self.radius;
+			self.velocity.y *= -1;
+			LK.getSound('hit').play();
+		} else if (self.y > 2732 - self.radius) {
+			self.y = 2732 - self.radius;
+			self.velocity.y *= -1;
+			LK.getSound('hit').play();
+		}
+	};
+	self.hitPaddle = function (paddle) {
+		// Normalize collision point (-1 to 1) from paddle center
+		var relativeY = (self.y - paddle.y) / (paddle.height / 2);
+		// Adjust angle based on where the ball hit the paddle
+		var angle = relativeY * Math.PI / 3; // max ±60 degrees
+		// Reverse x direction and apply new angle
+		self.velocity.x = -Math.sign(self.velocity.x) * Math.cos(angle) * self.baseSpeed;
+		self.velocity.y = Math.sin(angle) * self.baseSpeed;
+		// Increase speed with each hit, up to a maximum
+		self.speedMultiplier = Math.min(self.maxSpeedMultiplier, self.speedMultiplier + 0.05);
+		// Play hit sound
+		LK.getSound('hit').play();
+	};
+	return self;
+});
+var Paddle = Container.expand(function () {
+	var self = Container.call(this);
+	var paddleGraphics = self.attachAsset('paddle', {
+		anchorX: 0.5,
+		anchorY: 0.5
+	});
+	self.width = paddleGraphics.width;
+	self.height = paddleGraphics.height;
+	self.speed = 0;
+	self.target = 0;
+	self.isAI = false;
+	self.aiReactionSpeed = 0.7; // Default AI difficulty level (0.1-0.9)
+	// AI paddle movement logic
+	self.updateAI = function (ball, dt) {
+		if (!self.isAI) {
+			return;
+		}
+		// Only update target if ball is moving toward this paddle
+		if (self.x < 1024 && ball.velocity.x < 0 || self.x > 1024 && ball.velocity.x > 0) {
+			// Predict where the ball will be
+			var distanceX = Math.abs(self.x - ball.x);
+			var timeToReach = distanceX / Math.abs(ball.velocity.x);
+			var futureY = ball.y + ball.velocity.y * timeToReach;
+			// Keep the future position in bounds
+			futureY = Math.max(self.height / 2, Math.min(2732 - self.height / 2, futureY));
+			// Add some imperfection based on AI difficulty
+			var errorFactor = (1 - self.aiReactionSpeed) * 300;
+			futureY += Math.random() * errorFactor * 2 - errorFactor;
+			// Gradually move toward the predicted position
+			self.target = futureY;
+		}
+	};
+	self.update = function (dt) {
+		// Gradually move toward target position (whether controlled by player or AI)
+		if (self.target !== null) {
+			self.speed = (self.target - self.y) * 0.2;
+			// Cap movement speed
+			var maxSpeed = 40;
+			self.speed = Math.max(-maxSpeed, Math.min(maxSpeed, self.speed));
+			self.y += self.speed;
+			// Keep paddle in bounds
+			self.y = Math.max(self.height / 2, Math.min(2732 - self.height / 2, self.y));
+		}
+	};
+	return self;
+});
+
+/**** 
 * Initialize Game
-****/
+****/ 
 var game = new LK.Game({
 	backgroundColor: 0x000000
-});
\ No newline at end of file
+});
+
+/**** 
+* Game Code
+****/ 
+// Game state
+var gameStarted = false;
+var gameMode = "single"; // "single" or "multi"
+var scoreLeft = 0;
+var scoreRight = 0;
+var maxScore = 11;
+var lastFrameTime = Date.now();
+// Create paddles
+var leftPaddle = game.addChild(new Paddle());
+leftPaddle.x = 100;
+leftPaddle.y = 2732 / 2;
+var rightPaddle = game.addChild(new Paddle());
+rightPaddle.x = 2048 - 100;
+rightPaddle.y = 2732 / 2;
+rightPaddle.isAI = true;
+rightPaddle.aiReactionSpeed = storage.aiDifficulty;
+// Create ball
+var ball = game.addChild(new Ball());
+ball.reset();
+// Create center line
+var centerLineContainer = game.addChild(new Container());
+centerLineContainer.x = 2048 / 2;
+for (var y = 15; y < 2732; y += 60) {
+	var lineSegment = centerLineContainer.attachAsset('centerLine', {
+		anchorX: 0.5,
+		anchorY: 0.5,
+		y: y
+	});
+}
+// Score text
+var scoreLeftText = new Text2(scoreLeft.toString(), {
+	size: 150,
+	fill: 0xFFFFFF
+});
+scoreLeftText.anchor.set(1, 0);
+scoreLeftText.x = 2048 / 2 - 50;
+scoreLeftText.y = 50;
+LK.gui.addChild(scoreLeftText);
+var scoreRightText = new Text2(scoreRight.toString(), {
+	size: 150,
+	fill: 0xFFFFFF
+});
+scoreRightText.anchor.set(0, 0);
+scoreRightText.x = 2048 / 2 + 50;
+scoreRightText.y = 50;
+LK.gui.addChild(scoreRightText);
+// Game mode button
+var singlePlayerButton = new Text2("1P", {
+	size: 80,
+	fill: gameMode === "single" ? "#ffffff" : "#888888"
+});
+singlePlayerButton.anchor.set(1, 0);
+singlePlayerButton.x = 2048 / 2 - 20;
+singlePlayerButton.y = 220;
+LK.gui.addChild(singlePlayerButton);
+var multiPlayerButton = new Text2("2P", {
+	size: 80,
+	fill: gameMode === "multi" ? "#ffffff" : "#888888"
+});
+multiPlayerButton.anchor.set(0, 0);
+multiPlayerButton.x = 2048 / 2 + 20;
+multiPlayerButton.y = 220;
+LK.gui.addChild(multiPlayerButton);
+// Start text
+var startText = new Text2("TAP TO START", {
+	size: 100,
+	fill: 0xFFFFFF
+});
+startText.anchor.set(0.5, 0.5);
+startText.x = 2048 / 2;
+startText.y = 2732 / 2;
+LK.gui.addChild(startText);
+// Store which paddle the user is currently controlling
+var activePaddle = null;
+// Update scores
+function updateScore() {
+	scoreLeftText.setText(scoreLeft.toString());
+	scoreRightText.setText(scoreRight.toString());
+}
+// Check for win condition
+function checkWinCondition() {
+	if (scoreLeft >= maxScore) {
+		if (gameMode === "single") {
+			// Update high score if playing single player
+			if (scoreLeft > storage.highScore) {
+				storage.highScore = scoreLeft;
+			}
+		}
+		LK.showYouWin();
+	} else if (scoreRight >= maxScore) {
+		if (gameMode === "multi") {
+			LK.showYouWin(); // In multiplayer, right player winning is still a win
+		} else {
+			LK.showGameOver();
+		}
+	}
+}
+// Handle touch events
+game.down = function (x, y, obj) {
+	if (!gameStarted) {
+		gameStarted = true;
+		startText.visible = false;
+		LK.playMusic('gameMusic');
+		return;
+	}
+	// Check if game mode buttons were clicked
+	if (!gameStarted && y < 300) {
+		var centerX = 2048 / 2;
+		if (x < centerX) {
+			gameMode = "single";
+			rightPaddle.isAI = true;
+			singlePlayerButton.style.fill = "#ffffff";
+			multiPlayerButton.style.fill = "#888888";
+		} else {
+			gameMode = "multi";
+			rightPaddle.isAI = false;
+			singlePlayerButton.style.fill = "#888888";
+			multiPlayerButton.style.fill = "#ffffff";
+		}
+		return;
+	}
+	// Determine which paddle to control based on screen side
+	if (gameMode === "multi") {
+		if (x < 2048 / 2) {
+			activePaddle = leftPaddle;
+		} else {
+			activePaddle = rightPaddle;
+		}
+	} else {
+		// In single player, only control left paddle
+		activePaddle = leftPaddle;
+	}
+	if (activePaddle) {
+		activePaddle.target = y;
+	}
+};
+game.move = function (x, y, obj) {
+	if (activePaddle) {
+		activePaddle.target = y;
+	}
+};
+game.up = function (x, y, obj) {
+	// Keep tracking the paddle's target position
+	// This allows for smooth movement even after lifting finger
+};
+// Main game update loop
+game.update = function () {
+	// Calculate delta time for smoother animations
+	var currentTime = Date.now();
+	var dt = (currentTime - lastFrameTime) / 16.67; // Normalize to 60fps
+	lastFrameTime = currentTime;
+	// Don't update game logic if not started
+	if (!gameStarted) {
+		return;
+	}
+	// Update AI
+	rightPaddle.updateAI(ball, dt);
+	// Update paddles
+	leftPaddle.update(dt);
+	rightPaddle.update(dt);
+	// Update ball
+	ball.update();
+	// Check for collisions with paddles
+	if (ball.velocity.x < 0 && ball.x - ball.radius <= leftPaddle.x + leftPaddle.width / 2 && ball.x - ball.radius > leftPaddle.x - leftPaddle.width / 2 && ball.y >= leftPaddle.y - leftPaddle.height / 2 && ball.y <= leftPaddle.y + leftPaddle.height / 2) {
+		// Position ball at paddle edge to prevent sticking
+		ball.x = leftPaddle.x + leftPaddle.width / 2 + ball.radius;
+		ball.hitPaddle(leftPaddle);
+	} else if (ball.velocity.x > 0 && ball.x + ball.radius >= rightPaddle.x - rightPaddle.width / 2 && ball.x + ball.radius < rightPaddle.x + rightPaddle.width / 2 && ball.y >= rightPaddle.y - rightPaddle.height / 2 && ball.y <= rightPaddle.y + rightPaddle.height / 2) {
+		// Position ball at paddle edge to prevent sticking
+		ball.x = rightPaddle.x - rightPaddle.width / 2 - ball.radius;
+		ball.hitPaddle(rightPaddle);
+	}
+	// Check for scoring
+	if (ball.x < -ball.radius) {
+		// Right scores
+		scoreRight++;
+		updateScore();
+		LK.getSound('score').play();
+		ball.reset();
+		checkWinCondition();
+	} else if (ball.x > 2048 + ball.radius) {
+		// Left scores
+		scoreLeft++;
+		updateScore();
+		LK.getSound('score').play();
+		ball.reset();
+		checkWinCondition();
+	}
+	// Flash effect for center line if ball crosses it
+	if (ball.x < 1024 && ball.velocity.x > 0 && ball.x + ball.velocity.x >= 1024 || ball.x > 1024 && ball.velocity.x < 0 && ball.x + ball.velocity.x <= 1024) {
+		tween(centerLineContainer, {
+			alpha: 0.3
+		}, {
+			duration: 100,
+			onFinish: function onFinish() {
+				tween(centerLineContainer, {
+					alpha: 1
+				}, {
+					duration: 100
+				});
+			}
+		});
+	}
+};
\ No newline at end of file