User prompt
level text shoudl be white
User prompt
make $ color neon green
Code edit (10 edits merged)
Please save this source code
User prompt
move welcom message 200 pixels down
User prompt
welcome message is not being shown even after clearing storage
User prompt
make sure to clear all storage with reset ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
on reset, reset welcome message local storate too ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Great! welcome message should last untill you have clicked on 5 bricks
User prompt
only the first time the game is loaded when storage is empty, show some text on the first level below the bricks. It should say: Welcome! Start clicking to earn money and get your upgrades! ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (3 edits merged)
Please save this source code
User prompt
Un comment all levels
Code edit (1 edits merged)
Please save this source code
User prompt
Change end game button text for restart!
User prompt
when reset is pressed show game ove
User prompt
when reset is pressed, also restart game
User prompt
make sure reste button also reset timme played
Code edit (5 edits merged)
Please save this source code
User prompt
comment out all levels, to only play level 1
User prompt
move endgame button 100 pixels up
User prompt
display again rest button on endscren
Code edit (1 edits merged)
Please save this source code
User prompt
Add a new note belwo time played,that says: Now you can start over with all your upgrades, o reset for a fresh new run! Your choice!
User prompt
do not hide balls on end screen
Code edit (2 edits merged)
Please save this source code
User prompt
increase run number by one when endscre is reached.
/**** * 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; self.type = type; self.speed = type === 'splash' ? upgrades.splashSpeed : type === 'sniper' ? upgrades.sniperSpeed : type === 'scatter' ? upgrades.scatterSpeed : type === 'smallScatter' ? upgrades.scatterSpeed * 0.8 : 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.5)) : upgrades.normalPower; self.direction = { x: 1, y: -1 }; self.update = function () { var gridSize = levelConfig[level] ? levelConfig[level].gridSize : 200; var stepSize = self.speed; if (self.type === 'sniper') { 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.direction.x = dx / magnitude; self.direction.y = dy / magnitude; } } var dx = self.direction.x * stepSize; var dy = self.direction.y * stepSize; self.x += dx; self.y += dy; if (self.x <= BALL_RADIUS || self.x >= GAME_WIDTH - BALL_RADIUS) { self.direction.x *= -1; self.x = Math.max(BALL_RADIUS, Math.min(GAME_WIDTH - BALL_RADIUS, self.x)); LK.getSound('bounce').play(); } if (self.y <= BALL_RADIUS || self.y >= GAME_HEIGHT - BALL_RADIUS) { self.direction.y *= -1; self.y = Math.max(BALL_RADIUS, Math.min(GAME_HEIGHT - BALL_RADIUS, self.y)); LK.getSound('bounce').play(); } if (!isNearBricks(self.x, self.y)) { return; } var gridXMin = Math.floor((self.x - BALL_RADIUS) / gridSize); var gridXMax = Math.floor((self.x + BALL_RADIUS) / gridSize); var gridYMin = Math.floor((self.y - BALL_RADIUS) / gridSize); var gridYMax = Math.floor((self.y + BALL_RADIUS) / gridSize); var hasCollided = false; for (var gx = gridXMin; gx <= gridXMax && !hasCollided; gx++) { for (var gy = gridYMin; gy <= gridYMax && !hasCollided; gy++) { var gridKey = "".concat(gx, ",").concat(gy); var cellBricks = brickGrid[gridKey]; if (!cellBricks || cellBricks.length === 0) { continue; } for (var j = cellBricks.length - 1; j >= 0; j--) { var brick = cellBricks[j]; if (!brick || brick.health <= 0 || !self.intersects(brick)) { continue; } handleBallBrickCollision(self, brick); brick.hit(self.power); if (self.type === 'splash' && brick.health > 0) { applySplashDamage(brick, gridSize); } else if (self.type === 'scatter') { scatterOnImpact(self); self.destroy(); balls.splice(balls.indexOf(self), 1); hasCollided = true; break; } if (brick.health <= 0) { cellBricks.splice(j, 1); } hasCollided = true; break; } } } }; }); 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); // Helper function to convert hex color to RGB function hexToRGB(hex) { return { r: hex >> 16 & 0xff, g: hex >> 8 & 0xff, b: hex & 0xff }; } // Helper function to convert RGB back to hex function rgbToHex(r, g, b) { return (Math.floor(r) << 16) + (Math.floor(g) << 8) + Math.floor(b); } // Update brick tint based on health self.updateTint = function () { var baseColors = LEVEL_COLORS; var colorCount = baseColors.length; // 10 colors if (self.health <= colorCount) { // For HP 1-10, use the direct color from LEVEL_COLORS brickGraphics.tint = baseColors[self.health - 1]; } else { // For HP > 10, use the last digit to determine the color var lastDigit = self.health % 10; // Get the last digit (0-9) // Map last digit 0 to index 9 (HP 10), 1 to index 0 (HP 1), etc. 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 }); var titleText = new Text2('Idle BrickBreaker', { size: 150, 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(); // Show game over when reset is pressed }; }); 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 }); var buttonText = new Text2('START', { size: 80, fill: 0x000000, fontWeight: 'bold' }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.interactive = true; self.down = function () { LK.getSound('click').play(); startGame(); }; }); 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('UPGRADE', { 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 ****/ function showEndScreen() { game.isGameOver = true; // Set the flag to indicate the end screen is up // Hide all game elements 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; }); 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 - 500 + 550; game.addChild(congratsText); // Add game title with color switching var gameTitle = new GameTitle(); gameTitle.x = GAME_WIDTH / 2; gameTitle.y = congratsText.y - 400; game.addChild(gameTitle); function animateEndTitleColor() { tween(gameTitle, { tint: 0xff33cc }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(gameTitle, { tint: 0x00ff99 }, { duration: 2000, easing: tween.easeInOut, onFinish: animateEndTitleColor }); } }); } animateEndTitleColor(); // Add play time text var playTimeText = new Text2('Time Played: ' + playTime + ' seconds', { size: 80, fill: 0xffffff }); playTimeText.anchor.set(0.5, 0); playTimeText.x = GAME_WIDTH / 2; playTimeText.y = congratsText.y + 300; game.addChild(playTimeText); // Add a note below the time played 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 = playTimeText.y + 400; game.addChild(noteText); // Add end game button var endGameButton = new Container(); var buttonGraphics = endGameButton.attachAsset('endGameButton', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ffff // Match the upgrade button tint }); 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 = GAME_HEIGHT - 200; endGameButton.interactive = true; endGameButton.down = function () { LK.showGameOver(); }; game.addChild(endGameButton); // Add reset button var resetButton = new ResetButton(); resetButton.x = GAME_WIDTH / 2; resetButton.y = endGameButton.y + 200; game.addChild(resetButton); // Debugging: Log to ensure animations are triggered LK.clearInterval(playTimeInterval); playTimeInterval = null; // Reset the interval variable to null playTimeInterval = null; // Reset the interval variable to null } 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; } var GAME_WIDTH = 2048; var GAME_HEIGHT = 2632; 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: 70, hitpoints: 1, gridSize: 400, pattern: 'grid' }, 2: { totalBricks: 66, hitpoints: 3, gridSize: 200, pattern: 'grid' }, 3: { totalBricks: 84, hitpoints: 6, gridSize: 320, pattern: 'staggered' }, 4: { totalBricks: 102, hitpoints: 10, gridSize: 500, pattern: 'clustered' }, 5: { totalBricks: 96, hitpoints: 12, gridSize: 240, pattern: 'grid' }, 6: { totalBricks: 106, hitpoints: 15, gridSize: 220, pattern: 'clustered' }, 7: { totalBricks: 106, hitpoints: 20, gridSize: 200, pattern: 'grid' }, 8: { totalBricks: 106, hitpoints: 99, gridSize: 180, pattern: 'clustered' }, 9: { totalBricks: 106, hitpoints: 99, gridSize: 160, pattern: 'grid' }, 10: { totalBricks: 10, hitpoints: 999, gridSize: 140, pattern: 'clustered' } }; var upgrades = storage.upgrades || { normalSpeed: 1, normalPower: 1, splashSpeed: 1, splashPower: 1, sniperSpeed: 1.5, sniperPower: 2, scatterSpeed: 1, scatterPower: 1, clickDamage: 1, normalSpeedCost: 50, normalPowerCost: 75, splashSpeedCost: 50, splashPowerCost: 75, sniperSpeedCost: 75, sniperPowerCost: 100, scatterSpeedCost: 50, scatterPowerCost: 75, clickCost: 25, normalBallCost: 50, splashBallCost: 100, sniperBallCost: 500, scatterBallCost: 2000 }; var balls = []; var ballQuantities = storage.ballQuantities || { normal: 0, splash: 0, sniper: 0, scatter: 0 }; var bricks = []; var brickGrid = {}; 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; playTimeInterval = LK.setInterval(function () { if (!game.isGameOver) { // Check if the game is not over playTime += 1; storage.playTime = playTime; console.log('Time Played2:', playTime, 'seconds'); } }, 1000); var playTimeInterval = null; game.isGameOver = false; // Initialize the flag to indicate the end screen is not up 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: 1, sniperSpeed: 1.5, sniperPower: 2, scatterSpeed: 1, scatterPower: 1, clickDamage: 1, normalSpeedCost: 50, normalPowerCost: 75, splashSpeedCost: 50, splashPowerCost: 75, sniperSpeedCost: 75, sniperPowerCost: 100, scatterSpeedCost: 50, scatterPowerCost: 75, clickCost: 25, normalBallCost: 50, splashBallCost: 100, sniperBallCost: 500, scatterBallCost: 2000 }; score = 0; storage.ballQuantities = { normal: 0, splash: 0, sniper: 0, scatter: 0 }; ballQuantities = Object.assign({}, storage.ballQuantities); level = 1; unlockedTiers = Object.assign({}, storage.unlockedTiers); scoreTxt.setText('$' + score.toString()); levelTxt.setText('Level: ' + level); updateButtonStates(); } // HUD Setup var hud = new Container(); LK.gui.top.addChild(hud); var scoreTxt = new Text2('$0', { size: 60, fill: 0x00ffff }); scoreTxt.anchor.set(0.3, 0); scoreTxt.x += 450; hud.addChild(scoreTxt); var levelTxt = new Text2('Level: ' + level, { size: 60, fill: 0x00ffff }); 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 }); // Set initial tint ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff; // Normal ball contentContainer.addChild(ballIcon); var displayType = type === 'scatter' ? 'Multi' : type.charAt(0).toUpperCase() + type.slice(1); var typeText = new Text2(displayType, { size: 30, fill: 0xffffff, // Initial white color fontWeight: 'bold' }); typeText.anchor.set(0.5, 0); typeText.y = -50; button.addChild(typeText); var costText = new Text2('$' + (type === 'sniper' ? 500 : type === 'splash' ? 150 : type === 'scatter' ? 2000 : upgrades[type + 'BallCost']), { size: 50, fill: 0x00ffff // Initial cyan color }); costText.anchor.set(0.5, 0); costText.y = 100; button.addChild(costText); button.interactive = true; button.down = function () { if (score < upgrades[type + 'BallCost']) { return; } 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'] * 1.3); 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 background tint button.interactive = isEnabled; // Update ballIcon tint based on enabled state if (isEnabled) { ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff; // Restore original ball color typeText.fill = 0xffffff; // White for ball name costText.fill = 0x00ffff; // Cyan for price } else { ballIcon.tint = 0x666666; // Grey out ball icon typeText.fill = 0x666666; // Grey out ball name costText.fill = 0x666666; // Grey out price } }; hud.addChild(button); ballButtons[type] = button; } createBallButton('normal', -450, upgrades.normalBallCost, '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); 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 // Fallback }); contentContainer.addChild(icon); } var labelText = new Text2("".concat(labelPrefix, " x").concat(upgrades[upgradeKey]), { size: 30, fill: 0x000000, fontWeight: 'bold' }); labelText.anchor.set(0.5, 0); labelText.y = 100; contentContainer.addChild(labelText); var costText = new Text2('$' + (baseCost * upgrades[upgradeKey]).toString(), { size: 40, fill: 0x000000 }); costText.anchor.set(0.5, 0); costText.y = 140; contentContainer.addChild(costText); button.interactive = true; button.down = function () { var cost = baseCost * upgrades[upgradeKey]; 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); costText.setText('$' + (baseCost * upgrades[upgradeKey]).toString()); labelText.setText("".concat(labelPrefix, " x").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); } }; button.updateState = function () { var ballType = upgradeKey.split('Speed')[0].split('Power')[0]; var isEnabled = upgradeKey === 'clickDamage' ? score >= baseCost * upgrades[upgradeKey] : unlockedTiers[ballType] && (prevTier ? unlockedTiers[prevTier] : true) && score >= baseCost * upgrades[upgradeKey]; buttonGraphics.tint = isEnabled ? 0x00ffff : 0x666666; // Button background tint button.interactive = isEnabled; // Update icon tint based on enabled state if (icon) { if (isEnabled) { // Restore original ball color when enabled icon.tint = iconType === 'splashBall' ? 0xff0066 : iconType === 'sniperBall' ? 0x00ff99 : iconType === 'scatterBall' ? 0xffff00 : iconType === 'ball' ? 0xffffff : 0x00ffff; } else { // Grey out when disabled icon.tint = 0x666666; } } }; powerupContainer.addChild(button); upgradeButtons[upgradeKey] = button; } var buttonWidth = 150; var spacing = 50; var totalButtons = 9; var totalWidth = totalButtons * buttonWidth + (totalButtons - 1) * spacing; var startX = (GAME_WIDTH - totalWidth) / 2; createUpgradeButton('Speed', startX, 'normalSpeedCost', 'normalSpeed', 50, 'ball', null); createUpgradeButton('Power', startX + (buttonWidth + spacing), 'normalPowerCost', 'normalPower', 75, 'ball', null); createUpgradeButton('Speed', startX + 2 * (buttonWidth + spacing), 'splashSpeedCost', 'splashSpeed', 50, 'splashBall', 'normal'); createUpgradeButton('Power', startX + 3 * (buttonWidth + spacing), 'splashPowerCost', 'splashPower', 75, 'splashBall', 'normal'); createUpgradeButton('Speed', startX + 4 * (buttonWidth + spacing), 'sniperSpeedCost', 'sniperSpeed', 75, 'sniperBall', 'splash'); createUpgradeButton('Power', startX + 5 * (buttonWidth + spacing), 'sniperPowerCost', 'sniperPower', 100, 'sniperBall', 'splash'); createUpgradeButton('Speed', startX + 6 * (buttonWidth + spacing), 'scatterSpeedCost', 'scatterSpeed', 50, 'scatterBall', 'sniper'); createUpgradeButton('Power', startX + 7 * (buttonWidth + spacing), 'scatterPowerCost', 'scatterPower', 75, '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(); } for (var key in upgradeButtons) { upgradeButtons[key].updateState(); } } function handleBallBrickCollision(ball, brick) { var relativeX = (ball.x - brick.x) / (brick.width / 2); var relativeY = (ball.y - brick.y) / (brick.height / 2); if (Math.abs(relativeX) > Math.abs(relativeY)) { ball.direction.x = -ball.direction.x + relativeX * 0.5; ball.x = brick.x + (relativeX > 0 ? brick.width / 2 + BALL_RADIUS : -brick.width / 2 - BALL_RADIUS); } else { ball.direction.y = -ball.direction.y; ball.y = brick.y + (relativeY > 0 ? brick.height / 2 + BALL_RADIUS : -brick.height / 2 - BALL_RADIUS); } LK.getSound('bounce').play(); ball.direction.x += (Math.random() - 0.5) * 0.1; var magnitude = Math.sqrt(ball.direction.x * ball.direction.x + ball.direction.y * ball.direction.y); ball.direction.x /= magnitude; ball.direction.y /= magnitude; } function applySplashDamage(brick, gridSize) { var gridX = Math.floor(brick.x / gridSize); var gridY = Math.floor(brick.y / gridSize); var adjacentKeys = ["".concat(gridX - 1, ",").concat(gridY), "".concat(gridX + 1, ",").concat(gridY), "".concat(gridX, ",").concat(gridY - 1), "".concat(gridX, ",").concat(gridY + 1)]; adjacentKeys.forEach(function (key) { if (brickGrid[key]) { brickGrid[key].forEach(function (adjBrick) { if (adjBrick && adjBrick.health > 0) { adjBrick.hit(Math.floor(upgrades.splashPower * 0.25)); } }); } }); } function scatterOnImpact(ball) { for (var i = 0; i < 4; i++) { var smallBall = new Ball('smallScatter'); smallBall.x = ball.x; smallBall.y = ball.y; var angle = i / 4 * 2 * Math.PI; smallBall.direction.x = Math.cos(angle); smallBall.direction.y = Math.sin(angle); balls.push(smallBall); game.addChild(smallBall); } } 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 isNearBricks(x, y) { if (!brickGridBounds) { return true; } var buffer = BALL_RADIUS * 2; return x >= brickGridBounds.minX - buffer && x <= brickGridBounds.maxX + buffer && y >= brickGridBounds.minY - buffer && y <= brickGridBounds.maxY + buffer; } function createBricks() { var config = levelConfig[level] || {}; var totalBricks = config.totalBricks || 50; var baseHitpoints = config.hitpoints || 1; // Base HP from level config var gridSize = config.gridSize || 200; var pattern = config.pattern || 'grid'; var spacingX = 1; // Reduced spacing between columns var spacingY = 2; brickGrid = {}; bricks = []; var cols = 7; // Set to 7 columns 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) / 3 + 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, gridSize); brickCount++; } } } else if (pattern === 'staggered') { // Staggered pattern with HP gradient from center var centerRow = Math.floor(rows / 2); // Approximate center row var centerCol = Math.floor(cols / 2); // Approximate center column for (var i = 0; i < rows && brickCount < totalBricks; i++) { var offsetX = 0; // No offset for staggered grid for (var j = 0; j < cols && brickCount < totalBricks; j++) { var x = startX + offsetX + j * (BRICK_WIDTH + spacingX); var y = startY + i * (BRICK_HEIGHT + spacingY); // Calculate distance from center (Manhattan distance for simplicity) var rowDistance = Math.abs(i - centerRow); var colDistance = Math.abs(j - centerCol); var maxDistance = Math.max(centerRow, centerCol); // Max possible distance to edge var distance = Math.max(rowDistance, colDistance); // HP decreases linearly from center to edge // Center gets baseHitpoints, edges get at least 1 HP var hitpoints = Math.max(1, Math.round(baseHitpoints * (1 - distance / maxDistance))); addBrick(x, y, hitpoints, gridSize); brickCount++; } } } else if (pattern === 'clustered') { // Clustered pattern: fill from outside in var centerRow = Math.floor(rows / 2); var centerCol = Math.floor(cols / 2); var maxDistance = Math.max(centerRow, centerCol); // Create a list of all possible grid positions with their distances 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 }); } } // Sort positions by distance (descending) to fill from outside in positions.sort(function (a, b) { return b.distance - a.distance; }); // Place bricks up to totalBricks limit 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); // Optional: HP can still vary if desired, higher on edges here var hitpoints = Math.max(1, Math.round(baseHitpoints * (distance / maxDistance))); addBrick(x, y, hitpoints, gridSize); brickCount++; } } else if (pattern === 'diagonal') { // [Unchanged diagonal pattern code] var stepX = (GAME_WIDTH - BRICK_WIDTH) / (totalBricks - 1); var stepY = GAME_HEIGHT / 3 / (totalBricks - 1); for (var i = 0; i < totalBricks; i++) { var offsetX = i % 2 === 0 ? BRICK_WIDTH / 4 : 0; addBrick(startX + i * stepX + offsetX, startY + i * stepY, baseHitpoints, gridSize); brickCount++; } } else if (pattern === 'sparse') { // Sparse pattern: groups of 3 rows with 2-row gaps var groupSize = 3; // 3 rows per group var gapSize = 2; // 2 rows gap var cycleLength = groupSize + gapSize; // Total rows in one cycle (3 + 2 = 5) while (brickCount < totalBricks) { // Pick a random column var col = Math.floor(Math.random() * cols); var x = startX + col * (BRICK_WIDTH + spacingX); // Pick a random group start row, ensuring space for 3 rows var maxGroupStart = rows - groupSize; // Leave room for 3 rows var groupStart = Math.floor(Math.random() * Math.floor(maxGroupStart / cycleLength)) * cycleLength; // Place bricks in the 3 rows of the group for (var rowOffset = 0; rowOffset < groupSize && brickCount < totalBricks; rowOffset++) { var row = groupStart + rowOffset; if (row >= rows) { continue; } // Skip if beyond grid bounds var y = startY + row * (BRICK_HEIGHT + spacingY); // Check for collision to maintain sparsity if (!bricks.some(function (b) { return b.x === x && b.y === y; })) { addBrick(x, y, baseHitpoints, gridSize); 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, gridSize) { 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); var gridX = Math.floor(brick.x / gridSize); var gridY = Math.floor(brick.y / gridSize); var gridKey = "".concat(gridX, ",").concat(gridY); if (!brickGrid[gridKey]) { brickGrid[gridKey] = []; } brickGrid[gridKey].push(brick); } function createBall() { var type = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'normal'; var ball = new Ball(type); var gridBottom = brickGridBounds ? brickGridBounds.maxY + 150 : GAME_HEIGHT * 0.7; ball.x = GAME_WIDTH / 2 + (Math.random() * 200 - 100); ball.y = Math.min(gridBottom + 100, GAME_HEIGHT - BALL_RADIUS * 2); var angle = (Math.random() * 0.5 + 0.25) * Math.PI; ball.direction.x = Math.cos(angle); ball.direction.y = -Math.sin(angle); var magnitude = Math.sqrt(ball.direction.x * ball.direction.x + ball.direction.y * ball.direction.y); ball.direction.x /= magnitude; ball.direction.y /= magnitude; for (var i = 0; i < bricks.length; i++) { if (ball.intersects(bricks[i])) { ball.y = brickGridBounds.maxY + BALL_RADIUS + 10; break; } } 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) { if (level === Object.keys(levelConfig).length) { showEndScreen(); } else { level += 1; storage.level = level; levelTxt.setText('Level: ' + level); createBricks(); } } updateButtonStates(); // Increment playTime by 1 second (assuming update is called 60 times per second) // Removed playTime increment to ensure it only prints once }; 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); 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 - 600; 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: GAME_HEIGHT / 2 - 500 }, { duration: 1000, easing: tween.bounceOut }); var startButton = new StartButton(); startButton.x = GAME_WIDTH / 2; startButton.y = GAME_HEIGHT / 2 + 300; startButton.tint = 0x00ff99; game.addChild(startButton); tween(startButton, { y: startButton.y - 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(startButton, { y: startButton.y + 20 }, { duration: 1000, easing: tween.easeInOut }); } }); var resetButton = new ResetButton(); resetButton.x = GAME_WIDTH / 2; resetButton.y = startButton.y + 900; game.addChild(resetButton); tween(resetButton, { y: resetButton.y - 20 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(resetButton, { y: resetButton.y + 20 }, { duration: 1000, easing: tween.easeInOut }); } }); LK.playMusic('backgroundmusic'); function startGame() { startButton.destroy(); gameTitle.destroy(); resetButton.visible = false; upgradeButton.visible = true; hud.visible = true; createBricks(); playTimeInterval = LK.setInterval(function () { playTime += 1; // Ensure playTime is printed once console.log('Time Played:', playTime, 'seconds'); }, 1000); // Load balls from storage 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) { if (level === Object.keys(levelConfig).length) { showEndScreen(); } else { level += 1; storage.level = level; levelTxt.setText('Level: ' + level); createBricks(); } } updateButtonStates(); }; } game.update = function () { for (var i = 0; i < stars.length; i++) { stars[i].update(); } };
===================================================================
--- original.js
+++ change.js
@@ -431,67 +431,67 @@
var BRICK_HEIGHT = 99;
var LEVEL_COLORS = [0xff00ff, 0x00ffff, 0xffff00, 0xff0066, 0x00ff99, 0xff33cc, 0x66ff33, 0xcc00ff, 0x33ffcc, 0xff3300];
var levelConfig = {
1: {
- totalBricks: 60,
+ totalBricks: 70,
hitpoints: 1,
gridSize: 400,
pattern: 'grid'
+ },
+ 2: {
+ totalBricks: 66,
+ hitpoints: 3,
+ gridSize: 200,
+ pattern: 'grid'
+ },
+ 3: {
+ totalBricks: 84,
+ hitpoints: 6,
+ gridSize: 320,
+ pattern: 'staggered'
+ },
+ 4: {
+ totalBricks: 102,
+ hitpoints: 10,
+ gridSize: 500,
+ pattern: 'clustered'
+ },
+ 5: {
+ totalBricks: 96,
+ hitpoints: 12,
+ gridSize: 240,
+ pattern: 'grid'
+ },
+ 6: {
+ totalBricks: 106,
+ hitpoints: 15,
+ gridSize: 220,
+ pattern: 'clustered'
+ },
+ 7: {
+ totalBricks: 106,
+ hitpoints: 20,
+ gridSize: 200,
+ pattern: 'grid'
+ },
+ 8: {
+ totalBricks: 106,
+ hitpoints: 99,
+ gridSize: 180,
+ pattern: 'clustered'
+ },
+ 9: {
+ totalBricks: 106,
+ hitpoints: 99,
+ gridSize: 160,
+ pattern: 'grid'
+ },
+ 10: {
+ totalBricks: 10,
+ hitpoints: 999,
+ gridSize: 140,
+ pattern: 'clustered'
}
- // 2: {
- // totalBricks: 66,
- // hitpoints: 3,
- // gridSize: 200,
- // pattern: 'grid'
- // },
- // 3: {
- // totalBricks: 84,
- // hitpoints: 6,
- // gridSize: 320,
- // pattern: 'staggered'
- // },
- // 4: {
- // totalBricks: 102,
- // hitpoints: 10,
- // gridSize: 500,
- // pattern: 'clustered'
- // },
- // 5: {
- // totalBricks: 96,
- // hitpoints: 12,
- // gridSize: 240,
- // pattern: 'grid'
- // },
- // 6: {
- // totalBricks: 106,
- // hitpoints: 15,
- // gridSize: 220,
- // pattern: 'clustered'
- // },
- // 7: {
- // totalBricks: 106,
- // hitpoints: 20,
- // gridSize: 200,
- // pattern: 'grid'
- // },
- // 8: {
- // totalBricks: 106,
- // hitpoints: 99,
- // gridSize: 180,
- // pattern: 'clustered'
- // },
- // 9: {
- // totalBricks: 106,
- // hitpoints: 99,
- // gridSize: 160,
- // pattern: 'grid'
- // },
- // 10: {
- // totalBricks: 10,
- // hitpoints: 999,
- // gridSize: 140,
- // pattern: 'clustered'
- // }
};
var upgrades = storage.upgrades || {
normalSpeed: 1,
normalPower: 1,