User prompt
tüm açtığımız level verilerini silip baştan ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
oyunu bozmadan hataları düzeltin
User prompt
Admin menüsünü kaldır.
User prompt
11. Level ile aynı olmuş
User prompt
hayır telefon tıklamak gibi birden 9'a kadar ve sıfır sayıları olsun şifreyi ise 2010 olsun
User prompt
ayarlar kısmında tıklayınca hani menü var ya oraya admin menüsü ekle ve birden ona kadar sayılar olsun doğru sırayla dokununca tüm leveller açılsın doğru
User prompt
16'dan 30'a kadar olan level'leri göstermek için tıkladığımız düğmeleri biraz diğer düğmelerden tuşlardan uzaklaştır.
User prompt
topumuz en yukardaki yeşil topa çarpınca oyun bitsin ve kazandın animasyonu ile birlikte sonraki bölüme geç veya menüye dön tuşları olsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ayarlar kısmı tam ekran kaplıyor fakat tuşlar yine de kısıtlı yerlerde daha düzgün yerlere yerleştir
User prompt
yeni bir tuş eklediğinde daha önceki tuşları sil
User prompt
kodların neden azalmadığını öğrendim sen bir logo eklediğinde veya yerini değiştirdiğinde ondan öncekini silmiyorsun sil
User prompt
bir menü seçtiğimizde tam ekran olsun ayarlar tuşuna tıklayınca falan gibi
User prompt
hər mönüdən çıxmaq üçün geri tuşu olsun
User prompt
ayarlara tıklayınca dil tuşu olsun orayı seçince diller gözüksün böylece daha çok ayar ekleyebileceğiz
User prompt
tuşlar ve menüleri kare tuşa çevir
User prompt
Yukarıdaki yeşil çubuk baştan sona her yere yetişsin.
User prompt
Please fix the bug: 'ReferenceError: winTarget is not defined' in or related to this line: 'if (ball.intersects(winTarget)) {' Line Number: 1486
User prompt
Tüm bulukların en üstünde bir yer olsun. Topumuz oraya deyince bölümü bitirmiş olalım.
User prompt
bölüm geçişleri olsun mesela bir bölümde en üstteki boşluğa top değdiğinde yeni bölüme geçebilelim yani bölüm bitmiş olsun
User prompt
bölümleri geçmek için de tüm tuğlaları kırmak zorunda kalmayalım bir tuğlanın arasından yani en üst boşluk var ya topumuz oraya deyince yeni bölme geçmiş olalım yani kazanmış olalım
User prompt
Topun hızını 2 kat arttır.
User prompt
orjinal tuğla kırma oyunundan esinlenerek level 10'u yap
User prompt
orjinal tuğla kırma oyunundan esinlenerek level 9'u yap
User prompt
orjinal tuğla kırma oyunundan esnenerek lvl 8'i yap
User prompt
Orijinal Tula Kırma Oyunundan Esinlenerek Level 7'yi Yap
/**** * 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 = 4; self.velocityY = -6; self.radius = 14; self.maxSpeed = 8; 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 () { // Create language switching button at the top var languageButton = new Container(); var languageBg = languageButton.attachAsset('paddle', { 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('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 1.0 }); 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); button.x = 1024 + (col - 2) * 300; button.y = 800 + row * 200; 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('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 2 }); 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('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 2 }); 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('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 6 }); overlayBg.tint = 0x2c3e50; overlayBg.alpha = 0.9; overlay.x = 1024; overlay.y = 1366; // Turkish button var turkishBtn = new Container(); var turkishBg = turkishBtn.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); turkishBg.tint = currentLanguage === 'tr' ? 0x27ae60 : 0x7f8c8d; var turkishText = new Text2(getText('turkish'), { size: 60, fill: 0xFFFFFF }); turkishText.anchor.set(0.5, 0.5); turkishBtn.addChild(turkishText); turkishBtn.x = 0; turkishBtn.y = -100; turkishBtn.down = function () { switchLanguage('tr'); self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(turkishBtn); // English button var englishBtn = new Container(); var englishBg = englishBtn.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); englishBg.tint = currentLanguage === 'en' ? 0x27ae60 : 0x7f8c8d; var englishText = new Text2(getText('english'), { size: 60, fill: 0xFFFFFF }); englishText.anchor.set(0.5, 0.5); englishBtn.addChild(englishText); englishBtn.x = 0; englishBtn.y = 100; englishBtn.down = function () { switchLanguage('en'); self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(englishBtn); self.addChild(overlay); }; self.showSettingsMenu = function () { // Create settings overlay var overlay = new Container(); var overlayBg = overlay.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 6 }); overlayBg.tint = 0x2c3e50; overlayBg.alpha = 0.9; overlay.x = 1024; overlay.y = 1366; // Language section in settings var languageLabel = new Text2(getText('language'), { size: 70, fill: 0xFFFFFF }); languageLabel.anchor.set(0.5, 0.5); languageLabel.x = 0; languageLabel.y = -200; overlay.addChild(languageLabel); // Turkish button var turkishBtn = new Container(); var turkishBg = turkishBtn.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7 }); turkishBg.tint = currentLanguage === 'tr' ? 0x27ae60 : 0x7f8c8d; var turkishText = new Text2(getText('turkish'), { size: 50, fill: 0xFFFFFF }); turkishText.anchor.set(0.5, 0.5); turkishBtn.addChild(turkishText); turkishBtn.x = -150; turkishBtn.y = -100; turkishBtn.down = function () { switchLanguage('tr'); self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(turkishBtn); // English button var englishBtn = new Container(); var englishBg = englishBtn.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.7, scaleY: 0.7 }); englishBg.tint = currentLanguage === 'en' ? 0x27ae60 : 0x7f8c8d; var englishText = new Text2(getText('english'), { size: 50, fill: 0xFFFFFF }); englishText.anchor.set(0.5, 0.5); englishBtn.addChild(englishText); englishBtn.x = 150; englishBtn.y = -100; englishBtn.down = function () { switchLanguage('en'); self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(englishBtn); // Close button var closeBtn = new Container(); var closeBg = closeBtn.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.6 }); closeBg.tint = 0xe74c3c; var closeText = new Text2('X', { size: 60, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeBtn.addChild(closeText); closeBtn.x = 0; closeBtn.y = 150; closeBtn.down = function () { self.removeChild(overlay); overlay.destroy(); }; overlay.addChild(closeBtn); 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 ****/ // 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 = []; // 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; // Create paddle paddle = game.addChild(new Paddle()); paddle.x = 2048 / 2; paddle.y = 2600; // Create ball ball = game.addChild(new Ball()); ball.x = 2048 / 2; ball.y = 2400; // 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 { // 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); } } } // 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) * 3; ball.velocityY = -6; 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 all bricks are destroyed for level progression 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; } // Check if all levels completed if (currentLevel >= 30) { LK.showYouWin(); } else { // Auto-progress to next level currentLevel++; // Clear current game elements 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 after short delay LK.setTimeout(function () { startGame(); }, 1000); 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 = 4;
self.velocityY = -6;
self.radius = 14;
self.maxSpeed = 8;
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 () {
// Create language switching button at the top
var languageButton = new Container();
var languageBg = languageButton.attachAsset('paddle', {
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('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 1.0
});
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);
button.x = 1024 + (col - 2) * 300;
button.y = 800 + row * 200;
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('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 2
});
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('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 2
});
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('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 6
});
overlayBg.tint = 0x2c3e50;
overlayBg.alpha = 0.9;
overlay.x = 1024;
overlay.y = 1366;
// Turkish button
var turkishBtn = new Container();
var turkishBg = turkishBtn.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
turkishBg.tint = currentLanguage === 'tr' ? 0x27ae60 : 0x7f8c8d;
var turkishText = new Text2(getText('turkish'), {
size: 60,
fill: 0xFFFFFF
});
turkishText.anchor.set(0.5, 0.5);
turkishBtn.addChild(turkishText);
turkishBtn.x = 0;
turkishBtn.y = -100;
turkishBtn.down = function () {
switchLanguage('tr');
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(turkishBtn);
// English button
var englishBtn = new Container();
var englishBg = englishBtn.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
englishBg.tint = currentLanguage === 'en' ? 0x27ae60 : 0x7f8c8d;
var englishText = new Text2(getText('english'), {
size: 60,
fill: 0xFFFFFF
});
englishText.anchor.set(0.5, 0.5);
englishBtn.addChild(englishText);
englishBtn.x = 0;
englishBtn.y = 100;
englishBtn.down = function () {
switchLanguage('en');
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(englishBtn);
self.addChild(overlay);
};
self.showSettingsMenu = function () {
// Create settings overlay
var overlay = new Container();
var overlayBg = overlay.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 6
});
overlayBg.tint = 0x2c3e50;
overlayBg.alpha = 0.9;
overlay.x = 1024;
overlay.y = 1366;
// Language section in settings
var languageLabel = new Text2(getText('language'), {
size: 70,
fill: 0xFFFFFF
});
languageLabel.anchor.set(0.5, 0.5);
languageLabel.x = 0;
languageLabel.y = -200;
overlay.addChild(languageLabel);
// Turkish button
var turkishBtn = new Container();
var turkishBg = turkishBtn.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
turkishBg.tint = currentLanguage === 'tr' ? 0x27ae60 : 0x7f8c8d;
var turkishText = new Text2(getText('turkish'), {
size: 50,
fill: 0xFFFFFF
});
turkishText.anchor.set(0.5, 0.5);
turkishBtn.addChild(turkishText);
turkishBtn.x = -150;
turkishBtn.y = -100;
turkishBtn.down = function () {
switchLanguage('tr');
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(turkishBtn);
// English button
var englishBtn = new Container();
var englishBg = englishBtn.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
englishBg.tint = currentLanguage === 'en' ? 0x27ae60 : 0x7f8c8d;
var englishText = new Text2(getText('english'), {
size: 50,
fill: 0xFFFFFF
});
englishText.anchor.set(0.5, 0.5);
englishBtn.addChild(englishText);
englishBtn.x = 150;
englishBtn.y = -100;
englishBtn.down = function () {
switchLanguage('en');
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(englishBtn);
// Close button
var closeBtn = new Container();
var closeBg = closeBtn.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.6
});
closeBg.tint = 0xe74c3c;
var closeText = new Text2('X', {
size: 60,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeText);
closeBtn.x = 0;
closeBtn.y = 150;
closeBtn.down = function () {
self.removeChild(overlay);
overlay.destroy();
};
overlay.addChild(closeBtn);
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
****/
// 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 = [];
// 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;
// Create paddle
paddle = game.addChild(new Paddle());
paddle.x = 2048 / 2;
paddle.y = 2600;
// Create ball
ball = game.addChild(new Ball());
ball.x = 2048 / 2;
ball.y = 2400;
// 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 {
// 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);
}
}
}
// 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) * 3;
ball.velocityY = -6;
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 all bricks are destroyed for level progression
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;
}
// Check if all levels completed
if (currentLevel >= 30) {
LK.showYouWin();
} else {
// Auto-progress to next level
currentLevel++;
// Clear current game elements
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 after short delay
LK.setTimeout(function () {
startGame();
}, 1000);
return;
}
}
lastBallY = ball.y;
};