User prompt
brick text should be black
User prompt
upgrade button text color should be black
User prompt
upgrade button should use light blue tint like the color of the level font
User prompt
use tint for upgrade button ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
can upgrade button be created the same way as start button in terms of its design
User prompt
also use click when clicking on upgrade or on start or reset
User prompt
play background musci on ame load
User prompt
play explosion when a brick is destroyed
User prompt
play click sound when player clicks on a brick
User prompt
add bounce sound when ball bounces or touches a brick and do not destoyr it
Code edit (2 edits merged)
Please save this source code
User prompt
hide ball purchase buttons when they are disabled
User prompt
Do the same for scatter, increase it to 2000
User prompt
scatter price should be 2000
User prompt
Do the samefor splash, increase it to 150
User prompt
increase price of sniper ball to 500. make sure to update the text of the button.
User prompt
add a litttle more space between them
User prompt
add a little more space between buttons of ball purchase
User prompt
reduce size of prices of ball buttons
User prompt
update also sniper price in the button
User prompt
sniper price should be 500
Code edit (1 edits merged)
Please save this source code
User prompt
remove particle effect
Code edit (1 edits merged)
Please save this source code
User prompt
tween effect on brick explosion should also change a be random ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * 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 : 0x00ffff; 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)); } 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)); } 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: 0xffffff }); self.healthText.anchor.set(0.5, 0.5); self.addChild(self.healthText); self.updateTint = function () { var healthPercent = self.health / self.maxHealth; var colorIndex = Math.min(Math.floor((1 - healthPercent) * LEVEL_COLORS.length), LEVEL_COLORS.length - 1); brickGraphics.tint = LEVEL_COLORS[colorIndex]; }; self.updateTint(); self.hit = function () { var damage = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; self.health -= damage; if (self.health <= 0) { score += level === 1 ? 1 : Math.max(1, Math.floor(self.maxHealth * 0.5)); scoreTxt.setText('$' + score.toString()); storage.score = score; var brickIndex = bricks.indexOf(self); if (brickIndex !== -1) { bricks.splice(brickIndex, 1); } // Create a colorful tween explosion effect with random properties 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; // Random scale between 1.5 and 3 var randomDuration = Math.random() * 300 + 400; // Random duration between 400ms and 700ms 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 }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.interactive = true; self.down = function () { clearLocalStorage(); }; }); 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 }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.interactive = true; self.down = function () { startGame(); }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ 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: 60, hitpoints: 1, gridSize: 400, pattern: 'grid' }, 2: { totalBricks: 50, hitpoints: 2, gridSize: 360, pattern: 'staggered' }, 3: { totalBricks: 70, hitpoints: 3, gridSize: 320, pattern: 'clustered' }, 4: { totalBricks: 80, hitpoints: 4, gridSize: 280, pattern: 'diagonal' }, 5: { totalBricks: 80, hitpoints: 5, gridSize: 240, pattern: 'sparse' } }; 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, // Integrated BALL_COST into upgrades splashBallCost: 100, sniperBallCost: 150, scatterBallCost: 125 }; var balls = []; 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 }; function clearLocalStorage() { storage.score = 0; storage.level = 1; storage.unlockedTiers = { normal: true, splash: false, sniper: false, scatter: false }; 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: 150, scatterBallCost: 125 }; score = 0; 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 = LK.getAsset('button', { size: 80, fill: 0x1a1a2e, anchorX: 0.5, anchorY: 0, y: 50, x: x }); 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, tint: type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0x00ffff }); contentContainer.addChild(ballIcon); var typeText = new Text2(type.charAt(0).toUpperCase() + type.slice(1), { size: 30, fill: 0xffffff }); typeText.anchor.set(0.5, 0); typeText.y = -50; button.addChild(typeText); var costText = new Text2('$' + upgrades[type + 'BallCost'], { size: 50, fill: 0x00ffff }); 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); 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']; button.tint = isEnabled ? 0x00ffff : 0x666666; button.interactive = isEnabled; }; hud.addChild(button); ballButtons[type] = button; } createBallButton('normal', -400, upgrades.normalBallCost, 'ball', null); createBallButton('splash', -280, upgrades.splashBallCost, 'splashBall', 'normal'); createBallButton('sniper', -160, upgrades.sniperBallCost, 'sniperBall', 'splash'); createBallButton('scatter', -40, 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 = LK.getAsset('powerupbutton', { size: 150, fill: 0x1a1a2e, anchorX: 0.5, anchorY: 0, x: x + 60, y: 350 }); var contentContainer = new Container(); button.addChild(contentContainer); if (iconType) { var 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 : 0x00ffff }); contentContainer.addChild(icon); } var labelText = new Text2("".concat(labelPrefix, " x").concat(upgrades[upgradeKey]), { size: 30, fill: 0xffffff }); labelText.anchor.set(0.5, 0); labelText.y = 100; button.addChild(labelText); var costText = new Text2('$' + (baseCost * upgrades[upgradeKey]).toString(), { size: 40, fill: 0x00ffff }); costText.anchor.set(0.5, 0); costText.y = 140; button.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; 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]; button.tint = isEnabled ? 0x00ffff : 0x666666; button.interactive = isEnabled; }; 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 = LK.getAsset('upgrade', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT - 100, tint: 0x00ffff }); var upgradeText = new Text2('UPGRADE', { size: 50, fill: 0xffffff }); upgradeText.anchor.set(0.5, 0.5); upgradeButton.addChild(upgradeText); upgradeButton.down = function () { powerupContainer.visible = !powerupContainer.visible; }; 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); } 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 hitpoints = config.hitpoints || 1; var gridSize = config.gridSize || 200; var pattern = config.pattern || 'grid'; var spacingX = 2; var spacingY = 2; brickGrid = {}; bricks = []; var cols = Math.floor(GAME_WIDTH / (BRICK_WIDTH + spacingX)); 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), hitpoints, gridSize); brickCount++; } } } else if (pattern === 'staggered') { for (var i = 0; i < rows && brickCount < totalBricks; i++) { var offsetX = i % 2 === 0 ? 0 : BRICK_WIDTH / 2; for (var j = 0; j < cols && brickCount < totalBricks; j++) { addBrick(startX + offsetX + j * (BRICK_WIDTH + spacingX), startY + i * (BRICK_HEIGHT + spacingY), hitpoints, gridSize); brickCount++; } } } else if (pattern === 'clustered') { var clusterCols = Math.floor(cols / 2); var clusterRows = Math.floor(rows / 2); var clusterStartX = GAME_WIDTH / 2 - clusterCols * BRICK_WIDTH / 2; var clusterStartY = GAME_HEIGHT / 3 - clusterRows * BRICK_HEIGHT / 2; for (var i = 0; i < clusterRows && brickCount < totalBricks; i++) { for (var j = 0; j < clusterCols && brickCount < totalBricks; j++) { addBrick(clusterStartX + j * (BRICK_WIDTH + spacingX), clusterStartY + i * (BRICK_HEIGHT + spacingY), hitpoints, gridSize); brickCount++; } } } else if (pattern === 'diagonal') { 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; // Add offset for better alignment addBrick(startX + i * stepX + offsetX, startY + i * stepY, hitpoints, gridSize); brickCount++; } } else if (pattern === 'sparse') { while (brickCount < totalBricks) { var x = startX + Math.floor(Math.random() * cols) * (BRICK_WIDTH + spacingX); var y = startY + Math.floor(Math.random() * rows) * (BRICK_HEIGHT + spacingY); if (!bricks.some(function (b) { return b.x === x && b.y === y; })) { addBrick(x, y, hitpoints, 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) { LK.showGameOver(); } else { level += 1; storage.level = level; levelTxt.setText('Level: ' + level); createBricks(); } } 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); score += upgrades.clickDamage; 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 gameTitle = new GameTitle(); gameTitle.x = GAME_WIDTH / 2; gameTitle.y = GAME_HEIGHT / 2 - 600; game.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 }); } }); function startGame() { startButton.destroy(); gameTitle.destroy(); resetButton.visible = false; upgradeButton.visible = true; hud.visible = true; createBricks(); 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) { LK.showGameOver(); } 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
@@ -135,34 +135,8 @@
onFinish: function onFinish() {
self.destroy();
}
});
- // Add enhanced particle effect
- var particleCount = 30;
- var explosionColors = LEVEL_COLORS; // Use LEVEL_COLORS for particle effect tints
- for (var i = 0; i < particleCount; i++) {
- var particle = new Star();
- particle.x = self.x;
- particle.y = self.y;
- particle.speed = Math.random() * 7 + 3;
- var angle = Math.random() * 2 * Math.PI; // Random angle for direction
- particle.direction = {
- x: Math.cos(angle),
- y: Math.sin(angle)
- };
- particle.tint = explosionColors[Math.floor(Math.random() * explosionColors.length)];
- game.addChild(particle);
- tween(particle, {
- alpha: 0,
- x: particle.x + particle.direction.x * 100,
- y: particle.y + particle.direction.y * 100
- }, {
- duration: 700,
- onFinish: function onFinish() {
- particle.destroy();
- }
- });
- }
} else {
self.healthText.setText(self.health.toString());
self.updateTint();
}
@@ -313,11 +287,11 @@
var BRICK_HEIGHT = 99;
var LEVEL_COLORS = [0xff00ff, 0x00ffff, 0xffff00, 0xff0066, 0x00ff99, 0xff33cc, 0x66ff33, 0xcc00ff, 0x33ffcc, 0xff3300];
var levelConfig = {
1: {
- totalBricks: 80,
+ totalBricks: 60,
hitpoints: 1,
- gridSize: 600,
+ gridSize: 400,
pattern: 'grid'
},
2: {
totalBricks: 50,