User prompt
Please fix the bug: 'c is not defined' in or related to this line: 'c;' Line Number: 336
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
upgrades cost are not reflecing the price they have, can you fix that
User prompt
increase in cost of upgrades should increase te same way the balls cost increase. make sure to update also the visual references and not only the logic
User prompt
for the cost of the upgrades, instead of just adding the original cost, make them duplicate their current cost
Code edit (1 edits merged)
Please save this source code
User prompt
powerups cost should be double each time, not 1.5. Make sure to udpate the price in the button as well.
User prompt
Can we also multiply that for the level of the upgrade. Say if the button was upgraded twice, its level 2, so do, 1.5 x 2
User prompt
Make sure the formula is used on every new price of the powerupda
User prompt
Make sure to also update the display of the cost in the powerup button with the new formula
User prompt
Lets change how the cost of powerups is calculated. Use this formula but make sure results have not decimals: baseCost * Math.pow(1.15, upgrades[upgradeKey])
Code edit (3 edits merged)
Please save this source code
User prompt
Update powerups cost by using this formula: baseCost * Math.pow(1.15, upgrades[upgradeKey])
Code edit (1 edits merged)
Please save this source code
User prompt
text inside teh clickupgrade button should be handled different that the rest of the powerups
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
OKay, so move click up50 pixxels and remove the damage next to it since we have it below now
User prompt
Can we should the clickdamage belwo the cick text here: createUpgradeButton('Click', startX + 8 * (buttonWidth + spacing), 'clickCost', 'clickDamage', 25, null, null);
User prompt
Please fix the bug: 'Uncaught ReferenceError: labelText is not defined' in or related to this line: 'labelText.fill = isEnabled ? 0x000000 : 0x666666; // Grey out label text when disabled' Line Number: 1065
User prompt
clisck powerup button, should have 3 rows: 1: Click text 2: Power up level 3: Powe up cost
User prompt
increse the size of the font on the ball powerups button
User prompt
add a little more space between the upgrade buttons, but make sure they are still in the screen
User prompt
For text in upgrades us SPD instead of Speed, and DMG instead of Power.
/**** * 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.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; // Smaller steps to prevent tunneling 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; // Move and check collisions in sub-steps var nextX = self.x + dx; var nextY = self.y + dy; // Wall collisions 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(); } // Brick collisions 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; // AABB overlap check if (ballLeft < brickRight && ballRight > brickLeft && ballTop < brickBottom && ballBottom > brickTop) { // Determine collision side 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); 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; // Only handle one collision per sub-step } } self.x = nextX; self.y = nextY; if (collided) { break; } // Stop sub-stepping after a collision } // Normalize velocity 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 }); 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(); }; }); 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('UPGRADES', { size: 50, fill: 0x000000, fontWeight: 'bold' }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.interactive = true; self.down = function () { LK.getSound('click').play(); powerupContainer.visible = !powerupContainer.visible; }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ 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); 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; }); 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); var gameTitle = new GameTitle(); gameTitle.x = GAME_WIDTH / 2; gameTitle.y = congratsText.y - 400; 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('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); 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); var endGameButton = new Container(); var buttonGraphics = endGameButton.attachAsset('endGameButton', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ffff }); var buttonText = new Text2('RESTART!', { size: 50, fill: 0x000000, fontWeight: 'bold' }); buttonText.anchor.set(0.5, 0.5); endGameButton.addChild(buttonText); endGameButton.x = GAME_WIDTH / 2; endGameButton.y = GAME_HEIGHT - 240; endGameButton.interactive = true; endGameButton.down = function () { LK.showGameOver(); }; game.addChild(endGameButton); var resetButton = new ResetButton(); resetButton.x = GAME_WIDTH / 2; resetButton.y = endGameButton.y + 160; 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: 63, hitpoints: 2, pattern: 'clustered' }, 2: { totalBricks: 77, hitpoints: 3, pattern: 'clustered' }, 3: { totalBricks: 91, hitpoints: 6, pattern: 'staggered' }, 4: { totalBricks: 90, hitpoints: 10, pattern: 'cross' }, 5: { totalBricks: 96, hitpoints: 12, pattern: 'staggered' }, 6: { totalBricks: 112, hitpoints: 15, pattern: 'clustered' }, 7: { totalBricks: 112, hitpoints: 20, pattern: 'staggered' }, 8: { totalBricks: 112, hitpoints: 99, pattern: 'clustered' }, 9: { totalBricks: 112, hitpoints: 997, pattern: 'staggered' }, 10: { totalBricks: 112, hitpoints: 9998, pattern: 'clustered' } }; var upgrades = storage.upgrades || { normalSpeed: 1, normalPower: 1, splashSpeed: 1, splashPower: 2, sniperSpeed: 1, sniperPower: 1, scatterSpeed: 1, scatterPower: 1, clickDamage: 1, normalSpeedCost: 25, normalPowerCost: 50, splashSpeedCost: 75, splashPowerCost: 75, sniperSpeedCost: 100, sniperPowerCost: 100, scatterSpeedCost: 125, scatterPowerCost: 125, clickCost: 25, normalBallCost: 25, splashBallCost: 150, sniperBallCost: 500, scatterBallCost: 2000 }; var balls = []; var ballQuantities = storage.ballQuantities || { normal: 0, splash: 0, sniper: 0, scatter: 0 }; var bricks = []; var score = storage.score || 0; var level = storage.level || 1; var brickGridBounds = null; var unlockedTiers = storage.unlockedTiers || { normal: true, splash: false, sniper: false, scatter: false }; var playTime = storage.playTime || 0; var playTimeInterval = LK.setInterval(function () { if (!game.isGameOver) { playTime += 1; storage.playTime = playTime; console.log('Time Played2:', playTime, 'seconds'); } }, 1000); game.isGameOver = false; function clearLocalStorage() { storage.score = 0; storage.level = 1; storage.unlockedTiers = { normal: true, splash: false, sniper: false, scatter: false }; unlockedTiers = Object.assign({}, storage.unlockedTiers); storage.upgrades = { normalSpeed: 1, normalPower: 1, splashSpeed: 1, splashPower: 2, sniperSpeed: 1, sniperPower: 1, scatterSpeed: 1, scatterPower: 1, clickDamage: 1, normalSpeedCost: 50, normalPowerCost: 50, splashSpeedCost: 75, splashPowerCost: 75, sniperSpeedCost: 100, sniperPowerCost: 100, scatterSpeedCost: 125, scatterPowerCost: 125, clickCost: 25, normalBallCost: 25, splashBallCost: 150, sniperBallCost: 500, scatterBallCost: 2000 }; score = 0; storage.ballQuantities = { normal: 0, splash: 0, sniper: 0, scatter: 0 }; storage.firstLoad = false; ballQuantities = Object.assign({}, storage.ballQuantities); level = 1; unlockedTiers = Object.assign({}, storage.unlockedTiers); scoreTxt.setText('$' + score.toString()); levelTxt.setText('Level: ' + level); updateButtonStates(); } var hud = new Container(); LK.gui.top.addChild(hud); var scoreTxt = new Text2('$0', { size: 60, fill: 0x39ff14 }); scoreTxt.anchor.set(0.3, 0); scoreTxt.x += 570; hud.addChild(scoreTxt); var levelTxt = new Text2('Level: ' + level, { size: 50, fill: 0xffffff }); levelTxt.anchor.set(1, 0); levelTxt.x = scoreTxt.x + 100; levelTxt.y = scoreTxt.height + 10; hud.addChild(levelTxt); var ballButtons = {}; function createBallButton(type, x, cost, asset, prevTier) { var button = new Container(); var buttonGraphics = button.attachAsset('button', { anchorX: 0.5, anchorY: 0, tint: 0x1a1a2e }); button.y = 50; button.x = x + 20; var contentContainer = new Container(); button.addChild(contentContainer); var ballIcon = button.attachAsset('ball', { anchorX: 0.5, anchorY: -0.5, scaleX: 0.6, scaleY: 0.6, y: -10 }); ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff; contentContainer.addChild(ballIcon); var displayType = type === 'scatter' ? 'Multi' : type.charAt(0).toUpperCase() + type.slice(1); var typeText = new Text2(displayType, { size: 30, fill: 0xffffff, fontWeight: 'bold' }); typeText.anchor.set(0.5, 0); typeText.y = -50; button.addChild(typeText); var costText = new Text2('$' + upgrades[type + 'BallCost'], { size: 40, fill: 0xffffff }); costText.anchor.set(0.5, 0); costText.y = 100; button.addChild(costText); button.interactive = true; button.down = function () { if (score < upgrades[type + 'BallCost']) { return; } if (welcomeText && welcomeText.parent) { welcomeText.parent.removeChild(welcomeText); } score -= upgrades[type + 'BallCost']; scoreTxt.setText('$' + score.toString()); createBall(type); ballQuantities[type] = (ballQuantities[type] || 0) + 1; storage.ballQuantities = Object.assign({}, ballQuantities); upgrades[type + 'BallCost'] = Math.floor(upgrades[type + 'BallCost'] * 2); storage.upgrades = Object.assign({}, upgrades); costText.setText('$' + upgrades[type + 'BallCost']); if (!unlockedTiers[type]) { unlockedTiers[type] = true; storage.unlockedTiers = Object.assign({}, unlockedTiers); updateButtonStates(); } }; button.updateState = function () { var isEnabled = (prevTier ? unlockedTiers[prevTier] : true) && score >= upgrades[type + 'BallCost']; buttonGraphics.tint = isEnabled ? 0x00ffff : 0x666666; button.interactive = isEnabled; if (isEnabled) { ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff; typeText.fill = 0xffffff; costText.fill = 0x00ffff; } else { ballIcon.tint = 0x666666; typeText.fill = 0x666666; costText.fill = 0x666666; } }; hud.addChild(button); ballButtons[type] = button; } createBallButton('normal', -450, 25, 'ball', null); createBallButton('splash', -300, upgrades.splashBallCost, 'splashBall', 'normal'); createBallButton('sniper', -150, upgrades.sniperBallCost, 'sniperBall', 'splash'); createBallButton('scatter', 0, upgrades.scatterBallCost, 'scatterBall', 'sniper'); var clearStorageButton = LK.getAsset('button', { size: 0, fill: 0x1a1a2e, anchorX: 0.5, anchorY: 0, x: scoreTxt.width + 12000, y: 0 }); var clearStorageText = new Text2('', { size: 0, fill: 0xffffff }); clearStorageText.anchor.set(0.5, 0); clearStorageText.y = 100; clearStorageButton.addChild(clearStorageText); clearStorageButton.down = clearLocalStorage; hud.addChild(clearStorageButton); var powerupContainer = new Container(); powerupContainer.y = 1800; powerupContainer.visible = false; game.addChild(powerupContainer); var bottomHud = new Container(); bottomHud.y = GAME_HEIGHT - 200; game.addChild(bottomHud); var upgradeButtons = {}; function createUpgradeButton(labelPrefix, x, costKey, upgradeKey, baseCost, iconType, prevTier) { var button = new Container(); var buttonGraphics = button.attachAsset('powerupbutton', { anchorX: 0.5, anchorY: 0, tint: 0x1a1a2e }); button.x = x + 60; button.y = 350; button.addChild(buttonGraphics); var contentContainer = new Container(); button.addChild(contentContainer); var icon = null; if (iconType) { icon = button.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, y: 40, tint: iconType === 'splashBall' ? 0xff0066 : iconType === 'sniperBall' ? 0x00ff99 : iconType === 'scatterBall' ? 0xffff00 : iconType === 'ball' ? 0xffffff : 0x00ffff }); contentContainer.addChild(icon); } var labelText = new Text2("".concat(labelPrefix.replace('Speed', 'SPD').replace('Power', 'DMG'), " +").concat(upgrades[upgradeKey]), { size: upgradeKey === 'clickDamage' ? 40 : 40, fill: 0x000000, fontWeight: 'bold' }); labelText.anchor.set(0.5, 0); labelText.y = 80; contentContainer.addChild(labelText); var currentCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1); var costText = new Text2("$".concat(currentCost), { size: 40, fill: 0x000000 }); costText.anchor.set(0.5, 0); costText.y = 140; contentContainer.addChild(costText); button.interactive = true; button.down = function () { if (welcomeText && welcomeText.parent) { welcomeText.parent.removeChild(welcomeText); } var cost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1); var ballType = upgradeKey.split('Speed')[0].split('Power')[0]; if (upgradeKey === 'clickDamage') { if (score < cost) { return; } } else { if (!unlockedTiers[ballType] || score < cost) { return; } } score -= cost; LK.getSound('click').play(); upgrades[upgradeKey]++; storage.upgrades = Object.assign({}, upgrades); var newCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1); costText.setText("$".concat(newCost)); labelText.setText("".concat(labelPrefix, " +").concat(upgrades[upgradeKey])); scoreTxt.setText('$' + score.toString()); balls.forEach(function (b) { if (b.type === 'normal' && upgradeKey.includes('normal')) { b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey]; } else if (b.type === 'splash' && upgradeKey.includes('splash')) { b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey]; } else if (b.type === 'sniper' && upgradeKey.includes('sniper')) { b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey]; } else if ((b.type === 'scatter' || b.type === 'smallScatter') && upgradeKey.includes('scatter')) { b[upgradeKey.includes('Speed') ? 'speed' : 'power'] = upgrades[upgradeKey]; } }); if (upgradeKey === 'clickDamage') { upgrades.clickDamage = upgrades[upgradeKey]; storage.upgrades = Object.assign({}, upgrades); } updateButtonStates(); }; button.updateState = function () { var ballType = upgradeKey.split('Speed')[0].split('Power')[0]; var currentCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1); var isEnabled = upgradeKey === 'clickDamage' ? score >= currentCost : unlockedTiers[ballType] && (prevTier ? unlockedTiers[prevTier] : true) && score >= currentCost; buttonGraphics.tint = isEnabled ? 0x00ffff : 0x666666; button.interactive = isEnabled; if (icon) { icon.tint = isEnabled ? iconType === 'splashBall' ? 0xff0066 : iconType === 'sniperBall' ? 0x00ff99 : iconType === 'scatterBall' ? 0xffff00 : iconType === 'ball' ? 0xffffff : 0x00ffff : 0x666666; } labelText.fill = isEnabled ? 0x000000 : 0x666666; costText.fill = isEnabled ? 0x000000 : 0x666666; costText.setText("$".concat(currentCost)); }; powerupContainer.addChild(button); upgradeButtons[upgradeKey] = button; } var buttonWidth = 150; var spacing = 70; var totalButtons = 9; var totalWidth = totalButtons * buttonWidth + (totalButtons - 1) * spacing; var startX = (GAME_WIDTH - totalWidth) / 2; createUpgradeButton('Speed', startX, 'normalSpeedCost', 'normalSpeed', 25, 'ball', null); createUpgradeButton('Power', startX + (buttonWidth + spacing), 'normalPowerCost', 'normalPower', 50, 'ball', null); createUpgradeButton('Speed', startX + 2 * (buttonWidth + spacing), 'splashSpeedCost', 'splashSpeed', 75, 'splashBall', 'normal'); createUpgradeButton('Power', startX + 3 * (buttonWidth + spacing), 'splashPowerCost', 'splashPower', 75, 'splashBall', 'normal'); createUpgradeButton('Speed', startX + 4 * (buttonWidth + spacing), 'sniperSpeedCost', 'sniperSpeed', 100, 'sniperBall', 'splash'); createUpgradeButton('Power', startX + 5 * (buttonWidth + spacing), 'sniperPowerCost', 'sniperPower', 100, 'sniperBall', 'splash'); createUpgradeButton('Speed', startX + 6 * (buttonWidth + spacing), 'scatterSpeedCost', 'scatterSpeed', 125, 'scatterBall', 'sniper'); createUpgradeButton('Power', startX + 7 * (buttonWidth + spacing), 'scatterPowerCost', 'scatterPower', 125, 'scatterBall', 'sniper'); createUpgradeButton('Click', startX + 8 * (buttonWidth + spacing), 'clickCost', 'clickDamage', 25, null, null); var upgradeButton = new UpgradeButton(); upgradeButton.x = GAME_WIDTH / 2; upgradeButton.y = GAME_HEIGHT - 100; upgradeButton.visible = false; game.addChild(upgradeButton); game.setChildIndex(upgradeButton, game.children.length - 1); hud.visible = false; function updateButtonStates() { for (var type in ballButtons) { ballButtons[type].updateState(); } var canPurchaseAny = false; for (var key in upgradeButtons) { upgradeButtons[key].updateState(); if (upgradeButtons[key].interactive) { canPurchaseAny = true; } } upgradeButton.tint = canPurchaseAny ? 0x00ffff : 0x666666; upgradeButton.interactive = canPurchaseAny; } function applySplashDamage(brick) { var splashDamage = Math.floor(upgrades.splashPower / 2); var horizontalMaxDistance = BRICK_WIDTH + 15; var verticalMaxDistance = BRICK_HEIGHT + 15; bricks.forEach(function (adjBrick) { if (adjBrick === brick || adjBrick.health <= 0) { return; } var dx = Math.abs(adjBrick.x - brick.x); var dy = Math.abs(adjBrick.y - brick.y); var isHorizontalAdjacent = dx <= horizontalMaxDistance && dy <= BRICK_HEIGHT / 2; var isVerticalAdjacent = dy <= verticalMaxDistance && dx <= BRICK_WIDTH / 2; if (isHorizontalAdjacent || isVerticalAdjacent) { adjBrick.hit(splashDamage); } }); } 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.velocity.x = Math.cos(angle); smallBall.velocity.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 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); // Create thick vertical section (5 columns wide) 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) { // Stay within bounds 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++; } } } // Create thick horizontal section (5 rows wide) with extended sides for (var j = 0; j < cols && brickCount < totalBricks; j++) { if (Math.abs(j - centerCol) > 2) { // Skip the vertical section to avoid duplicates for (var rowOffset = -2; rowOffset <= 2 && brickCount < totalBricks; rowOffset++) { var row = centerRow + rowOffset; if (row >= 0 && row < rows) { // Stay within bounds 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++; } } } } // Add extra side extensions to horizontal arms for (var j = 0; j < cols && brickCount < totalBricks; j++) { if (Math.abs(j - centerCol) > 3) { // Extend beyond the main horizontal section 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++; } } } } } brickGridBounds = { minX: Math.min.apply(Math, _toConsumableArray(bricks.map(function (b) { return b.x - BRICK_WIDTH / 2; }))), maxX: Math.max.apply(Math, _toConsumableArray(bricks.map(function (b) { return b.x + BRICK_WIDTH / 2; }))), minY: Math.min.apply(Math, _toConsumableArray(bricks.map(function (b) { return b.y - BRICK_HEIGHT / 2; }))), maxY: Math.max.apply(Math, _toConsumableArray(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 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; var spawnFromTop = balls.length % 2 === 0; ball.x = GAME_WIDTH / 2 + (Math.random() * 200 - 100); ball.y = spawnFromTop ? BALL_RADIUS : GAME_HEIGHT - BALL_RADIUS; 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; 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(); balls.forEach(function (ball, index) { ball.x = GAME_WIDTH / 2 + (Math.random() * 200 - 100); ball.y = index % 2 === 0 ? BALL_RADIUS : GAME_HEIGHT - BALL_RADIUS; var angle = (Math.random() * 0.5 + 0.25) * Math.PI; ball.velocity.x = Math.cos(angle); ball.velocity.y = index % 2 === 0 ? 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; }); } } 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 - 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(); createBall('normal'); if (score > 0) { scoreTxt.setText('$' + score.toString()); } if (storage.firstLoad !== true) { welcomeText = new Text2('Welcome! Click to cash in and power up!', { size: 90, fill: 0xffffff }); welcomeText.anchor.set(0.5, 0); welcomeText.x = GAME_WIDTH / 2; welcomeText.y = GAME_HEIGHT / 2 + 650; game.addChild(welcomeText); storage.firstLoad = true; } playTimeInterval = LK.setInterval(function () { playTime += 1; console.log('Time Played:', playTime, 'seconds'); }, 1000); for (var type in ballQuantities) { for (var i = 0; i < ballQuantities[type]; i++) { createBall(type); } } updateButtonStates(); game.update = function () { for (var i = 0; i < stars.length; i++) { stars[i].update(); } for (var i = balls.length - 1; i >= 0; i--) { var ball = balls[i]; ball.update(); if (ball.y > GAME_HEIGHT + BALL_RADIUS) { ball.destroy(); balls.splice(i, 1); } } if (bricks.length === 0) { 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
@@ -17,161 +17,139 @@
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 = {
+ 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.direction.x = Math.cos(angle);
- self.direction.y = Math.sin(angle);
- var magnitude = Math.sqrt(self.direction.x * self.direction.x + self.direction.y * self.direction.y);
- self.direction.x /= magnitude;
- self.direction.y /= magnitude;
+ 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 gridSize = levelConfig[level] ? levelConfig[level].gridSize : 200;
- var stepSize = self.speed;
+ var SHIELD_BUFFER = 5;
+ var MAX_STEP = BALL_RADIUS / 2; // Smaller steps to prevent tunneling
+ 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.direction.x = dx / magnitude;
- self.direction.y = dy / magnitude;
+ self.velocity.x = dx / magnitude;
+ self.velocity.y = dy / magnitude;
self.sniperCooldown = self.sniperCooldownMax;
}
}
}
- var steps = Math.ceil(stepSize / BALL_RADIUS);
- var dx = self.direction.x * stepSize / steps;
- var dy = self.direction.y * stepSize / steps;
- var splashApplied = false;
for (var step = 0; step < steps; step++) {
- 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));
- self.direction.y += (Math.random() - 0.5) * 0.1;
+ var dx = self.velocity.x * stepDistance;
+ var dy = self.velocity.y * stepDistance;
+ // Move and check collisions in sub-steps
+ var nextX = self.x + dx;
+ var nextY = self.y + dy;
+ // Wall collisions
+ 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 (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));
- self.direction.x += (Math.random() - 0.5) * 0.1;
+ 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();
}
- if (!isNearBricks(self.x, self.y)) {
- continue;
- }
- 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;
- var firstHitBrick = null;
- 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;
+ // Brick collisions
+ 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;
+ // AABB overlap check
+ if (ballLeft < brickRight && ballRight > brickLeft && ballTop < brickBottom && ballBottom > brickTop) {
+ // Determine collision side
+ 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;
}
- for (var j = cellBricks.length - 1; j >= 0; j--) {
- var brick = cellBricks[j];
- if (!brick || brick.health <= 0) {
- continue;
- }
- var collision = checkCollision(self, brick);
- if (!collision) {
- continue;
- }
- resolveCollision(self, brick, collision);
- brick.hit(self.power);
- if (self.type === 'splash' && !splashApplied) {
- firstHitBrick = brick;
- applySplashDamage(firstHitBrick);
- splashApplied = true;
- } 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;
+ 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);
+ 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; // Only handle one collision per sub-step
}
}
- if (hasCollided) {
+ self.x = nextX;
+ self.y = nextY;
+ if (collided) {
break;
- }
+ } // Stop sub-stepping after a collision
}
- var magnitude = Math.sqrt(self.direction.x * self.direction.x + self.direction.y * self.direction.y);
+ // Normalize velocity
+ var magnitude = Math.sqrt(self.velocity.x * self.velocity.x + self.velocity.y * self.velocity.y);
if (magnitude > 0) {
- self.direction.x /= magnitude;
- self.direction.y /= magnitude;
+ self.velocity.x /= magnitude;
+ self.velocity.y /= magnitude;
}
};
- function checkCollision(ball, brick) {
- var closestX = Math.max(brick.x - BRICK_WIDTH / 2, Math.min(ball.x, brick.x + BRICK_WIDTH / 2));
- var closestY = Math.max(brick.y - BRICK_HEIGHT / 2, Math.min(ball.y, brick.y + BRICK_HEIGHT / 2));
- var dx = ball.x - closestX;
- var dy = ball.y - closestY;
- var distanceSquared = dx * dx + dy * dy;
- if (distanceSquared <= BALL_RADIUS * BALL_RADIUS) {
- var relX = ball.x - brick.x;
- var relY = ball.y - brick.y;
- var absX = Math.abs(relX);
- var absY = Math.abs(relY);
- var halfW = BRICK_WIDTH / 2 + BALL_RADIUS;
- var halfH = BRICK_HEIGHT / 2 + BALL_RADIUS;
- if (absX > halfW || absY > halfH) {
- return null;
- }
- if (absX / halfW > absY / halfH) {
- return {
- side: relX > 0 ? 'right' : 'left',
- normalX: relX > 0 ? 1 : -1,
- normalY: 0
- };
- } else {
- return {
- side: relY > 0 ? 'bottom' : 'top',
- normalX: 0,
- normalY: relY > 0 ? 1 : -1
- };
- }
- }
- return null;
- }
- function resolveCollision(ball, brick, collision) {
- var overlapX = BALL_RADIUS - Math.abs(ball.x - (brick.x + collision.normalX * BRICK_WIDTH / 2));
- var overlapY = BALL_RADIUS - Math.abs(ball.y - (brick.y + collision.normalY * BRICK_HEIGHT / 2));
- if (collision.normalX !== 0) {
- ball.x += collision.normalX * overlapX;
- ball.direction.x = -ball.direction.x;
- } else if (collision.normalY !== 0) {
- ball.y += collision.normalY * overlapY;
- ball.direction.y = -ball.direction.y;
- }
- ball.direction.x += (Math.random() - 0.5) * 0.2;
- ball.direction.y += (Math.random() - 0.5) * 0.2;
- LK.getSound('bounce').play();
- }
});
var Brick = Container.expand(function () {
var self = Container.call(this);
var brickGraphics = self.attachAsset('brick', {
@@ -186,31 +164,15 @@
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
+ var colorCount = baseColors.length;
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 lastDigit = self.health % 10;
var colorIndex = lastDigit === 0 ? 9 : lastDigit - 1;
brickGraphics.tint = baseColors[colorIndex];
}
};
@@ -281,9 +243,9 @@
LK.getSound('click').play();
clearLocalStorage();
playTime = 0;
storage.playTime = playTime;
- LK.showGameOver(); // Show game over when reset is pressed
+ LK.showGameOver();
};
});
var Star = Container.expand(function () {
var self = Container.call(this);
@@ -349,18 +311,46 @@
/****
* Game Code
****/
+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() {
- // This function will tint the end screen game title container
- // You can customize the tint logic here if needed
gameTitleContainer.children.forEach(function (child) {
- child.tint = 0xff33cc; // Example tint color
+ child.tint = 0xff33cc;
});
}
-// Create a frame around the screen using a custom 'frame' asset
-var frameThickness = 10; // Thickness of the frame
-// Top frame
+var frameThickness = 10;
var topFrame = new Container();
var topFrameGraphics = topFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
@@ -387,9 +377,8 @@
}
});
}
animateTopFrameTint();
-// Bottom frame
var bottomFrame = new Container();
var bottomFrameGraphics = bottomFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
@@ -416,9 +405,8 @@
}
});
}
animateBottomFrameTint();
-// Left frame
var leftFrame = new Container();
var leftFrameGraphics = leftFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
@@ -445,17 +433,16 @@
}
});
}
animateLeftFrameTint();
-// Right frame
var rightFrame = new Container();
var rightFrameGraphics = rightFrame.attachAsset('frame', {
anchorX: 0,
anchorY: 0,
width: frameThickness,
height: GAME_HEIGHT
});
-rightFrame.x = 2035;
+rightFrame.x = 2040;
rightFrame.y = 0;
game.addChild(rightFrame);
function animateRightFrameTint() {
tween(rightFrameGraphics, {
@@ -476,10 +463,9 @@
}
animateRightFrameTint();
var welcomeText = null;
function showEndScreen() {
- game.isGameOver = true; // Set the flag to indicate the end screen is up
- // Hide all game elements
+ game.isGameOver = true;
hud.visible = false;
powerupContainer.visible = false;
upgradeButton.visible = false;
balls.forEach(function (ball) {
@@ -495,9 +481,8 @@
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;
gameTitleContainer.addChild(gameTitle);
@@ -519,32 +504,29 @@
}
});
}
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
+ tint: 0x00ffff
});
var buttonText = new Text2('RESTART!', {
size: 50,
fill: 0x000000,
@@ -558,147 +540,70 @@
endGameButton.down = function () {
LK.showGameOver();
};
game.addChild(endGameButton);
- // Add reset button
var resetButton = new ResetButton();
resetButton.x = GAME_WIDTH / 2;
resetButton.y = endGameButton.y + 160;
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
+ playTimeInterval = 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 = 2720; // Adjusted to match bottom frame position
+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: 63,
hitpoints: 2,
- gridSize: 400,
pattern: 'clustered'
},
2: {
totalBricks: 77,
hitpoints: 3,
- gridSize: 400,
pattern: 'clustered'
},
3: {
totalBricks: 91,
hitpoints: 6,
- gridSize: 320,
pattern: 'staggered'
},
4: {
totalBricks: 90,
hitpoints: 10,
- gridSize: 500,
- pattern: 'clustered'
+ pattern: 'cross'
},
5: {
totalBricks: 96,
hitpoints: 12,
- gridSize: 240,
pattern: 'staggered'
},
6: {
totalBricks: 112,
hitpoints: 15,
- gridSize: 220,
pattern: 'clustered'
},
7: {
totalBricks: 112,
hitpoints: 20,
- gridSize: 200,
pattern: 'staggered'
},
8: {
totalBricks: 112,
hitpoints: 99,
- gridSize: 180,
pattern: 'clustered'
},
9: {
totalBricks: 112,
hitpoints: 997,
- gridSize: 160,
pattern: 'staggered'
},
10: {
totalBricks: 112,
hitpoints: 9998,
- gridSize: 140,
pattern: 'clustered'
}
};
var upgrades = storage.upgrades || {
@@ -711,32 +616,20 @@
scatterSpeed: 1,
scatterPower: 1,
clickDamage: 1,
normalSpeedCost: 25,
- // Base cost
normalPowerCost: 50,
- // Base cost
splashSpeedCost: 75,
- // Base cost
splashPowerCost: 75,
- // Base cost
sniperSpeedCost: 100,
- // Base cost
sniperPowerCost: 100,
- // Base cost
scatterSpeedCost: 125,
- // Base cost
scatterPowerCost: 125,
- // Base cost
clickCost: 25,
- // Base cost
normalBallCost: 25,
- // Base cost
splashBallCost: 150,
- // Base cost
sniperBallCost: 500,
- // Base cost
- scatterBallCost: 2000 // Base cost
+ scatterBallCost: 2000
};
var balls = [];
var ballQuantities = storage.ballQuantities || {
normal: 0,
@@ -744,9 +637,8 @@
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 || {
@@ -755,18 +647,16 @@
sniper: false,
scatter: false
};
var playTime = storage.playTime || 0;
-playTimeInterval = LK.setInterval(function () {
+var 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
+game.isGameOver = false;
function clearLocalStorage() {
storage.score = 0;
storage.level = 1;
storage.unlockedTiers = {
@@ -814,14 +704,13 @@
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: 0x39ff14 // Neon green color
+ fill: 0x39ff14
});
scoreTxt.anchor.set(0.3, 0);
scoreTxt.x += 570;
hud.addChild(scoreTxt);
@@ -851,24 +740,22 @@
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
+ 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,
- // 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']), {
+ var costText = new Text2('$' + upgrades[type + 'BallCost'], {
size: 40,
- fill: 0xffffff // Change to white color
+ fill: 0xffffff
});
costText.anchor.set(0.5, 0);
costText.y = 100;
button.addChild(costText);
@@ -876,9 +763,8 @@
button.down = function () {
if (score < upgrades[type + 'BallCost']) {
return;
}
- // Remove welcome message if it exists
if (welcomeText && welcomeText.parent) {
welcomeText.parent.removeChild(welcomeText);
}
score -= upgrades[type + 'BallCost'];
@@ -896,19 +782,18 @@
}
};
button.updateState = function () {
var isEnabled = (prevTier ? unlockedTiers[prevTier] : true) && score >= upgrades[type + 'BallCost'];
- buttonGraphics.tint = isEnabled ? 0x00ffff : 0x666666; // Button background tint
+ buttonGraphics.tint = isEnabled ? 0x00ffff : 0x666666;
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
+ ballIcon.tint = type === 'splash' ? 0xff0066 : type === 'sniper' ? 0x00ff99 : type === 'scatter' ? 0xffff00 : 0xffffff;
+ typeText.fill = 0xffffff;
+ costText.fill = 0x00ffff;
} else {
- ballIcon.tint = 0x666666; // Grey out ball icon
- typeText.fill = 0x666666; // Grey out ball name
- costText.fill = 0x666666; // Grey out price
+ ballIcon.tint = 0x666666;
+ typeText.fill = 0x666666;
+ costText.fill = 0x666666;
}
};
hud.addChild(button);
ballButtons[type] = button;
@@ -941,9 +826,8 @@
var bottomHud = new Container();
bottomHud.y = GAME_HEIGHT - 200;
game.addChild(bottomHud);
var upgradeButtons = {};
-// Modified createUpgradeButton function
function createUpgradeButton(labelPrefix, x, costKey, upgradeKey, baseCost, iconType, prevTier) {
var button = new Container();
var buttonGraphics = button.attachAsset('powerupbutton', {
anchorX: 0.5,
@@ -974,9 +858,8 @@
});
labelText.anchor.set(0.5, 0);
labelText.y = 80;
contentContainer.addChild(labelText);
- // Calculate current cost based on level (baseCost * 2^(level-1))
var currentCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1);
var costText = new Text2("$".concat(currentCost), {
size: 40,
fill: 0x000000
@@ -1003,14 +886,12 @@
score -= cost;
LK.getSound('click').play();
upgrades[upgradeKey]++;
storage.upgrades = Object.assign({}, upgrades);
- // Update cost to double for next purchase
var newCost = baseCost * Math.pow(2, upgrades[upgradeKey] - 1);
costText.setText("$".concat(newCost));
labelText.setText("".concat(labelPrefix, " +").concat(upgrades[upgradeKey]));
scoreTxt.setText('$' + score.toString());
- // Update existing balls
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')) {
@@ -1074,28 +955,23 @@
if (upgradeButtons[key].interactive) {
canPurchaseAny = true;
}
}
- upgradeButton.tint = canPurchaseAny ? 0x00ffff : 0x666666; // Grey out if no power-ups can be purchased
+ upgradeButton.tint = canPurchaseAny ? 0x00ffff : 0x666666;
upgradeButton.interactive = canPurchaseAny;
}
-function handleBallBrickCollision(ball, brick) {
- // No need for position/direction logic here; handled in Ball.update
- // Just handle special effects if needed
-}
function applySplashDamage(brick) {
var splashDamage = Math.floor(upgrades.splashPower / 2);
- // Maximum distance for "adjacent" - slightly more than brick width/height to account for spacing
- var maxDistance = Math.max(BRICK_WIDTH, BRICK_HEIGHT) + 5; // 15 accounts for your spacingX
+ 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);
- // Check if brick is immediately adjacent (horizontally or vertically touching)
- var isHorizontalAdjacent = dx <= maxDistance && dy <= BRICK_HEIGHT / 2;
- var isVerticalAdjacent = dy <= maxDistance && dx <= BRICK_WIDTH / 2;
+ var isHorizontalAdjacent = dx <= horizontalMaxDistance && dy <= BRICK_HEIGHT / 2;
+ var isVerticalAdjacent = dy <= verticalMaxDistance && dx <= BRICK_WIDTH / 2;
if (isHorizontalAdjacent || isVerticalAdjacent) {
adjBrick.hit(splashDamage);
}
});
@@ -1105,10 +981,10 @@
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);
+ smallBall.velocity.x = Math.cos(angle);
+ smallBall.velocity.y = Math.sin(angle);
balls.push(smallBall);
game.addChild(smallBall);
}
}
@@ -1125,26 +1001,17 @@
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 baseHitpoints = config.hitpoints || 1;
var pattern = config.pattern || 'grid';
- var spacingX = -15; // Reduced spacing between columns
+ var spacingX = -15;
var spacingY = 0;
- brickGrid = {};
bricks = [];
- var cols = 7; // Set to 7 columns
+ 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;
@@ -1152,39 +1019,33 @@
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);
+ addBrick(startX + j * (BRICK_WIDTH + spacingX), startY + i * (BRICK_HEIGHT + spacingY), baseHitpoints);
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
+ var centerRow = Math.floor(rows / 2);
+ var centerCol = Math.floor(cols / 2);
for (var i = 0; i < rows && brickCount < totalBricks; i++) {
- var offsetX = 0; // No offset for staggered grid
+ 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);
- // 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 maxDistance = Math.max(centerRow, centerCol);
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);
+ addBrick(x, y, hitpoints);
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);
@@ -1196,79 +1057,92 @@
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);
+ addBrick(x, y, hitpoints);
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);
+ } else if (pattern === 'cross') {
+ var centerRow = Math.floor(rows / 2);
+ var centerCol = Math.floor(cols / 2);
+ // Create thick vertical section (5 columns wide)
+ 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) {
+ // Stay within bounds
+ 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++;
}
}
}
+ // Create thick horizontal section (5 rows wide) with extended sides
+ for (var j = 0; j < cols && brickCount < totalBricks; j++) {
+ if (Math.abs(j - centerCol) > 2) {
+ // Skip the vertical section to avoid duplicates
+ for (var rowOffset = -2; rowOffset <= 2 && brickCount < totalBricks; rowOffset++) {
+ var row = centerRow + rowOffset;
+ if (row >= 0 && row < rows) {
+ // Stay within bounds
+ 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++;
+ }
+ }
+ }
+ }
+ // Add extra side extensions to horizontal arms
+ for (var j = 0; j < cols && brickCount < totalBricks; j++) {
+ if (Math.abs(j - centerCol) > 3) {
+ // Extend beyond the main horizontal section
+ 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++;
+ }
+ }
+ }
+ }
}
brickGridBounds = {
- minX: Math.min.apply(Math, _toConsumableArray2(bricks.map(function (b) {
+ minX: Math.min.apply(Math, _toConsumableArray(bricks.map(function (b) {
return b.x - BRICK_WIDTH / 2;
}))),
- maxX: Math.max.apply(Math, _toConsumableArray2(bricks.map(function (b) {
+ maxX: Math.max.apply(Math, _toConsumableArray(bricks.map(function (b) {
return b.x + BRICK_WIDTH / 2;
}))),
- minY: Math.min.apply(Math, _toConsumableArray2(bricks.map(function (b) {
+ minY: Math.min.apply(Math, _toConsumableArray(bricks.map(function (b) {
return b.y - BRICK_HEIGHT / 2;
}))),
- maxY: Math.max.apply(Math, _toConsumableArray2(bricks.map(function (b) {
+ maxY: Math.max.apply(Math, _toConsumableArray(bricks.map(function (b) {
return b.y + BRICK_HEIGHT / 2;
})))
};
}
-function addBrick(x, y, hitpoints, gridSize) {
+function addBrick(x, y, hitpoints) {
var brick = new Brick();
brick.x = x;
brick.y = y;
brick.health = hitpoints;
@@ -1276,41 +1150,22 @@
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;
var spawnFromTop = balls.length % 2 === 0;
ball.x = GAME_WIDTH / 2 + (Math.random() * 200 - 100);
ball.y = spawnFromTop ? BALL_RADIUS : GAME_HEIGHT - BALL_RADIUS;
- for (var i = 0; i < bricks.length; i++) {
- if (ball.intersects(bricks[i])) {
- ball.y = spawnFromTop ? BALL_RADIUS : GAME_HEIGHT - BALL_RADIUS;
- break;
- }
- }
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;
- }
- }
+ 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;
balls.push(ball);
game.addChild(ball);
}
game.update = function () {
@@ -1332,24 +1187,21 @@
level += 1;
storage.level = level;
levelTxt.setText('Level: ' + level);
createBricks();
- // Respawn balls from top or bottom
balls.forEach(function (ball, index) {
ball.x = GAME_WIDTH / 2 + (Math.random() * 200 - 100);
ball.y = index % 2 === 0 ? BALL_RADIUS : GAME_HEIGHT - BALL_RADIUS;
var angle = (Math.random() * 0.5 + 0.25) * Math.PI;
- ball.direction.x = Math.cos(angle);
- ball.direction.y = index % 2 === 0 ? Math.sin(angle) : -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;
+ ball.velocity.x = Math.cos(angle);
+ ball.velocity.y = index % 2 === 0 ? 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;
});
}
}
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;
@@ -1453,32 +1305,27 @@
resetButton.visible = false;
upgradeButton.visible = true;
hud.visible = true;
createBricks();
- createBall('normal'); // Add a normal ball to the game on start
+ createBall('normal');
if (score > 0) {
scoreTxt.setText('$' + score.toString());
}
- // Check if it's the first time the game is loaded
if (storage.firstLoad !== true) {
- // Display welcome message
welcomeText = new Text2('Welcome! Click to cash in and power up!', {
size: 90,
fill: 0xffffff
});
welcomeText.anchor.set(0.5, 0);
welcomeText.x = GAME_WIDTH / 2;
welcomeText.y = GAME_HEIGHT / 2 + 650;
game.addChild(welcomeText);
- // Set firstLoad to true to prevent showing the message again
storage.firstLoad = true;
}
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);
}