/**** * 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.reset = function () { self.x = 2048 / 2; self.y = 2732 / 2; // Random angle between -45 and 45 degrees (avoiding too horizontal angles) var angle = (Math.random() * 90 - 45) * Math.PI / 180; // Random direction (left or right) if (Math.random() < 0.5) { angle = Math.PI - angle; } // Adjust initial speed based on difficulty var initialSpeed = 10; // Default (medium) if (typeof difficultySelector !== 'undefined') { switch (difficultySelector.difficulty) { case "easy": initialSpeed = 8; break; case "medium": initialSpeed = 10; break; case "hard": initialSpeed = 12; break; } } self.velocityX = Math.cos(angle) * initialSpeed; self.velocityY = Math.sin(angle) * initialSpeed; self.baseSpeed = initialSpeed; self.speedMultiplier = 1.0; }; self.bounceFromPaddle = function (paddle, hitPosition) { // Calculate bounce angle based on where the ball hit the paddle // hitPosition is a normalized value from -1 (top) to 1 (bottom) var bounceAngle = hitPosition * (Math.PI / 4); // Max 45-degree angle // Determine direction based on which paddle was hit var direction = self.x < 2048 / 2 ? 1 : -1; // Get difficulty from selector and adjust speed increase var speedIncrease = 0.05; // Default (medium) if (difficultySelector) { switch (difficultySelector.difficulty) { case "easy": speedIncrease = 0.03; self.speedMultiplier = Math.min(self.speedMultiplier, 1.5); // Cap lower for easy break; case "medium": speedIncrease = 0.05; self.speedMultiplier = Math.min(self.speedMultiplier, 2.0); // Default cap break; case "hard": speedIncrease = 0.08; self.speedMultiplier = Math.min(self.speedMultiplier, 2.5); // Higher cap for hard break; } } // Increase speed based on difficulty self.speedMultiplier += speedIncrease; var speed = self.baseSpeed * self.speedMultiplier; // Set new velocity self.velocityX = direction * Math.cos(bounceAngle) * speed; self.velocityY = Math.sin(bounceAngle) * speed; // Play hit sound LK.getSound('hit').play(); }; self.update = function () { // Update position self.x += self.velocityX; self.y += self.velocityY; // Bounce off top and bottom walls if (self.y < self.height / 2 || self.y > 2732 - self.height / 2) { self.velocityY = -self.velocityY; // Keep ball in bounds self.y = Math.max(self.height / 2, Math.min(2732 - self.height / 2, self.y)); // Play hit sound LK.getSound('hit').play(); } }; return self; }); var DifficultySelector = Container.expand(function () { var self = Container.call(this); self.difficulty = "medium"; // Default difficulty // Create the container for the buttons var buttonsContainer = new Container(); self.addChild(buttonsContainer); // Create button texts var easyButton = new Text2('EASY', { size: 70, fill: 0xAAAAAA }); easyButton.anchor.set(0.5, 0.5); easyButton.x = -250; var mediumButton = new Text2('MEDIUM', { size: 70, fill: 0xFFFFFF }); mediumButton.anchor.set(0.5, 0.5); mediumButton.x = 0; var hardButton = new Text2('HARD', { size: 70, fill: 0xAAAAAA }); hardButton.anchor.set(0.5, 0.5); hardButton.x = 250; // Add buttons to container buttonsContainer.addChild(easyButton); buttonsContainer.addChild(mediumButton); buttonsContainer.addChild(hardButton); // Set interactivity easyButton.interactive = true; mediumButton.interactive = true; hardButton.interactive = true; // Event handlers easyButton.down = function () { self.setDifficulty("easy"); easyButton.tint = 0xFFFFFF; mediumButton.tint = 0xAAAAAA; hardButton.tint = 0xAAAAAA; }; mediumButton.down = function () { self.setDifficulty("medium"); easyButton.tint = 0xAAAAAA; mediumButton.tint = 0xFFFFFF; hardButton.tint = 0xAAAAAA; }; hardButton.down = function () { self.setDifficulty("hard"); easyButton.tint = 0xAAAAAA; mediumButton.tint = 0xAAAAAA; hardButton.tint = 0xFFFFFF; }; self.setDifficulty = function (level) { self.difficulty = level; // Apply difficulty settings to AI paddle if (aiPaddle) { switch (level) { case "easy": aiPaddle.difficulty = 0.4; aiPaddle.speed = 8; break; case "medium": aiPaddle.difficulty = 0.7; aiPaddle.speed = 12; break; case "hard": aiPaddle.difficulty = 0.9; aiPaddle.speed = 16; break; } } // Update winning score if (typeof updateWinningScore === 'function') { updateWinningScore(level); } // Reset the ball with new difficulty settings if game is in progress if (ball && gameActive) { ball.reset(); } // Update difficulty display in bottom left if it exists if (typeof difficultyValueText !== 'undefined') { difficultyValueText.setText(level.toUpperCase()); } }; return self; }); var GameStartScreen = Container.expand(function () { var self = Container.call(this); // Create a transparent overlay var overlay = new Container(); self.addChild(overlay); // Game title var titleText = new Text2('PONG', { size: 150, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.y = -250; overlay.addChild(titleText); // Instruction text var instructionText = new Text2('SELECT DIFFICULTY', { size: 70, fill: 0xFFFFFF }); instructionText.anchor.set(0.5, 0.5); instructionText.y = -100; overlay.addChild(instructionText); // Create difficulty selector for the start screen var startScreenSelector = null; self.init = function () { // Create difficulty selector startScreenSelector = new DifficultySelector(); startScreenSelector.y = 50; overlay.addChild(startScreenSelector); // Start button var startButton = new Text2('START GAME', { size: 80, fill: 0xFFFFFF }); startButton.anchor.set(0.5, 0.5); startButton.y = 200; startButton.interactive = true; startButton.down = function () { self.startGame(startScreenSelector.difficulty); }; overlay.addChild(startButton); }; self.startGame = function (difficulty) { // Remove start screen self.visible = false; // Start the actual game with selected difficulty startGame(difficulty); }; // Position the overlay in the center overlay.x = 2048 / 2; overlay.y = 2732 / 2; return self; }); var Paddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 12; self.targetY = null; self.isAI = false; self.difficulty = 0.7; // AI difficulty - higher is better self.moveTowards = function (targetY) { self.targetY = targetY; }; self.update = function () { if (self.targetY !== null) { // Move towards target position var distance = self.targetY - self.y; var moveSpeed = Math.min(Math.abs(distance), self.speed); if (Math.abs(distance) > 1) { self.y += distance > 0 ? moveSpeed : -moveSpeed; } // Constrain paddle to screen boundaries self.y = Math.max(self.height / 2, Math.min(2732 - self.height / 2, self.y)); } }; self.updateAI = function (ball) { if (!self.isAI || !ball) return; // AI prediction logic if (ball.velocityX > 0) { // Ball is moving toward AI // Predict where ball will be when it reaches AI's x position var timeToReach = (self.x - ball.x) / ball.velocityX; var predictedY = ball.y + ball.velocityY * timeToReach; // Add some randomness based on difficulty var errorAmount = (1 - self.difficulty) * 300; var randomError = Math.random() * errorAmount - errorAmount / 2; // Move towards predicted position with some error self.moveTowards(predictedY + randomError); } else { // When ball is moving away, move towards center with some randomness var centerY = 2732 / 2; var randomOffset = Math.random() * 100 - 50; self.moveTowards(centerY + randomOffset); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var WINNING_SCORE = 10; // Default for medium, will be adjusted by difficulty // Function to update winning score based on difficulty function updateWinningScore(difficulty) { switch (difficulty) { case "easy": WINNING_SCORE = 7; break; case "medium": WINNING_SCORE = 10; break; case "hard": WINNING_SCORE = 15; break; } } // Game state var playerScore = 0; var aiScore = 0; var lastScorer = null; var gameActive = false; var gameInitialized = false; var centerLineSegments = []; var playerPaddle, aiPaddle, ball, difficultySelector; var playerScoreText, aiScoreText; // Create start screen var startScreen = new GameStartScreen(); game.addChild(startScreen); startScreen.init(); // Initialize game elements function function startGame(difficulty) { gameInitialized = true; // Setup score display if not already created if (!playerScoreText) { playerScoreText = new Text2('0', { size: 120, fill: 0xFFFFFF }); playerScoreText.anchor.set(0.5, 0); playerScoreText.x = GAME_WIDTH / 4; playerScoreText.y = 50; LK.gui.addChild(playerScoreText); aiScoreText = new Text2('0', { size: 120, fill: 0xFFFFFF }); aiScoreText.anchor.set(1, 0); aiScoreText.x = GAME_WIDTH - 50; aiScoreText.y = 50; LK.gui.addChild(aiScoreText); } // Create center line if not already created if (centerLineSegments.length === 0) { var LINE_SEGMENTS = 20; var SEGMENT_HEIGHT = GAME_HEIGHT / (LINE_SEGMENTS * 2); for (var i = 0; i < LINE_SEGMENTS; i++) { var segment = LK.getAsset('centerLine', { anchorX: 0.5, anchorY: 0.5 }); segment.y = i * SEGMENT_HEIGHT * 2 + SEGMENT_HEIGHT; segment.x = GAME_WIDTH / 2; game.addChild(segment); centerLineSegments.push(segment); } } // Create difficulty selector if not already created if (!difficultySelector) { difficultySelector = new DifficultySelector(); difficultySelector.x = GAME_WIDTH / 2; difficultySelector.y = 150; difficultySelector.visible = false; // Hide during gameplay LK.gui.addChild(difficultySelector); } // Create paddles if not already created if (!playerPaddle) { playerPaddle = new Paddle(); playerPaddle.x = 80; playerPaddle.y = GAME_HEIGHT / 2; game.addChild(playerPaddle); aiPaddle = new Paddle(); aiPaddle.x = GAME_WIDTH - 80; aiPaddle.y = GAME_HEIGHT / 2; aiPaddle.isAI = true; game.addChild(aiPaddle); } // Apply selected difficulty difficultySelector.setDifficulty(difficulty); // Create ball if not already created if (!ball) { ball = new Ball(); game.addChild(ball); } // Reset scores at game start playerScore = 0; aiScore = 0; // Reset ball to start game ball.reset(); // Update score displays to make sure enemy score is shown updateScoreDisplays(); // Set game as active gameActive = true; } // Handle touch and mouse events var touchActive = false; game.down = function (x, y, obj) { if (gameInitialized) { touchActive = true; playerPaddle.moveTowards(y); } }; game.move = function (x, y, obj) { if (gameInitialized && touchActive) { playerPaddle.moveTowards(y); } }; game.up = function (x, y, obj) { touchActive = false; }; // Check for paddle-ball collision function checkPaddleCollision(paddle, ball) { if (ball.intersects(paddle)) { // Calculate hit position relative to paddle center (normalized from -1 to 1) var hitPosition = (ball.y - paddle.y) / (paddle.height / 2); hitPosition = Math.max(-1, Math.min(1, hitPosition)); // Clamp between -1 and 1 ball.bounceFromPaddle(paddle, hitPosition); } } // Reset game after scoring function resetAfterScore() { gameActive = true; // Reset ball with a short delay LK.setTimeout(function () { ball.reset(); // If AI was the last scorer, give the ball initial direction toward the player if (lastScorer === "ai" && ball.velocityX < 0) { ball.velocityX = -ball.velocityX; } // If player was the last scorer, give the ball initial direction toward the AI else if (lastScorer === "player" && ball.velocityX > 0) { ball.velocityX = -ball.velocityX; } }, 1000); } // Create a variable for difficulty value text that will be used by difficultySelector var difficultyValueText; // Update score displays function updateScoreDisplays() { playerScoreText.setText(playerScore.toString()); aiScoreText.setText("0"); } // Play background music LK.playMusic('gameBgm'); // Game update loop game.update = function () { if (!gameInitialized || !gameActive) return; // Update paddles playerPaddle.update(); aiPaddle.updateAI(ball); // Update ball ball.update(); // Check for paddle collisions checkPaddleCollision(playerPaddle, ball); checkPaddleCollision(aiPaddle, ball); // Check for scoring if (ball.x < 0) { // AI scores - player loses lastScorer = "ai"; gameActive = false; LK.getSound('score').play(); // Show game over when ball reaches player's side LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } else if (ball.x > GAME_WIDTH) { // Player scores playerScore++; updateScoreDisplays(); lastScorer = "player"; gameActive = false; LK.getSound('score').play(); // Check for win if (playerScore >= WINNING_SCORE) { LK.setScore(playerScore); // Set player's score LK.showYouWin(); } else { resetAfterScore(); } } // Update LK score (we'll use player's score) LK.setScore(playerScore); };
/****
* 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.reset = function () {
self.x = 2048 / 2;
self.y = 2732 / 2;
// Random angle between -45 and 45 degrees (avoiding too horizontal angles)
var angle = (Math.random() * 90 - 45) * Math.PI / 180;
// Random direction (left or right)
if (Math.random() < 0.5) {
angle = Math.PI - angle;
}
// Adjust initial speed based on difficulty
var initialSpeed = 10; // Default (medium)
if (typeof difficultySelector !== 'undefined') {
switch (difficultySelector.difficulty) {
case "easy":
initialSpeed = 8;
break;
case "medium":
initialSpeed = 10;
break;
case "hard":
initialSpeed = 12;
break;
}
}
self.velocityX = Math.cos(angle) * initialSpeed;
self.velocityY = Math.sin(angle) * initialSpeed;
self.baseSpeed = initialSpeed;
self.speedMultiplier = 1.0;
};
self.bounceFromPaddle = function (paddle, hitPosition) {
// Calculate bounce angle based on where the ball hit the paddle
// hitPosition is a normalized value from -1 (top) to 1 (bottom)
var bounceAngle = hitPosition * (Math.PI / 4); // Max 45-degree angle
// Determine direction based on which paddle was hit
var direction = self.x < 2048 / 2 ? 1 : -1;
// Get difficulty from selector and adjust speed increase
var speedIncrease = 0.05; // Default (medium)
if (difficultySelector) {
switch (difficultySelector.difficulty) {
case "easy":
speedIncrease = 0.03;
self.speedMultiplier = Math.min(self.speedMultiplier, 1.5); // Cap lower for easy
break;
case "medium":
speedIncrease = 0.05;
self.speedMultiplier = Math.min(self.speedMultiplier, 2.0); // Default cap
break;
case "hard":
speedIncrease = 0.08;
self.speedMultiplier = Math.min(self.speedMultiplier, 2.5); // Higher cap for hard
break;
}
}
// Increase speed based on difficulty
self.speedMultiplier += speedIncrease;
var speed = self.baseSpeed * self.speedMultiplier;
// Set new velocity
self.velocityX = direction * Math.cos(bounceAngle) * speed;
self.velocityY = Math.sin(bounceAngle) * speed;
// Play hit sound
LK.getSound('hit').play();
};
self.update = function () {
// Update position
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off top and bottom walls
if (self.y < self.height / 2 || self.y > 2732 - self.height / 2) {
self.velocityY = -self.velocityY;
// Keep ball in bounds
self.y = Math.max(self.height / 2, Math.min(2732 - self.height / 2, self.y));
// Play hit sound
LK.getSound('hit').play();
}
};
return self;
});
var DifficultySelector = Container.expand(function () {
var self = Container.call(this);
self.difficulty = "medium"; // Default difficulty
// Create the container for the buttons
var buttonsContainer = new Container();
self.addChild(buttonsContainer);
// Create button texts
var easyButton = new Text2('EASY', {
size: 70,
fill: 0xAAAAAA
});
easyButton.anchor.set(0.5, 0.5);
easyButton.x = -250;
var mediumButton = new Text2('MEDIUM', {
size: 70,
fill: 0xFFFFFF
});
mediumButton.anchor.set(0.5, 0.5);
mediumButton.x = 0;
var hardButton = new Text2('HARD', {
size: 70,
fill: 0xAAAAAA
});
hardButton.anchor.set(0.5, 0.5);
hardButton.x = 250;
// Add buttons to container
buttonsContainer.addChild(easyButton);
buttonsContainer.addChild(mediumButton);
buttonsContainer.addChild(hardButton);
// Set interactivity
easyButton.interactive = true;
mediumButton.interactive = true;
hardButton.interactive = true;
// Event handlers
easyButton.down = function () {
self.setDifficulty("easy");
easyButton.tint = 0xFFFFFF;
mediumButton.tint = 0xAAAAAA;
hardButton.tint = 0xAAAAAA;
};
mediumButton.down = function () {
self.setDifficulty("medium");
easyButton.tint = 0xAAAAAA;
mediumButton.tint = 0xFFFFFF;
hardButton.tint = 0xAAAAAA;
};
hardButton.down = function () {
self.setDifficulty("hard");
easyButton.tint = 0xAAAAAA;
mediumButton.tint = 0xAAAAAA;
hardButton.tint = 0xFFFFFF;
};
self.setDifficulty = function (level) {
self.difficulty = level;
// Apply difficulty settings to AI paddle
if (aiPaddle) {
switch (level) {
case "easy":
aiPaddle.difficulty = 0.4;
aiPaddle.speed = 8;
break;
case "medium":
aiPaddle.difficulty = 0.7;
aiPaddle.speed = 12;
break;
case "hard":
aiPaddle.difficulty = 0.9;
aiPaddle.speed = 16;
break;
}
}
// Update winning score
if (typeof updateWinningScore === 'function') {
updateWinningScore(level);
}
// Reset the ball with new difficulty settings if game is in progress
if (ball && gameActive) {
ball.reset();
}
// Update difficulty display in bottom left if it exists
if (typeof difficultyValueText !== 'undefined') {
difficultyValueText.setText(level.toUpperCase());
}
};
return self;
});
var GameStartScreen = Container.expand(function () {
var self = Container.call(this);
// Create a transparent overlay
var overlay = new Container();
self.addChild(overlay);
// Game title
var titleText = new Text2('PONG', {
size: 150,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -250;
overlay.addChild(titleText);
// Instruction text
var instructionText = new Text2('SELECT DIFFICULTY', {
size: 70,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0.5);
instructionText.y = -100;
overlay.addChild(instructionText);
// Create difficulty selector for the start screen
var startScreenSelector = null;
self.init = function () {
// Create difficulty selector
startScreenSelector = new DifficultySelector();
startScreenSelector.y = 50;
overlay.addChild(startScreenSelector);
// Start button
var startButton = new Text2('START GAME', {
size: 80,
fill: 0xFFFFFF
});
startButton.anchor.set(0.5, 0.5);
startButton.y = 200;
startButton.interactive = true;
startButton.down = function () {
self.startGame(startScreenSelector.difficulty);
};
overlay.addChild(startButton);
};
self.startGame = function (difficulty) {
// Remove start screen
self.visible = false;
// Start the actual game with selected difficulty
startGame(difficulty);
};
// Position the overlay in the center
overlay.x = 2048 / 2;
overlay.y = 2732 / 2;
return self;
});
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 12;
self.targetY = null;
self.isAI = false;
self.difficulty = 0.7; // AI difficulty - higher is better
self.moveTowards = function (targetY) {
self.targetY = targetY;
};
self.update = function () {
if (self.targetY !== null) {
// Move towards target position
var distance = self.targetY - self.y;
var moveSpeed = Math.min(Math.abs(distance), self.speed);
if (Math.abs(distance) > 1) {
self.y += distance > 0 ? moveSpeed : -moveSpeed;
}
// Constrain paddle to screen boundaries
self.y = Math.max(self.height / 2, Math.min(2732 - self.height / 2, self.y));
}
};
self.updateAI = function (ball) {
if (!self.isAI || !ball) return;
// AI prediction logic
if (ball.velocityX > 0) {
// Ball is moving toward AI
// Predict where ball will be when it reaches AI's x position
var timeToReach = (self.x - ball.x) / ball.velocityX;
var predictedY = ball.y + ball.velocityY * timeToReach;
// Add some randomness based on difficulty
var errorAmount = (1 - self.difficulty) * 300;
var randomError = Math.random() * errorAmount - errorAmount / 2;
// Move towards predicted position with some error
self.moveTowards(predictedY + randomError);
} else {
// When ball is moving away, move towards center with some randomness
var centerY = 2732 / 2;
var randomOffset = Math.random() * 100 - 50;
self.moveTowards(centerY + randomOffset);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var WINNING_SCORE = 10; // Default for medium, will be adjusted by difficulty
// Function to update winning score based on difficulty
function updateWinningScore(difficulty) {
switch (difficulty) {
case "easy":
WINNING_SCORE = 7;
break;
case "medium":
WINNING_SCORE = 10;
break;
case "hard":
WINNING_SCORE = 15;
break;
}
}
// Game state
var playerScore = 0;
var aiScore = 0;
var lastScorer = null;
var gameActive = false;
var gameInitialized = false;
var centerLineSegments = [];
var playerPaddle, aiPaddle, ball, difficultySelector;
var playerScoreText, aiScoreText;
// Create start screen
var startScreen = new GameStartScreen();
game.addChild(startScreen);
startScreen.init();
// Initialize game elements function
function startGame(difficulty) {
gameInitialized = true;
// Setup score display if not already created
if (!playerScoreText) {
playerScoreText = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
playerScoreText.anchor.set(0.5, 0);
playerScoreText.x = GAME_WIDTH / 4;
playerScoreText.y = 50;
LK.gui.addChild(playerScoreText);
aiScoreText = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
aiScoreText.anchor.set(1, 0);
aiScoreText.x = GAME_WIDTH - 50;
aiScoreText.y = 50;
LK.gui.addChild(aiScoreText);
}
// Create center line if not already created
if (centerLineSegments.length === 0) {
var LINE_SEGMENTS = 20;
var SEGMENT_HEIGHT = GAME_HEIGHT / (LINE_SEGMENTS * 2);
for (var i = 0; i < LINE_SEGMENTS; i++) {
var segment = LK.getAsset('centerLine', {
anchorX: 0.5,
anchorY: 0.5
});
segment.y = i * SEGMENT_HEIGHT * 2 + SEGMENT_HEIGHT;
segment.x = GAME_WIDTH / 2;
game.addChild(segment);
centerLineSegments.push(segment);
}
}
// Create difficulty selector if not already created
if (!difficultySelector) {
difficultySelector = new DifficultySelector();
difficultySelector.x = GAME_WIDTH / 2;
difficultySelector.y = 150;
difficultySelector.visible = false; // Hide during gameplay
LK.gui.addChild(difficultySelector);
}
// Create paddles if not already created
if (!playerPaddle) {
playerPaddle = new Paddle();
playerPaddle.x = 80;
playerPaddle.y = GAME_HEIGHT / 2;
game.addChild(playerPaddle);
aiPaddle = new Paddle();
aiPaddle.x = GAME_WIDTH - 80;
aiPaddle.y = GAME_HEIGHT / 2;
aiPaddle.isAI = true;
game.addChild(aiPaddle);
}
// Apply selected difficulty
difficultySelector.setDifficulty(difficulty);
// Create ball if not already created
if (!ball) {
ball = new Ball();
game.addChild(ball);
}
// Reset scores at game start
playerScore = 0;
aiScore = 0;
// Reset ball to start game
ball.reset();
// Update score displays to make sure enemy score is shown
updateScoreDisplays();
// Set game as active
gameActive = true;
}
// Handle touch and mouse events
var touchActive = false;
game.down = function (x, y, obj) {
if (gameInitialized) {
touchActive = true;
playerPaddle.moveTowards(y);
}
};
game.move = function (x, y, obj) {
if (gameInitialized && touchActive) {
playerPaddle.moveTowards(y);
}
};
game.up = function (x, y, obj) {
touchActive = false;
};
// Check for paddle-ball collision
function checkPaddleCollision(paddle, ball) {
if (ball.intersects(paddle)) {
// Calculate hit position relative to paddle center (normalized from -1 to 1)
var hitPosition = (ball.y - paddle.y) / (paddle.height / 2);
hitPosition = Math.max(-1, Math.min(1, hitPosition)); // Clamp between -1 and 1
ball.bounceFromPaddle(paddle, hitPosition);
}
}
// Reset game after scoring
function resetAfterScore() {
gameActive = true;
// Reset ball with a short delay
LK.setTimeout(function () {
ball.reset();
// If AI was the last scorer, give the ball initial direction toward the player
if (lastScorer === "ai" && ball.velocityX < 0) {
ball.velocityX = -ball.velocityX;
}
// If player was the last scorer, give the ball initial direction toward the AI
else if (lastScorer === "player" && ball.velocityX > 0) {
ball.velocityX = -ball.velocityX;
}
}, 1000);
}
// Create a variable for difficulty value text that will be used by difficultySelector
var difficultyValueText;
// Update score displays
function updateScoreDisplays() {
playerScoreText.setText(playerScore.toString());
aiScoreText.setText("0");
}
// Play background music
LK.playMusic('gameBgm');
// Game update loop
game.update = function () {
if (!gameInitialized || !gameActive) return;
// Update paddles
playerPaddle.update();
aiPaddle.updateAI(ball);
// Update ball
ball.update();
// Check for paddle collisions
checkPaddleCollision(playerPaddle, ball);
checkPaddleCollision(aiPaddle, ball);
// Check for scoring
if (ball.x < 0) {
// AI scores - player loses
lastScorer = "ai";
gameActive = false;
LK.getSound('score').play();
// Show game over when ball reaches player's side
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
} else if (ball.x > GAME_WIDTH) {
// Player scores
playerScore++;
updateScoreDisplays();
lastScorer = "player";
gameActive = false;
LK.getSound('score').play();
// Check for win
if (playerScore >= WINNING_SCORE) {
LK.setScore(playerScore); // Set player's score
LK.showYouWin();
} else {
resetAfterScore();
}
}
// Update LK score (we'll use player's score)
LK.setScore(playerScore);
};