Code edit (4 edits merged)
Please save this source code
Code edit (14 edits merged)
Please save this source code
User prompt
Please fix the bug: 'customFrameGraphics is not defined' in or related to this line: 'tween(customFrameGraphics, {' Line Number: 475 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { lastRunStartTime: "undefined", lastRunTime: 0, ballDamage: { normal: 0, splash: 0, sniper: 0, scatter: 0, smallScatter: 0 } }); /**** * 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; storage.ballDamage = Object.assign({}, ballDamage); 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 ResetButton = Container.expand(function () { var self = Container.call(this); var buttonGraphics = self.attachAsset('resetButton', { anchorX: 0.5, anchorY: 0.5, tint: 0xffc0cb }); self.interactive = true; self.down = function () { LK.getSound('click').play(); clearLocalStorage(); storage.lastRunTime = 0; // Reset lastRunTime in storage lastRunStartTime = Date.now(); storage.lastRunStartTime = lastRunStartTime; // lastRunTime is no longer reset to ensure it persists across sessions ballDamage = { normal: 0, splash: 0, sniper: 0, scatter: 0, smallScatter: 0 }; storage.ballDamage = Object.assign({}, ballDamage); playTime = 0; storage.playTime = 0; 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 }); 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 }); 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 = storage.lastRunStartTime !== "undefined" ? parseInt(storage.lastRunStartTime) : Date.now(); var lastRunTime = storage.lastRunTime || 0; var playTime = storage.playTime || 0; var ballDamage = storage.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; }); storage.ballDamage = Object.assign({}, ballDamage); 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; game.addChild(congratsText); var gameTitle = new GameTitle(); gameTitle.x = GAME_WIDTH / 2; gameTitle.y = congratsText.y - 300; 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 lastRunTimeText = new Text2('Last Run Time: ' + lastRunTime + ' seconds', { size: 60, fill: 0xffffff }); lastRunTimeText.anchor.set(0.5, 0); lastRunTimeText.x = GAME_WIDTH / 2; lastRunTimeText.y = playTimeText.y + 80; game.addChild(lastRunTimeText); 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 = lastRunTimeText.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 }); endGameButton.x = GAME_WIDTH / 2; endGameButton.y = noteText.y + 300; endGameButton.interactive = true; endGameButton.down = function () { storage.level = 1; storage.lastRunTime = 0; // Clear lastRunTime from storage lastRunStartTime = Date.now(); storage.lastRunStartTime = lastRunStartTime; ballDamage = { normal: 0, splash: 0, sniper: 0, scatter: 0, smallScatter: 0 }; storage.ballDamage = Object.assign({}, ballDamage); 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: 10, normalPowerCost: 50, splashSpeedCost: 75, splashPowerCost: 75, sniperSpeedCost: 100, sniperPowerCost: 100, scatterSpeedCost: 125, scatterPowerCost: 125, clickCost: 10, normalBallCost: 10, 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; lastRunTime += 1; // Increment lastRunTime by 1 second for each update storage.playTime = playTime; storage.lastRunTime = lastRunTime; // Persist lastRunTime to storage } }, 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: 10, normalBallCost: 10, splashBallCost: 150, sniperBallCost: 500, scatterBallCost: 2000 }; storage.lastRunStartTime = Date.now(); storage.lastRunTime = 0; storage.ballDamage = { normal: 0, splash: 0, sniper: 0, scatter: 0, smallScatter: 0 }; 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 = 0x3bc7e0; } else { ballIcon.tint = 0x666666; typeText.fill = 0x666666; costText.fill = 0x666666; } }; hud.addChild(button); ballButtons[type] = button; } createBallButton('normal', -450, 10, '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', 10, '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', 10, 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; storage.ballDamage = Object.assign({}, ballDamage); } }); } 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); ballDamage['scatter'] = (ballDamage['scatter'] || 0) + ball.power; storage.ballDamage = Object.assign({}, ballDamage); } } 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; 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; 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++; } } } } } 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) { 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); }); } } lastRunTime += 1; // Increment lastRunTime by 1 second for each update storage.lastRunTime = lastRunTime; 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 - 1050; 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: 600 }, { duration: 1000, easing: tween.bounceOut }); var startButton = new StartButton(); startButton.x = GAME_WIDTH / 2; startButton.y = GAME_HEIGHT / 2 + 400; 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; game.addChild(resetButton); tween(resetButton, { y: startButton.y + 800 }, { 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(); createBall('normal'); if (score > 0) { scoreTxt.setText('$' + score.toString()); } lastRunStartTime = Date.now(); lastRunTime = storage.lastRunTime || 0; // Initialize lastRunTime from storage if (storage.firstLoad !== true) { welcomeText = LK.getAsset('welcomemsg', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 + 600 }); game.addChild(welcomeText); storage.firstLoad = true; } playTimeInterval = LK.setInterval(function () { playTime += 1; storage.playTime = playTime; }, 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) { 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(); } };
===================================================================
--- original.js
+++ change.js
@@ -906,9 +906,9 @@
button.interactive = isEnabled;
if (isEnabled) {
ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff;
typeText.fill = 0xffffff;
- costText.fill = 0x00ffff;
+ costText.fill = 0x3bc7e0;
} else {
ballIcon.tint = 0x666666;
typeText.fill = 0x666666;
costText.fill = 0x666666;