/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var AIPaddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('aiPaddle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.targetX = 0; self.update = function () { // AI follows the ball with some lag for realistic gameplay var diff = self.targetX - self.x; if (Math.abs(diff) > 2) { if (diff > 0) { self.x += Math.min(self.speed, diff); } else { self.x += Math.max(-self.speed, diff); } } // Keep AI paddle within bounds var halfWidth = 100; // Half of paddle width if (self.x - halfWidth < 0) { self.x = halfWidth; } if (self.x + halfWidth > 2048) { self.x = 2048 - halfWidth; } }; return self; }); var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 5; self.velocityY = 5; self.baseSpeed = 5; self.maxSpeed = 12; self.reset = function () { self.x = 1024; self.y = 1366; self.velocityX = (Math.random() > 0.5 ? 1 : -1) * self.baseSpeed; self.velocityY = (Math.random() > 0.5 ? 1 : -1) * self.baseSpeed; }; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Bounce off side walls if (self.x <= 15 || self.x >= 2033) { self.velocityX = -self.velocityX; LK.getSound('wallHit').play(); } // Check collision with player paddle if (self.intersects(playerPaddle) && self.velocityY > 0) { self.velocityY = -Math.abs(self.velocityY); // Add paddle influence on ball direction var paddleCenter = playerPaddle.x; var ballRelativeX = self.x - paddleCenter; self.velocityX += ballRelativeX * 0.1; // Increase speed slightly var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY); if (currentSpeed < self.maxSpeed) { var speedMultiplier = 1.05; self.velocityX *= speedMultiplier; self.velocityY *= speedMultiplier; } LK.getSound('paddleHit').play(); } // Check collision with AI paddle if (self.intersects(aiPaddle) && self.velocityY < 0) { self.velocityY = Math.abs(self.velocityY); // Add paddle influence on ball direction var paddleCenter = aiPaddle.x; var ballRelativeX = self.x - paddleCenter; self.velocityX += ballRelativeX * 0.1; // Increase speed slightly var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY); if (currentSpeed < self.maxSpeed) { var speedMultiplier = 1.05; self.velocityX *= speedMultiplier; self.velocityY *= speedMultiplier; } LK.getSound('paddleHit').play(); } // Check for scoring if (self.y < -15) { // Player scores playerScore++; LK.setScore(playerScore); playerScoreText.setText('Player: ' + playerScore); LK.getSound('score').play(); self.reset(); if (playerScore >= 10) { LK.showYouWin(); } } else if (self.y > 2747) { // AI scores aiScore++; aiScoreText.setText('AI: ' + aiScore); LK.getSound('score').play(); self.reset(); if (aiScore >= 10) { LK.showGameOver(); } } // Update AI target based on ball position if (self.velocityY < 0) { // Ball moving toward AI, predict position var timeToReach = Math.abs(self.y - aiPaddle.y) / Math.abs(self.velocityY); aiPaddle.targetX = self.x + self.velocityX * timeToReach; } }; return self; }); var Paddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('playerPaddle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x001122 }); /**** * Game Code ****/ var playerScore = 0; var aiScore = 0; var dragActive = false; // Create game objects var playerPaddle = game.addChild(new Paddle()); playerPaddle.x = 1024; playerPaddle.y = 2600; var aiPaddle = game.addChild(new AIPaddle()); aiPaddle.x = 1024; aiPaddle.y = 132; var ball = game.addChild(new Ball()); ball.reset(); // Create score display var playerScoreText = new Text2('Player: 0', { size: 60, fill: '#00ff00' }); playerScoreText.anchor.set(0.5, 0); LK.gui.bottom.addChild(playerScoreText); playerScoreText.y = -100; var aiScoreText = new Text2('AI: 0', { size: 60, fill: '#ff0000' }); aiScoreText.anchor.set(0.5, 0); LK.gui.top.addChild(aiScoreText); aiScoreText.y = 100; // Create center line for visual appeal var centerLine = LK.getAsset('playerPaddle', { anchorX: 0.5, anchorY: 0.5, scaleY: 0.1, scaleX: 10, alpha: 0.3 }); centerLine.x = 1024; centerLine.y = 1366; game.addChild(centerLine); // Touch controls game.down = function (x, y, obj) { dragActive = true; playerPaddle.x = x; }; game.move = function (x, y, obj) { if (dragActive) { playerPaddle.x = x; // Keep player paddle within bounds var halfWidth = 100; // Half of paddle width if (playerPaddle.x - halfWidth < 0) { playerPaddle.x = halfWidth; } if (playerPaddle.x + halfWidth > 2048) { playerPaddle.x = 2048 - halfWidth; } } }; game.up = function (x, y, obj) { dragActive = false; }; game.update = function () { // Game runs automatically through object updates };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AIPaddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('aiPaddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.targetX = 0;
self.update = function () {
// AI follows the ball with some lag for realistic gameplay
var diff = self.targetX - self.x;
if (Math.abs(diff) > 2) {
if (diff > 0) {
self.x += Math.min(self.speed, diff);
} else {
self.x += Math.max(-self.speed, diff);
}
}
// Keep AI paddle within bounds
var halfWidth = 100; // Half of paddle width
if (self.x - halfWidth < 0) {
self.x = halfWidth;
}
if (self.x + halfWidth > 2048) {
self.x = 2048 - halfWidth;
}
};
return self;
});
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 5;
self.velocityY = 5;
self.baseSpeed = 5;
self.maxSpeed = 12;
self.reset = function () {
self.x = 1024;
self.y = 1366;
self.velocityX = (Math.random() > 0.5 ? 1 : -1) * self.baseSpeed;
self.velocityY = (Math.random() > 0.5 ? 1 : -1) * self.baseSpeed;
};
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off side walls
if (self.x <= 15 || self.x >= 2033) {
self.velocityX = -self.velocityX;
LK.getSound('wallHit').play();
}
// Check collision with player paddle
if (self.intersects(playerPaddle) && self.velocityY > 0) {
self.velocityY = -Math.abs(self.velocityY);
// Add paddle influence on ball direction
var paddleCenter = playerPaddle.x;
var ballRelativeX = self.x - paddleCenter;
self.velocityX += ballRelativeX * 0.1;
// Increase speed slightly
var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (currentSpeed < self.maxSpeed) {
var speedMultiplier = 1.05;
self.velocityX *= speedMultiplier;
self.velocityY *= speedMultiplier;
}
LK.getSound('paddleHit').play();
}
// Check collision with AI paddle
if (self.intersects(aiPaddle) && self.velocityY < 0) {
self.velocityY = Math.abs(self.velocityY);
// Add paddle influence on ball direction
var paddleCenter = aiPaddle.x;
var ballRelativeX = self.x - paddleCenter;
self.velocityX += ballRelativeX * 0.1;
// Increase speed slightly
var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (currentSpeed < self.maxSpeed) {
var speedMultiplier = 1.05;
self.velocityX *= speedMultiplier;
self.velocityY *= speedMultiplier;
}
LK.getSound('paddleHit').play();
}
// Check for scoring
if (self.y < -15) {
// Player scores
playerScore++;
LK.setScore(playerScore);
playerScoreText.setText('Player: ' + playerScore);
LK.getSound('score').play();
self.reset();
if (playerScore >= 10) {
LK.showYouWin();
}
} else if (self.y > 2747) {
// AI scores
aiScore++;
aiScoreText.setText('AI: ' + aiScore);
LK.getSound('score').play();
self.reset();
if (aiScore >= 10) {
LK.showGameOver();
}
}
// Update AI target based on ball position
if (self.velocityY < 0) {
// Ball moving toward AI, predict position
var timeToReach = Math.abs(self.y - aiPaddle.y) / Math.abs(self.velocityY);
aiPaddle.targetX = self.x + self.velocityX * timeToReach;
}
};
return self;
});
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('playerPaddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001122
});
/****
* Game Code
****/
var playerScore = 0;
var aiScore = 0;
var dragActive = false;
// Create game objects
var playerPaddle = game.addChild(new Paddle());
playerPaddle.x = 1024;
playerPaddle.y = 2600;
var aiPaddle = game.addChild(new AIPaddle());
aiPaddle.x = 1024;
aiPaddle.y = 132;
var ball = game.addChild(new Ball());
ball.reset();
// Create score display
var playerScoreText = new Text2('Player: 0', {
size: 60,
fill: '#00ff00'
});
playerScoreText.anchor.set(0.5, 0);
LK.gui.bottom.addChild(playerScoreText);
playerScoreText.y = -100;
var aiScoreText = new Text2('AI: 0', {
size: 60,
fill: '#ff0000'
});
aiScoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(aiScoreText);
aiScoreText.y = 100;
// Create center line for visual appeal
var centerLine = LK.getAsset('playerPaddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleY: 0.1,
scaleX: 10,
alpha: 0.3
});
centerLine.x = 1024;
centerLine.y = 1366;
game.addChild(centerLine);
// Touch controls
game.down = function (x, y, obj) {
dragActive = true;
playerPaddle.x = x;
};
game.move = function (x, y, obj) {
if (dragActive) {
playerPaddle.x = x;
// Keep player paddle within bounds
var halfWidth = 100; // Half of paddle width
if (playerPaddle.x - halfWidth < 0) {
playerPaddle.x = halfWidth;
}
if (playerPaddle.x + halfWidth > 2048) {
playerPaddle.x = 2048 - halfWidth;
}
}
};
game.up = function (x, y, obj) {
dragActive = false;
};
game.update = function () {
// Game runs automatically through object updates
};