User prompt
Move endscreen title 100 pixels more, and so the rest of the endscreen elelments
Code edit (6 edits merged)
Please save this source code
User prompt
lets add a background asset for that covers all the text in the endscreen, from congratulations to the note
User prompt
use resultsbg instead of frame for the endscreen
Code edit (14 edits merged)
Please save this source code
/****
* 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 + 300;
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 + 250;
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 + 400;
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: [[222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [222, 222, 0, 0, 0, 222, 222], [0, 222, 222, 222, 222, 222, 0], [0, 0, 222, 222, 222, 0, 0]]
},
14: {
totalBricks: 140,
pattern: 'custom',
customPattern: [[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, 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, 0], [333, 333, 0, 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: 112,
hitpoints: 15,
pattern: 'clustered'
}
};
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();
}
};