/****
* 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
};