User prompt
Açık olan leveller yeşil değiller.
User prompt
Açık olan leveller yeşil kapalı olanlar kırmızı gözüksün
User prompt
Can logosu sağa çek yazının üzerine geliyor
User prompt
Anladım, tuğla kırma oyununuzdaki can sistemini geliştirmek ve bir level atlama (seviye ilerleme) sistemi eklemek istiyorsunuz. Yapay zekaya bu değişiklikleri şu şekilde açıklayabilirsiniz: "Tuğla kırma oyunundaki can sistemi şu şekilde güncellenecek: * Can sayısının (örneğin 'Lives: 3' yazısının) hemen yanında kalp şeklinde bir logo bulunacak. Bu logo, can sayısıyla birlikte oyun arayüzünde görünür olmalı. Oyunun seviye atlama sistemi ise şöyle çalışacak: * Bir leveldeki tüm tuğlalar kırıldığında, oyuncu otomatik olarak bir sonraki levele geçecek. * Level 30'a kadar bu sistemin çalışması gerekiyor (çünkü şu an toplam 30 level ile başlıyoruz). * Level menüsü, oyuncunun tamamladığı levelleri kaydedecek ve bir sonraki sefer oyuna girdiğinde, tamamlanmış levellere erişimini sağlayacak (kilitli olmayan leveller). Oyuncu sadece tamamladığı levelin bir sonrakini oynayabilecek. Örneğin, Level 1 tamamlandığında Level 2 açılacak. Tüm leveller tamamlandığında (şimdilik Level 30), oyuncuya bir 'Tebrikler' mesajı gösterilebilir veya oyun tekrar en baştan başlatılabilir." ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Level'ı seçince Level'ı seçince Level'ın açılmaması hatası var
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'levelIndex')' in or related to this line: 'var levelToStart = self.currentPage * self.levelsPerPage + obj.parent.levelIndex + 1;' Line Number: 100
User prompt
Anladım. Tuğla kırma oyununuzun başlangıç ekranının bir level (seviye) seçme menüsü olmasını ve bu menünün sayfalar halinde ilerlemesini istiyorsunuz. Her sayfada 15 level gösterilecek ve sağdaki/soldaki tuşlarla diğer 15 level'lık sayfalara geçiş yapılabilecek. Şimdilik 30 level ile (iki sayfa) başlanacak, ancak gelecekte 100'e kadar çıkma potansiyeli olacak. Yapay zekaya bu yeni menü sistemini şu şekilde anlatabilirsiniz: "Tuğla kırma oyunu, doğrudan ilk levele başlamak yerine, bir level seçme menüsüyle açılacak. Bu menüde leveller sayfalar halinde gösterilecek. * Her sayfada 15 level bulunacak. * Menünün sağında ve solunda sayfa değiştirme tuşları (ok işaretleri gibi) olacak. * Sağdaki tuşa tıklandığında sonraki 15 level (örn: 16-30 arası) gösterilecek. * Soldaki tuşa tıklandığında önceki 15 level (örn: 1-15 arası) gösterilecek. * Başlangıçta toplam 30 level olacak, yani menüde 2 sayfa bulunacak (1-15 ve 16-30). * Her level kutucuğuna tıklandığında o level başlayacak. * Levellerin kilitli/açık durumu gösterilecek (örn: sadece tamamlanan leveller bir sonraki leveli açacak). * Menüde 'Geri' veya 'Ana Menü' gibi bir kapatma düğmesi de bulunabilir." ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Tuğla kırma oyununuzdaki öğelerin boyutlarını ve topun hızını artırmak için yapay zekaya verebileceğiniz talimatlar madde madde şu şekildedir: * Tuğlaların boyutunu %50 artırın. * Oyuncunun kontrol ettiği platformun (kürek) genişliğini %30 artırın. * Oyuncunun kontrol ettiği platformun (kürek) yüksekliğini %20 artırın. * Topun çapını %40 artırın. * Topun hareket hızını 2 katına çıkarın.
Code edit (1 edits merged)
Please save this source code
User prompt
Brick Breaker Blitz
Initial prompt
Bir tuğla kırma oyununu yapay zekaya kısaca ve anlaşılır biçimde şöyle anlatabiliriz: "Bu bir tuğla kırma oyunu. Amacı, oyuncunun alttaki küreği kontrol ederek bir topu sektirmesi ve bu topun yukarıdaki renkli tuğlaları kırmasını sağlamasıdır. Tüm tuğlalar kırıldığında seviye tamamlanır. Top aşağı düşerse can kaybedilir."
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 8; self.velocityY = -12; self.radius = 14; self.maxSpeed = 16; self.update = function () { // Don't move ball until it's launched if (!ballLaunched) return; // Limit ball speed to prevent it from becoming too fast var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY); if (currentSpeed > self.maxSpeed) { var ratio = self.maxSpeed / currentSpeed; self.velocityX *= ratio; self.velocityY *= ratio; } self.x += self.velocityX; self.y += self.velocityY; // Wall collision detection if (self.x - self.radius <= 0 || self.x + self.radius >= 2048) { self.velocityX = -self.velocityX; if (self.x - self.radius <= 0) self.x = self.radius; if (self.x + self.radius >= 2048) self.x = 2048 - self.radius; LK.getSound('hitWall').play(); } // Top wall collision if (self.y - self.radius <= 0) { self.velocityY = -self.velocityY; self.y = self.radius; LK.getSound('hitWall').play(); } }; return self; }); var Brick = Container.expand(function (brickType) { var self = Container.call(this); var assetName = brickType || 'brick'; var brickGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.width = 150; self.height = 45; self.destroyed = false; return self; }); var LevelMenu = Container.expand(function () { var self = Container.call(this); self.currentPage = 0; self.levelsPerPage = 15; self.totalLevels = 30; self.unlockedLevel = storage.unlockedLevel || 1; var levelButtons = []; var leftArrow = null; var rightArrow = null; var pageText = null; self.createMenu = function () { // Remove existing buttons before creating new ones if (self.languageButton) { self.removeChild(self.languageButton); self.languageButton.destroy(); self.languageButton = null; } if (self.settingsButton) { self.removeChild(self.settingsButton); self.settingsButton.destroy(); self.settingsButton = null; } if (levelButtons && levelButtons.length > 0) { for (var i = 0; i < levelButtons.length; i++) { if (levelButtons[i]) { self.removeChild(levelButtons[i]); levelButtons[i].destroy(); } } levelButtons = []; } if (leftArrow) { self.removeChild(leftArrow); leftArrow.destroy(); leftArrow = null; } if (rightArrow) { self.removeChild(rightArrow); rightArrow.destroy(); rightArrow = null; } if (pageText) { self.removeChild(pageText); pageText.destroy(); pageText = null; } // Create language switching button at the top var languageButton = new Container(); var languageBg = languageButton.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); languageBg.tint = 0x3498db; // Blue color for language button var languageText = new Text2(getText('language'), { size: 50, fill: 0xFFFFFF }); languageText.anchor.set(0.5, 0.5); languageButton.addChild(languageText); languageButton.x = 1024; // Center of screen languageButton.y = 300; // Top of screen languageButton.setText = function (text) { languageText.setText(text); }; languageButton.down = function (x, y, obj) { self.showLanguageMenu(); }; self.addChild(languageButton); self.languageButton = languageButton; // Create settings button to the left of Level 1 var settingsButton = new Container(); var settingsBg = settingsButton.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); settingsBg.tint = 0x95a5a6; // Gray color for settings var settingsText = new Text2(getText('settings'), { size: 45, fill: 0xFFFFFF }); settingsText.anchor.set(0.5, 0.5); settingsButton.addChild(settingsText); settingsButton.x = 200; // Position to the left of first level button with spacing settingsButton.y = 800; // Same Y as first row of level buttons settingsButton.setText = function (text) { settingsText.setText(text); }; settingsButton.down = function (x, y, obj) { self.showSettingsMenu(); }; self.addChild(settingsButton); self.settingsButton = settingsButton; // Create level buttons in 3 rows of 5 for (var i = 0; i < self.levelsPerPage; i++) { var row = Math.floor(i / 5); var col = i % 5; var button = new Container(); var buttonBg = button.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5 }); var levelNum = new Text2('1', { size: 60, fill: 0xFFFFFF }); levelNum.anchor.set(0.5, 0.5); button.addChild(levelNum); // Calculate level number to determine if it's in the second page (16-30) var levelNumber = self.currentPage * self.levelsPerPage + i + 1; var extraSpacing = 0; if (levelNumber >= 16 && levelNumber <= 30) { // Add extra spacing for levels 16-30 to separate them from other buttons extraSpacing = 150; } button.x = 1024 + (col - 2) * (300 + extraSpacing); button.y = 800 + row * (200 + extraSpacing); button.levelIndex = i; button.levelText = levelNum; button.bg = buttonBg; button.down = function (x, y, obj) { var levelToStart = self.currentPage * self.levelsPerPage + this.levelIndex + 1; if (levelToStart <= self.unlockedLevel) { self.startLevel(levelToStart); } }; levelButtons.push(button); self.addChild(button); } // Create navigation arrows leftArrow = new Container(); var leftBg = leftArrow.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); var leftText = new Text2('<', { size: 120, fill: 0xFFFFFF }); leftText.anchor.set(0.5, 0.5); leftArrow.addChild(leftText); leftArrow.x = 300; leftArrow.y = 1000; leftArrow.down = function () { if (self.currentPage > 0) { self.currentPage--; self.updatePage(); } }; self.addChild(leftArrow); rightArrow = new Container(); var rightBg = rightArrow.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); var rightText = new Text2('>', { size: 120, fill: 0xFFFFFF }); rightText.anchor.set(0.5, 0.5); rightArrow.addChild(rightText); rightArrow.x = 1748; rightArrow.y = 1000; rightArrow.down = function () { var maxPages = Math.ceil(self.totalLevels / self.levelsPerPage); if (self.currentPage < maxPages - 1) { self.currentPage++; self.updatePage(); } }; self.addChild(rightArrow); // Create page indicator pageText = new Text2('Page 1 / 2', { size: 80, fill: 0xFFFFFF }); pageText.anchor.set(0.5, 0.5); pageText.x = 1024; pageText.y = 1400; self.addChild(pageText); self.updatePage(); }; self.updatePage = function () { var maxPages = Math.ceil(self.totalLevels / self.levelsPerPage); for (var i = 0; i < levelButtons.length; i++) { var levelNum = self.currentPage * self.levelsPerPage + i + 1; var button = levelButtons[i]; if (levelNum <= self.totalLevels) { button.levelText.setText(levelNum.toString()); button.visible = true; // Set button color based on unlock status if (levelNum <= self.unlockedLevel) { button.bg.tint = 0x00ff00; // Green for unlocked } else { button.bg.tint = 0xff0000; // Red for locked } } else { button.visible = false; } } // Update page text pageText.setText(getText('page') + ' ' + (self.currentPage + 1) + ' / ' + maxPages); self.pageText = pageText; // Update arrow visibility leftArrow.visible = self.currentPage > 0; rightArrow.visible = self.currentPage < maxPages - 1; }; self.showLanguageMenu = function () { // Create language selection overlay var overlay = new Container(); var overlayBg = overlay.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 20 }); overlayBg.tint = 0x2c3e50; overlayBg.alpha = 0.9; overlay.x = 1024; overlay.y = 1366; // Turkish button var turkishBtn = new Container(); var turkishBg = turkishBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.0 }); turkishBg.tint = currentLanguage === 'tr' ? 0x27ae60 : 0x7f8c8d; var turkishText = new Text2(getText('turkish'), { size: 70, fill: 0xFFFFFF }); turkishText.anchor.set(0.5, 0.5); turkishBtn.addChild(turkishText); turkishBtn.x = 0; turkishBtn.y = -150; turkishBtn.down = function () { switchLanguage('tr'); self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(turkishBtn); // English button var englishBtn = new Container(); var englishBg = englishBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.0 }); englishBg.tint = currentLanguage === 'en' ? 0x27ae60 : 0x7f8c8d; var englishText = new Text2(getText('english'), { size: 70, fill: 0xFFFFFF }); englishText.anchor.set(0.5, 0.5); englishBtn.addChild(englishText); englishBtn.x = 0; englishBtn.y = 50; englishBtn.down = function () { switchLanguage('en'); self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(englishBtn); // Back button var backBtn = new Container(); var backBg = backBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.0 }); backBg.tint = 0x95a5a6; // Gray color for back button var backText = new Text2('←', { size: 80, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backBtn.addChild(backText); backBtn.x = 0; backBtn.y = 400; backBtn.down = function () { self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(backBtn); self.addChild(overlay); }; self.showSettingsMenu = function () { // Create settings overlay var overlay = new Container(); var overlayBg = overlay.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 20 }); overlayBg.tint = 0x2c3e50; overlayBg.alpha = 0.9; overlay.x = 1024; overlay.y = 1366; // Language button in settings var languageBtn = new Container(); var languageBg = languageBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.0 }); languageBg.tint = 0x3498db; // Blue color for language button var languageText = new Text2(getText('language'), { size: 70, fill: 0xFFFFFF }); languageText.anchor.set(0.5, 0.5); languageBtn.addChild(languageText); languageBtn.x = 0; languageBtn.y = -200; languageBtn.down = function () { self.removeChild(overlay); overlay.destroy(); self.showLanguageMenu(); }; overlay.addChild(languageBtn); // Close button var closeBtn = new Container(); var closeBg = closeBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.0 }); closeBg.tint = 0xe74c3c; var closeText = new Text2('X', { size: 70, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeBtn.addChild(closeText); closeBtn.x = 0; closeBtn.y = 0; closeBtn.down = function () { self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(closeBtn); // Back button var backBtn = new Container(); var backBg = backBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.0 }); backBg.tint = 0x95a5a6; // Gray color for back button var backText = new Text2('←', { size: 80, fill: 0xFFFFFF }); backText.anchor.set(0.5, 0.5); backBtn.addChild(backText); backBtn.x = 0; backBtn.y = 500; backBtn.down = function () { self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(backBtn); self.addChild(overlay); }; self.startLevel = function (levelNumber) { currentLevel = levelNumber; self.destroy(); startGame(); }; return self; }); var Paddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); self.width = 260; self.height = 24; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Reset all storage data to start fresh storage.unlockedLevel = 1; storage.language = 'tr'; // Language system var currentLanguage = storage.language || 'tr'; var texts = { tr: { settings: 'Ayarlar', language: 'Dil', english: 'İngilizce', turkish: 'Türkçe', score: 'Skor', lives: 'Can', page: 'Sayfa' }, en: { settings: 'Settings', language: 'Language', english: 'English', turkish: 'Turkish', score: 'Score', lives: 'Lives', page: 'Page' } }; function getText(key) { return texts[currentLanguage][key] || key; } function switchLanguage(newLanguage) { currentLanguage = newLanguage; storage.language = newLanguage; // Update all UI text elements updateLanguageTexts(); } function updateLanguageTexts() { if (levelMenu && levelMenu.languageButton) { levelMenu.languageButton.setText(getText('language')); } if (levelMenu && levelMenu.settingsButton) { levelMenu.settingsButton.setText(getText('settings')); } if (scoreTxt) { scoreTxt.setText(getText('score') + ': ' + LK.getScore()); } if (livesTxt) { livesTxt.setText(getText('lives') + ':'); } if (levelMenu && levelMenu.pageText) { var maxPages = Math.ceil(levelMenu.totalLevels / levelMenu.levelsPerPage); levelMenu.pageText.setText(getText('page') + ' ' + (levelMenu.currentPage + 1) + ' / ' + maxPages); } } var currentLevel = 1; var gameStarted = false; var ballLaunched = false; var levelMenu = null; var lives = 3; var heartIcons = []; var winTarget = null; // Initialize level menu first levelMenu = game.addChild(new LevelMenu()); levelMenu.createMenu(); var paddle = null; var ball = null; var bricks = []; var scoreTxt = null; var livesTxt = null; function startGame() { gameStarted = true; ballLaunched = false; // Remove old paddle if it exists if (paddle) { paddle.destroy(); paddle = null; } // Create paddle paddle = game.addChild(new Paddle()); paddle.x = 2048 / 2; paddle.y = 2600; // Remove old ball if it exists if (ball) { ball.destroy(); ball = null; } // Create ball ball = game.addChild(new Ball()); ball.x = 2048 / 2; ball.y = 2400; // Remove old win target if it exists if (winTarget) { winTarget.destroy(); winTarget = null; } // Create win target zone at the top winTarget = LK.getAsset('brickGreen', { anchorX: 0.5, anchorY: 0.5, scaleX: 9.1, scaleY: 0.5 }); winTarget.x = 2048 / 2; winTarget.y = 50; winTarget.tint = 0x00ff00; // Bright green color game.addChild(winTarget); // Remove old bricks if they exist for (var oldBrick = 0; oldBrick < bricks.length; oldBrick++) { if (bricks[oldBrick]) { bricks[oldBrick].destroy(); } } // Create bricks based on current level bricks = []; var brickColors = ['brick', 'brickBlue', 'brickGreen', 'brickYellow', 'brickPurple']; if (currentLevel === 1) { // Level 1: Standard rectangular layout var rows = 8; var cols = 18; var brickSpacingX = 165; var brickSpacingY = 60; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 200; for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var colorIndex = row % brickColors.length; var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } else if (currentLevel === 2) { // Level 2: Pyramid pattern like original Breakout var maxCols = 16; var brickSpacingX = 165; var brickSpacingY = 60; var startY = 200; for (var row = 0; row < 8; row++) { var colsInRow = maxCols - row; var startX = (2048 - (colsInRow - 1) * brickSpacingX) / 2; for (var col = 0; col < colsInRow; col++) { var colorIndex = row % brickColors.length; var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } else if (currentLevel === 3) { // Level 3: Diamond pattern inspired by classic Breakout var rows = 8; var cols = 14; var brickSpacingX = 165; var brickSpacingY = 60; var centerX = 2048 / 2; var startY = 200; for (var row = 0; row < rows; row++) { // Create diamond shape: wider in middle, narrower at top and bottom var bricksInRow; if (row <= 3) { bricksInRow = 4 + row * 2; // Growing: 4, 6, 8, 10 } else { bricksInRow = 4 + (7 - row) * 2; // Shrinking: 8, 6, 4, 2 } var startX = centerX - (bricksInRow - 1) * brickSpacingX / 2; for (var col = 0; col < bricksInRow; col++) { // Add some strategic gaps for challenge var skipBrick = false; // Create gaps in the middle rows for more interesting gameplay if (row >= 2 && row <= 5) { if (col === Math.floor(bricksInRow / 3) || col === Math.floor(bricksInRow * 2 / 3)) { skipBrick = true; } } if (!skipBrick) { // Use different colors for different sections var colorIndex; if (row <= 1) { colorIndex = 0; // Red at top } else if (row <= 3) { colorIndex = 1; // Blue } else if (row <= 5) { colorIndex = 2; // Green in middle } else { colorIndex = 3; // Yellow at bottom } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 4) { // Level 4: Classic Breakout fortress with walls and corridors var rows = 10; var cols = 16; var brickSpacingX = 165; var brickSpacingY = 55; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 180; for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Create fortress-like structure with strategic openings if (row >= 2 && row <= 7) { // Create vertical corridors every 4 columns if (col % 4 === 1 || col % 4 === 2) { // Leave gaps in middle rows for corridors if (row >= 4 && row <= 5) { skipBrick = true; } } // Create horizontal opening in the middle if (row === 5 && col >= 6 && col <= 9) { skipBrick = true; } // Create defensive walls on sides if ((col <= 2 || col >= cols - 3) && row >= 1 && row <= 8) { // Solid side walls with occasional gaps if (row === 3 || row === 6) { if (col === 1 || col === cols - 2) { skipBrick = true; // Small openings in walls } } } } if (!skipBrick) { // Color scheme like classic Breakout - different colors for different rows var colorIndex; if (row <= 1) { colorIndex = 0; // Red at top (hardest to reach) } else if (row <= 3) { colorIndex = 4; // Purple for fortress walls } else if (row <= 5) { colorIndex = 1; // Blue for middle section } else if (row <= 7) { colorIndex = 2; // Green for lower middle } else { colorIndex = 3; // Yellow at bottom (easiest to reach) } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 5) { // Level 5: Classic Breakout castle with towers and defensive structure var rows = 12; var cols = 15; var brickSpacingX = 170; var brickSpacingY = 50; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 150; for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Create castle-like structure with towers // Tower positions at columns 1, 7, 13 (left, center, right towers) var isTowerCol = col === 1 || col === 7 || col === 13; var isWallCol = col >= 3 && col <= 5 || col >= 9 && col <= 11; // Build tall towers if (isTowerCol) { // Towers are solid except for strategic openings if (row === 5 || row === 8) { // Small windows in towers skipBrick = true; } } else if (isWallCol) { // Connecting walls between towers if (row >= 4 && row <= 6) { // Leave gaps in middle section of walls for strategy if (row === 5) { skipBrick = true; } } else if (row >= 9) { // Lower walls are mostly solid skipBrick = false; } else { // Upper sections have some gaps if (row <= 2 && (col === 4 || col === 10)) { skipBrick = true; } } } else { // Areas between structures if (row >= 3 && row <= 8) { // Create strategic openings and passages if ((col === 0 || col === 14) && row >= 6) { // Side passages skipBrick = false; } else if (col >= 2 && col <= 6 && row >= 6 || col >= 8 && col <= 12 && row >= 6) { // Lower defensive walls skipBrick = false; } else { // Open areas for ball movement skipBrick = true; } } else if (row >= 9) { // Foundation level - mostly solid if (col % 3 === 1) { // Small gaps in foundation skipBrick = true; } } } if (!skipBrick) { // Color scheme inspired by castle architecture var colorIndex; if (row <= 2) { colorIndex = 0; // Red at top (castle peaks) } else if (isTowerCol) { if (row <= 6) { colorIndex = 4; // Purple for tower walls } else { colorIndex = 2; // Green for tower base } } else if (isWallCol) { colorIndex = 1; // Blue for connecting walls } else if (row >= 9) { colorIndex = 3; // Yellow for foundation } else { colorIndex = 2; // Green for general structure } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 6) { // Level 6: Classic Breakout-inspired spiral maze pattern var rows = 11; var cols = 17; var brickSpacingX = 160; var brickSpacingY = 55; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 170; var centerX = Math.floor(cols / 2); var centerY = Math.floor(rows / 2); for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Calculate distance from center for spiral effect var dx = col - centerX; var dy = row - centerY; var distance = Math.sqrt(dx * dx + dy * dy); // Create spiral pattern inspired by classic arcade design var angle = Math.atan2(dy, dx); var spiralRadius = distance + angle * 1.5; // Create the main spiral structure if (distance <= 1.5) { // Keep center mostly open with small obstacles if (row === centerY && col === centerX) { skipBrick = true; // Complete center open } else if (distance <= 1.2) { skipBrick = Math.random() > 0.3; // Some random gaps near center } } else if (distance <= 6) { // Create spiral arms with strategic gaps var spiralArm = Math.floor((angle + Math.PI) / (Math.PI / 3)); // 6 arms var armOffset = spiralRadius % 2; if (armOffset < 0.8) { // Create gaps in spiral for ball passages if ((row + col) % 3 === 0) { skipBrick = true; } } else if (armOffset > 1.5) { // Solid sections of spiral skipBrick = false; } else { // Transition areas - some gaps skipBrick = (row + col) % 4 === 0; } } else { // Outer perimeter - create defensive walls with strategic openings if (row === 0 || row === rows - 1) { // Top and bottom walls with gaps if (col % 4 === 1 || col % 4 === 2) { skipBrick = true; } } else if (col === 0 || col === cols - 1) { // Side walls with gaps if (row % 3 === 1) { skipBrick = true; } } else if (row === 1 || row === rows - 2) { // Inner perimeter walls if (col % 5 === 2 || col % 5 === 3) { skipBrick = true; } } else { // Outer field area - mostly open with some obstacles skipBrick = true; if ((row + col) % 6 === 0) { skipBrick = false; // Scattered obstacles } } } if (!skipBrick) { // Color scheme based on distance from center (classic arcade style) var colorIndex; if (distance <= 1.5) { colorIndex = 0; // Red for center core } else if (distance <= 3) { colorIndex = 4; // Purple for inner spiral } else if (distance <= 4.5) { colorIndex = 1; // Blue for middle spiral } else if (distance <= 6) { colorIndex = 2; // Green for outer spiral } else { colorIndex = 3; // Yellow for perimeter } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 7) { // Level 7: Classic Breakout-inspired honeycomb hexagonal pattern var rows = 10; var cols = 15; var brickSpacingX = 170; var brickSpacingY = 65; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 180; var centerX = Math.floor(cols / 2); var centerY = Math.floor(rows / 2); for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Calculate distance from center for hexagonal pattern var dx = col - centerX; var dy = row - centerY; var distance = Math.sqrt(dx * dx + dy * dy); // Offset alternating rows for honeycomb effect var offsetX = row % 2 * brickSpacingX * 0.5; // Create honeycomb hexagonal structure if (distance <= 2) { // Center hexagon - solid core with small opening if (row === centerY && col === centerX) { skipBrick = true; // Center opening } else if (distance <= 1.2) { skipBrick = false; // Inner hex ring } } else if (distance <= 4) { // Middle hexagonal rings with strategic gaps var hexRing = Math.floor(distance); var hexAngle = Math.atan2(dy, dx); var hexSector = Math.floor((hexAngle + Math.PI) / (Math.PI / 3)); // 6 sectors // Create hexagonal pattern with gaps at vertices if (hexRing === 2) { // First outer ring - gaps at hex vertices if (hexSector % 2 === 0 && (Math.abs(dx) === 2 || Math.abs(dy) === 2)) { skipBrick = true; } } else if (hexRing === 3) { // Second outer ring - alternating pattern if ((row + col) % 3 === 0) { skipBrick = true; } } } else if (distance <= 6) { // Outer defensive hex structure var outerHexAngle = Math.atan2(dy, dx); var outerSector = Math.floor((outerHexAngle + Math.PI) / (Math.PI / 3)); // Create outer hexagonal walls with strategic openings if (distance >= 5.5) { // Outer perimeter - gaps for ball entry if (outerSector === 1 || outerSector === 4) { // Top and bottom entry points if (row === 1 && col >= centerX - 1 && col <= centerX + 1) { skipBrick = true; } else if (row === rows - 2 && col >= centerX - 1 && col <= centerX + 1) { skipBrick = true; } } else if (outerSector === 0 || outerSector === 3) { // Side entry points if (col === 2 || col === cols - 3) { if (row >= centerY - 1 && row <= centerY + 1) { skipBrick = true; } } } } else { // Mid-outer ring - honeycomb cells var cellX = Math.floor((col - centerX + 6) / 3); var cellY = Math.floor((row - centerY + 5) / 3); if ((cellX + cellY) % 2 === 0) { // Create honeycomb cell walls if ((col - centerX) % 3 === 1 || (row - centerY) % 3 === 1) { skipBrick = true; } } } } else { // Outermost area - scattered defensive structures if (row === 0 || row === rows - 1 || col === 0 || col === cols - 1) { // Perimeter walls with regular gaps if ((row + col) % 4 === 0) { skipBrick = true; } } else { // Scattered outer obstacles if ((row + col) % 7 === 0) { skipBrick = false; } else { skipBrick = true; } } } if (!skipBrick) { // Color scheme based on hexagonal structure var colorIndex; if (distance <= 1.5) { colorIndex = 0; // Red for center core } else if (distance <= 2.5) { colorIndex = 4; // Purple for inner hex } else if (distance <= 4) { colorIndex = 1; // Blue for middle hex rings } else if (distance <= 5.5) { colorIndex = 2; // Green for outer hex structure } else { colorIndex = 3; // Yellow for perimeter } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX + offsetX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 8) { // Level 8: Classic Breakout-inspired cross/plus pattern with strategic chambers var rows = 12; var cols = 16; var brickSpacingX = 160; var brickSpacingY = 55; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 170; var centerX = Math.floor(cols / 2); var centerY = Math.floor(rows / 2); for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Calculate position relative to center var dx = Math.abs(col - centerX); var dy = Math.abs(row - centerY); // Create cross/plus pattern inspired by classic arcade design // Vertical arm of the cross var isVerticalArm = dx <= 2; // Horizontal arm of the cross var isHorizontalArm = dy <= 2; // Main cross structure if (isVerticalArm || isHorizontalArm) { // Center intersection - keep open for strategy if (dx <= 1 && dy <= 1) { skipBrick = true; // Central crossing } else if (isVerticalArm && !isHorizontalArm) { // Vertical arm - create strategic gaps if (row % 3 === 1) { skipBrick = true; // Regular gaps in vertical arm } } else if (isHorizontalArm && !isVerticalArm) { // Horizontal arm - create strategic gaps if (col % 3 === 1) { skipBrick = true; // Regular gaps in horizontal arm } } else { // Intersection areas - mostly solid with some gaps if ((row + col) % 4 === 0) { skipBrick = true; } } } else { // Outer chambers in the four quadrants var quadrantX = col < centerX ? 0 : 1; // Left=0, Right=1 var quadrantY = row < centerY ? 0 : 1; // Top=0, Bottom=1 // Create defensive structures in each quadrant if (dx >= 4 && dy >= 4) { // Corner fortresses - solid defensive structures if (quadrantX === 0 && quadrantY === 0 || quadrantX === 1 && quadrantY === 1) { // Top-left and bottom-right corners - fortress pattern if (dx >= 6 || dy >= 6) { // Outer fortress walls if ((row + col) % 3 !== 0) { skipBrick = false; } else { skipBrick = true; // Small gaps for ball entry } } else { // Inner fortress area - mostly open with obstacles if ((row + col) % 5 === 0) { skipBrick = false; // Scattered obstacles } else { skipBrick = true; } } } else { // Top-right and bottom-left corners - maze pattern if (dx >= 6 || dy >= 6) { // Outer maze walls with passages if (row % 2 === 0 && col % 3 === 0 || col % 2 === 0 && row % 3 === 0) { skipBrick = false; } else { skipBrick = true; } } else { // Inner maze area if ((row + col) % 4 === 2) { skipBrick = false; } else { skipBrick = true; } } } } else { // Transition zones between cross and corners if (dx === 3 || dy === 3) { // Boundary walls with strategic openings if ((row + col) % 4 === 0) { skipBrick = true; // Regular openings } } else { // Open areas for ball movement skipBrick = true; // Add some scattered obstacles if ((row + col) % 8 === 0) { skipBrick = false; } } } } if (!skipBrick) { // Color scheme based on cross structure var colorIndex; if (dx <= 1 && dy <= 1) { colorIndex = 0; // Red for center intersection } else if (isVerticalArm || isHorizontalArm) { if (dx <= 2 && dy <= 2) { colorIndex = 4; // Purple for cross intersection areas } else if (isVerticalArm) { colorIndex = 1; // Blue for vertical arm } else { colorIndex = 2; // Green for horizontal arm } } else if (dx >= 6 || dy >= 6) { colorIndex = 3; // Yellow for outer fortresses } else { colorIndex = 0; // Red for transition areas } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 9) { // Level 9: Classic Breakout-inspired target/bullseye pattern with concentric rings var rows = 11; var cols = 17; var brickSpacingX = 160; var brickSpacingY = 55; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 170; var centerX = Math.floor(cols / 2); var centerY = Math.floor(rows / 2); for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Calculate distance from center for concentric rings var dx = col - centerX; var dy = row - centerY; var distance = Math.sqrt(dx * dx + dy * dy); // Create bullseye/target pattern with concentric rings if (distance <= 1.5) { // Center bullseye - keep open for strategic targeting skipBrick = true; } else if (distance <= 2.5) { // First inner ring - solid with small gaps if ((row + col) % 6 === 0) { skipBrick = true; // Small targeting gaps } } else if (distance <= 3.5) { // Second ring - alternating pattern for visual distinction if ((row + col) % 3 === 1) { skipBrick = true; // Regular gaps for ball movement } } else if (distance <= 4.5) { // Third ring - mostly solid defensive ring if ((row + col) % 4 === 0) { skipBrick = true; // Strategic openings } } else if (distance <= 5.5) { // Fourth ring - outer defensive perimeter if ((row + col) % 5 === 0) { skipBrick = true; // Larger gaps for ball entry } } else if (distance <= 6.5) { // Fifth ring - sparse outer ring if ((row + col) % 2 === 0) { skipBrick = true; // Many gaps for easier access } } else { // Outer fortification - corner defensive structures // Create corner bastions inspired by classic arcade design var cornerDistance = Math.min(Math.min(dx, cols - 1 - dx), Math.min(dy, rows - 1 - dy)); if (cornerDistance <= 1) { // Corner walls with strategic openings if ((row === 0 || row === rows - 1) && col % 4 === 1) { skipBrick = true; // Top/bottom wall gaps } else if ((col === 0 || col === cols - 1) && row % 3 === 1) { skipBrick = true; // Side wall gaps } } else { // Open areas between corners and target skipBrick = true; // Add scattered obstacles for challenge if ((row + col) % 7 === 0) { skipBrick = false; // Random obstacles } } } if (!skipBrick) { // Color scheme based on target rings - classic arcade bullseye colors var colorIndex; if (distance <= 2.5) { colorIndex = 0; // Red for center target ring (highest value) } else if (distance <= 3.5) { colorIndex = 4; // Purple for second ring } else if (distance <= 4.5) { colorIndex = 1; // Blue for third ring } else if (distance <= 5.5) { colorIndex = 2; // Green for fourth ring } else if (distance <= 6.5) { colorIndex = 3; // Yellow for outer ring } else { colorIndex = 0; // Red for corner fortifications } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 10) { // Level 10: Classic Breakout-inspired infinity/figure-8 pattern var rows = 12; var cols = 18; var brickSpacingX = 155; var brickSpacingY = 55; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 160; var centerX = Math.floor(cols / 2); var centerY = Math.floor(rows / 2); for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Calculate position relative to center for infinity pattern var dx = col - centerX; var dy = row - centerY; var distance = Math.sqrt(dx * dx + dy * dy); // Create figure-8/infinity symbol pattern // Upper loop center var upperLoopCenterY = centerY - 3; var upperDx = col - centerX; var upperDy = row - upperLoopCenterY; var upperDistance = Math.sqrt(upperDx * upperDx + upperDy * upperDy); // Lower loop center var lowerLoopCenterY = centerY + 3; var lowerDx = col - centerX; var lowerDy = row - lowerLoopCenterY; var lowerDistance = Math.sqrt(lowerDx * lowerDx + lowerDy * lowerDy); // Central crossing area if (Math.abs(dx) <= 1 && Math.abs(dy) <= 1) { // Center intersection - keep mostly open skipBrick = true; } else if (upperDistance <= 3.5 && row <= centerY) { // Upper loop of infinity symbol if (upperDistance >= 1.5 && upperDistance <= 3.5) { // Create loop structure with strategic gaps var upperAngle = Math.atan2(upperDy, upperDx); var angleSector = Math.floor((upperAngle + Math.PI) / (Math.PI / 4)); // 8 sectors if (angleSector % 3 === 0) { skipBrick = true; // Gaps for ball movement } } else if (upperDistance < 1.5) { // Inner area of upper loop - mostly open skipBrick = true; } } else if (lowerDistance <= 3.5 && row >= centerY) { // Lower loop of infinity symbol if (lowerDistance >= 1.5 && lowerDistance <= 3.5) { // Create loop structure with strategic gaps var lowerAngle = Math.atan2(lowerDy, lowerDx); var angleSector = Math.floor((lowerAngle + Math.PI) / (Math.PI / 4)); // 8 sectors if (angleSector % 3 === 0) { skipBrick = true; // Gaps for ball movement } } else if (lowerDistance < 1.5) { // Inner area of lower loop - mostly open skipBrick = true; } } else if (Math.abs(dy) <= 2 && Math.abs(dx) >= 2 && Math.abs(dx) <= 4) { // Connecting bridge between loops if (Math.abs(dx) === 3 && Math.abs(dy) <= 1) { // Narrow bridge connection skipBrick = false; } else { // Side areas of bridge - some gaps if ((row + col) % 3 === 0) { skipBrick = true; } } } else if (distance <= 7) { // Outer defensive perimeter around infinity pattern if (distance >= 6) { // Outer ring - walls with strategic openings if (row === 0 || row === rows - 1) { // Top and bottom walls if (col % 5 === 0 || col % 5 === 1) { skipBrick = true; // Entry gaps } } else if (col === 0 || col === cols - 1) { // Side walls if (row % 4 === 0) { skipBrick = true; // Side entry gaps } } } else { // Mid-range defensive structures if ((row + col) % 4 === 0) { skipBrick = true; // Strategic openings } } } else { // Outermost corners - scattered defensive obstacles if ((row + col) % 6 === 0) { skipBrick = false; // Corner obstacles } else { skipBrick = true; } } if (!skipBrick) { // Color scheme based on infinity pattern structure var colorIndex; if (Math.abs(dx) <= 1 && Math.abs(dy) <= 1) { colorIndex = 0; // Red for center crossing } else if (upperDistance <= 3.5 && row <= centerY || lowerDistance <= 3.5 && row >= centerY) { // Color loops differently for visual distinction if (row <= centerY) { colorIndex = 4; // Purple for upper loop } else { colorIndex = 1; // Blue for lower loop } } else if (Math.abs(dy) <= 2 && Math.abs(dx) >= 2 && Math.abs(dx) <= 4) { colorIndex = 2; // Green for connecting bridge } else if (distance <= 6) { colorIndex = 3; // Yellow for mid-range defenses } else { colorIndex = 0; // Red for outer obstacles } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else if (currentLevel === 11) { // Level 11: Classic Breakout-inspired triangular fortress with defensive walls var rows = 13; var cols = 19; var brickSpacingX = 150; var brickSpacingY = 50; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 160; var centerX = Math.floor(cols / 2); for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var skipBrick = false; // Calculate distance from center for triangular pattern var dx = Math.abs(col - centerX); var dy = row; // Create triangular fortress pattern if (row <= 4) { // Top triangular section - solid defensive peak var maxColsForRow = Math.min(cols, 2 * row + 3); var triangleStart = centerX - Math.floor(maxColsForRow / 2); var triangleEnd = centerX + Math.floor(maxColsForRow / 2); if (col >= triangleStart && col <= triangleEnd) { // Inside triangle - create strategic gaps if (row === 2 && (col === centerX - 1 || col === centerX + 1)) { skipBrick = true; // Small gaps in upper section } else if (row === 4 && col === centerX) { skipBrick = true; // Central gap for targeting } } else { skipBrick = true; // Outside triangle bounds } } else if (row >= 5 && row <= 8) { // Middle fortress walls with strategic openings if (dx <= 8) { // Main fortress body if (dx >= 6) { // Side towers if (row === 6 || row === 7) { // Tower windows if (dx === 7) { skipBrick = true; } } } else if (dx >= 3 && dx <= 5) { // Inner defensive walls if (row === 6 && dx === 4) { skipBrick = true; // Gate opening } else if (row === 7 && (dx === 3 || dx === 5)) { skipBrick = true; // Side passages } } else if (dx <= 2) { // Central keep area if (row === 6 && dx === 1) { skipBrick = true; // Keep entrance } } } else { // Outside main fortress skipBrick = true; } } else if (row >= 9) { // Lower defensive perimeter if (dx <= 9) { // Foundation walls if (row >= 11) { // Lower foundation - mostly solid with small gaps if ((col + row) % 5 === 0) { skipBrick = true; // Drainage gaps } } else { // Mid foundation - strategic openings if (dx >= 7) { // Outer foundation walls if ((col + row) % 3 === 0) { skipBrick = true; // Regular gaps } } else if (dx >= 4) { // Inner foundation area if (row === 9 && (dx === 5 || dx === 6)) { skipBrick = true; // Main entrances } } else { // Central foundation if (row === 10 && dx <= 1) { skipBrick = true; // Central courtyard } } } } else { skipBrick = true; // Outside foundation } } if (!skipBrick) { // Color scheme based on fortress architecture var colorIndex; if (row <= 2) { colorIndex = 0; // Red for peak } else if (row <= 4) { colorIndex = 4; // Purple for upper triangle } else if (row <= 6) { colorIndex = 1; // Blue for main walls } else if (row <= 8) { colorIndex = 2; // Green for middle section } else if (row <= 10) { colorIndex = 3; // Yellow for lower walls } else { colorIndex = 0; // Red for foundation } var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } } else { // Default pattern for other levels var rows = Math.min(8, 5 + Math.floor(currentLevel / 5)); var cols = 18; var brickSpacingX = 165; var brickSpacingY = 60; var startX = (2048 - (cols - 1) * brickSpacingX) / 2; var startY = 200; for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var colorIndex = row % brickColors.length; var brick = new Brick(brickColors[colorIndex]); brick.x = startX + col * brickSpacingX; brick.y = startY + row * brickSpacingY; bricks.push(brick); game.addChild(brick); } } } // Remove old UI elements if they exist if (scoreTxt) { scoreTxt.destroy(); scoreTxt = null; } if (livesTxt) { livesTxt.destroy(); livesTxt = null; } // Create UI elements scoreTxt = new Text2(getText('score') + ': 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); livesTxt = new Text2(getText('lives') + ':', { size: 80, fill: 0xFFFFFF }); livesTxt.anchor.set(0, 0); livesTxt.x = -600; LK.gui.topRight.addChild(livesTxt); // Clear existing heart icons for (var hi = 0; hi < heartIcons.length; hi++) { if (heartIcons[hi]) heartIcons[hi].destroy(); } heartIcons = []; // Add heart icons based on remaining lives for (var h = 0; h < lives; h++) { var heartIcon = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); heartIcon.x = -350 + h * 80; heartIcon.y = 40; LK.gui.topRight.addChild(heartIcon); heartIcons.push(heartIcon); } // Reset game state lives = 3; if (currentLevel === 1) { LK.setScore(0); } } var dragNode = null; var lastBallY = 0; function handleMove(x, y, obj) { if (!gameStarted) return; if (dragNode) { // Launch ball on first paddle movement if (!ballLaunched) { ballLaunched = true; } dragNode.x = x; // Keep paddle within screen bounds if (dragNode.x < dragNode.width / 2) { dragNode.x = dragNode.width / 2; } if (dragNode.x > 2048 - dragNode.width / 2) { dragNode.x = 2048 - dragNode.width / 2; } } } game.move = handleMove; game.down = function (x, y, obj) { if (!gameStarted) return; // Launch ball on first touch if (!ballLaunched) { ballLaunched = true; } dragNode = paddle; handleMove(x, y, obj); }; game.up = function (x, y, obj) { if (!gameStarted) return; dragNode = null; }; function resetBall() { if (!ball) return; ball.x = 2048 / 2; ball.y = 2400; // Start with consistent angle like original Breakout ball.velocityX = (Math.random() > 0.5 ? 1 : -1) * 6; ball.velocityY = -12; ballLaunched = false; } function checkPaddleCollision() { if (!paddle || !ball) return; var paddleLeft = paddle.x - paddle.width / 2; var paddleRight = paddle.x + paddle.width / 2; var paddleTop = paddle.y - paddle.height / 2; var paddleBottom = paddle.y + paddle.height / 2; if (ball.x + ball.radius >= paddleLeft && ball.x - ball.radius <= paddleRight && ball.y + ball.radius >= paddleTop && ball.y - ball.radius <= paddleBottom && ball.velocityY > 0) { // Calculate hit position relative to paddle center (-1 to 1) var hitPos = (ball.x - paddle.x) / (paddle.width / 2); // Adjust ball velocity based on hit position with more realistic physics var speed = Math.sqrt(ball.velocityX * ball.velocityX + ball.velocityY * ball.velocityY); var angle = hitPos * Math.PI * 0.25; // Max 45 degree angle ball.velocityX = Math.sin(angle) * speed; ball.velocityY = -Math.cos(angle) * speed; // Position ball above paddle ball.y = paddleTop - ball.radius; LK.getSound('hitPaddle').play(); } } function checkBrickCollisions() { if (!ball) return; for (var i = bricks.length - 1; i >= 0; i--) { var brick = bricks[i]; if (brick.destroyed) continue; var brickLeft = brick.x - brick.width / 2; var brickRight = brick.x + brick.width / 2; var brickTop = brick.y - brick.height / 2; var brickBottom = brick.y + brick.height / 2; if (ball.x + ball.radius >= brickLeft && ball.x - ball.radius <= brickRight && ball.y + ball.radius >= brickTop && ball.y - ball.radius <= brickBottom) { // Determine collision side var overlapLeft = ball.x + ball.radius - brickLeft; var overlapRight = brickRight - (ball.x - ball.radius); var overlapTop = ball.y + ball.radius - brickTop; var overlapBottom = brickBottom - (ball.y - ball.radius); var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom); if (minOverlap === overlapTop || minOverlap === overlapBottom) { ball.velocityY = -ball.velocityY; } else { ball.velocityX = -ball.velocityX; } brick.destroyed = true; brick.destroy(); bricks.splice(i, 1); LK.setScore(LK.getScore() + 10); scoreTxt.setText(getText('score') + ': ' + LK.getScore()); LK.getSound('hitBrick').play(); // No automatic level progression when bricks are destroyed // Level progression now happens when ball reaches top break; } } } game.update = function () { if (!gameStarted || !ball) return; // Check if ball fell below paddle if (lastBallY <= 2732 && ball.y > 2732) { lives--; livesTxt.setText(getText('lives') + ':'); // Remove a heart icon when life is lost if (heartIcons.length > 0) { var heartToRemove = heartIcons.pop(); heartToRemove.destroy(); } if (lives <= 0) { LK.showGameOver(); } else { resetBall(); } } checkPaddleCollision(); checkBrickCollisions(); // Check if ball hits the win target zone if (winTarget && ball.intersects(winTarget)) { // Stop the game immediately gameStarted = false; ballLaunched = false; // Level completed by reaching top - unlock next level var unlockedLevel = storage.unlockedLevel || 1; if (currentLevel >= unlockedLevel && currentLevel < 30) { storage.unlockedLevel = currentLevel + 1; } // Create victory animation with multiple effects LK.effects.flashScreen(0x00ff00, 1000); // Green flash for victory // Animate the win target with a scaling effect tween(winTarget, { scaleX: 12, scaleY: 2, alpha: 0.3 }, { duration: 1000, easing: tween.bounceOut }); // Create victory overlay var victoryOverlay = new Container(); var overlayBg = victoryOverlay.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 20 }); overlayBg.tint = 0x2c3e50; overlayBg.alpha = 0.9; victoryOverlay.x = 1024; victoryOverlay.y = 1366; game.addChild(victoryOverlay); // Victory title with animation var victoryTitle = new Text2(currentLanguage === 'tr' ? 'KAZANDIN!' : 'YOU WIN!', { size: 150, fill: 0x00ff00 }); victoryTitle.anchor.set(0.5, 0.5); victoryTitle.x = 0; victoryTitle.y = -200; victoryTitle.alpha = 0; victoryOverlay.addChild(victoryTitle); // Animate victory title tween(victoryTitle, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 800, easing: tween.bounceOut }); // Level completion text var levelText = new Text2(currentLanguage === 'tr' ? 'Seviye ' + currentLevel + ' Tamamlandı!' : 'Level ' + currentLevel + ' Complete!', { size: 80, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.x = 0; levelText.y = -50; levelText.alpha = 0; victoryOverlay.addChild(levelText); // Animate level text with delay LK.setTimeout(function () { tween(levelText, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); }, 400); // Check if all levels completed if (currentLevel >= 30) { // Final victory - show you win LK.setTimeout(function () { LK.showYouWin(); }, 2000); } else { // Create next level button var nextLevelBtn = new Container(); var nextBg = nextLevelBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.0 }); nextBg.tint = 0x27ae60; // Green for next level var nextText = new Text2(currentLanguage === 'tr' ? 'Sonraki Seviye' : 'Next Level', { size: 60, fill: 0xFFFFFF }); nextText.anchor.set(0.5, 0.5); nextLevelBtn.addChild(nextText); nextLevelBtn.x = -200; nextLevelBtn.y = 150; nextLevelBtn.alpha = 0; nextLevelBtn.down = function () { // Progress to next level currentLevel++; // Clean up victory overlay victoryOverlay.destroy(); // Restart game with next level startGame(); }; victoryOverlay.addChild(nextLevelBtn); // Create menu button var menuBtn = new Container(); var menuBg = menuBtn.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.0 }); menuBg.tint = 0x3498db; // Blue for menu var menuText = new Text2(currentLanguage === 'tr' ? 'Menüye Dön' : 'Back to Menu', { size: 60, fill: 0xFFFFFF }); menuText.anchor.set(0.5, 0.5); menuBtn.addChild(menuText); menuBtn.x = 200; menuBtn.y = 150; menuBtn.alpha = 0; menuBtn.down = function () { // Return to menu gameStarted = false; // Clean up all game elements if (paddle) { paddle.destroy(); paddle = null; } if (ball) { ball.destroy(); ball = null; } if (winTarget) { game.removeChild(winTarget); winTarget.destroy(); winTarget = null; } for (var j = 0; j < bricks.length; j++) { if (bricks[j]) bricks[j].destroy(); } bricks = []; // Clear UI elements if (scoreTxt) { scoreTxt.destroy(); scoreTxt = null; } if (livesTxt) { livesTxt.destroy(); livesTxt = null; } for (var hi = 0; hi < heartIcons.length; hi++) { if (heartIcons[hi]) heartIcons[hi].destroy(); } heartIcons = []; LK.gui.topRight.removeChildren(); // Clean up victory overlay victoryOverlay.destroy(); // Show level menu levelMenu = game.addChild(new LevelMenu()); levelMenu.createMenu(); }; victoryOverlay.addChild(menuBtn); // Animate buttons with delay LK.setTimeout(function () { tween(nextLevelBtn, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); tween(menuBtn, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); }, 800); } return; } // Check if all bricks are destroyed for level progression (alternative win condition) var activeBricks = 0; for (var b = 0; b < bricks.length; b++) { if (!bricks[b].destroyed) { activeBricks++; } } if (activeBricks === 0) { // Level completed - unlock next level var unlockedLevel = storage.unlockedLevel || 1; if (currentLevel >= unlockedLevel && currentLevel < 30) { storage.unlockedLevel = currentLevel + 1; } // Add level completion visual effect LK.effects.flashScreen(0x00ff00, 500); // Green flash for level completion // Check if all levels completed if (currentLevel >= 30) { LK.showYouWin(); } else { // Show level transition message var levelCompleteText = new Text2('Level ' + currentLevel + ' Complete!', { size: 120, fill: 0xFFFFFF }); levelCompleteText.anchor.set(0.5, 0.5); levelCompleteText.x = 1024; levelCompleteText.y = 1366; game.addChild(levelCompleteText); // Auto-progress to next level currentLevel++; // Show next level message var nextLevelText = new Text2('Starting Level ' + currentLevel, { size: 100, fill: 0xFFFF00 }); nextLevelText.anchor.set(0.5, 0.5); nextLevelText.x = 1024; nextLevelText.y = 1500; game.addChild(nextLevelText); // Clear current game elements after delay LK.setTimeout(function () { // Remove transition texts levelCompleteText.destroy(); nextLevelText.destroy(); if (paddle) { paddle.destroy(); paddle = null; } if (ball) { ball.destroy(); ball = null; } for (var j = 0; j < bricks.length; j++) { if (bricks[j]) bricks[j].destroy(); } bricks = []; // Clear UI elements properly if (scoreTxt) { scoreTxt.destroy(); scoreTxt = null; } if (livesTxt) { livesTxt.destroy(); livesTxt = null; } // Clear heart icons for (var hi = 0; hi < heartIcons.length; hi++) { if (heartIcons[hi]) heartIcons[hi].destroy(); } heartIcons = []; // Clear all GUI elements to prevent orphaned references LK.gui.topRight.removeChildren(); // Start next level startGame(); }, 1500); return; } } lastBallY = ball.y; };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 8;
self.velocityY = -12;
self.radius = 14;
self.maxSpeed = 16;
self.update = function () {
// Don't move ball until it's launched
if (!ballLaunched) return;
// Limit ball speed to prevent it from becoming too fast
var currentSpeed = Math.sqrt(self.velocityX * self.velocityX + self.velocityY * self.velocityY);
if (currentSpeed > self.maxSpeed) {
var ratio = self.maxSpeed / currentSpeed;
self.velocityX *= ratio;
self.velocityY *= ratio;
}
self.x += self.velocityX;
self.y += self.velocityY;
// Wall collision detection
if (self.x - self.radius <= 0 || self.x + self.radius >= 2048) {
self.velocityX = -self.velocityX;
if (self.x - self.radius <= 0) self.x = self.radius;
if (self.x + self.radius >= 2048) self.x = 2048 - self.radius;
LK.getSound('hitWall').play();
}
// Top wall collision
if (self.y - self.radius <= 0) {
self.velocityY = -self.velocityY;
self.y = self.radius;
LK.getSound('hitWall').play();
}
};
return self;
});
var Brick = Container.expand(function (brickType) {
var self = Container.call(this);
var assetName = brickType || 'brick';
var brickGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.width = 150;
self.height = 45;
self.destroyed = false;
return self;
});
var LevelMenu = Container.expand(function () {
var self = Container.call(this);
self.currentPage = 0;
self.levelsPerPage = 15;
self.totalLevels = 30;
self.unlockedLevel = storage.unlockedLevel || 1;
var levelButtons = [];
var leftArrow = null;
var rightArrow = null;
var pageText = null;
self.createMenu = function () {
// Remove existing buttons before creating new ones
if (self.languageButton) {
self.removeChild(self.languageButton);
self.languageButton.destroy();
self.languageButton = null;
}
if (self.settingsButton) {
self.removeChild(self.settingsButton);
self.settingsButton.destroy();
self.settingsButton = null;
}
if (levelButtons && levelButtons.length > 0) {
for (var i = 0; i < levelButtons.length; i++) {
if (levelButtons[i]) {
self.removeChild(levelButtons[i]);
levelButtons[i].destroy();
}
}
levelButtons = [];
}
if (leftArrow) {
self.removeChild(leftArrow);
leftArrow.destroy();
leftArrow = null;
}
if (rightArrow) {
self.removeChild(rightArrow);
rightArrow.destroy();
rightArrow = null;
}
if (pageText) {
self.removeChild(pageText);
pageText.destroy();
pageText = null;
}
// Create language switching button at the top
var languageButton = new Container();
var languageBg = languageButton.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
languageBg.tint = 0x3498db; // Blue color for language button
var languageText = new Text2(getText('language'), {
size: 50,
fill: 0xFFFFFF
});
languageText.anchor.set(0.5, 0.5);
languageButton.addChild(languageText);
languageButton.x = 1024; // Center of screen
languageButton.y = 300; // Top of screen
languageButton.setText = function (text) {
languageText.setText(text);
};
languageButton.down = function (x, y, obj) {
self.showLanguageMenu();
};
self.addChild(languageButton);
self.languageButton = languageButton;
// Create settings button to the left of Level 1
var settingsButton = new Container();
var settingsBg = settingsButton.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
settingsBg.tint = 0x95a5a6; // Gray color for settings
var settingsText = new Text2(getText('settings'), {
size: 45,
fill: 0xFFFFFF
});
settingsText.anchor.set(0.5, 0.5);
settingsButton.addChild(settingsText);
settingsButton.x = 200; // Position to the left of first level button with spacing
settingsButton.y = 800; // Same Y as first row of level buttons
settingsButton.setText = function (text) {
settingsText.setText(text);
};
settingsButton.down = function (x, y, obj) {
self.showSettingsMenu();
};
self.addChild(settingsButton);
self.settingsButton = settingsButton;
// Create level buttons in 3 rows of 5
for (var i = 0; i < self.levelsPerPage; i++) {
var row = Math.floor(i / 5);
var col = i % 5;
var button = new Container();
var buttonBg = button.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5
});
var levelNum = new Text2('1', {
size: 60,
fill: 0xFFFFFF
});
levelNum.anchor.set(0.5, 0.5);
button.addChild(levelNum);
// Calculate level number to determine if it's in the second page (16-30)
var levelNumber = self.currentPage * self.levelsPerPage + i + 1;
var extraSpacing = 0;
if (levelNumber >= 16 && levelNumber <= 30) {
// Add extra spacing for levels 16-30 to separate them from other buttons
extraSpacing = 150;
}
button.x = 1024 + (col - 2) * (300 + extraSpacing);
button.y = 800 + row * (200 + extraSpacing);
button.levelIndex = i;
button.levelText = levelNum;
button.bg = buttonBg;
button.down = function (x, y, obj) {
var levelToStart = self.currentPage * self.levelsPerPage + this.levelIndex + 1;
if (levelToStart <= self.unlockedLevel) {
self.startLevel(levelToStart);
}
};
levelButtons.push(button);
self.addChild(button);
}
// Create navigation arrows
leftArrow = new Container();
var leftBg = leftArrow.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var leftText = new Text2('<', {
size: 120,
fill: 0xFFFFFF
});
leftText.anchor.set(0.5, 0.5);
leftArrow.addChild(leftText);
leftArrow.x = 300;
leftArrow.y = 1000;
leftArrow.down = function () {
if (self.currentPage > 0) {
self.currentPage--;
self.updatePage();
}
};
self.addChild(leftArrow);
rightArrow = new Container();
var rightBg = rightArrow.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
var rightText = new Text2('>', {
size: 120,
fill: 0xFFFFFF
});
rightText.anchor.set(0.5, 0.5);
rightArrow.addChild(rightText);
rightArrow.x = 1748;
rightArrow.y = 1000;
rightArrow.down = function () {
var maxPages = Math.ceil(self.totalLevels / self.levelsPerPage);
if (self.currentPage < maxPages - 1) {
self.currentPage++;
self.updatePage();
}
};
self.addChild(rightArrow);
// Create page indicator
pageText = new Text2('Page 1 / 2', {
size: 80,
fill: 0xFFFFFF
});
pageText.anchor.set(0.5, 0.5);
pageText.x = 1024;
pageText.y = 1400;
self.addChild(pageText);
self.updatePage();
};
self.updatePage = function () {
var maxPages = Math.ceil(self.totalLevels / self.levelsPerPage);
for (var i = 0; i < levelButtons.length; i++) {
var levelNum = self.currentPage * self.levelsPerPage + i + 1;
var button = levelButtons[i];
if (levelNum <= self.totalLevels) {
button.levelText.setText(levelNum.toString());
button.visible = true;
// Set button color based on unlock status
if (levelNum <= self.unlockedLevel) {
button.bg.tint = 0x00ff00; // Green for unlocked
} else {
button.bg.tint = 0xff0000; // Red for locked
}
} else {
button.visible = false;
}
}
// Update page text
pageText.setText(getText('page') + ' ' + (self.currentPage + 1) + ' / ' + maxPages);
self.pageText = pageText;
// Update arrow visibility
leftArrow.visible = self.currentPage > 0;
rightArrow.visible = self.currentPage < maxPages - 1;
};
self.showLanguageMenu = function () {
// Create language selection overlay
var overlay = new Container();
var overlayBg = overlay.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20
});
overlayBg.tint = 0x2c3e50;
overlayBg.alpha = 0.9;
overlay.x = 1024;
overlay.y = 1366;
// Turkish button
var turkishBtn = new Container();
var turkishBg = turkishBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0
});
turkishBg.tint = currentLanguage === 'tr' ? 0x27ae60 : 0x7f8c8d;
var turkishText = new Text2(getText('turkish'), {
size: 70,
fill: 0xFFFFFF
});
turkishText.anchor.set(0.5, 0.5);
turkishBtn.addChild(turkishText);
turkishBtn.x = 0;
turkishBtn.y = -150;
turkishBtn.down = function () {
switchLanguage('tr');
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(turkishBtn);
// English button
var englishBtn = new Container();
var englishBg = englishBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0
});
englishBg.tint = currentLanguage === 'en' ? 0x27ae60 : 0x7f8c8d;
var englishText = new Text2(getText('english'), {
size: 70,
fill: 0xFFFFFF
});
englishText.anchor.set(0.5, 0.5);
englishBtn.addChild(englishText);
englishBtn.x = 0;
englishBtn.y = 50;
englishBtn.down = function () {
switchLanguage('en');
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(englishBtn);
// Back button
var backBtn = new Container();
var backBg = backBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0
});
backBg.tint = 0x95a5a6; // Gray color for back button
var backText = new Text2('←', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backBtn.addChild(backText);
backBtn.x = 0;
backBtn.y = 400;
backBtn.down = function () {
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(backBtn);
self.addChild(overlay);
};
self.showSettingsMenu = function () {
// Create settings overlay
var overlay = new Container();
var overlayBg = overlay.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20
});
overlayBg.tint = 0x2c3e50;
overlayBg.alpha = 0.9;
overlay.x = 1024;
overlay.y = 1366;
// Language button in settings
var languageBtn = new Container();
var languageBg = languageBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0
});
languageBg.tint = 0x3498db; // Blue color for language button
var languageText = new Text2(getText('language'), {
size: 70,
fill: 0xFFFFFF
});
languageText.anchor.set(0.5, 0.5);
languageBtn.addChild(languageText);
languageBtn.x = 0;
languageBtn.y = -200;
languageBtn.down = function () {
self.removeChild(overlay);
overlay.destroy();
self.showLanguageMenu();
};
overlay.addChild(languageBtn);
// Close button
var closeBtn = new Container();
var closeBg = closeBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0
});
closeBg.tint = 0xe74c3c;
var closeText = new Text2('X', {
size: 70,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeText);
closeBtn.x = 0;
closeBtn.y = 0;
closeBtn.down = function () {
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(closeBtn);
// Back button
var backBtn = new Container();
var backBg = backBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0
});
backBg.tint = 0x95a5a6; // Gray color for back button
var backText = new Text2('←', {
size: 80,
fill: 0xFFFFFF
});
backText.anchor.set(0.5, 0.5);
backBtn.addChild(backText);
backBtn.x = 0;
backBtn.y = 500;
backBtn.down = function () {
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(backBtn);
self.addChild(overlay);
};
self.startLevel = function (levelNumber) {
currentLevel = levelNumber;
self.destroy();
startGame();
};
return self;
});
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = 260;
self.height = 24;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Reset all storage data to start fresh
storage.unlockedLevel = 1;
storage.language = 'tr';
// Language system
var currentLanguage = storage.language || 'tr';
var texts = {
tr: {
settings: 'Ayarlar',
language: 'Dil',
english: 'İngilizce',
turkish: 'Türkçe',
score: 'Skor',
lives: 'Can',
page: 'Sayfa'
},
en: {
settings: 'Settings',
language: 'Language',
english: 'English',
turkish: 'Turkish',
score: 'Score',
lives: 'Lives',
page: 'Page'
}
};
function getText(key) {
return texts[currentLanguage][key] || key;
}
function switchLanguage(newLanguage) {
currentLanguage = newLanguage;
storage.language = newLanguage;
// Update all UI text elements
updateLanguageTexts();
}
function updateLanguageTexts() {
if (levelMenu && levelMenu.languageButton) {
levelMenu.languageButton.setText(getText('language'));
}
if (levelMenu && levelMenu.settingsButton) {
levelMenu.settingsButton.setText(getText('settings'));
}
if (scoreTxt) {
scoreTxt.setText(getText('score') + ': ' + LK.getScore());
}
if (livesTxt) {
livesTxt.setText(getText('lives') + ':');
}
if (levelMenu && levelMenu.pageText) {
var maxPages = Math.ceil(levelMenu.totalLevels / levelMenu.levelsPerPage);
levelMenu.pageText.setText(getText('page') + ' ' + (levelMenu.currentPage + 1) + ' / ' + maxPages);
}
}
var currentLevel = 1;
var gameStarted = false;
var ballLaunched = false;
var levelMenu = null;
var lives = 3;
var heartIcons = [];
var winTarget = null;
// Initialize level menu first
levelMenu = game.addChild(new LevelMenu());
levelMenu.createMenu();
var paddle = null;
var ball = null;
var bricks = [];
var scoreTxt = null;
var livesTxt = null;
function startGame() {
gameStarted = true;
ballLaunched = false;
// Remove old paddle if it exists
if (paddle) {
paddle.destroy();
paddle = null;
}
// Create paddle
paddle = game.addChild(new Paddle());
paddle.x = 2048 / 2;
paddle.y = 2600;
// Remove old ball if it exists
if (ball) {
ball.destroy();
ball = null;
}
// Create ball
ball = game.addChild(new Ball());
ball.x = 2048 / 2;
ball.y = 2400;
// Remove old win target if it exists
if (winTarget) {
winTarget.destroy();
winTarget = null;
}
// Create win target zone at the top
winTarget = LK.getAsset('brickGreen', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 9.1,
scaleY: 0.5
});
winTarget.x = 2048 / 2;
winTarget.y = 50;
winTarget.tint = 0x00ff00; // Bright green color
game.addChild(winTarget);
// Remove old bricks if they exist
for (var oldBrick = 0; oldBrick < bricks.length; oldBrick++) {
if (bricks[oldBrick]) {
bricks[oldBrick].destroy();
}
}
// Create bricks based on current level
bricks = [];
var brickColors = ['brick', 'brickBlue', 'brickGreen', 'brickYellow', 'brickPurple'];
if (currentLevel === 1) {
// Level 1: Standard rectangular layout
var rows = 8;
var cols = 18;
var brickSpacingX = 165;
var brickSpacingY = 60;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 200;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var colorIndex = row % brickColors.length;
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
} else if (currentLevel === 2) {
// Level 2: Pyramid pattern like original Breakout
var maxCols = 16;
var brickSpacingX = 165;
var brickSpacingY = 60;
var startY = 200;
for (var row = 0; row < 8; row++) {
var colsInRow = maxCols - row;
var startX = (2048 - (colsInRow - 1) * brickSpacingX) / 2;
for (var col = 0; col < colsInRow; col++) {
var colorIndex = row % brickColors.length;
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
} else if (currentLevel === 3) {
// Level 3: Diamond pattern inspired by classic Breakout
var rows = 8;
var cols = 14;
var brickSpacingX = 165;
var brickSpacingY = 60;
var centerX = 2048 / 2;
var startY = 200;
for (var row = 0; row < rows; row++) {
// Create diamond shape: wider in middle, narrower at top and bottom
var bricksInRow;
if (row <= 3) {
bricksInRow = 4 + row * 2; // Growing: 4, 6, 8, 10
} else {
bricksInRow = 4 + (7 - row) * 2; // Shrinking: 8, 6, 4, 2
}
var startX = centerX - (bricksInRow - 1) * brickSpacingX / 2;
for (var col = 0; col < bricksInRow; col++) {
// Add some strategic gaps for challenge
var skipBrick = false;
// Create gaps in the middle rows for more interesting gameplay
if (row >= 2 && row <= 5) {
if (col === Math.floor(bricksInRow / 3) || col === Math.floor(bricksInRow * 2 / 3)) {
skipBrick = true;
}
}
if (!skipBrick) {
// Use different colors for different sections
var colorIndex;
if (row <= 1) {
colorIndex = 0; // Red at top
} else if (row <= 3) {
colorIndex = 1; // Blue
} else if (row <= 5) {
colorIndex = 2; // Green in middle
} else {
colorIndex = 3; // Yellow at bottom
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 4) {
// Level 4: Classic Breakout fortress with walls and corridors
var rows = 10;
var cols = 16;
var brickSpacingX = 165;
var brickSpacingY = 55;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 180;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Create fortress-like structure with strategic openings
if (row >= 2 && row <= 7) {
// Create vertical corridors every 4 columns
if (col % 4 === 1 || col % 4 === 2) {
// Leave gaps in middle rows for corridors
if (row >= 4 && row <= 5) {
skipBrick = true;
}
}
// Create horizontal opening in the middle
if (row === 5 && col >= 6 && col <= 9) {
skipBrick = true;
}
// Create defensive walls on sides
if ((col <= 2 || col >= cols - 3) && row >= 1 && row <= 8) {
// Solid side walls with occasional gaps
if (row === 3 || row === 6) {
if (col === 1 || col === cols - 2) {
skipBrick = true; // Small openings in walls
}
}
}
}
if (!skipBrick) {
// Color scheme like classic Breakout - different colors for different rows
var colorIndex;
if (row <= 1) {
colorIndex = 0; // Red at top (hardest to reach)
} else if (row <= 3) {
colorIndex = 4; // Purple for fortress walls
} else if (row <= 5) {
colorIndex = 1; // Blue for middle section
} else if (row <= 7) {
colorIndex = 2; // Green for lower middle
} else {
colorIndex = 3; // Yellow at bottom (easiest to reach)
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 5) {
// Level 5: Classic Breakout castle with towers and defensive structure
var rows = 12;
var cols = 15;
var brickSpacingX = 170;
var brickSpacingY = 50;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 150;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Create castle-like structure with towers
// Tower positions at columns 1, 7, 13 (left, center, right towers)
var isTowerCol = col === 1 || col === 7 || col === 13;
var isWallCol = col >= 3 && col <= 5 || col >= 9 && col <= 11;
// Build tall towers
if (isTowerCol) {
// Towers are solid except for strategic openings
if (row === 5 || row === 8) {
// Small windows in towers
skipBrick = true;
}
} else if (isWallCol) {
// Connecting walls between towers
if (row >= 4 && row <= 6) {
// Leave gaps in middle section of walls for strategy
if (row === 5) {
skipBrick = true;
}
} else if (row >= 9) {
// Lower walls are mostly solid
skipBrick = false;
} else {
// Upper sections have some gaps
if (row <= 2 && (col === 4 || col === 10)) {
skipBrick = true;
}
}
} else {
// Areas between structures
if (row >= 3 && row <= 8) {
// Create strategic openings and passages
if ((col === 0 || col === 14) && row >= 6) {
// Side passages
skipBrick = false;
} else if (col >= 2 && col <= 6 && row >= 6 || col >= 8 && col <= 12 && row >= 6) {
// Lower defensive walls
skipBrick = false;
} else {
// Open areas for ball movement
skipBrick = true;
}
} else if (row >= 9) {
// Foundation level - mostly solid
if (col % 3 === 1) {
// Small gaps in foundation
skipBrick = true;
}
}
}
if (!skipBrick) {
// Color scheme inspired by castle architecture
var colorIndex;
if (row <= 2) {
colorIndex = 0; // Red at top (castle peaks)
} else if (isTowerCol) {
if (row <= 6) {
colorIndex = 4; // Purple for tower walls
} else {
colorIndex = 2; // Green for tower base
}
} else if (isWallCol) {
colorIndex = 1; // Blue for connecting walls
} else if (row >= 9) {
colorIndex = 3; // Yellow for foundation
} else {
colorIndex = 2; // Green for general structure
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 6) {
// Level 6: Classic Breakout-inspired spiral maze pattern
var rows = 11;
var cols = 17;
var brickSpacingX = 160;
var brickSpacingY = 55;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 170;
var centerX = Math.floor(cols / 2);
var centerY = Math.floor(rows / 2);
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Calculate distance from center for spiral effect
var dx = col - centerX;
var dy = row - centerY;
var distance = Math.sqrt(dx * dx + dy * dy);
// Create spiral pattern inspired by classic arcade design
var angle = Math.atan2(dy, dx);
var spiralRadius = distance + angle * 1.5;
// Create the main spiral structure
if (distance <= 1.5) {
// Keep center mostly open with small obstacles
if (row === centerY && col === centerX) {
skipBrick = true; // Complete center open
} else if (distance <= 1.2) {
skipBrick = Math.random() > 0.3; // Some random gaps near center
}
} else if (distance <= 6) {
// Create spiral arms with strategic gaps
var spiralArm = Math.floor((angle + Math.PI) / (Math.PI / 3)); // 6 arms
var armOffset = spiralRadius % 2;
if (armOffset < 0.8) {
// Create gaps in spiral for ball passages
if ((row + col) % 3 === 0) {
skipBrick = true;
}
} else if (armOffset > 1.5) {
// Solid sections of spiral
skipBrick = false;
} else {
// Transition areas - some gaps
skipBrick = (row + col) % 4 === 0;
}
} else {
// Outer perimeter - create defensive walls with strategic openings
if (row === 0 || row === rows - 1) {
// Top and bottom walls with gaps
if (col % 4 === 1 || col % 4 === 2) {
skipBrick = true;
}
} else if (col === 0 || col === cols - 1) {
// Side walls with gaps
if (row % 3 === 1) {
skipBrick = true;
}
} else if (row === 1 || row === rows - 2) {
// Inner perimeter walls
if (col % 5 === 2 || col % 5 === 3) {
skipBrick = true;
}
} else {
// Outer field area - mostly open with some obstacles
skipBrick = true;
if ((row + col) % 6 === 0) {
skipBrick = false; // Scattered obstacles
}
}
}
if (!skipBrick) {
// Color scheme based on distance from center (classic arcade style)
var colorIndex;
if (distance <= 1.5) {
colorIndex = 0; // Red for center core
} else if (distance <= 3) {
colorIndex = 4; // Purple for inner spiral
} else if (distance <= 4.5) {
colorIndex = 1; // Blue for middle spiral
} else if (distance <= 6) {
colorIndex = 2; // Green for outer spiral
} else {
colorIndex = 3; // Yellow for perimeter
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 7) {
// Level 7: Classic Breakout-inspired honeycomb hexagonal pattern
var rows = 10;
var cols = 15;
var brickSpacingX = 170;
var brickSpacingY = 65;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 180;
var centerX = Math.floor(cols / 2);
var centerY = Math.floor(rows / 2);
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Calculate distance from center for hexagonal pattern
var dx = col - centerX;
var dy = row - centerY;
var distance = Math.sqrt(dx * dx + dy * dy);
// Offset alternating rows for honeycomb effect
var offsetX = row % 2 * brickSpacingX * 0.5;
// Create honeycomb hexagonal structure
if (distance <= 2) {
// Center hexagon - solid core with small opening
if (row === centerY && col === centerX) {
skipBrick = true; // Center opening
} else if (distance <= 1.2) {
skipBrick = false; // Inner hex ring
}
} else if (distance <= 4) {
// Middle hexagonal rings with strategic gaps
var hexRing = Math.floor(distance);
var hexAngle = Math.atan2(dy, dx);
var hexSector = Math.floor((hexAngle + Math.PI) / (Math.PI / 3)); // 6 sectors
// Create hexagonal pattern with gaps at vertices
if (hexRing === 2) {
// First outer ring - gaps at hex vertices
if (hexSector % 2 === 0 && (Math.abs(dx) === 2 || Math.abs(dy) === 2)) {
skipBrick = true;
}
} else if (hexRing === 3) {
// Second outer ring - alternating pattern
if ((row + col) % 3 === 0) {
skipBrick = true;
}
}
} else if (distance <= 6) {
// Outer defensive hex structure
var outerHexAngle = Math.atan2(dy, dx);
var outerSector = Math.floor((outerHexAngle + Math.PI) / (Math.PI / 3));
// Create outer hexagonal walls with strategic openings
if (distance >= 5.5) {
// Outer perimeter - gaps for ball entry
if (outerSector === 1 || outerSector === 4) {
// Top and bottom entry points
if (row === 1 && col >= centerX - 1 && col <= centerX + 1) {
skipBrick = true;
} else if (row === rows - 2 && col >= centerX - 1 && col <= centerX + 1) {
skipBrick = true;
}
} else if (outerSector === 0 || outerSector === 3) {
// Side entry points
if (col === 2 || col === cols - 3) {
if (row >= centerY - 1 && row <= centerY + 1) {
skipBrick = true;
}
}
}
} else {
// Mid-outer ring - honeycomb cells
var cellX = Math.floor((col - centerX + 6) / 3);
var cellY = Math.floor((row - centerY + 5) / 3);
if ((cellX + cellY) % 2 === 0) {
// Create honeycomb cell walls
if ((col - centerX) % 3 === 1 || (row - centerY) % 3 === 1) {
skipBrick = true;
}
}
}
} else {
// Outermost area - scattered defensive structures
if (row === 0 || row === rows - 1 || col === 0 || col === cols - 1) {
// Perimeter walls with regular gaps
if ((row + col) % 4 === 0) {
skipBrick = true;
}
} else {
// Scattered outer obstacles
if ((row + col) % 7 === 0) {
skipBrick = false;
} else {
skipBrick = true;
}
}
}
if (!skipBrick) {
// Color scheme based on hexagonal structure
var colorIndex;
if (distance <= 1.5) {
colorIndex = 0; // Red for center core
} else if (distance <= 2.5) {
colorIndex = 4; // Purple for inner hex
} else if (distance <= 4) {
colorIndex = 1; // Blue for middle hex rings
} else if (distance <= 5.5) {
colorIndex = 2; // Green for outer hex structure
} else {
colorIndex = 3; // Yellow for perimeter
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX + offsetX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 8) {
// Level 8: Classic Breakout-inspired cross/plus pattern with strategic chambers
var rows = 12;
var cols = 16;
var brickSpacingX = 160;
var brickSpacingY = 55;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 170;
var centerX = Math.floor(cols / 2);
var centerY = Math.floor(rows / 2);
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Calculate position relative to center
var dx = Math.abs(col - centerX);
var dy = Math.abs(row - centerY);
// Create cross/plus pattern inspired by classic arcade design
// Vertical arm of the cross
var isVerticalArm = dx <= 2;
// Horizontal arm of the cross
var isHorizontalArm = dy <= 2;
// Main cross structure
if (isVerticalArm || isHorizontalArm) {
// Center intersection - keep open for strategy
if (dx <= 1 && dy <= 1) {
skipBrick = true; // Central crossing
} else if (isVerticalArm && !isHorizontalArm) {
// Vertical arm - create strategic gaps
if (row % 3 === 1) {
skipBrick = true; // Regular gaps in vertical arm
}
} else if (isHorizontalArm && !isVerticalArm) {
// Horizontal arm - create strategic gaps
if (col % 3 === 1) {
skipBrick = true; // Regular gaps in horizontal arm
}
} else {
// Intersection areas - mostly solid with some gaps
if ((row + col) % 4 === 0) {
skipBrick = true;
}
}
} else {
// Outer chambers in the four quadrants
var quadrantX = col < centerX ? 0 : 1; // Left=0, Right=1
var quadrantY = row < centerY ? 0 : 1; // Top=0, Bottom=1
// Create defensive structures in each quadrant
if (dx >= 4 && dy >= 4) {
// Corner fortresses - solid defensive structures
if (quadrantX === 0 && quadrantY === 0 || quadrantX === 1 && quadrantY === 1) {
// Top-left and bottom-right corners - fortress pattern
if (dx >= 6 || dy >= 6) {
// Outer fortress walls
if ((row + col) % 3 !== 0) {
skipBrick = false;
} else {
skipBrick = true; // Small gaps for ball entry
}
} else {
// Inner fortress area - mostly open with obstacles
if ((row + col) % 5 === 0) {
skipBrick = false; // Scattered obstacles
} else {
skipBrick = true;
}
}
} else {
// Top-right and bottom-left corners - maze pattern
if (dx >= 6 || dy >= 6) {
// Outer maze walls with passages
if (row % 2 === 0 && col % 3 === 0 || col % 2 === 0 && row % 3 === 0) {
skipBrick = false;
} else {
skipBrick = true;
}
} else {
// Inner maze area
if ((row + col) % 4 === 2) {
skipBrick = false;
} else {
skipBrick = true;
}
}
}
} else {
// Transition zones between cross and corners
if (dx === 3 || dy === 3) {
// Boundary walls with strategic openings
if ((row + col) % 4 === 0) {
skipBrick = true; // Regular openings
}
} else {
// Open areas for ball movement
skipBrick = true;
// Add some scattered obstacles
if ((row + col) % 8 === 0) {
skipBrick = false;
}
}
}
}
if (!skipBrick) {
// Color scheme based on cross structure
var colorIndex;
if (dx <= 1 && dy <= 1) {
colorIndex = 0; // Red for center intersection
} else if (isVerticalArm || isHorizontalArm) {
if (dx <= 2 && dy <= 2) {
colorIndex = 4; // Purple for cross intersection areas
} else if (isVerticalArm) {
colorIndex = 1; // Blue for vertical arm
} else {
colorIndex = 2; // Green for horizontal arm
}
} else if (dx >= 6 || dy >= 6) {
colorIndex = 3; // Yellow for outer fortresses
} else {
colorIndex = 0; // Red for transition areas
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 9) {
// Level 9: Classic Breakout-inspired target/bullseye pattern with concentric rings
var rows = 11;
var cols = 17;
var brickSpacingX = 160;
var brickSpacingY = 55;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 170;
var centerX = Math.floor(cols / 2);
var centerY = Math.floor(rows / 2);
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Calculate distance from center for concentric rings
var dx = col - centerX;
var dy = row - centerY;
var distance = Math.sqrt(dx * dx + dy * dy);
// Create bullseye/target pattern with concentric rings
if (distance <= 1.5) {
// Center bullseye - keep open for strategic targeting
skipBrick = true;
} else if (distance <= 2.5) {
// First inner ring - solid with small gaps
if ((row + col) % 6 === 0) {
skipBrick = true; // Small targeting gaps
}
} else if (distance <= 3.5) {
// Second ring - alternating pattern for visual distinction
if ((row + col) % 3 === 1) {
skipBrick = true; // Regular gaps for ball movement
}
} else if (distance <= 4.5) {
// Third ring - mostly solid defensive ring
if ((row + col) % 4 === 0) {
skipBrick = true; // Strategic openings
}
} else if (distance <= 5.5) {
// Fourth ring - outer defensive perimeter
if ((row + col) % 5 === 0) {
skipBrick = true; // Larger gaps for ball entry
}
} else if (distance <= 6.5) {
// Fifth ring - sparse outer ring
if ((row + col) % 2 === 0) {
skipBrick = true; // Many gaps for easier access
}
} else {
// Outer fortification - corner defensive structures
// Create corner bastions inspired by classic arcade design
var cornerDistance = Math.min(Math.min(dx, cols - 1 - dx), Math.min(dy, rows - 1 - dy));
if (cornerDistance <= 1) {
// Corner walls with strategic openings
if ((row === 0 || row === rows - 1) && col % 4 === 1) {
skipBrick = true; // Top/bottom wall gaps
} else if ((col === 0 || col === cols - 1) && row % 3 === 1) {
skipBrick = true; // Side wall gaps
}
} else {
// Open areas between corners and target
skipBrick = true;
// Add scattered obstacles for challenge
if ((row + col) % 7 === 0) {
skipBrick = false; // Random obstacles
}
}
}
if (!skipBrick) {
// Color scheme based on target rings - classic arcade bullseye colors
var colorIndex;
if (distance <= 2.5) {
colorIndex = 0; // Red for center target ring (highest value)
} else if (distance <= 3.5) {
colorIndex = 4; // Purple for second ring
} else if (distance <= 4.5) {
colorIndex = 1; // Blue for third ring
} else if (distance <= 5.5) {
colorIndex = 2; // Green for fourth ring
} else if (distance <= 6.5) {
colorIndex = 3; // Yellow for outer ring
} else {
colorIndex = 0; // Red for corner fortifications
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 10) {
// Level 10: Classic Breakout-inspired infinity/figure-8 pattern
var rows = 12;
var cols = 18;
var brickSpacingX = 155;
var brickSpacingY = 55;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 160;
var centerX = Math.floor(cols / 2);
var centerY = Math.floor(rows / 2);
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Calculate position relative to center for infinity pattern
var dx = col - centerX;
var dy = row - centerY;
var distance = Math.sqrt(dx * dx + dy * dy);
// Create figure-8/infinity symbol pattern
// Upper loop center
var upperLoopCenterY = centerY - 3;
var upperDx = col - centerX;
var upperDy = row - upperLoopCenterY;
var upperDistance = Math.sqrt(upperDx * upperDx + upperDy * upperDy);
// Lower loop center
var lowerLoopCenterY = centerY + 3;
var lowerDx = col - centerX;
var lowerDy = row - lowerLoopCenterY;
var lowerDistance = Math.sqrt(lowerDx * lowerDx + lowerDy * lowerDy);
// Central crossing area
if (Math.abs(dx) <= 1 && Math.abs(dy) <= 1) {
// Center intersection - keep mostly open
skipBrick = true;
} else if (upperDistance <= 3.5 && row <= centerY) {
// Upper loop of infinity symbol
if (upperDistance >= 1.5 && upperDistance <= 3.5) {
// Create loop structure with strategic gaps
var upperAngle = Math.atan2(upperDy, upperDx);
var angleSector = Math.floor((upperAngle + Math.PI) / (Math.PI / 4)); // 8 sectors
if (angleSector % 3 === 0) {
skipBrick = true; // Gaps for ball movement
}
} else if (upperDistance < 1.5) {
// Inner area of upper loop - mostly open
skipBrick = true;
}
} else if (lowerDistance <= 3.5 && row >= centerY) {
// Lower loop of infinity symbol
if (lowerDistance >= 1.5 && lowerDistance <= 3.5) {
// Create loop structure with strategic gaps
var lowerAngle = Math.atan2(lowerDy, lowerDx);
var angleSector = Math.floor((lowerAngle + Math.PI) / (Math.PI / 4)); // 8 sectors
if (angleSector % 3 === 0) {
skipBrick = true; // Gaps for ball movement
}
} else if (lowerDistance < 1.5) {
// Inner area of lower loop - mostly open
skipBrick = true;
}
} else if (Math.abs(dy) <= 2 && Math.abs(dx) >= 2 && Math.abs(dx) <= 4) {
// Connecting bridge between loops
if (Math.abs(dx) === 3 && Math.abs(dy) <= 1) {
// Narrow bridge connection
skipBrick = false;
} else {
// Side areas of bridge - some gaps
if ((row + col) % 3 === 0) {
skipBrick = true;
}
}
} else if (distance <= 7) {
// Outer defensive perimeter around infinity pattern
if (distance >= 6) {
// Outer ring - walls with strategic openings
if (row === 0 || row === rows - 1) {
// Top and bottom walls
if (col % 5 === 0 || col % 5 === 1) {
skipBrick = true; // Entry gaps
}
} else if (col === 0 || col === cols - 1) {
// Side walls
if (row % 4 === 0) {
skipBrick = true; // Side entry gaps
}
}
} else {
// Mid-range defensive structures
if ((row + col) % 4 === 0) {
skipBrick = true; // Strategic openings
}
}
} else {
// Outermost corners - scattered defensive obstacles
if ((row + col) % 6 === 0) {
skipBrick = false; // Corner obstacles
} else {
skipBrick = true;
}
}
if (!skipBrick) {
// Color scheme based on infinity pattern structure
var colorIndex;
if (Math.abs(dx) <= 1 && Math.abs(dy) <= 1) {
colorIndex = 0; // Red for center crossing
} else if (upperDistance <= 3.5 && row <= centerY || lowerDistance <= 3.5 && row >= centerY) {
// Color loops differently for visual distinction
if (row <= centerY) {
colorIndex = 4; // Purple for upper loop
} else {
colorIndex = 1; // Blue for lower loop
}
} else if (Math.abs(dy) <= 2 && Math.abs(dx) >= 2 && Math.abs(dx) <= 4) {
colorIndex = 2; // Green for connecting bridge
} else if (distance <= 6) {
colorIndex = 3; // Yellow for mid-range defenses
} else {
colorIndex = 0; // Red for outer obstacles
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else if (currentLevel === 11) {
// Level 11: Classic Breakout-inspired triangular fortress with defensive walls
var rows = 13;
var cols = 19;
var brickSpacingX = 150;
var brickSpacingY = 50;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 160;
var centerX = Math.floor(cols / 2);
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var skipBrick = false;
// Calculate distance from center for triangular pattern
var dx = Math.abs(col - centerX);
var dy = row;
// Create triangular fortress pattern
if (row <= 4) {
// Top triangular section - solid defensive peak
var maxColsForRow = Math.min(cols, 2 * row + 3);
var triangleStart = centerX - Math.floor(maxColsForRow / 2);
var triangleEnd = centerX + Math.floor(maxColsForRow / 2);
if (col >= triangleStart && col <= triangleEnd) {
// Inside triangle - create strategic gaps
if (row === 2 && (col === centerX - 1 || col === centerX + 1)) {
skipBrick = true; // Small gaps in upper section
} else if (row === 4 && col === centerX) {
skipBrick = true; // Central gap for targeting
}
} else {
skipBrick = true; // Outside triangle bounds
}
} else if (row >= 5 && row <= 8) {
// Middle fortress walls with strategic openings
if (dx <= 8) {
// Main fortress body
if (dx >= 6) {
// Side towers
if (row === 6 || row === 7) {
// Tower windows
if (dx === 7) {
skipBrick = true;
}
}
} else if (dx >= 3 && dx <= 5) {
// Inner defensive walls
if (row === 6 && dx === 4) {
skipBrick = true; // Gate opening
} else if (row === 7 && (dx === 3 || dx === 5)) {
skipBrick = true; // Side passages
}
} else if (dx <= 2) {
// Central keep area
if (row === 6 && dx === 1) {
skipBrick = true; // Keep entrance
}
}
} else {
// Outside main fortress
skipBrick = true;
}
} else if (row >= 9) {
// Lower defensive perimeter
if (dx <= 9) {
// Foundation walls
if (row >= 11) {
// Lower foundation - mostly solid with small gaps
if ((col + row) % 5 === 0) {
skipBrick = true; // Drainage gaps
}
} else {
// Mid foundation - strategic openings
if (dx >= 7) {
// Outer foundation walls
if ((col + row) % 3 === 0) {
skipBrick = true; // Regular gaps
}
} else if (dx >= 4) {
// Inner foundation area
if (row === 9 && (dx === 5 || dx === 6)) {
skipBrick = true; // Main entrances
}
} else {
// Central foundation
if (row === 10 && dx <= 1) {
skipBrick = true; // Central courtyard
}
}
}
} else {
skipBrick = true; // Outside foundation
}
}
if (!skipBrick) {
// Color scheme based on fortress architecture
var colorIndex;
if (row <= 2) {
colorIndex = 0; // Red for peak
} else if (row <= 4) {
colorIndex = 4; // Purple for upper triangle
} else if (row <= 6) {
colorIndex = 1; // Blue for main walls
} else if (row <= 8) {
colorIndex = 2; // Green for middle section
} else if (row <= 10) {
colorIndex = 3; // Yellow for lower walls
} else {
colorIndex = 0; // Red for foundation
}
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
} else {
// Default pattern for other levels
var rows = Math.min(8, 5 + Math.floor(currentLevel / 5));
var cols = 18;
var brickSpacingX = 165;
var brickSpacingY = 60;
var startX = (2048 - (cols - 1) * brickSpacingX) / 2;
var startY = 200;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var colorIndex = row % brickColors.length;
var brick = new Brick(brickColors[colorIndex]);
brick.x = startX + col * brickSpacingX;
brick.y = startY + row * brickSpacingY;
bricks.push(brick);
game.addChild(brick);
}
}
}
// Remove old UI elements if they exist
if (scoreTxt) {
scoreTxt.destroy();
scoreTxt = null;
}
if (livesTxt) {
livesTxt.destroy();
livesTxt = null;
}
// Create UI elements
scoreTxt = new Text2(getText('score') + ': 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
livesTxt = new Text2(getText('lives') + ':', {
size: 80,
fill: 0xFFFFFF
});
livesTxt.anchor.set(0, 0);
livesTxt.x = -600;
LK.gui.topRight.addChild(livesTxt);
// Clear existing heart icons
for (var hi = 0; hi < heartIcons.length; hi++) {
if (heartIcons[hi]) heartIcons[hi].destroy();
}
heartIcons = [];
// Add heart icons based on remaining lives
for (var h = 0; h < lives; h++) {
var heartIcon = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heartIcon.x = -350 + h * 80;
heartIcon.y = 40;
LK.gui.topRight.addChild(heartIcon);
heartIcons.push(heartIcon);
}
// Reset game state
lives = 3;
if (currentLevel === 1) {
LK.setScore(0);
}
}
var dragNode = null;
var lastBallY = 0;
function handleMove(x, y, obj) {
if (!gameStarted) return;
if (dragNode) {
// Launch ball on first paddle movement
if (!ballLaunched) {
ballLaunched = true;
}
dragNode.x = x;
// Keep paddle within screen bounds
if (dragNode.x < dragNode.width / 2) {
dragNode.x = dragNode.width / 2;
}
if (dragNode.x > 2048 - dragNode.width / 2) {
dragNode.x = 2048 - dragNode.width / 2;
}
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameStarted) return;
// Launch ball on first touch
if (!ballLaunched) {
ballLaunched = true;
}
dragNode = paddle;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
if (!gameStarted) return;
dragNode = null;
};
function resetBall() {
if (!ball) return;
ball.x = 2048 / 2;
ball.y = 2400;
// Start with consistent angle like original Breakout
ball.velocityX = (Math.random() > 0.5 ? 1 : -1) * 6;
ball.velocityY = -12;
ballLaunched = false;
}
function checkPaddleCollision() {
if (!paddle || !ball) return;
var paddleLeft = paddle.x - paddle.width / 2;
var paddleRight = paddle.x + paddle.width / 2;
var paddleTop = paddle.y - paddle.height / 2;
var paddleBottom = paddle.y + paddle.height / 2;
if (ball.x + ball.radius >= paddleLeft && ball.x - ball.radius <= paddleRight && ball.y + ball.radius >= paddleTop && ball.y - ball.radius <= paddleBottom && ball.velocityY > 0) {
// Calculate hit position relative to paddle center (-1 to 1)
var hitPos = (ball.x - paddle.x) / (paddle.width / 2);
// Adjust ball velocity based on hit position with more realistic physics
var speed = Math.sqrt(ball.velocityX * ball.velocityX + ball.velocityY * ball.velocityY);
var angle = hitPos * Math.PI * 0.25; // Max 45 degree angle
ball.velocityX = Math.sin(angle) * speed;
ball.velocityY = -Math.cos(angle) * speed;
// Position ball above paddle
ball.y = paddleTop - ball.radius;
LK.getSound('hitPaddle').play();
}
}
function checkBrickCollisions() {
if (!ball) return;
for (var i = bricks.length - 1; i >= 0; i--) {
var brick = bricks[i];
if (brick.destroyed) continue;
var brickLeft = brick.x - brick.width / 2;
var brickRight = brick.x + brick.width / 2;
var brickTop = brick.y - brick.height / 2;
var brickBottom = brick.y + brick.height / 2;
if (ball.x + ball.radius >= brickLeft && ball.x - ball.radius <= brickRight && ball.y + ball.radius >= brickTop && ball.y - ball.radius <= brickBottom) {
// Determine collision side
var overlapLeft = ball.x + ball.radius - brickLeft;
var overlapRight = brickRight - (ball.x - ball.radius);
var overlapTop = ball.y + ball.radius - brickTop;
var overlapBottom = brickBottom - (ball.y - ball.radius);
var minOverlap = Math.min(overlapLeft, overlapRight, overlapTop, overlapBottom);
if (minOverlap === overlapTop || minOverlap === overlapBottom) {
ball.velocityY = -ball.velocityY;
} else {
ball.velocityX = -ball.velocityX;
}
brick.destroyed = true;
brick.destroy();
bricks.splice(i, 1);
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(getText('score') + ': ' + LK.getScore());
LK.getSound('hitBrick').play();
// No automatic level progression when bricks are destroyed
// Level progression now happens when ball reaches top
break;
}
}
}
game.update = function () {
if (!gameStarted || !ball) return;
// Check if ball fell below paddle
if (lastBallY <= 2732 && ball.y > 2732) {
lives--;
livesTxt.setText(getText('lives') + ':');
// Remove a heart icon when life is lost
if (heartIcons.length > 0) {
var heartToRemove = heartIcons.pop();
heartToRemove.destroy();
}
if (lives <= 0) {
LK.showGameOver();
} else {
resetBall();
}
}
checkPaddleCollision();
checkBrickCollisions();
// Check if ball hits the win target zone
if (winTarget && ball.intersects(winTarget)) {
// Stop the game immediately
gameStarted = false;
ballLaunched = false;
// Level completed by reaching top - unlock next level
var unlockedLevel = storage.unlockedLevel || 1;
if (currentLevel >= unlockedLevel && currentLevel < 30) {
storage.unlockedLevel = currentLevel + 1;
}
// Create victory animation with multiple effects
LK.effects.flashScreen(0x00ff00, 1000); // Green flash for victory
// Animate the win target with a scaling effect
tween(winTarget, {
scaleX: 12,
scaleY: 2,
alpha: 0.3
}, {
duration: 1000,
easing: tween.bounceOut
});
// Create victory overlay
var victoryOverlay = new Container();
var overlayBg = victoryOverlay.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20
});
overlayBg.tint = 0x2c3e50;
overlayBg.alpha = 0.9;
victoryOverlay.x = 1024;
victoryOverlay.y = 1366;
game.addChild(victoryOverlay);
// Victory title with animation
var victoryTitle = new Text2(currentLanguage === 'tr' ? 'KAZANDIN!' : 'YOU WIN!', {
size: 150,
fill: 0x00ff00
});
victoryTitle.anchor.set(0.5, 0.5);
victoryTitle.x = 0;
victoryTitle.y = -200;
victoryTitle.alpha = 0;
victoryOverlay.addChild(victoryTitle);
// Animate victory title
tween(victoryTitle, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.bounceOut
});
// Level completion text
var levelText = new Text2(currentLanguage === 'tr' ? 'Seviye ' + currentLevel + ' Tamamlandı!' : 'Level ' + currentLevel + ' Complete!', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
levelText.x = 0;
levelText.y = -50;
levelText.alpha = 0;
victoryOverlay.addChild(levelText);
// Animate level text with delay
LK.setTimeout(function () {
tween(levelText, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
}, 400);
// Check if all levels completed
if (currentLevel >= 30) {
// Final victory - show you win
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
} else {
// Create next level button
var nextLevelBtn = new Container();
var nextBg = nextLevelBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.0
});
nextBg.tint = 0x27ae60; // Green for next level
var nextText = new Text2(currentLanguage === 'tr' ? 'Sonraki Seviye' : 'Next Level', {
size: 60,
fill: 0xFFFFFF
});
nextText.anchor.set(0.5, 0.5);
nextLevelBtn.addChild(nextText);
nextLevelBtn.x = -200;
nextLevelBtn.y = 150;
nextLevelBtn.alpha = 0;
nextLevelBtn.down = function () {
// Progress to next level
currentLevel++;
// Clean up victory overlay
victoryOverlay.destroy();
// Restart game with next level
startGame();
};
victoryOverlay.addChild(nextLevelBtn);
// Create menu button
var menuBtn = new Container();
var menuBg = menuBtn.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.0
});
menuBg.tint = 0x3498db; // Blue for menu
var menuText = new Text2(currentLanguage === 'tr' ? 'Menüye Dön' : 'Back to Menu', {
size: 60,
fill: 0xFFFFFF
});
menuText.anchor.set(0.5, 0.5);
menuBtn.addChild(menuText);
menuBtn.x = 200;
menuBtn.y = 150;
menuBtn.alpha = 0;
menuBtn.down = function () {
// Return to menu
gameStarted = false;
// Clean up all game elements
if (paddle) {
paddle.destroy();
paddle = null;
}
if (ball) {
ball.destroy();
ball = null;
}
if (winTarget) {
game.removeChild(winTarget);
winTarget.destroy();
winTarget = null;
}
for (var j = 0; j < bricks.length; j++) {
if (bricks[j]) bricks[j].destroy();
}
bricks = [];
// Clear UI elements
if (scoreTxt) {
scoreTxt.destroy();
scoreTxt = null;
}
if (livesTxt) {
livesTxt.destroy();
livesTxt = null;
}
for (var hi = 0; hi < heartIcons.length; hi++) {
if (heartIcons[hi]) heartIcons[hi].destroy();
}
heartIcons = [];
LK.gui.topRight.removeChildren();
// Clean up victory overlay
victoryOverlay.destroy();
// Show level menu
levelMenu = game.addChild(new LevelMenu());
levelMenu.createMenu();
};
victoryOverlay.addChild(menuBtn);
// Animate buttons with delay
LK.setTimeout(function () {
tween(nextLevelBtn, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
tween(menuBtn, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
}, 800);
}
return;
}
// Check if all bricks are destroyed for level progression (alternative win condition)
var activeBricks = 0;
for (var b = 0; b < bricks.length; b++) {
if (!bricks[b].destroyed) {
activeBricks++;
}
}
if (activeBricks === 0) {
// Level completed - unlock next level
var unlockedLevel = storage.unlockedLevel || 1;
if (currentLevel >= unlockedLevel && currentLevel < 30) {
storage.unlockedLevel = currentLevel + 1;
}
// Add level completion visual effect
LK.effects.flashScreen(0x00ff00, 500); // Green flash for level completion
// Check if all levels completed
if (currentLevel >= 30) {
LK.showYouWin();
} else {
// Show level transition message
var levelCompleteText = new Text2('Level ' + currentLevel + ' Complete!', {
size: 120,
fill: 0xFFFFFF
});
levelCompleteText.anchor.set(0.5, 0.5);
levelCompleteText.x = 1024;
levelCompleteText.y = 1366;
game.addChild(levelCompleteText);
// Auto-progress to next level
currentLevel++;
// Show next level message
var nextLevelText = new Text2('Starting Level ' + currentLevel, {
size: 100,
fill: 0xFFFF00
});
nextLevelText.anchor.set(0.5, 0.5);
nextLevelText.x = 1024;
nextLevelText.y = 1500;
game.addChild(nextLevelText);
// Clear current game elements after delay
LK.setTimeout(function () {
// Remove transition texts
levelCompleteText.destroy();
nextLevelText.destroy();
if (paddle) {
paddle.destroy();
paddle = null;
}
if (ball) {
ball.destroy();
ball = null;
}
for (var j = 0; j < bricks.length; j++) {
if (bricks[j]) bricks[j].destroy();
}
bricks = [];
// Clear UI elements properly
if (scoreTxt) {
scoreTxt.destroy();
scoreTxt = null;
}
if (livesTxt) {
livesTxt.destroy();
livesTxt = null;
}
// Clear heart icons
for (var hi = 0; hi < heartIcons.length; hi++) {
if (heartIcons[hi]) heartIcons[hi].destroy();
}
heartIcons = [];
// Clear all GUI elements to prevent orphaned references
LK.gui.topRight.removeChildren();
// Start next level
startGame();
}, 1500);
return;
}
}
lastBallY = ball.y;
};