/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// 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 = 5;
self.speedY = 5;
self.lastSpeedIncreaseTick = 0; // Track last tick when speed was increased
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Gradually increase ball speed over time
self.speedX = Math.min(self.speedX * 1.0005, 15); // Further reduce rate of speed increase
self.speedY = Math.min(self.speedY * 1.0005, 15); // Further reduce rate of speed increase
// Add glow effect to ball
ballGraphics.alpha = 0.8 + Math.sin(LK.ticks / 10) * 0.2;
// Add trail effect
var trail = LK.getAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
trail.x = self.x;
trail.y = self.y;
trail.alpha = 0.5;
game.addChild(trail);
tween(trail, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
trail.destroy();
}
});
};
});
//<Assets used in the game will automatically appear here>
//<Write imports for supported plugins here>
// Paddle class for player and AI paddles
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.height = 300; // Increase paddle height
self.width = 20;
self.speed = 10;
self.update = function () {
// Paddle update logic
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
// Removed custom TextStyle class definition
var GameManager = {
gameRunning: true,
playerScore: 0,
aiScore: 0,
powerUpActive: false,
powerUpDuration: 5000,
difficulty: DIFFICULTY_MEDIUM,
scoreToWin: 10,
roundsPlayed: 0,
maxRounds: 5,
resetGame: function resetGame() {
this.playerScore = 0;
this.aiScore = 0;
this.gameRunning = true;
resetBall();
setDifficulty(this.difficulty);
}
};
LK.playMusic('backgroundMusic', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 1000
} // Fade in music
});
// Create animated background
var background = new Container();
// Create a dashed line in the center of the game screen
//<Assets used in the game will automatically appear here>
var dashedLine = new Container();
var DASH_HEIGHT = 40;
var DASH_SPACING = 10;
var GAME_HEIGHT = 2732;
var GAME_WIDTH = 2048;
var CENTER_X = GAME_WIDTH / 2;
var CENTER_Y = GAME_HEIGHT / 2;
for (var i = 0; i < GAME_HEIGHT; i += DASH_HEIGHT + DASH_SPACING) {
var dash = LK.getAsset('dash', {
width: 10,
height: DASH_HEIGHT,
color: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0.5,
shape: 'ellipse'
});
dash.x = CENTER_X; // Centered horizontally
dash.y = i + DASH_HEIGHT / 2;
dashedLine.addChild(dash);
}
game.addChild(dashedLine);
// Initialize paddles and ball
var playerPaddle = game.addChild(new Paddle());
var aiPaddle = game.addChild(new Paddle());
var ball = game.addChild(new Ball());
// Set initial positions
playerPaddle.x = 50;
playerPaddle.y = 1366; // Centered vertically
aiPaddle.x = 1998;
aiPaddle.y = 1366; // Centered vertically
ball.x = 1024;
ball.y = 1366; // Centered
// Game state variables
var playerScore = 0;
var aiScore = 0;
var gameRunning = true;
var powerUps = [];
var powerUpActive = false;
var powerUpDuration = 5000; // 5 seconds
// Function to spawn power-ups
function spawnPowerUp() {
if (Math.random() < 0.005 && !powerUpActive) {
// Adjust spawn frequency
var powerUpTypes = ['paddleSizeIncrease', 'ballSpeedBoost', 'aiPaddleSlowdown', 'stickyPaddle', 'confusion', 'multiBall', 'slowMotion'];
powerUp.type = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
// 1% chance to spawn a power-up
var powerUp = LK.getAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
powerUp.x = Math.random() * 2048;
powerUp.y = Math.random() * 2732;
powerUp.type = ['paddleSizeIncrease', 'ballSpeedBoost', 'aiPaddleSlowdown'][Math.floor(Math.random() * 3)];
powerUp.lastY = powerUp.y; // Initialize lastY for tracking changes on Y
powerUps.push(powerUp);
game.addChild(powerUp);
}
}
// Function to activate power-up effects
function activatePowerUp(powerUp) {
powerUpActive = true;
switch (powerUp.type) {
case 'paddleSizeIncrease':
playerPaddle.height *= 1.5;
break;
case 'ballSpeedBoost':
ball.speedX *= 1.5;
ball.speedY *= 1.5;
break;
case 'aiPaddleSlowdown':
aiPaddle.speed *= 0.5;
break;
}
setTimeout(function () {
deactivatePowerUp(powerUp);
}, powerUpDuration);
}
// Function to deactivate power-up effects
function deactivatePowerUp(powerUp) {
powerUpActive = false;
switch (powerUp.type) {
case 'paddleSizeIncrease':
playerPaddle.height /= 1.5;
break;
case 'ballSpeedBoost':
ball.speedX /= 1.5;
ball.speedY /= 1.5;
break;
case 'aiPaddleSlowdown':
aiPaddle.speed /= 0.5;
break;
}
}
// Difficulty settings
var DIFFICULTY_EASY = 'Easy';
var DIFFICULTY_MEDIUM = 'Medium';
var DIFFICULTY_HARD = 'Hard';
var difficulty = DIFFICULTY_MEDIUM; // Default difficulty
var scoreToWin = 10; // Default score to win
var difficultySettings = {
Easy: {
aiSpeed: 5,
ballSpeed: 3
},
Medium: {
aiSpeed: 10,
ballSpeed: 5
},
Hard: {
aiSpeed: 15,
ballSpeed: 7
}
};
// Function to set difficulty
function setDifficulty(level) {
switch (level) {
case 'Easy':
aiPaddle.speed = 5;
ball.speedX = 3;
ball.speedY = 3;
break;
case 'Medium':
aiPaddle.speed = 20; // Significantly increase AI paddle speed
ball.speedX = 5;
ball.speedY = 5;
break;
case 'Hard':
aiPaddle.speed = 30; // Significantly increase AI paddle speed
ball.speedX = 7;
ball.speedY = 7;
break;
}
}
// Function to reset ball position
function resetBall() {
ball.x = 1024;
ball.y = 1366;
var ballSpeed = difficultySettings[difficulty].ballSpeed;
ball.speedX = Math.random() > 0.5 ? ballSpeed : -ballSpeed;
ball.speedY = Math.random() > 0.5 ? ballSpeed : -ballSpeed;
}
// Function to update AI paddle position
function updateAIPaddle() {
// Check if the ball is moving towards the AI paddle
if (ball.speedX > 0) {
// Add randomness to AI movement
var randomOffset = (Math.random() - 0.5) * 10; // Random offset between -5 and 5
var targetY = ball.y + randomOffset;
// Anticipate ball position
var anticipationFactor = 0.1; // Adjust anticipation level
targetY += ball.speedY * anticipationFactor;
if (targetY < aiPaddle.y) {
aiPaddle.y -= aiPaddle.speed;
} else if (targetY > aiPaddle.y) {
aiPaddle.y += aiPaddle.speed;
}
}
}
// Function to check for collisions
function checkCollisions() {
// Ball collision with top and bottom
if (ball.y <= 0 || ball.y >= 2732) {
ball.speedY *= -1;
// Play wall bounce sound
LK.getSound('wallBounce').play();
}
// Ball collision with paddles
if (ball.x <= playerPaddle.x + playerPaddle.width && ball.y >= playerPaddle.y - playerPaddle.height / 2 && ball.y <= playerPaddle.y + playerPaddle.height / 2) {
ball.speedX *= -1;
// Change ball angle based on where it hits the paddle
var hitPosition = (ball.y - playerPaddle.y) / playerPaddle.height;
ball.speedY += hitPosition * 5; // Adjust angle based on hit position
ball.speedX *= 1 + Math.abs(hitPosition) * 0.1; // Add spin effect based on hit position
ball.speedX *= 1.1; // Increase speed on paddle hit
ball.speedX = Math.min(ball.speedX, difficultySettings[difficulty].ballSpeed * 2); // Cap speed per difficulty
// Play paddle hit sound
LK.getSound('paddleHit').play();
}
if (ball.x >= aiPaddle.x - aiPaddle.width && ball.y >= aiPaddle.y - aiPaddle.height / 2 && ball.y <= aiPaddle.y + aiPaddle.height / 2) {
ball.speedX *= -1;
// Change ball angle based on where it hits the paddle
var hitPosition = (ball.y - aiPaddle.y) / aiPaddle.height;
ball.speedY += hitPosition * 2;
}
// Ball out of bounds
if (ball.x <= 0) {
aiScore++;
resetBall();
// Play score sound
// Play score sound
LK.getSound('score').play();
if (aiScore >= scoreToWin) {
gameRunning = false;
showGameOverScreen();
}
}
if (ball.x >= 2048) {
playerScore++;
resetBall();
// Play score sound
LK.getSound('score').play();
if (playerScore >= scoreToWin) {
gameRunning = false;
showGameOverScreen();
}
}
// Game over screen
function showGameOverScreen() {
var gameOverScreen = new Container();
var gameOverText = new Text2('Game Over', {
size: 150,
fill: 0xFFFFFF
});
gameOverText.x = CENTER_X;
gameOverText.y = CENTER_Y;
gameOverScreen.addChild(gameOverText);
game.addChild(gameOverScreen);
// Stop music on game over
LK.stopMusic();
var playAgainButton = new Text2('Play Again', {
size: 100,
fill: 0xFFFFFF
});
playAgainButton.x = CENTER_X;
playAgainButton.y = CENTER_Y + 200;
gameOverScreen.addChild(playAgainButton);
playAgainButton.on('down', function () {
gameRunning = true;
playerScore = 0;
aiScore = 0;
updateScores();
gameOverScreen.visible = false;
resetBall();
setDifficulty(difficulty); // Reset difficulty settings
roundsPlayed++;
if (roundsPlayed >= maxRounds) {
// End match logic
roundsPlayed = 0;
// Show match over screen or reset match
}
});
}
// Check for power-up collisions
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (!powerUp.lastWasIntersecting && ball.intersects(powerUp)) {
activatePowerUp(powerUp);
powerUp.lastWasIntersecting = true; // Ensure single activation
powerUp.destroy();
powerUps.splice(i, 1);
} else if (powerUp.lastWasIntersecting && !ball.intersects(powerUp)) {
powerUp.lastWasIntersecting = false; // Reset for future collisions
}
}
}
// Difficulty selection screen
var difficultyMenu = new Container();
var easyButton = new Text2('', {
size: 100,
fill: 0xFFFFFF
});
var mediumButton = new Text2('', {
size: 100,
fill: 0xFFFFFF
});
var hardButton = new Text2('', {
size: 100,
fill: 0xFFFFFF
});
easyButton.x = 1024;
easyButton.y = 1200;
mediumButton.x = 1024;
mediumButton.y = 1366;
hardButton.x = 1024;
hardButton.y = 1532;
difficultyMenu.addChild(easyButton);
difficultyMenu.addChild(mediumButton);
difficultyMenu.addChild(hardButton);
game.addChild(difficultyMenu);
easyButton.on('down', function () {
setDifficulty('Easy');
difficultyMenu.visible = true;
menu.visible = true;
});
mediumButton.on('down', function () {
setDifficulty('Medium');
difficultyMenu.visible = true;
menu.visible = true;
});
hardButton.on('down', function () {
setDifficulty('Hard');
difficultyMenu.visible = true;
menu.visible = true;
});
// Start/Pause menu
var menu = new Container();
var startButton = new Text2('Start', {
size: 100,
fill: 0xFFFFFF,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
dropShadow: true,
dropShadowColor: '#000000'
});
startButton.on('hover', function () {
tween(startButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200
});
});
startButton.on('out', function () {
tween(startButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
});
startButton.x = 1024;
startButton.y = 1366;
menu.addChild(startButton);
menu.visible = !gameRunning; // Set initial visibility based on gameRunning state
game.addChild(menu);
startButton.on('down', function () {
gameRunning = true;
menu.visible = false;
// Pause music when game is paused
if (!gameRunning) {
LK.stopMusic();
} else {
LK.playMusic('backgroundMusic', {
loop: true
});
}
});
// Game update loop
game.update = function () {
if (gameRunning) {
ball.update();
updateAIPaddle();
checkCollisions();
updateScores();
} else {
menu.visible = true; // Set menu visible when game is not running
}
};
game.down = function (x, y, obj) {
playerPaddle.y = y;
};
// Display scores
var playerScoreDisplay = new Text2('Human: 0', {
size: 120,
fill: 0xFFD700,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
// Bold font for emphasis
dropShadow: true,
dropShadowColor: '#000000'
});
var aiScoreText = new Text2('Bot: 0', {
size: 120,
fill: 0xFFD700,
// Gold color for visual emphasis
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
// Bold font for emphasis
dropShadow: true,
dropShadowColor: '#000000'
});
playerScoreDisplay.x = 1024 - 500; // Move even further to the left
playerScoreDisplay.y = 50;
aiScoreText.x = 1024 + 150; // Position to the right of the dashed line
aiScoreText.y = 50;
// Add shadow effect to score text
// Initialize playerScoreText with a style object to fix undefined error
playerScoreDisplay.style = {
dropShadow: true,
dropShadowColor: '#000000'
};
aiScoreText.style = {
dropShadow: true,
dropShadowColor: '#000000'
};
game.addChild(playerScoreDisplay);
tween(playerScoreDisplay, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.elasticOut
});
game.addChild(aiScoreText);
tween(aiScoreText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.elasticOut
});
// Add "Glaud" text to top right corner
var glaudText = new Text2('Glaud', {
size: 60,
fill: 0xFF8C00,
// Orange color
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
dropShadow: true,
dropShadowColor: '#000000'
});
glaudText.x = GAME_WIDTH - 150; // Position in top right corner
glaudText.y = 50; // Small margin from the top
game.addChild(glaudText);
// Update score display
function updateScores() {
if (playerScoreDisplay.text !== 'Human: ' + playerScore) {
playerScoreDisplay.setText('Human: ' + playerScore);
// Add animation to score text
tween(playerScoreDisplay, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playerScoreDisplay, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
// Add color change animation
tween(playerScoreDisplay, {
fill: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(playerScoreDisplay, {
fill: 0xFFD700
}, {
duration: 100
});
}
});
}
if (aiScoreText.text !== 'Bot: ' + aiScore) {
aiScoreText.setText('Bot: ' + aiScore);
tween(aiScoreText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(aiScoreText, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
}
// Main game loop /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// 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 = 5;
self.speedY = 5;
self.lastSpeedIncreaseTick = 0; // Track last tick when speed was increased
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Gradually increase ball speed over time
self.speedX = Math.min(self.speedX * 1.0005, 15); // Further reduce rate of speed increase
self.speedY = Math.min(self.speedY * 1.0005, 15); // Further reduce rate of speed increase
// Add glow effect to ball
ballGraphics.alpha = 0.8 + Math.sin(LK.ticks / 10) * 0.2;
// Add trail effect
var trail = LK.getAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
trail.x = self.x;
trail.y = self.y;
trail.alpha = 0.5;
game.addChild(trail);
tween(trail, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
trail.destroy();
}
});
};
});
//<Assets used in the game will automatically appear here>
//<Write imports for supported plugins here>
// Paddle class for player and AI paddles
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.height = 300; // Increase paddle height
self.width = 20;
self.speed = 10;
self.update = function () {
// Paddle update logic
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
// Removed custom TextStyle class definition
var GameManager = {
gameRunning: true,
playerScore: 0,
aiScore: 0,
powerUpActive: false,
powerUpDuration: 5000,
difficulty: DIFFICULTY_MEDIUM,
scoreToWin: 10,
roundsPlayed: 0,
maxRounds: 5,
resetGame: function resetGame() {
this.playerScore = 0;
this.aiScore = 0;
this.gameRunning = true;
resetBall();
setDifficulty(this.difficulty);
}
};
LK.playMusic('backgroundMusic', {
loop: true,
fade: {
start: 0,
end: 1,
duration: 1000
} // Fade in music
});
// Create animated background
var background = new Container();
// Create a dashed line in the center of the game screen
//<Assets used in the game will automatically appear here>
var dashedLine = new Container();
var DASH_HEIGHT = 40;
var DASH_SPACING = 10;
var GAME_HEIGHT = 2732;
var GAME_WIDTH = 2048;
var CENTER_X = GAME_WIDTH / 2;
var CENTER_Y = GAME_HEIGHT / 2;
for (var i = 0; i < GAME_HEIGHT; i += DASH_HEIGHT + DASH_SPACING) {
var dash = LK.getAsset('dash', {
width: 10,
height: DASH_HEIGHT,
color: 0xFFFFFF,
anchorX: 0.5,
anchorY: 0.5,
shape: 'ellipse'
});
dash.x = CENTER_X; // Centered horizontally
dash.y = i + DASH_HEIGHT / 2;
dashedLine.addChild(dash);
}
game.addChild(dashedLine);
// Initialize paddles and ball
var playerPaddle = game.addChild(new Paddle());
var aiPaddle = game.addChild(new Paddle());
var ball = game.addChild(new Ball());
// Set initial positions
playerPaddle.x = 50;
playerPaddle.y = 1366; // Centered vertically
aiPaddle.x = 1998;
aiPaddle.y = 1366; // Centered vertically
ball.x = 1024;
ball.y = 1366; // Centered
// Game state variables
var playerScore = 0;
var aiScore = 0;
var gameRunning = true;
var powerUps = [];
var powerUpActive = false;
var powerUpDuration = 5000; // 5 seconds
// Function to spawn power-ups
function spawnPowerUp() {
if (Math.random() < 0.005 && !powerUpActive) {
// Adjust spawn frequency
var powerUpTypes = ['paddleSizeIncrease', 'ballSpeedBoost', 'aiPaddleSlowdown', 'stickyPaddle', 'confusion', 'multiBall', 'slowMotion'];
powerUp.type = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
// 1% chance to spawn a power-up
var powerUp = LK.getAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
powerUp.x = Math.random() * 2048;
powerUp.y = Math.random() * 2732;
powerUp.type = ['paddleSizeIncrease', 'ballSpeedBoost', 'aiPaddleSlowdown'][Math.floor(Math.random() * 3)];
powerUp.lastY = powerUp.y; // Initialize lastY for tracking changes on Y
powerUps.push(powerUp);
game.addChild(powerUp);
}
}
// Function to activate power-up effects
function activatePowerUp(powerUp) {
powerUpActive = true;
switch (powerUp.type) {
case 'paddleSizeIncrease':
playerPaddle.height *= 1.5;
break;
case 'ballSpeedBoost':
ball.speedX *= 1.5;
ball.speedY *= 1.5;
break;
case 'aiPaddleSlowdown':
aiPaddle.speed *= 0.5;
break;
}
setTimeout(function () {
deactivatePowerUp(powerUp);
}, powerUpDuration);
}
// Function to deactivate power-up effects
function deactivatePowerUp(powerUp) {
powerUpActive = false;
switch (powerUp.type) {
case 'paddleSizeIncrease':
playerPaddle.height /= 1.5;
break;
case 'ballSpeedBoost':
ball.speedX /= 1.5;
ball.speedY /= 1.5;
break;
case 'aiPaddleSlowdown':
aiPaddle.speed /= 0.5;
break;
}
}
// Difficulty settings
var DIFFICULTY_EASY = 'Easy';
var DIFFICULTY_MEDIUM = 'Medium';
var DIFFICULTY_HARD = 'Hard';
var difficulty = DIFFICULTY_MEDIUM; // Default difficulty
var scoreToWin = 10; // Default score to win
var difficultySettings = {
Easy: {
aiSpeed: 5,
ballSpeed: 3
},
Medium: {
aiSpeed: 10,
ballSpeed: 5
},
Hard: {
aiSpeed: 15,
ballSpeed: 7
}
};
// Function to set difficulty
function setDifficulty(level) {
switch (level) {
case 'Easy':
aiPaddle.speed = 5;
ball.speedX = 3;
ball.speedY = 3;
break;
case 'Medium':
aiPaddle.speed = 20; // Significantly increase AI paddle speed
ball.speedX = 5;
ball.speedY = 5;
break;
case 'Hard':
aiPaddle.speed = 30; // Significantly increase AI paddle speed
ball.speedX = 7;
ball.speedY = 7;
break;
}
}
// Function to reset ball position
function resetBall() {
ball.x = 1024;
ball.y = 1366;
var ballSpeed = difficultySettings[difficulty].ballSpeed;
ball.speedX = Math.random() > 0.5 ? ballSpeed : -ballSpeed;
ball.speedY = Math.random() > 0.5 ? ballSpeed : -ballSpeed;
}
// Function to update AI paddle position
function updateAIPaddle() {
// Check if the ball is moving towards the AI paddle
if (ball.speedX > 0) {
// Add randomness to AI movement
var randomOffset = (Math.random() - 0.5) * 10; // Random offset between -5 and 5
var targetY = ball.y + randomOffset;
// Anticipate ball position
var anticipationFactor = 0.1; // Adjust anticipation level
targetY += ball.speedY * anticipationFactor;
if (targetY < aiPaddle.y) {
aiPaddle.y -= aiPaddle.speed;
} else if (targetY > aiPaddle.y) {
aiPaddle.y += aiPaddle.speed;
}
}
}
// Function to check for collisions
function checkCollisions() {
// Ball collision with top and bottom
if (ball.y <= 0 || ball.y >= 2732) {
ball.speedY *= -1;
// Play wall bounce sound
LK.getSound('wallBounce').play();
}
// Ball collision with paddles
if (ball.x <= playerPaddle.x + playerPaddle.width && ball.y >= playerPaddle.y - playerPaddle.height / 2 && ball.y <= playerPaddle.y + playerPaddle.height / 2) {
ball.speedX *= -1;
// Change ball angle based on where it hits the paddle
var hitPosition = (ball.y - playerPaddle.y) / playerPaddle.height;
ball.speedY += hitPosition * 5; // Adjust angle based on hit position
ball.speedX *= 1 + Math.abs(hitPosition) * 0.1; // Add spin effect based on hit position
ball.speedX *= 1.1; // Increase speed on paddle hit
ball.speedX = Math.min(ball.speedX, difficultySettings[difficulty].ballSpeed * 2); // Cap speed per difficulty
// Play paddle hit sound
LK.getSound('paddleHit').play();
}
if (ball.x >= aiPaddle.x - aiPaddle.width && ball.y >= aiPaddle.y - aiPaddle.height / 2 && ball.y <= aiPaddle.y + aiPaddle.height / 2) {
ball.speedX *= -1;
// Change ball angle based on where it hits the paddle
var hitPosition = (ball.y - aiPaddle.y) / aiPaddle.height;
ball.speedY += hitPosition * 2;
}
// Ball out of bounds
if (ball.x <= 0) {
aiScore++;
resetBall();
// Play score sound
// Play score sound
LK.getSound('score').play();
if (aiScore >= scoreToWin) {
gameRunning = false;
showGameOverScreen();
}
}
if (ball.x >= 2048) {
playerScore++;
resetBall();
// Play score sound
LK.getSound('score').play();
if (playerScore >= scoreToWin) {
gameRunning = false;
showGameOverScreen();
}
}
// Game over screen
function showGameOverScreen() {
var gameOverScreen = new Container();
var gameOverText = new Text2('Game Over', {
size: 150,
fill: 0xFFFFFF
});
gameOverText.x = CENTER_X;
gameOverText.y = CENTER_Y;
gameOverScreen.addChild(gameOverText);
game.addChild(gameOverScreen);
// Stop music on game over
LK.stopMusic();
var playAgainButton = new Text2('Play Again', {
size: 100,
fill: 0xFFFFFF
});
playAgainButton.x = CENTER_X;
playAgainButton.y = CENTER_Y + 200;
gameOverScreen.addChild(playAgainButton);
playAgainButton.on('down', function () {
gameRunning = true;
playerScore = 0;
aiScore = 0;
updateScores();
gameOverScreen.visible = false;
resetBall();
setDifficulty(difficulty); // Reset difficulty settings
roundsPlayed++;
if (roundsPlayed >= maxRounds) {
// End match logic
roundsPlayed = 0;
// Show match over screen or reset match
}
});
}
// Check for power-up collisions
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (!powerUp.lastWasIntersecting && ball.intersects(powerUp)) {
activatePowerUp(powerUp);
powerUp.lastWasIntersecting = true; // Ensure single activation
powerUp.destroy();
powerUps.splice(i, 1);
} else if (powerUp.lastWasIntersecting && !ball.intersects(powerUp)) {
powerUp.lastWasIntersecting = false; // Reset for future collisions
}
}
}
// Difficulty selection screen
var difficultyMenu = new Container();
var easyButton = new Text2('', {
size: 100,
fill: 0xFFFFFF
});
var mediumButton = new Text2('', {
size: 100,
fill: 0xFFFFFF
});
var hardButton = new Text2('', {
size: 100,
fill: 0xFFFFFF
});
easyButton.x = 1024;
easyButton.y = 1200;
mediumButton.x = 1024;
mediumButton.y = 1366;
hardButton.x = 1024;
hardButton.y = 1532;
difficultyMenu.addChild(easyButton);
difficultyMenu.addChild(mediumButton);
difficultyMenu.addChild(hardButton);
game.addChild(difficultyMenu);
easyButton.on('down', function () {
setDifficulty('Easy');
difficultyMenu.visible = true;
menu.visible = true;
});
mediumButton.on('down', function () {
setDifficulty('Medium');
difficultyMenu.visible = true;
menu.visible = true;
});
hardButton.on('down', function () {
setDifficulty('Hard');
difficultyMenu.visible = true;
menu.visible = true;
});
// Start/Pause menu
var menu = new Container();
var startButton = new Text2('Start', {
size: 100,
fill: 0xFFFFFF,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
dropShadow: true,
dropShadowColor: '#000000'
});
startButton.on('hover', function () {
tween(startButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200
});
});
startButton.on('out', function () {
tween(startButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
});
startButton.x = 1024;
startButton.y = 1366;
menu.addChild(startButton);
menu.visible = !gameRunning; // Set initial visibility based on gameRunning state
game.addChild(menu);
startButton.on('down', function () {
gameRunning = true;
menu.visible = false;
// Pause music when game is paused
if (!gameRunning) {
LK.stopMusic();
} else {
LK.playMusic('backgroundMusic', {
loop: true
});
}
});
// Game update loop
game.update = function () {
if (gameRunning) {
ball.update();
updateAIPaddle();
checkCollisions();
updateScores();
} else {
menu.visible = true; // Set menu visible when game is not running
}
};
game.down = function (x, y, obj) {
playerPaddle.y = y;
};
// Display scores
var playerScoreDisplay = new Text2('Human: 0', {
size: 120,
fill: 0xFFD700,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
// Bold font for emphasis
dropShadow: true,
dropShadowColor: '#000000'
});
var aiScoreText = new Text2('Bot: 0', {
size: 120,
fill: 0xFFD700,
// Gold color for visual emphasis
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
// Bold font for emphasis
dropShadow: true,
dropShadowColor: '#000000'
});
playerScoreDisplay.x = 1024 - 500; // Move even further to the left
playerScoreDisplay.y = 50;
aiScoreText.x = 1024 + 150; // Position to the right of the dashed line
aiScoreText.y = 50;
// Add shadow effect to score text
// Initialize playerScoreText with a style object to fix undefined error
playerScoreDisplay.style = {
dropShadow: true,
dropShadowColor: '#000000'
};
aiScoreText.style = {
dropShadow: true,
dropShadowColor: '#000000'
};
game.addChild(playerScoreDisplay);
tween(playerScoreDisplay, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.elasticOut
});
game.addChild(aiScoreText);
tween(aiScoreText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.elasticOut
});
// Add "Glaud" text to top right corner
var glaudText = new Text2('Glaud', {
size: 60,
fill: 0xFF8C00,
// Orange color
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
dropShadow: true,
dropShadowColor: '#000000'
});
glaudText.x = GAME_WIDTH - 150; // Position in top right corner
glaudText.y = 50; // Small margin from the top
game.addChild(glaudText);
// Update score display
function updateScores() {
if (playerScoreDisplay.text !== 'Human: ' + playerScore) {
playerScoreDisplay.setText('Human: ' + playerScore);
// Add animation to score text
tween(playerScoreDisplay, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(playerScoreDisplay, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
// Add color change animation
tween(playerScoreDisplay, {
fill: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(playerScoreDisplay, {
fill: 0xFFD700
}, {
duration: 100
});
}
});
}
if (aiScoreText.text !== 'Bot: ' + aiScore) {
aiScoreText.setText('Bot: ' + aiScore);
tween(aiScoreText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(aiScoreText, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
}
}
// Main game loop