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