/**** * 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;
};