/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 5;
self.vy = -8;
self.baseSpeed = 8;
self.speedMultiplier = 1;
self.update = function () {
self.x += self.vx * self.speedMultiplier;
self.y += self.vy * self.speedMultiplier;
// Wall bouncing
if (self.x <= 15 || self.x >= 2048 - 15) {
self.vx = -self.vx;
self.x = Math.max(15, Math.min(2048 - 15, self.x));
}
if (self.y <= 15) {
self.vy = Math.abs(self.vy);
}
};
self.increaseSpeed = function () {
self.speedMultiplier = Math.min(self.speedMultiplier + 0.05, 3);
};
self.resetSpeed = function () {
self.speedMultiplier = 1;
};
return self;
});
var Block = Container.expand(function (hits, color, points) {
var self = Container.call(this);
self.hitsRequired = hits || 1;
self.hitsRemaining = self.hitsRequired;
self.points = points || 10;
var assetName = 'block';
if (color === 'green') assetName = 'block2';else if (color === 'yellow') assetName = 'block3';else if (color === 'gold') assetName = 'blockGold';
var blockGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.hit = function () {
self.hitsRemaining--;
if (self.hitsRemaining <= 0) {
return true; // Destroyed
}
// Flash effect
LK.effects.flashObject(self, 0xffffff, 200);
blockGraphics.alpha = 0.5 + self.hitsRemaining / self.hitsRequired * 0.5;
return false;
};
return self;
});
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.normalWidth = 300;
self.currentWidth = self.normalWidth;
self.setWidth = function (newWidth) {
self.currentWidth = newWidth;
paddleGraphics.scaleX = newWidth / self.normalWidth;
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.type = type; // 'multiball', 'slow', 'wide'
self.speed = 3;
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
// Tint based on type
if (type === 'multiball') powerupGraphics.tint = 0xff0000;else if (type === 'slow') powerupGraphics.tint = 0x00ff00;else if (type === 'wide') powerupGraphics.tint = 0x0000ff;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Game variables
var paddle;
var balls = [];
var blocks = [];
var powerups = [];
var lives = 3;
var level = 1;
var score = 0;
var combo = 0;
var isPowerActive = false;
var powerTimer = null;
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var livesTxt = new Text2('Lives: 3', {
size: 80,
fill: 0xFFFFFF
});
livesTxt.anchor.set(1, 0);
livesTxt.x = -50;
LK.gui.topRight.addChild(livesTxt);
var levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
levelTxt.x = 150;
LK.gui.topLeft.addChild(levelTxt);
// Initialize paddle
paddle = game.addChild(new Paddle());
paddle.x = 1024;
paddle.y = 2400;
// Create first ball
function createBall(x, y) {
var ball = new Ball();
ball.x = x || 1024;
ball.y = y || 2300;
balls.push(ball);
game.addChild(ball);
return ball;
}
// Create level
function createLevel(levelNum) {
blocks = [];
var rows = Math.min(5 + Math.floor(levelNum / 2), 10);
var cols = 10;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var blockType = 'red';
var hits = 1;
var points = 10;
// Vary block types by row
if (row < 2) {
blockType = 'yellow';
hits = 3;
points = 30;
} else if (row < 4) {
blockType = 'green';
hits = 2;
points = 20;
}
// Random gold blocks
if (Math.random() < 0.1) {
blockType = 'gold';
hits = 1;
points = 100;
}
var block = new Block(hits, blockType, points);
block.x = 200 + col * 165;
block.y = 300 + row * 80;
blocks.push(block);
game.addChild(block);
}
}
}
// Movement handling
var touchX = 1024;
game.down = function (x, y, obj) {
touchX = x;
};
game.move = function (x, y, obj) {
touchX = x;
};
// Power-up effects
function activatePowerUp(type) {
isPowerActive = true;
if (powerTimer) {
LK.clearTimeout(powerTimer);
}
if (type === 'multiball') {
var originalBall = balls[0];
if (originalBall) {
for (var i = 0; i < 2; i++) {
var newBall = createBall(originalBall.x, originalBall.y);
newBall.vx = (Math.random() - 0.5) * 10;
newBall.vy = -Math.abs(originalBall.vy);
}
}
} else if (type === 'slow') {
for (var i = 0; i < balls.length; i++) {
balls[i].speedMultiplier *= 0.5;
}
powerTimer = LK.setTimeout(function () {
for (var j = 0; j < balls.length; j++) {
if (balls[j]) balls[j].speedMultiplier *= 2;
}
isPowerActive = false;
}, 5000);
} else if (type === 'wide') {
paddle.setWidth(450);
powerTimer = LK.setTimeout(function () {
paddle.setWidth(300);
isPowerActive = false;
}, 8000);
}
}
// Reset ball
function resetBall() {
// Clear all balls
for (var i = balls.length - 1; i >= 0; i--) {
balls[i].destroy();
}
balls = [];
// Create new ball
createBall();
combo = 0;
}
// Game update
game.update = function () {
// Move paddle smoothly
var targetX = Math.max(150, Math.min(1898, touchX));
paddle.x += (targetX - paddle.x) * 0.3;
// Update balls
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
// Track last position
if (ball.lastY === undefined) ball.lastY = ball.y;
// Check paddle collision
if (ball.vy > 0 && ball.intersects(paddle)) {
ball.vy = -Math.abs(ball.vy);
// Angle based on hit position
var hitPos = (ball.x - paddle.x) / (paddle.currentWidth / 2);
ball.vx = hitPos * 8;
LK.getSound('hit').play();
combo++;
// Add some randomness to prevent infinite loops
ball.y = paddle.y - 40;
}
// Check block collisions
for (var j = blocks.length - 1; j >= 0; j--) {
var block = blocks[j];
if (ball.intersects(block)) {
ball.vy = -ball.vy;
ball.increaseSpeed();
if (block.hit()) {
// Block destroyed
score += block.points * Math.max(1, Math.floor(combo / 5));
scoreTxt.setText('Score: ' + score);
LK.getSound('break').play();
LK.effects.flashObject(block, 0xffffff, 300);
// Random power-up drop
if (Math.random() < 0.15) {
var types = ['multiball', 'slow', 'wide'];
var powerup = new PowerUp(types[Math.floor(Math.random() * types.length)]);
powerup.x = block.x;
powerup.y = block.y;
powerups.push(powerup);
game.addChild(powerup);
}
block.destroy();
blocks.splice(j, 1);
// Check level complete
if (blocks.length === 0) {
level++;
levelTxt.setText('Level: ' + level);
createLevel(level);
resetBall();
}
} else {
LK.getSound('hit').play();
}
break;
}
}
// Check if ball fell off screen
if (ball.lastY < 2732 && ball.y >= 2732) {
ball.destroy();
balls.splice(i, 1);
if (balls.length === 0) {
lives--;
livesTxt.setText('Lives: ' + lives);
if (lives <= 0) {
LK.setScore(score);
LK.showGameOver();
} else {
resetBall();
LK.effects.flashScreen(0xff0000, 500);
}
}
}
ball.lastY = ball.y;
}
// Update power-ups
for (var k = powerups.length - 1; k >= 0; k--) {
var powerup = powerups[k];
if (powerup.lastY === undefined) powerup.lastY = powerup.y;
// Check paddle collection
if (powerup.intersects(paddle)) {
activatePowerUp(powerup.type);
LK.getSound('powerup').play();
powerup.destroy();
powerups.splice(k, 1);
continue;
}
// Remove if off screen
if (powerup.lastY < 2732 && powerup.y >= 2732) {
powerup.destroy();
powerups.splice(k, 1);
}
powerup.lastY = powerup.y;
}
};
// Initialize game
createLevel(1);
createBall();
LK.playMusic('bgmusic'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 5;
self.vy = -8;
self.baseSpeed = 8;
self.speedMultiplier = 1;
self.update = function () {
self.x += self.vx * self.speedMultiplier;
self.y += self.vy * self.speedMultiplier;
// Wall bouncing
if (self.x <= 15 || self.x >= 2048 - 15) {
self.vx = -self.vx;
self.x = Math.max(15, Math.min(2048 - 15, self.x));
}
if (self.y <= 15) {
self.vy = Math.abs(self.vy);
}
};
self.increaseSpeed = function () {
self.speedMultiplier = Math.min(self.speedMultiplier + 0.05, 3);
};
self.resetSpeed = function () {
self.speedMultiplier = 1;
};
return self;
});
var Block = Container.expand(function (hits, color, points) {
var self = Container.call(this);
self.hitsRequired = hits || 1;
self.hitsRemaining = self.hitsRequired;
self.points = points || 10;
var assetName = 'block';
if (color === 'green') assetName = 'block2';else if (color === 'yellow') assetName = 'block3';else if (color === 'gold') assetName = 'blockGold';
var blockGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.hit = function () {
self.hitsRemaining--;
if (self.hitsRemaining <= 0) {
return true; // Destroyed
}
// Flash effect
LK.effects.flashObject(self, 0xffffff, 200);
blockGraphics.alpha = 0.5 + self.hitsRemaining / self.hitsRequired * 0.5;
return false;
};
return self;
});
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.normalWidth = 300;
self.currentWidth = self.normalWidth;
self.setWidth = function (newWidth) {
self.currentWidth = newWidth;
paddleGraphics.scaleX = newWidth / self.normalWidth;
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.type = type; // 'multiball', 'slow', 'wide'
self.speed = 3;
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
// Tint based on type
if (type === 'multiball') powerupGraphics.tint = 0xff0000;else if (type === 'slow') powerupGraphics.tint = 0x00ff00;else if (type === 'wide') powerupGraphics.tint = 0x0000ff;
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Game variables
var paddle;
var balls = [];
var blocks = [];
var powerups = [];
var lives = 3;
var level = 1;
var score = 0;
var combo = 0;
var isPowerActive = false;
var powerTimer = null;
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var livesTxt = new Text2('Lives: 3', {
size: 80,
fill: 0xFFFFFF
});
livesTxt.anchor.set(1, 0);
livesTxt.x = -50;
LK.gui.topRight.addChild(livesTxt);
var levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
levelTxt.x = 150;
LK.gui.topLeft.addChild(levelTxt);
// Initialize paddle
paddle = game.addChild(new Paddle());
paddle.x = 1024;
paddle.y = 2400;
// Create first ball
function createBall(x, y) {
var ball = new Ball();
ball.x = x || 1024;
ball.y = y || 2300;
balls.push(ball);
game.addChild(ball);
return ball;
}
// Create level
function createLevel(levelNum) {
blocks = [];
var rows = Math.min(5 + Math.floor(levelNum / 2), 10);
var cols = 10;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var blockType = 'red';
var hits = 1;
var points = 10;
// Vary block types by row
if (row < 2) {
blockType = 'yellow';
hits = 3;
points = 30;
} else if (row < 4) {
blockType = 'green';
hits = 2;
points = 20;
}
// Random gold blocks
if (Math.random() < 0.1) {
blockType = 'gold';
hits = 1;
points = 100;
}
var block = new Block(hits, blockType, points);
block.x = 200 + col * 165;
block.y = 300 + row * 80;
blocks.push(block);
game.addChild(block);
}
}
}
// Movement handling
var touchX = 1024;
game.down = function (x, y, obj) {
touchX = x;
};
game.move = function (x, y, obj) {
touchX = x;
};
// Power-up effects
function activatePowerUp(type) {
isPowerActive = true;
if (powerTimer) {
LK.clearTimeout(powerTimer);
}
if (type === 'multiball') {
var originalBall = balls[0];
if (originalBall) {
for (var i = 0; i < 2; i++) {
var newBall = createBall(originalBall.x, originalBall.y);
newBall.vx = (Math.random() - 0.5) * 10;
newBall.vy = -Math.abs(originalBall.vy);
}
}
} else if (type === 'slow') {
for (var i = 0; i < balls.length; i++) {
balls[i].speedMultiplier *= 0.5;
}
powerTimer = LK.setTimeout(function () {
for (var j = 0; j < balls.length; j++) {
if (balls[j]) balls[j].speedMultiplier *= 2;
}
isPowerActive = false;
}, 5000);
} else if (type === 'wide') {
paddle.setWidth(450);
powerTimer = LK.setTimeout(function () {
paddle.setWidth(300);
isPowerActive = false;
}, 8000);
}
}
// Reset ball
function resetBall() {
// Clear all balls
for (var i = balls.length - 1; i >= 0; i--) {
balls[i].destroy();
}
balls = [];
// Create new ball
createBall();
combo = 0;
}
// Game update
game.update = function () {
// Move paddle smoothly
var targetX = Math.max(150, Math.min(1898, touchX));
paddle.x += (targetX - paddle.x) * 0.3;
// Update balls
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
// Track last position
if (ball.lastY === undefined) ball.lastY = ball.y;
// Check paddle collision
if (ball.vy > 0 && ball.intersects(paddle)) {
ball.vy = -Math.abs(ball.vy);
// Angle based on hit position
var hitPos = (ball.x - paddle.x) / (paddle.currentWidth / 2);
ball.vx = hitPos * 8;
LK.getSound('hit').play();
combo++;
// Add some randomness to prevent infinite loops
ball.y = paddle.y - 40;
}
// Check block collisions
for (var j = blocks.length - 1; j >= 0; j--) {
var block = blocks[j];
if (ball.intersects(block)) {
ball.vy = -ball.vy;
ball.increaseSpeed();
if (block.hit()) {
// Block destroyed
score += block.points * Math.max(1, Math.floor(combo / 5));
scoreTxt.setText('Score: ' + score);
LK.getSound('break').play();
LK.effects.flashObject(block, 0xffffff, 300);
// Random power-up drop
if (Math.random() < 0.15) {
var types = ['multiball', 'slow', 'wide'];
var powerup = new PowerUp(types[Math.floor(Math.random() * types.length)]);
powerup.x = block.x;
powerup.y = block.y;
powerups.push(powerup);
game.addChild(powerup);
}
block.destroy();
blocks.splice(j, 1);
// Check level complete
if (blocks.length === 0) {
level++;
levelTxt.setText('Level: ' + level);
createLevel(level);
resetBall();
}
} else {
LK.getSound('hit').play();
}
break;
}
}
// Check if ball fell off screen
if (ball.lastY < 2732 && ball.y >= 2732) {
ball.destroy();
balls.splice(i, 1);
if (balls.length === 0) {
lives--;
livesTxt.setText('Lives: ' + lives);
if (lives <= 0) {
LK.setScore(score);
LK.showGameOver();
} else {
resetBall();
LK.effects.flashScreen(0xff0000, 500);
}
}
}
ball.lastY = ball.y;
}
// Update power-ups
for (var k = powerups.length - 1; k >= 0; k--) {
var powerup = powerups[k];
if (powerup.lastY === undefined) powerup.lastY = powerup.y;
// Check paddle collection
if (powerup.intersects(paddle)) {
activatePowerUp(powerup.type);
LK.getSound('powerup').play();
powerup.destroy();
powerups.splice(k, 1);
continue;
}
// Remove if off screen
if (powerup.lastY < 2732 && powerup.y >= 2732) {
powerup.destroy();
powerups.splice(k, 1);
}
powerup.lastY = powerup.y;
}
};
// Initialize game
createLevel(1);
createBall();
LK.playMusic('bgmusic');