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