/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'normal';
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
ballGraphics.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : type === 'smallScatter' ? 0xffff00 : 0xffffff;
if (type === 'smallScatter') {
ballGraphics.scaleX = 0.5;
ballGraphics.scaleY = 0.5;
}
self.type = type;
self.speed = type === 'splash' ? upgrades.splashSpeed : type === 'sniper' ? upgrades.sniperSpeed : type === 'scatter' ? upgrades.scatterSpeed : type === 'smallScatter' ? upgrades.scatterSpeed * 1.5 : upgrades.normalSpeed;
self.power = type === 'splash' ? upgrades.splashPower : type === 'sniper' ? upgrades.sniperPower : type === 'scatter' ? upgrades.scatterPower : type === 'smallScatter' ? Math.max(1, Math.floor(upgrades.scatterPower * 0.8)) : upgrades.normalPower;
self.velocity = {
x: 1,
y: -1
};
self.sniperCooldown = 0;
self.sniperCooldownMax = 60;
self.interactive = true;
self.down = function (x, y, obj) {
var angle = Math.random() * 2 * Math.PI;
self.velocity.x = Math.cos(angle);
self.velocity.y = Math.sin(angle);
var magnitude = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y);
self.velocity.x /= magnitude;
self.velocity.y /= magnitude;
};
self.update = function () {
var SHIELD_BUFFER = 5;
var MAX_STEP = BALL_RADIUS / 2;
var totalDistance = self.speed;
var steps = Math.ceil(totalDistance / MAX_STEP);
var stepDistance = totalDistance / steps;
var splashApplied = false;
if (self.type === 'sniper') {
self.sniperCooldown--;
if (self.sniperCooldown <= 0) {
var nearestBrick = findNearestBrick(self.x, self.y);
if (nearestBrick) {
var dx = nearestBrick.x - self.x;
var dy = nearestBrick.y - self.y;
var magnitude = Math.sqrt(dx * dx + dy * dy);
self.velocity.x = dx / magnitude;
self.velocity.y = dy / magnitude;
self.sniperCooldown = self.sniperCooldownMax;
}
}
}
for (var step = 0; step < steps; step++) {
var dx = self.velocity.x * stepDistance;
var dy = self.velocity.y * stepDistance;
var nextX = self.x + dx;
var nextY = self.y + dy;
if (nextX < BALL_RADIUS + SHIELD_BUFFER) {
nextX = BALL_RADIUS + SHIELD_BUFFER;
self.velocity.x = -self.velocity.x;
self.velocity.y += (Math.random() - 0.5) * 0.1;
LK.getSound('bounce').play();
} else if (nextX > GAME_WIDTH - BALL_RADIUS - SHIELD_BUFFER) {
nextX = GAME_WIDTH - BALL_RADIUS - SHIELD_BUFFER;
self.velocity.x = -self.velocity.x;
self.velocity.y += (Math.random() - 0.5) * 0.1;
LK.getSound('bounce').play();
}
if (nextY < BALL_RADIUS + SHIELD_BUFFER) {
nextY = BALL_RADIUS + SHIELD_BUFFER;
self.velocity.y = -self.velocity.y;
self.velocity.x += (Math.random() - 0.5) * 0.1;
LK.getSound('bounce').play();
} else if (nextY > GAME_HEIGHT - BALL_RADIUS - SHIELD_BUFFER) {
nextY = GAME_HEIGHT - BALL_RADIUS - SHIELD_BUFFER;
self.velocity.y = -self.velocity.y;
self.velocity.x += (Math.random() - 0.5) * 0.1;
LK.getSound('bounce').play();
}
var ballLeft = nextX - BALL_RADIUS - SHIELD_BUFFER;
var ballRight = nextX + BALL_RADIUS + SHIELD_BUFFER;
var ballTop = nextY - BALL_RADIUS - SHIELD_BUFFER;
var ballBottom = nextY + BALL_RADIUS + SHIELD_BUFFER;
var collided = false;
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (brick.health <= 0) {
continue;
}
var brickLeft = brick.x - BRICK_WIDTH / 2;
var brickRight = brick.x + BRICK_WIDTH / 2;
var brickTop = brick.y - BRICK_HEIGHT / 2;
var brickBottom = brick.y + BRICK_HEIGHT / 2;
if (ballLeft < brickRight && ballRight > brickLeft && ballTop < brickBottom && ballBottom > brickTop) {
var overlapLeft = ballRight - brickLeft;
var overlapRight = brickRight - ballLeft;
var overlapTop = ballBottom - brickTop;
var overlapBottom = brickBottom - ballTop;
var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);
if (minOverlap === overlapLeft) {
nextX = brickLeft - BALL_RADIUS - SHIELD_BUFFER;
self.velocity.x = -self.velocity.x;
} else if (minOverlap === overlapRight) {
nextX = brickRight + BALL_RADIUS + SHIELD_BUFFER;
self.velocity.x = -self.velocity.x;
} else if (minOverlap === overlapTop) {
nextY = brickTop - BALL_RADIUS - SHIELD_BUFFER;
self.velocity.y = -self.velocity.y;
} else {
nextY = brickBottom + BALL_RADIUS + SHIELD_BUFFER;
self.velocity.y = -self.velocity.y;
}
self.velocity.x += (Math.random() - 0.5) * 0.2;
self.velocity.y += (Math.random() - 0.5) * 0.2;
LK.getSound('bounce').play();
brick.hit(self.power);
ballDamage[self.type] = (ballDamage[self.type] || 0) + self.power;
if (self.type === 'splash' && !splashApplied) {
applySplashDamage(brick);
splashApplied = true;
} else if (self.type === 'scatter') {
scatterOnImpact(self);
self.destroy();
balls.splice(balls.indexOf(self), 1);
return;
}
collided = true;
break;
}
}
self.x = nextX;
self.y = nextY;
if (collided) {
break;
}
}
var magnitude = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y);
if (magnitude > 0) {
self.velocity.x /= magnitude;
self.velocity.y /= magnitude;
}
};
});
var Brick = Container.expand(function () {
var self = Container.call(this);
var brickGraphics = self.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.maxHealth = 1;
self.healthText = new Text2(self.health.toString(), {
size: 50,
fill: 0x000000,
fontWeight: 'bold'
});
self.healthText.anchor.set(0.5, 0.5);
self.addChild(self.healthText);
self.updateTint = function () {
var baseColors = LEVEL_COLORS;
var colorCount = baseColors.length;
if (self.health <= colorCount) {
brickGraphics.tint = baseColors[self.health - 1];
} else {
var lastDigit = self.health % 10;
var colorIndex = lastDigit === 0 ? 9 : lastDigit - 1;
brickGraphics.tint = baseColors[colorIndex];
}
};
self.updateTint();
self.hit = function () {
var damage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
self.health -= damage;
if (self.health <= 0) {
LK.getSound('explosion').play();
score += self.maxHealth === 1 ? 1 : self.maxHealth;
scoreTxt.setText('$' + score.toString());
storage.score = score;
var brickIndex = bricks.indexOf(self);
if (brickIndex !== -1) {
bricks.splice(brickIndex, 1);
}
var explosionColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
var randomColor = explosionColors[Math.floor(Math.random() * explosionColors.length)];
var randomScale = Math.random() * 1.5 + 1.5;
var randomDuration = Math.random() * 300 + 400;
tween(self, {
tint: randomColor,
scaleX: randomScale,
scaleY: randomScale,
alpha: 0
}, {
duration: randomDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
} else {
self.healthText.setText(self.health.toString());
self.updateTint();
}
};
});
var GameTitle = Container.expand(function () {
var self = Container.call(this);
var titleGraphics = self.attachAsset('gametitle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.35,
scaleY: 1.5
});
var titleText = new Text2('Idle BrickBreaker', {
size: 200,
fill: 0x000000
});
titleText.anchor.set(0.5, 0.5);
self.addChild(titleText);
});
var ResetButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('resetButton', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff6666
});
var buttonText = new Text2('RESET', {
size: 50,
fill: 0x000000,
fontWeight: 'bold'
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.interactive = true;
self.down = function () {
LK.getSound('click').play();
clearLocalStorage();
playTime = 0;
storage.playTime = playTime;
LK.showGameOver();
};
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 2 + 1;
self.update = function () {
self.y += self.speed;
if (self.y > GAME_HEIGHT) {
self.y = 0;
self.x = Math.random() * GAME_WIDTH;
}
};
});
var StartButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
var buttonText = new Text2('START', {
size: 100,
fill: 0x000000,
fontWeight: 'bold'
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.interactive = true;
self.down = function () {
LK.getSound('click').play();
self.interactive = false;
var explosionColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
var randomColor = explosionColors[Math.floor(Math.random() * explosionColors.length)];
LK.getSound('explosion').play();
tween(self, {
tint: randomColor,
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
startTransitionSequence();
}
});
};
});
var UpgradeButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('upgrade', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x00ffff
});
var buttonText = new Text2('UPGRADES', {
size: 50,
fill: 0x000000,
fontWeight: 'bold'
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.interactive = true;
self.down = function () {
LK.getSound('click').play();
powerupContainer.visible = !powerupContainer.visible;
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
var lastRunStartTime = 0;
var lastRunTime = 0;
var ballDamage = {
normal: 0,
splash: 0,
sniper: 0,
scatter: 0,
smallScatter: 0
};
function _toConsumableArray2(r) {
return _arrayWithoutHoles2(r) || _iterableToArray2(r) || _unsupportedIterableToArray2(r) || _nonIterableSpread2();
}
function _nonIterableSpread2() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray2(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray2(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray2(r, a) : void 0;
}
}
function _iterableToArray2(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles2(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray2(r);
}
}
function _arrayLikeToArray2(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray(r);
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function tintEndScreenTitle() {
gameTitleContainer.children.forEach(function (child) {
child.tint = 0xff33cc;
});
}
var frameThickness = 10;
var topFrame = new Container();
var topFrameGraphics = topFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
width: GAME_WIDTH,
height: frameThickness
});
topFrame.x = 0;
topFrame.y = 0;
game.addChild(topFrame);
function animateTopFrameTint() {
tween(topFrameGraphics, {
tint: 0xff33cc
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(topFrameGraphics, {
tint: 0x00ff99
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: animateTopFrameTint
});
}
});
}
animateTopFrameTint();
var bottomFrame = new Container();
var bottomFrameGraphics = bottomFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
width: GAME_WIDTH,
height: frameThickness
});
bottomFrame.x = 0;
bottomFrame.y = 2720;
game.addChild(bottomFrame); // Should be bottomFrame
function animateBottomFrameTint() {
tween(bottomFrameGraphics, {
tint: 0xff33cc
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(bottomFrameGraphics, {
tint: 0x00ff99
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: animateBottomFrameTint
});
}
});
}
animateBottomFrameTint();
var leftFrame = new Container();
var leftFrameGraphics = leftFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
width: frameThickness,
height: GAME_HEIGHT
});
leftFrame.x = 0;
leftFrame.y = 0;
game.addChild(leftFrame);
function animateLeftFrameTint() {
tween(leftFrameGraphics, {
tint: 0xff33cc
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(leftFrameGraphics, {
tint: 0x00ff99
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: animateLeftFrameTint
});
}
});
}
animateLeftFrameTint();
var rightFrame = new Container();
var rightFrameGraphics = rightFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
width: frameThickness,
height: GAME_HEIGHT
});
rightFrame.x = 2040;
rightFrame.y = 0;
game.addChild(rightFrame);
function animateRightFrameTint() {
tween(rightFrameGraphics, {
tint: 0xff33cc
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(rightFrameGraphics, {
tint: 0x00ff99
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: animateRightFrameTint
});
}
});
}
animateRightFrameTint();
var welcomeText = null;
function showEndScreen() {
game.isGameOver = true;
hud.visible = false;
powerupContainer.visible = false;
upgradeButton.visible = false;
balls.forEach(function (ball) {
return ball.visible = true;
});
bricks.forEach(function (brick) {
return brick.visible = false;
});
// Calculate last run time
lastRunTime = Math.floor((Date.now() - lastRunStartTime) / 1000);
var congratsText = new Text2('Congratulations! You broke them ALL!', {
size: 100,
fill: 0xffffff
});
congratsText.anchor.set(0.5, 0);
congratsText.x = GAME_WIDTH / 2;
congratsText.y = GAME_HEIGHT / 2 - 600; // Moved up slightly
game.addChild(congratsText);
// Move game title up
var gameTitle = new GameTitle();
gameTitle.x = GAME_WIDTH / 2;
gameTitle.y = congratsText.y - 400; // Moved down by 200 pixels
gameTitleContainer.addChild(gameTitle);
function animateEndTitleColor() {
tintEndScreenTitle();
tween(gameTitle, {
tint: 0xff33cc
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(gameTitle, {
tint: 0x00ff99
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: animateEndTitleColor
});
}
});
}
animateEndTitleColor();
var playTimeText = new Text2('Total Time Played: ' + playTime + ' seconds', {
size: 60,
fill: 0xffffff
});
playTimeText.anchor.set(0.5, 0);
playTimeText.x = GAME_WIDTH / 2;
playTimeText.y = congratsText.y + 200;
game.addChild(playTimeText);
var lastRunText = new Text2('Last Run Time: ' + lastRunTime + ' seconds', {
size: 60,
fill: 0xffffff
});
lastRunText.anchor.set(0.5, 0);
lastRunText.x = GAME_WIDTH / 2;
lastRunText.y = playTimeText.y + 200;
game.addChild(lastRunText);
// Add damage stats
var damageText = new Text2('Damage Dealt This Run:\n' + 'Normal: ' + ballDamage.normal + '\n' + 'Splash: ' + ballDamage.splash + '\n' + 'Sniper: ' + ballDamage.sniper + '\n' + 'Scatter: ' + ballDamage.scatter + '\n' + 'Small Scatter: ' + ballDamage.smallScatter, {
size: 50,
fill: 0xffffff,
align: 'center'
});
damageText.anchor.set(0.5, 0);
damageText.x = GAME_WIDTH / 2;
damageText.y = lastRunText.y + 120;
game.addChild(damageText);
var noteText = new Text2('Start over with all your upgrades, or reset for a fresh new run! Your choice!', {
size: 50,
fill: 0xffffff
});
noteText.anchor.set(0.5, 0);
noteText.x = GAME_WIDTH / 2;
noteText.y = damageText.y + 500;
game.addChild(noteText);
var endGameButton = new Container();
var buttonGraphics = endGameButton.attachAsset('endGameButton', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x00ffff
});
var buttonText = new Text2('RESTART!', {
size: 50,
fill: 0x000000,
fontWeight: 'bold'
});
buttonText.anchor.set(0.5, 0.5);
endGameButton.addChild(buttonText);
endGameButton.x = GAME_WIDTH / 2;
endGameButton.y = noteText.y + 300;
endGameButton.interactive = true;
endGameButton.down = function () {
storage.level = 1;
LK.showGameOver();
};
game.addChild(endGameButton);
var resetButton = new ResetButton();
resetButton.x = GAME_WIDTH / 2;
resetButton.y = endGameButton.y + 260;
game.addChild(resetButton);
LK.clearInterval(playTimeInterval);
playTimeInterval = null;
}
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2720;
var BALL_RADIUS = 50;
var BRICK_WIDTH = 300;
var BRICK_HEIGHT = 99;
var LEVEL_COLORS = [0xff00ff, 0x00ffff, 0xffff00, 0xff0066, 0x00ff99, 0xff33cc, 0x66ff33, 0xcc00ff, 0x33ffcc, 0xff3300];
var levelConfig = {
1: {
totalBricks: 28,
hitpoints: 1,
pattern: 'clustered'
},
2: {
totalBricks: 63,
hitpoints: 2,
pattern: 'staggered'
},
3: {
totalBricks: 63,
hitpoints: 3,
pattern: 'cross'
},
4: {
totalBricks: 77,
pattern: 'custom',
customPattern: [[0, 3, 3, 0, 3, 3, 0], [3, 4, 4, 3, 4, 4, 3], [3, 4, 4, 4, 4, 4, 3], [3, 4, 4, 4, 4, 4, 3], [3, 4, 4, 4, 4, 4, 3], [3, 4, 4, 4, 4, 4, 3], [3, 4, 4, 4, 4, 4, 3], [0, 3, 4, 4, 4, 3, 0], [0, 0, 3, 4, 3, 0, 0], [0, 0, 0, 3, 0, 0, 0], [0, 0, 0, 3, 0, 0, 0]]
},
5: {
totalBricks: 112,
pattern: 'custom',
customPattern: [[0, 0, 0, 3, 0, 0, 0], [0, 0, 3, 4, 3, 0, 0], [0, 3, 4, 5, 4, 3, 0], [3, 4, 5, 6, 5, 4, 3], [4, 5, 6, 7, 6, 5, 4], [3, 5, 6, 7, 6, 5, 3], [0, 4, 5, 6, 5, 4, 0], [0, 3, 4, 5, 4, 3, 0], [0, 0, 3, 4, 3, 0, 0], [0, 0, 2, 3, 2, 0, 0], [0, 0, 1, 2, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 2, 1, 0, 0], [0, 0, 1, 2, 1, 0, 0]]
},
6: {
totalBricks: 60,
hitpoints: 10,
pattern: 'cross'
},
7: {
totalBricks: 70,
hitpoints: 13,
pattern: 'clustered'
},
8: {
totalBricks: 112,
hitpoints: 15,
pattern: 'clustered'
},
9: {
totalBricks: 112,
hitpoints: 20,
pattern: 'cross'
},
10: {
totalBricks: 112,
hitpoints: 30,
pattern: 'clustered'
},
11: {
totalBricks: 112,
hitpoints: 50,
pattern: 'clustered'
},
12: {
totalBricks: 112,
hitpoints: 99,
pattern: 'clustered'
},
13: {
totalBricks: 140,
pattern: 'custom',
customPattern: [[0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 0, 0, 0, 222, 0], [0, 222, 222, 222, 222, 222, 0], [0, 222, 222, 222, 222, 222, 0]]
},
14: {
totalBricks: 140,
pattern: 'custom',
customPattern: [[0, 333, 333, 333, 333, 333, 0], [0, 333, 333, 333, 333, 333, 0], [0, 333, 0, 0, 0, 333, 0], [0, 333, 0, 0, 0, 333, 0], [0, 333, 0, 0, 0, 333, 0], [0, 333, 333, 333, 333, 333, 0], [0, 333, 333, 333, 333, 333, 0], [0, 333, 333, 0, 0, 0, 0], [0, 333, 333, 0, 0, 0, 0], [0, 333, 333, 0, 0, 0, 0], [0, 333, 333, 0, 0, 0, 0], [0, 333, 333, 0, 0, 0, 0], [0, 333, 333, 0, 0, 0, 0], [0, 333, 333, 0, 0, 0, 0]]
},
15: {
totalBricks: 140,
pattern: 'custom',
customPattern: [[0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0], [0, 444, 444, 444, 0]]
},
16: {
totalBricks: 140,
pattern: 'custom',
customPattern: [[555, 555, 555, 555, 555, 555, 555], [555, 555, 555, 555, 555, 555, 555], [555, 555, 555, 555, 555, 555, 555], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0], [0, 0, 555, 555, 555, 0, 0]]
}
};
var upgrades = storage.upgrades || {
normalSpeed: 1,
normalPower: 1,
splashSpeed: 1,
splashPower: 2,
sniperSpeed: 1,
sniperPower: 1,
scatterSpeed: 1,
scatterPower: 1,
clickDamage: 1,
normalSpeedCost: 25,
normalPowerCost: 50,
splashSpeedCost: 75,
splashPowerCost: 75,
sniperSpeedCost: 100,
sniperPowerCost: 100,
scatterSpeedCost: 125,
scatterPowerCost: 125,
clickCost: 25,
normalBallCost: 25,
splashBallCost: 150,
sniperBallCost: 500,
scatterBallCost: 2000
};
var balls = [];
var ballQuantities = storage.ballQuantities || {
normal: 0,
splash: 0,
sniper: 0,
scatter: 0
};
var bricks = [];
var score = storage.score || 0;
var level = storage.level || 1;
var brickGridBounds = null;
var unlockedTiers = storage.unlockedTiers || {
normal: true,
splash: false,
sniper: false,
scatter: false
};
var playTime = storage.playTime || 0;
var playTimeInterval = LK.setInterval(function () {
if (!game.isGameOver) {
playTime += 1;
storage.playTime = playTime;
console.log('Time Played2:', playTime, 'seconds');
}
}, 1000);
game.isGameOver = false;
function clearLocalStorage() {
storage.score = 0;
storage.level = 1;
storage.unlockedTiers = {
normal: true,
splash: false,
sniper: false,
scatter: false
};
unlockedTiers = Object.assign({}, storage.unlockedTiers);
storage.upgrades = {
normalSpeed: 1,
normalPower: 1,
splashSpeed: 1,
splashPower: 2,
sniperSpeed: 1,
sniperPower: 1,
scatterSpeed: 1,
scatterPower: 1,
clickDamage: 1,
normalSpeedCost: 50,
normalPowerCost: 50,
splashSpeedCost: 75,
splashPowerCost: 75,
sniperSpeedCost: 100,
sniperPowerCost: 100,
scatterSpeedCost: 125,
scatterPowerCost: 125,
clickCost: 25,
normalBallCost: 25,
splashBallCost: 150,
sniperBallCost: 500,
scatterBallCost: 2000
};
score = 0;
storage.ballQuantities = {
normal: 0,
splash: 0,
sniper: 0,
scatter: 0
};
storage.firstLoad = false;
ballQuantities = Object.assign({}, storage.ballQuantities);
level = 1;
unlockedTiers = Object.assign({}, storage.unlockedTiers);
scoreTxt.setText('$' + score.toString());
levelTxt.setText('Level: ' + level);
updateButtonStates();
}
var hud = new Container();
LK.gui.top.addChild(hud);
var scoreTxt = new Text2('$0', {
size: 60,
fill: 0x39ff14
});
scoreTxt.anchor.set(0.3, 0);
scoreTxt.x += 570;
hud.addChild(scoreTxt);
var levelTxt = new Text2('Level: ' + level, {
size: 50,
fill: 0xffffff
});
levelTxt.anchor.set(1, 0);
levelTxt.x = scoreTxt.x + 100;
levelTxt.y = scoreTxt.height + 10;
hud.addChild(levelTxt);
var ballButtons = {};
function createBallButton(type, x, cost, asset, prevTier) {
var button = new Container();
var buttonGraphics = button.attachAsset('button', {
anchorX: 0.5,
anchorY: 0,
tint: 0x1a1a2e
});
button.y = 50;
button.x = x + 20;
var contentContainer = new Container();
button.addChild(contentContainer);
var ballIcon = button.attachAsset('ball', {
anchorX: 0.5,
anchorY: -0.5,
scaleX: 0.6,
scaleY: 0.6,
y: -10
});
ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff;
contentContainer.addChild(ballIcon);
var displayType = type === 'scatter' ? 'Multi' : type.charAt(0).toUpperCase() + type.slice(1);
var typeText = new Text2(displayType, {
size: 30,
fill: 0xffffff,
fontWeight: 'bold'
});
typeText.anchor.set(0.5, 0);
typeText.y = -50;
button.addChild(typeText);
var costText = new Text2('$' + upgrades[type + 'BallCost'], {
size: 40,
fill: 0xffffff
});
costText.anchor.set(0.5, 0);
costText.y = 100;
button.addChild(costText);
button.interactive = true;
button.down = function () {
if (score < upgrades[type + 'BallCost']) {
return;
}
if (welcomeText && welcomeText.parent) {
welcomeText.parent.removeChild(welcomeText);
}
score -= upgrades[type + 'BallCost'];
scoreTxt.setText('$' + score.toString());
createBall(type);
ballQuantities[type] = (ballQuantities[type] || 0) + 1;
storage.ballQuantities = Object.assign({}, ballQuantities);
upgrades[type + 'BallCost'] = Math.floor(upgrades[type + 'BallCost'] * 2);
storage.upgrades = Object.assign({}, upgrades);
costText.setText('$' + upgrades[type + 'BallCost']);
if (!unlockedTiers[type]) {
unlockedTiers[type] = true;
storage.unlockedTiers = Object.assign({}, unlockedTiers);
updateButtonStates();
}
};
button.updateState = function () {
var isEnabled = (prevTier ? unlockedTiers[prevTier] : true) && score >= upgrades[type + 'BallCost'];
buttonGraphics.tint = isEnabled ? 0x00ffff : 0x666666;
button.interactive = isEnabled;
if (isEnabled) {
ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff;
typeText.fill = 0xffffff;
costText.fill = 0x00ffff;
} else {
ballIcon.tint = 0x666666;
typeText.fill = 0x666666;
costText.fill = 0x666666;
}
};
hud.addChild(button);
ballButtons[type] = button;
}
createBallButton('normal', -450, 25, 'ball', null);
createBallButton('splash', -300, upgrades.splashBallCost, 'splashBall', 'normal');
createBallButton('sniper', -150, upgrades.sniperBallCost, 'sniperBall', 'splash');
createBallButton('scatter', 0, upgrades.scatterBallCost, 'scatterBall', 'sniper');
var clearStorageButton = LK.getAsset('button', {
size: 0,
fill: 0x1a1a2e,
anchorX: 0.5,
anchorY: 0,
x: scoreTxt.width + 12000,
y: 0
});
var clearStorageText = new Text2('', {
size: 0,
fill: 0xffffff
});
clearStorageText.anchor.set(0.5, 0);
clearStorageText.y = 100;
clearStorageButton.addChild(clearStorageText);
clearStorageButton.down = clearLocalStorage;
hud.addChild(clearStorageButton);
var powerupContainer = new Container();
powerupContainer.y = 1800;
powerupContainer.visible = false;
game.addChild(powerupContainer);
var bottomHud = new Container();
bottomHud.y = GAME_HEIGHT - 200;
game.addChild(bottomHud); // Should be bottomHud
var upgradeButtons = {};
function createUpgradeButton(labelPrefix, x, costKey, upgradeKey, baseCost, iconType, prevTier) {
var button = new Container();
var buttonGraphics = button.attachAsset('powerupbutton', {
anchorX: 0.5,
anchorY: 0,
tint: 0x1a1a2e
});
button.x = x + 60;
button.y = 350;
button.addChild(buttonGraphics);
var contentContainer = new Container();
button.addChild(contentContainer);
var icon = null;
if (iconType) {
icon = button.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
y: 40,
tint: iconType === 'splashBall' ? 0xff0066 : iconType === 'sniperBall' ? 0x00ff99 : iconType === 'scatterBall' ? 0xffff00 : iconType === 'ball' ? 0xffffff : 0x00ffff
});
contentContainer.addChild(icon);
}
var labelText = new Text2("".concat(labelPrefix.replace('Speed', 'SPD').replace('Power', 'DMG'), " +").concat(upgrades[upgradeKey]), {
size: upgradeKey === 'clickDamage' ? 40 : 40,
fill: 0x000000,
fontWeight: 'bold'
});
labelText.anchor.set(0.5, 0);
labelText.y = 80;
contentContainer.addChild(labelText);
var currentCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1);
var costText = new Text2("$".concat(currentCost), {
size: 40,
fill: 0x000000
});
costText.anchor.set(0.5, 0);
costText.y = 140;
contentContainer.addChild(costText);
button.interactive = true;
button.down = function () {
if (welcomeText && welcomeText.parent) {
welcomeText.parent.removeChild(welcomeText);
}
var cost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1);
var ballType = upgradeKey.split('Speed')[0].split('Power')[0];
if (upgradeKey === 'clickDamage') {
if (score < cost) {
return;
}
} else {
if (!unlockedTiers[ballType] || score < cost) {
return;
}
}
score -= cost;
LK.getSound('click').play();
upgrades[upgradeKey]++;
storage.upgrades = Object.assign({}, upgrades);
var newCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1);
costText.setText("$".concat(newCost));
labelText.setText("".concat(labelPrefix, " +").concat(upgrades[upgradeKey]));
scoreTxt.setText('$' + score.toString());
balls.forEach(function (b) {
if (b.type === 'normal' && upgradeKey.includes('normal')) {
b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey];
} else if (b.type === 'splash' && upgradeKey.includes('splash')) {
b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey];
} else if (b.type === 'sniper' && upgradeKey.includes('sniper')) {
b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey];
} else if ((b.type === 'scatter' || b.type === 'smallScatter') && upgradeKey.includes('scatter')) {
b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey];
}
});
if (upgradeKey === 'clickDamage') {
upgrades.clickDamage = upgrades[upgradeKey], storage.upgrades = Object.assign({}, upgrades);
}
updateButtonStates();
};
button.updateState = function () {
var ballType = upgradeKey.split('Speed')[0].split('Power')[0];
var currentCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1);
var isEnabled = upgradeKey === 'clickDamage' ? score >= currentCost : unlockedTiers[ballType] && (prevTier ? unlockedTiers[prevTier] : true) && score >= currentCost;
buttonGraphics.tint = isEnabled ? 0x00ffff : 0x666666;
button.interactive = isEnabled;
if (icon) {
icon.tint = isEnabled ? iconType === 'splashBall' ? 0xff0066 : iconType === 'sniperBall' ? 0x00ff99 : iconType === 'scatterBall' ? 0xffff00 : iconType === 'ball' ? 0xffffff : 0x00ffff : 0x666666;
}
labelText.fill = isEnabled ? 0x000000 : 0x666666;
costText.fill = isEnabled ? 0x000000 : 0x666666;
costText.setText("$".concat(currentCost));
};
powerupContainer.addChild(button);
upgradeButtons[upgradeKey] = button;
}
var buttonWidth = 150;
var spacing = 70;
var totalButtons = 9;
var totalWidth = totalButtons * buttonWidth + (totalButtons - 1) * spacing;
var startX = (GAME_WIDTH - totalWidth) / 2;
createUpgradeButton('Speed', startX, 'normalSpeedCost', 'normalSpeed', 25, 'ball', null);
createUpgradeButton('Power', startX + (buttonWidth + spacing), 'normalPowerCost', 'normalPower', 50, 'ball', null);
createUpgradeButton('Speed', startX + 2 * (buttonWidth + spacing), 'splashSpeedCost', 'splashSpeed', 75, 'splashBall', 'normal');
createUpgradeButton('Power', startX + 3 * (buttonWidth + spacing), 'splashPowerCost', 'splashPower', 75, 'splashBall', 'normal');
createUpgradeButton('Speed', startX + 4 * (buttonWidth + spacing), 'sniperSpeedCost', 'sniperSpeed', 100, 'sniperBall', 'splash');
createUpgradeButton('Power', startX + 5 * (buttonWidth + spacing), 'sniperPowerCost', 'sniperPower', 100, 'sniperBall', 'splash');
createUpgradeButton('Speed', startX + 6 * (buttonWidth + spacing), 'scatterSpeedCost', 'scatterSpeed', 125, 'scatterBall', 'sniper');
createUpgradeButton('Power', startX + 7 * (buttonWidth + spacing), 'scatterPowerCost', 'scatterPower', 125, 'scatterBall', 'sniper');
createUpgradeButton('Click', startX + 8 * (buttonWidth + spacing), 'clickCost', 'clickDamage', 25, null, null);
var upgradeButton = new UpgradeButton();
upgradeButton.x = GAME_WIDTH / 2;
upgradeButton.y = GAME_HEIGHT - 100;
upgradeButton.visible = false;
game.addChild(upgradeButton);
game.setChildIndex(upgradeButton, game.children.length - 1);
hud.visible = false;
function updateButtonStates() {
for (var type in ballButtons) {
ballButtons[type].updateState();
}
var canPurchaseAny = false;
for (var key in upgradeButtons) {
upgradeButtons[key].updateState();
if (upgradeButtons[key].interactive) {
canPurchaseAny = true;
}
}
upgradeButton.tint = canPurchaseAny ? 0x00ffff : 0x666666;
upgradeButton.interactive = canPurchaseAny;
}
function applySplashDamage(brick) {
var splashDamage = Math.floor(upgrades.splashPower / 2);
var horizontalMaxDistance = BRICK_WIDTH + 15;
var verticalMaxDistance = BRICK_HEIGHT + 15;
bricks.forEach(function (adjBrick) {
if (adjBrick === brick || adjBrick.health <= 0) {
return;
}
var dx = Math.abs(adjBrick.x - brick.x);
var dy = Math.abs(adjBrick.y - brick.y);
var isHorizontalAdjacent = dx <= horizontalMaxDistance && dy <= BRICK_HEIGHT / 2;
var isVerticalAdjacent = dy <= verticalMaxDistance && dx <= BRICK_WIDTH / 2;
if (isHorizontalAdjacent || isVerticalAdjacent) {
adjBrick.hit(splashDamage);
ballDamage['splash'] = (ballDamage['splash'] || 0) + splashDamage;
}
});
}
function scatterOnImpact(ball) {
var numBalls = 4;
for (var i = 0; i < numBalls; i++) {
var smallBall = new Ball('smallScatter');
smallBall.x = ball.x;
smallBall.y = ball.y;
var angle = Math.random() * 2 * Math.PI;
var speedVariation = 0.8 + Math.random() * 0.4;
smallBall.speed = upgrades.scatterSpeed * 0.8 * speedVariation;
smallBall.velocity.x = Math.cos(angle);
smallBall.velocity.y = Math.sin(angle);
var magnitude = Math.sqrt(smallBall.velocity.x * smallBall.velocity.x + smallBall.velocity.y * smallBall.velocity.y);
smallBall.velocity.x /= magnitude;
smallBall.velocity.y /= magnitude;
balls.push(smallBall);
game.addChild(smallBall);
// Track the initial creation damage from scatter splitting
ballDamage['scatter'] = (ballDamage['scatter'] || 0) + ball.power;
}
}
function findNearestBrick(x, y) {
if (bricks.length === 0) {
return null;
}
return bricks.reduce(function (closest, brick) {
var dx = brick.x - x;
var dy = brick.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
return !closest || distance < closest.distance ? {
brick: brick,
distance: distance
} : closest;
}, null).brick;
}
function createBricks() {
var config = levelConfig[level] || {};
var totalBricks = config.totalBricks || 50;
var baseHitpoints = config.hitpoints || 1;
var pattern = config.pattern || 'grid';
var spacingX = -15;
var spacingY = 0;
bricks = [];
var cols = 7;
var rows = Math.ceil(totalBricks / cols);
var totalWidth = cols * BRICK_WIDTH + (cols - 1) * spacingX;
var totalHeight = rows * BRICK_HEIGHT + (rows - 1) * spacingY;
var startX = (GAME_WIDTH - totalWidth) / 2 + BRICK_WIDTH / 2;
var startY = (GAME_HEIGHT - totalHeight) / 2 + BRICK_HEIGHT / 2;
var brickCount = 0;
console.log("Creating bricks for level ".concat(level, ", pattern: ").concat(pattern, ", totalBricks: ").concat(totalBricks));
if (pattern === 'grid') {
for (var i = 0; i < rows && brickCount < totalBricks; i++) {
for (var j = 0; j < cols && brickCount < totalBricks; j++) {
addBrick(startX + j * (BRICK_WIDTH + spacingX), startY + i * (BRICK_HEIGHT + spacingY), baseHitpoints);
brickCount++;
}
}
} else if (pattern === 'staggered') {
var centerRow = Math.floor(rows / 2);
var centerCol = Math.floor(cols / 2);
for (var i = 0; i < rows && brickCount < totalBricks; i++) {
var offsetX = 0;
for (var j = 0; j < cols && brickCount < totalBricks; j++) {
var x = startX + offsetX + j * (BRICK_WIDTH + spacingX);
var y = startY + i * (BRICK_HEIGHT + spacingY);
var rowDistance = Math.abs(i - centerRow);
var colDistance = Math.abs(j - centerCol);
var maxDistance = Math.max(centerRow, centerCol);
var distance = Math.max(rowDistance, colDistance);
var hitpoints = Math.max(1, Math.round(baseHitpoints * (1 - distance / maxDistance)));
addBrick(x, y, hitpoints);
brickCount++;
}
}
} else if (pattern === 'clustered') {
var centerRow = Math.floor(rows / 2);
var centerCol = Math.floor(cols / 2);
var maxDistance = Math.max(centerRow, centerCol);
var positions = [];
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
var rowDistance = Math.abs(i - centerRow);
var colDistance = Math.abs(j - centerCol);
var distance = Math.max(rowDistance, colDistance);
positions.push({
i: i,
j: j,
distance: distance
});
}
}
positions.sort(function (a, b) {
return b.distance - a.distance;
});
for (var k = 0; k < positions.length && brickCount < totalBricks; k++) {
var pos = positions[k];
var i = pos.i;
var j = pos.j;
var distance = pos.distance;
var x = startX + j * (BRICK_WIDTH + spacingX);
var y = startY + i * (BRICK_HEIGHT + spacingY);
var hitpoints = Math.max(1, Math.round(baseHitpoints * (distance / maxDistance)));
addBrick(x, y, hitpoints);
brickCount++;
}
} else if (pattern === 'cross') {
var centerRow = Math.floor(rows / 2);
var centerCol = Math.floor(cols / 2);
for (var i = 0; i < rows && brickCount < totalBricks; i++) {
for (var colOffset = -2; colOffset <= 2 && brickCount < totalBricks; colOffset++) {
var col = centerCol + colOffset;
if (col >= 0 && col < cols) {
var x = startX + col * (BRICK_WIDTH + spacingX);
var y = startY + i * (BRICK_HEIGHT + spacingY);
var distanceFromCenter = Math.max(Math.abs(i - centerRow), Math.abs(colOffset));
var hitpoints = Math.max(1, baseHitpoints - distanceFromCenter);
addBrick(x, y, hitpoints);
brickCount++;
}
}
}
for (var j = 0; j < cols && brickCount < totalBricks; j++) {
if (Math.abs(j - centerCol) > 2) {
for (var rowOffset = -2; rowOffset <= 2 && brickCount < totalBricks; rowOffset++) {
var row = centerRow + rowOffset;
if (row >= 0 && row < rows) {
var x = startX + j * (BRICK_WIDTH + spacingX);
var y = startY + row * (BRICK_HEIGHT + spacingY);
var distanceFromCenter = Math.max(Math.abs(j - centerCol), Math.abs(rowOffset));
var hitpoints = Math.max(1, baseHitpoints - distanceFromCenter);
addBrick(x, y, hitpoints);
brickCount++;
}
}
}
}
for (var j = 0; j < cols && brickCount < totalBricks; j++) {
if (Math.abs(j - centerCol) > 3) {
for (var rowOffset = -1; rowOffset <= 1 && brickCount < totalBricks; rowOffset++) {
var row = centerRow + rowOffset;
if (row >= 0 && row < rows) {
var x = startX + j * (BRICK_WIDTH + spacingX);
var y = startY + row * (BRICK_HEIGHT + spacingY);
var distanceFromCenter = Math.max(Math.abs(j - centerCol), Math.abs(rowOffset));
var hitpoints = Math.max(1, baseHitpoints - distanceFromCenter);
addBrick(x, y, hitpoints);
brickCount++;
}
}
}
}
} else if (pattern === 'custom') {
var customPattern = config.customPattern || [];
var patternRows = customPattern.length;
var patternCols = patternRows > 0 ? customPattern[0].length : 0;
console.log("Custom pattern dimensions: ".concat(patternRows, "x").concat(patternCols, ", grid: ").concat(rows, "x").concat(cols));
rows = Math.max(rows, patternRows);
totalHeight = rows * BRICK_HEIGHT + (rows - 1) * spacingY;
startY = (GAME_HEIGHT - totalHeight) / 2 + BRICK_HEIGHT / 2;
if (patternRows > 0 && patternCols <= cols) {
var offsetX = Math.floor((cols - patternCols) / 2);
var offsetY = Math.floor((rows - patternRows) / 2);
for (var i = 0; i < patternRows && brickCount < totalBricks; i++) {
for (var j = 0; j < patternCols && brickCount < totalBricks; j++) {
var hitpoints = customPattern[i][j];
if (hitpoints > 0) {
var x = startX + (j + offsetX) * (BRICK_WIDTH + spacingX);
var y = startY + (i + offsetY) * (BRICK_HEIGHT + spacingY);
addBrick(x, y, hitpoints);
brickCount++;
console.log("Added brick at (".concat(x, ", ").concat(y, ") with hitpoints: ").concat(hitpoints));
}
}
}
} else {
console.error("Custom pattern (".concat(patternRows, "x").concat(patternCols, ") invalid or exceeds grid (").concat(rows, "x").concat(cols, ")"));
}
}
console.log("Total bricks created: ".concat(brickCount, ", bricks array length: ").concat(bricks.length));
brickGridBounds = {
minX: Math.min.apply(Math, _toConsumableArray2(bricks.map(function (b) {
return b.x - BRICK_WIDTH / 2;
}))),
maxX: Math.max.apply(Math, _toConsumableArray2(bricks.map(function (b) {
return b.x + BRICK_WIDTH / 2;
}))),
minY: Math.min.apply(Math, _toConsumableArray2(bricks.map(function (b) {
return b.y - BRICK_HEIGHT / 2;
}))),
maxY: Math.max.apply(Math, _toConsumableArray2(bricks.map(function (b) {
return b.y + BRICK_HEIGHT / 2;
})))
};
}
function addBrick(x, y, hitpoints) {
var brick = new Brick();
brick.x = x;
brick.y = y;
brick.health = hitpoints;
brick.maxHealth = hitpoints;
brick.healthText.setText(brick.health.toString());
brick.updateTint();
bricks.push(brick);
game.addChild(brick);
}
function repositionBall(ball, index) {
var spawnFromTop = index % 2 === 0;
var safeX = GAME_WIDTH / 2 + (Math.random() * 200 - 100);
var safeY = spawnFromTop ? BALL_RADIUS + 50 : GAME_HEIGHT - BALL_RADIUS - 50;
var attempts = 0;
var maxAttempts = 10;
while (attempts < maxAttempts && isOverlappingWithBricks(safeX, safeY)) {
safeX = GAME_WIDTH / 2 + (Math.random() * 200 - 100);
safeY = spawnFromTop ? BALL_RADIUS + 50 + attempts * 50 : GAME_HEIGHT - BALL_RADIUS - 50 - attempts * 50;
attempts++;
}
ball.x = safeX;
ball.y = safeY;
var angle = (Math.random() * 0.5 + 0.25) * Math.PI;
ball.velocity.x = Math.cos(angle);
ball.velocity.y = spawnFromTop ? Math.sin(angle) : -Math.sin(angle);
var magnitude = Math.sqrt(ball.velocity.x * ball.velocity.x + ball.velocity.y * ball.velocity.y);
ball.velocity.x /= magnitude;
ball.velocity.y /= magnitude;
}
function isOverlappingWithBricks(x, y) {
var ballLeft = x - BALL_RADIUS;
var ballRight = x + BALL_RADIUS;
var ballTop = y - BALL_RADIUS;
var ballBottom = y + BALL_RADIUS;
for (var i = 0; i < bricks.length; i++) {
var brick = bricks[i];
var brickLeft = brick.x - BRICK_WIDTH / 2;
var brickRight = brick.x + BRICK_WIDTH / 2;
var brickTop = brick.y - BRICK_HEIGHT / 2;
var brickBottom = brick.y + BRICK_HEIGHT / 2;
if (ballLeft < brickRight && ballRight > brickLeft && ballTop < brickBottom && ballBottom > brickTop) {
return true;
}
}
return false;
}
function createBall() {
var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'normal';
var ball = new Ball(type);
repositionBall(ball, balls.length);
balls.push(ball);
game.addChild(ball);
}
game.update = function () {
for (var i = 0; i < stars.length; i++) {
stars[i].update();
}
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
ball.update();
if (ball.y > GAME_HEIGHT + BALL_RADIUS) {
ball.destroy();
balls.splice(i, 1);
}
}
if (bricks.length === 0 && !game.isGameOver) {
console.log("Level ".concat(level, " cleared, advancing to next level"));
if (level === Object.keys(levelConfig).length) {
showEndScreen();
} else {
level += 1;
storage.level = level;
levelTxt.setText('Level: ' + level);
createBricks();
balls.forEach(function (ball, index) {
repositionBall(ball, index);
});
}
}
updateButtonStates();
};
game.down = function (x, y, obj) {
if (!bricks || !Array.isArray(bricks)) {
return;
}
x = Number(x);
y = Number(y);
for (var i = 0; i < bricks.length; i++) {
var brick = bricks[i];
if (!brick.x || !brick.y || !brick.width || !brick.height) {
continue;
}
if (x >= brick.x - brick.width / 2 && x <= brick.x + brick.width / 2 && y >= brick.y - brick.height / 2 && y <= brick.y + brick.height / 2) {
brick.hit(upgrades.clickDamage);
powerupContainer.visible = false;
LK.getSound('click').play();
scoreTxt.setText('$' + score.toString());
storage.score = score;
return;
}
}
};
var stars = [];
for (var i = 0; i < 100; i++) {
var star = new Star();
star.x = Math.random() * GAME_WIDTH;
star.y = Math.random() * GAME_HEIGHT;
stars.push(star);
game.addChildAt(star, 0);
}
var gameTitleContainer = new Container();
game.addChild(gameTitleContainer);
var gameTitle = new GameTitle();
gameTitle.x = GAME_WIDTH / 2;
gameTitle.y = GAME_HEIGHT / 2 - 1100;
gameTitleContainer.addChild(gameTitle);
function animateTitleColor() {
tween(gameTitle, {
tint: 0xff33cc
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(gameTitle, {
tint: 0x00ff99
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: animateTitleColor
});
}
});
}
animateTitleColor();
tween(gameTitle, {
y: 500
}, {
duration: 1000,
easing: tween.bounceOut
});
var startButton = new StartButton();
startButton.x = GAME_WIDTH / 2;
startButton.y = GAME_HEIGHT / 2 + 400;
startButton.tint = 0x00ff99;
game.addChild(startButton);
function animateStartButton() {
tween(startButton, {
y: 1500
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(startButton, {
y: startButton.y + 50
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: animateStartButton
});
}
});
}
animateStartButton();
var resetButton = new ResetButton();
resetButton.x = GAME_WIDTH / 2;
resetButton.y = GAME_HEIGHT + 200; // Start from below the screen
game.addChild(resetButton);
tween(resetButton, {
y: startButton.y + 800 // Tween to the desired position
}, {
duration: 1000,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(resetButton, {
y: resetButton.y + 20
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
LK.playMusic('backgroundmusic');
function startTransitionSequence() {
tween(gameTitle, {
y: -500,
alpha: 0
}, {
duration: 800,
easing: tween.easeIn
});
tween(resetButton, {
y: GAME_HEIGHT + 200,
alpha: 0
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
startGameLogic();
}, 500);
}
});
}
function startGameLogic() {
startButton.destroy();
gameTitle.destroy();
resetButton.visible = false;
upgradeButton.visible = true;
hud.visible = true;
createBricks();
console.log("Initial bricks after startGame: " + bricks.length);
createBall('normal');
if (score > 0) {
scoreTxt.setText('$' + score.toString());
}
// Add this line to reset damage tracking and set start time
lastRunStartTime = Date.now();
for (var type in ballDamage) {
ballDamage[type] = 0;
}
if (storage.firstLoad !== true) {
welcomeText = new Text2(' Smash bricks, earn cash,\nbuy balls, and power up to auto-win!', {
size: 90,
fill: 0xffffff
});
welcomeText.anchor.set(0.5, 0.5);
welcomeText.x = GAME_WIDTH / 2;
welcomeText.y = GAME_HEIGHT / 2 + 600;
game.addChild(welcomeText);
storage.firstLoad = true;
}
playTimeInterval = LK.setInterval(function () {
playTime += 1;
console.log('Time Played:', playTime, 'seconds');
}, 1000);
for (var type in ballQuantities) {
for (var i = 0; i < ballQuantities[type]; i++) {
createBall(type);
}
}
updateButtonStates();
game.update = function () {
for (var i = 0; i < stars.length; i++) {
stars[i].update();
}
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
ball.update();
if (ball.y > GAME_HEIGHT + BALL_RADIUS) {
ball.destroy();
balls.splice(i, 1);
}
}
if (bricks.length === 0 && !game.isGameOver) {
console.log("Level ".concat(level, " cleared in active game loop"));
if (level === Object.keys(levelConfig).length) {
showEndScreen();
} else {
level += 1;
storage.level = level;
levelTxt.setText('Level: ' + level);
createBricks();
balls.forEach(function (ball, index) {
repositionBall(ball, index);
});
}
}
updateButtonStates();
};
}
function startGame() {}
game.update = function () {
for (var i = 0; i < stars.length; i++) {
stars[i].update();
}
};