/****
* 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 = 5;
self.speedY = -5;
self._move_migrated = function () {
self.x += self.speedX;
self.y += self.speedY;
// Optimize trail particle creation by spawning less frequently
// Increase the interval for trail particle creation to reduce frequency and improve performance
if (LK.ticks % 15 == 0) {
var trailParticle = game.addChild(new BallTrail());
trailParticle.x = self.x;
trailParticle.y = self.y;
}
};
});
// BallTrail class for creating a trail effect behind the ball
var BallTrail = Container.expand(function () {
var self = Container.call(this);
var trailGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0; // Trail particles do not move horizontally
self.speedY = 0; // Trail particles do not move vertically
self.alpha = 0.5; // Start semi-transparent
self.scaleX = 0.25; // Start smaller than the original particle size
self.scaleY = 0.25; // Start smaller than the original particle size
self.update = function () {
self.alpha -= 0.05; // Fade out quickly
if (self.alpha <= 0) {
self.destroy(); // Remove the trail particle once fully faded
}
};
});
// Brick class
var Brick = Container.expand(function () {
var self = Container.call(this);
var brickGraphics = self.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5
});
});
// Enemy class that can only be destroyed by the ball
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xff0000 // Use red color to differentiate enemies from bricks
});
});
// Paddle class
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize RGB values
var r = 255;
var g = 0;
var b = 0;
// Cycle through RGB colors
self.update = function () {
// Correct RGB cycling logic
if (r > 0 && b == 0) {
if (g < 255) {
g++;
} else {
r--;
}
} else if (g > 0 && r == 0) {
if (b < 255) {
b++;
} else {
g--;
}
} else if (b > 0 && g == 0) {
if (r < 255) {
r++;
} else {
b--;
}
}
// Update paddle color with corrected RGB values
paddleGraphics.color = (r << 16) + (g << 8) + b;
};
self._move_migrated = function (xPosition) {
self.x = xPosition;
};
});
// Particle class
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = Math.random() * 10 - 5; // Random horizontal speed
self.speedY = Math.random() * 10 - 5; // Random vertical speed
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
self.speedY += 0.1; // Gravity
self.alpha -= 0.01; // Fade out
if (self.alpha <= 0) {
self.destroy();
}
};
});
// PowerUp class
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedY = 2; // Set PowerUp falling speed
self.update = function () {
self.y += self.speedY; // Make PowerUp fall down
};
self.effect = function (ball) {
ball.scaleX *= 1.5; // Scale up the ball by 50%
ball.scaleY *= 1.5; // Scale up the ball by 50%
};
});
// RedCube class for explosive interaction
var RedCube = Container.expand(function () {
var self = Container.call(this);
var redCubeGraphics = self.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xff0000 // Red color to signify danger
});
self.explosionRadius = 300; // Radius within which the ball will be affected
self.update = function () {
// Check for collision with the ball
if (self.intersects(ball)) {
// Trigger explosion effect
explodeBall();
self.destroy(); // Remove the RedCube after explosion
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Init game with black background
});
/****
* Game Code
****/
// Initialize level name text display
// Initialize level variable before using it
var currentLevel = 1;
var levelNameTxt = new Text2("Level " + currentLevel.toString(), {
size: 100,
fill: "#ffffff"
});
// Position the level name text at the top center of the screen
levelNameTxt.anchor.set(0.5, 0); // Sets anchor to the center of the top edge of the text.
levelNameTxt.x = 1024; // Center horizontally
levelNameTxt.y = 50; // Position towards the top
LK.gui.top.addChild(levelNameTxt); // Add the level name text to the GUI overlay at the top
// Removed ad display logic due to 'Uncaught TypeError: LK.showAd is not a function'
// Initialize level variable
var currentLevel = 1;
var totalLevels = 5; // Define total number of levels
// Function to setup level
function setupLevel(level) {
bricks = []; // Clear existing bricks
var levelBrickRowCount = 3 + level; // Increase row count with level
var levelBrickColumnCount = 5 + Math.floor(level / 2); // Increase column count every two levels
for (var c = 0; c < levelBrickColumnCount; c++) {
for (var r = 0; r < levelBrickRowCount; r++) {
var brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
var brick = game.addChild(new Brick());
brick.x = brickX + brickWidth / 2;
brick.y = brickY + brickHeight / 2;
bricks.push(brick);
}
}
}
// Call setupLevel with current level at game start
setupLevel(currentLevel);
// Function to handle ball explosion logic
function explodeBall() {
// Create explosion particles
for (var i = 0; i < 20; i++) {
var particle = game.addChild(new Particle());
particle.x = ball.x;
particle.y = ball.y;
}
// Reset ball position to the center after explosion
ball.x = 1024;
ball.y = 1366;
ball.speedX = 0;
ball.speedY = -5;
}
// Extra Balls Spawn Logic
var extraBalls = []; // Initialize extra balls array
LK.on('tick', function () {
// Check combo meter and spawn extra balls at certain thresholds
if (comboMeter == 10 || comboMeter == 20 || comboMeter == 30) {
var extraBall = game.addChild(new Ball());
extraBall.x = 1024; // Center horizontally
extraBall.y = 1366; // Center vertically
extraBalls.push(extraBall);
}
// Update and move all extra balls
for (var i = 0; i < extraBalls.length; i++) {
extraBalls[i]._move_migrated();
// Check for collision with paddle for each extra ball
if (extraBalls[i].intersects(paddle)) {
var hitPos = (extraBalls[i].x - paddle.x) / paddle.width;
extraBalls[i].speedY = -Math.abs(extraBalls[i].speedY); // Ensure the ball always bounces up
extraBalls[i].speedX = (hitPos - 0.5) * 10; // Adjust speedX based on hit position
}
// Check for collision with bricks and enemies for each extra ball
for (var b = bricks.length - 1; b >= 0; b--) {
if (extraBalls[i].intersects(bricks[b])) {
extraBalls[i].speedY = -extraBalls[i].speedY * 1.05;
extraBalls[i].speedX *= 1.05;
if (bricks[b] instanceof Enemy) {
score += 20;
} else {
score += 10;
}
bricks[b].destroy();
bricks.splice(b, 1);
scoreTxt.setText(score.toString());
}
}
// Remove extra ball if it goes off screen
if (extraBalls[i].y >= 2732) {
extraBalls[i].destroy();
extraBalls.splice(i, 1);
i--; // Adjust loop index after removal
}
}
});
var comboMeter = 0; // Initialize combo meter variable
var comboTxt = new Text2(comboMeter.toString(), {
size: 100,
fill: "#ff0000"
});
LK.gui.topRight.addChild(comboTxt); // Add the combo meter text to the GUI overlay at the top right
var score = 0; // Initialize score variable
var scoreTxt = new Text2(score.toString(), {
size: 150,
fill: "#ffffff"
});
LK.gui.top.addChild(scoreTxt); // Add the score text to the GUI overlay at the top
var ball = game.addChild(new Ball());
ball.x = 1024; // Center horizontally
ball.y = 1366; // Center vertically
var paddle = game.addChild(new Paddle());
paddle.x = 1024; // Center horizontally
paddle.y = 2500; // Position towards the bottom
var bricks = [];
var brickRowCount = 5;
var brickColumnCount = 8;
var brickWidth = 200;
var brickHeight = 100;
var brickPadding = 20;
var brickOffsetTop = 200;
var brickOffsetLeft = 204;
// Create bricks
for (var c = 0; c < brickColumnCount; c++) {
for (var r = 0; r < brickRowCount; r++) {
var brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
var brick = game.addChild(new Brick());
brick.x = brickX + brickWidth / 2;
brick.y = brickY + brickHeight / 2;
bricks.push(brick);
}
}
// Handle touch move for paddle
game.on('move', function (x, y, obj) {
var pos = game.toLocal(obj.global);
paddle._move_migrated(pos.x);
});
// Game tick
var spawnTick = 0; // Initialize spawn tick counter
LK.on('tick', function () {
spawnTick++;
// Every 600 ticks (10 seconds), spawn a new row of enemies at the top
if (spawnTick % 600 == 0) {
for (var c = 0; c < brickColumnCount; c++) {
var enemyX = c * (brickWidth + brickPadding) + brickOffsetLeft;
var enemy = game.addChild(new Enemy());
enemy.x = enemyX + brickWidth / 2;
enemy.y = brickOffsetTop; // Spawn enemies at the top without moving existing bricks down
bricks.push(enemy); // Add enemy to the bricks array for collision detection
}
}
ball._move_migrated();
// Spawn PowerUp and RedCube at game start and then randomly every 3000 ticks
if (spawnTick == 0 || spawnTick % 3000 == 0) {
var powerUpX = 1024; // Center X position for PowerUp
var powerUp = game.addChild(new PowerUp());
powerUp.x = powerUpX;
powerUp.y = 100; // Start from top for PowerUp
var redCubeX = Math.random() * 2048; // Random X position for RedCube
var redCube = game.addChild(new RedCube());
redCube.x = redCubeX;
redCube.y = 100; // Start from top for RedCube
}
// Check for PowerUp collision with ball
for (var p = 0; p < game.children.length; p++) {
var child = game.children[p];
if (child instanceof PowerUp && ball.intersects(child)) {
child.effect(ball); // Apply PowerUp effect to the ball
child.destroy(); // Remove PowerUp after use
}
}
// Ball collision with walls
if (ball.x <= ball.width / 2 || ball.x >= 2048 - ball.width / 2) {
ball.speedX = -ball.speedX;
}
if (ball.y <= ball.height / 2) {
ball.speedY = -ball.speedY;
}
// Ball collision with paddle
if (ball.intersects(paddle)) {
// Calculate bounce angle based on where the ball hits the paddle
var hitPos = (ball.x - paddle.x) / paddle.width;
ball.speedY = -Math.abs(ball.speedY); // Ensure the ball always bounces up
comboMeter = 0; // Reset combo meter on ball collision with paddle
ball.speedX = (hitPos - 0.5) * 10; // Adjust speedX based on hit position
}
// Ball collision with bricks and enemies
for (var b = bricks.length - 1; b >= 0; b--) {
if (ball.intersects(bricks[b])) {
// Reverse ball direction and slightly increase speed for dynamic gameplay
ball.speedY = -ball.speedY * 1.05;
ball.speedX *= 1.05;
// Add impact shake effect
// Removed flash effect
if (bricks[b] instanceof Enemy) {
score += 20; // Increase score by 20 for each enemy hit
comboMeter++; // Increment combo meter on enemy hit
// Spawn particles on enemy destruction
for (var i = 0; i < 10; i++) {
// Spawn more particles for enemies
var particle = game.addChild(new Particle());
particle.x = bricks[b].x;
particle.y = bricks[b].y;
}
} else {
score += 10; // Increase score by 10 for each brick hit
comboMeter++; // Increment combo meter on brick hit
// Spawn particles on brick destruction
for (var i = 0; i < 5; i++) {
var particle = game.addChild(new Particle());
particle.x = bricks[b].x;
particle.y = bricks[b].y;
}
}
bricks[b].destroy();
bricks.splice(b, 1);
scoreTxt.setText(score.toString()); // Update score display
// Add enemy paddle to the game when player hits 100 points and ensure it's only added once
if (score >= 100 && !game.children.some(function (child) {
return child instanceof EnemyPaddle;
})) {
var enemyPaddle = game.addChild(new EnemyPaddle());
enemyPaddle.x = 1024; // Center horizontally
enemyPaddle.y = brickOffsetTop + brickRowCount * (brickHeight + brickPadding) + 100; // Position below the bricks
}
comboTxt.setText(comboMeter.toString()); // Update combo meter display
}
}
// Check if all bricks are destroyed to advance to the next level
if (bricks.length === 0) {
if (currentLevel < totalLevels) {
currentLevel++;
setupLevel(currentLevel); // Setup the next level
ball.x = 1024; // Reset ball position to center
ball.y = 1366;
ball.speedX = 0;
ball.speedY = -5;
} else {
LK.showGameOver(); // Show game over if all levels are completed
}
} else if (ball.y >= 2732) {
// Game over condition
LK.showGameOver();
}
});