User prompt
10. seviyeden sonra topun hızı aşırı düşürülmüş, bu yüzden top çok yavaş hareket ediyor. Daha iyi bir oyun deneyimi için minimum hız limiti daha yüksek tutulmalı veya hız düşüşü daha az olmalı.
User prompt
10 leveden sonra 2 katına çıkar blokları
User prompt
Blokların hepsi ekranda gözüksün
User prompt
10.levleden sonra blok sayıları 2 karına çıkar
User prompt
10.levelxen sonra zor olsun
User prompt
10 .seviyeden sonraki bölümlerdeki topun hızını düşür ve blokları fazlalaştır
User prompt
Arkada oyun gözükmesin oyun seçme sayfasında
User prompt
Please fix the bug: 'tween.create is not a function. (In 'tween.create({ target: btn.scale, to: { x: 1, y: 1 }, duration: 400 + 30 * levelIdx, easing: function easing(k) { __$(429); return k; } })', 'tween.create' is undefined)' in or related to this line: 'tween.create({' Line Number: 770 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'tween.to is not a function. (In 'tween.to(btn.scale, { x: 1, y: 1 }, 400 + 30 * levelIdx, { easing: function easing(k) { __$(429); return k; } })', 'tween.to' is undefined)' in or related to this line: 'tween.to(btn.scale, {' Line Number: 770
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'tween.Easing.Linear')' in or related to this line: 'tween.to(btn.scale, {' Line Number: 770
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'tween.Easing.Quadratic')' in or related to this line: 'tween.to(btn.scale, {' Line Number: 770
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'tween.Easing.Cubic')' in or related to this line: 'tween.to(btn.scale, {' Line Number: 770
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'tween.Easing.Back')' in or related to this line: 'tween.to(btn.scale, {' Line Number: 770
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'txt.style.dropShadow = true')' in or related to this line: 'txt.style.dropShadow = true;' Line Number: 761
User prompt
Please fix the bug: 'undefined is not an object (evaluating 'title.style.dropShadow = true')' in or related to this line: 'title.style.dropShadow = true;' Line Number: 704
User prompt
Bölüm seçme sayfasını güzelleştir
User prompt
Beyzbol sopasının görüntüsünü düzelt
User prompt
Oyun bıyunca sürwkli çalsın
User prompt
1 müziğini oyunda kullan
User prompt
Renklerini oyunun içindede değiştir
User prompt
2defada kırılan bloklarıda değiştir
User prompt
Yaptığımn üç renk farklı bir renk olsun
User prompt
3defa kırılan blokları farklı bir renk yap
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Ball Class var Ball = Container.expand(function () { var self = Container.call(this); var ball = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.radius = ball.width / 2; // Ball velocity self.vx = 0; self.vy = 0; self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // Block Class var Block = Container.expand(function () { var self = Container.call(this); // Color variety: assign a colorId based on blockType, but also randomize for more variety var colorIds = ['block', 'block2', 'block3']; var colorId; var r = Math.random(); if (r < 0.1) { self.hitPoints = 3; colorId = 'block4'; // Unique color for 3-hit blocks } else if (r < 0.3) { self.hitPoints = 2; if (typeof self.blockType === "number" && self.blockType >= 1 && self.blockType <= 3) { colorId = colorIds[self.blockType - 1]; } else { colorId = colorIds[Math.floor(Math.random() * colorIds.length)]; } } else { self.hitPoints = 1; if (typeof self.blockType === "number" && self.blockType >= 1 && self.blockType <= 3) { colorId = colorIds[self.blockType - 1]; } else { colorId = colorIds[Math.floor(Math.random() * colorIds.length)]; } } var block = self.attachAsset(colorId, { anchorX: 0.5, anchorY: 0.5 }); self.width = block.width; self.height = block.height; self.updateBlockVisual = function () { // Change tint or alpha based on hitPoints if (self.hitPoints === 3) { block.alpha = 1; } else if (self.hitPoints === 2) { block.alpha = 0.7; } else { block.alpha = 0.4; } }; self.updateBlockVisual(); return self; }); // Platform (Paddle) Class var Platform = Container.expand(function () { var self = Container.call(this); var plat = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.width = plat.width; self.height = plat.height; return self; }); // Powerup Class var Powerup = Container.expand(function () { var self = Container.call(this); // Define multiple powerup types var types = [{ type: 'enlarge', label: 'E', color: 'block2' }, { type: 'shrink', label: 'S', color: 'block3' }, { type: 'life', label: '♥', color: 'block' }, { type: 'slow', label: '⏳', color: 'block2' }, { type: 'fast', label: '⚡', color: 'block3' }]; // Randomly pick a powerup type var chosen = types[Math.floor(Math.random() * types.length)]; self.type = chosen.type; // Use different asset color for each powerup type var asset = self.attachAsset(chosen.color, { anchorX: 0.5, anchorY: 0.5 }); asset.width = 100; asset.height = 60; // Add a text label for the powerup type var txt = new Text2(chosen.label, { size: 60, fill: "#fff" }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; self.addChild(txt); // Set speed self.vy = 10; self.update = function () { self.y += self.vy; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Block (third color for variety) // Block (second color for variety) // Block // Ball // Platform (paddle) // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var PLATFORM_Y = GAME_HEIGHT - 200; var BALL_START_Y = PLATFORM_Y - 80; var BALL_SPEED = 18; var BALL_MIN_ANGLE = Math.PI / 8; // ~22.5deg, to avoid too shallow var BALL_MAX_ANGLE = Math.PI - Math.PI / 8; var PLATFORM_SPEED = 60; // Not used, as platform is dragged directly var BLOCK_ROWS = 5; var BLOCK_COLS = 7; var BLOCK_MARGIN_X = 30; var BLOCK_MARGIN_Y = 30; var BLOCK_TOP_OFFSET = 350; var BLOCK_TYPES = [1, 2, 3]; // Game state var platform; var ball; var blocks = []; var powerups = []; // Track falling powerups var score = 0; var lives = 3; var isBallLaunched = false; var dragPlatform = false; var lastTouchX = 0; var scoreTxt; var livesTxt; // Helper: Reset ball to platform function resetBall() { ball.x = platform.x; ball.y = BALL_START_Y; ball.vx = 0; ball.vy = 0; isBallLaunched = false; // Ball speed increases after level 10 for more challenge if (currentLevel >= 10) { BALL_SPEED = 24 + (currentLevel - 10) * 2; if (BALL_SPEED > 50) BALL_SPEED = 50; } else { BALL_SPEED = 18 + currentLevel * 2; if (BALL_SPEED > 40) BALL_SPEED = 40; } } // Helper: Launch ball function launchBall() { if (!isBallLaunched) { // Randomize initial angle between 45 and 135 degrees (upwards) var angle = Math.PI / 4 + Math.random() * (Math.PI / 2); ball.vx = BALL_SPEED * Math.cos(angle); ball.vy = -BALL_SPEED * Math.sin(angle); isBallLaunched = true; } } // Helper: Clamp value function clamp(val, min, max) { if (val < min) return min; if (val > max) return max; return val; } // Level patterns: 20 unique block layouts (1: block, 0: empty, 2/3: alt color) var LEVEL_PATTERNS = [ // Level 1: Full grid [[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]], // Level 2: Checkerboard [[1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1]], // Level 3: Pyramid [[0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0]], // Level 4: Hollow rectangle [[2, 2, 2, 2, 2, 2, 2], [2, 0, 0, 0, 0, 0, 2], [2, 0, 0, 0, 0, 0, 2], [2, 0, 0, 0, 0, 0, 2], [2, 2, 2, 2, 2, 2, 2]], // Level 5: Diagonal [[3, 0, 0, 0, 0, 0, 3], [0, 3, 0, 0, 0, 3, 0], [0, 0, 3, 0, 3, 0, 0], [0, 0, 0, 3, 0, 0, 0], [0, 0, 3, 0, 3, 0, 0]], // Level 6: Two triangles [[1, 0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 1, 0, 1, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 0, 0, 0, 0, 0, 1]], // Level 7: Alternating rows [[1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1]], // Level 8: Center cross [[0, 0, 3, 3, 3, 0, 0], [0, 0, 3, 3, 3, 0, 0], [3, 3, 3, 3, 3, 3, 3], [0, 0, 3, 3, 3, 0, 0], [0, 0, 3, 3, 3, 0, 0]], // Level 9: Edges only [[1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1]], // Level 10: Zigzag [[1, 0, 0, 0, 0, 0, 1], [0, 1, 0, 0, 0, 1, 0], [0, 0, 1, 0, 1, 0, 0], [0, 1, 0, 0, 0, 1, 0], [1, 0, 0, 0, 0, 0, 1]], // Level 11: Dense center [[0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 2, 2, 2, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 0, 0]], // Level 12: Alternating columns [[1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1]], // Level 13: Arrow [[0, 0, 0, 3, 0, 0, 0], [0, 0, 3, 3, 3, 0, 0], [0, 3, 3, 3, 3, 3, 0], [3, 3, 3, 3, 3, 3, 3], [0, 0, 0, 0, 0, 0, 0]], // Level 14: Corners [[2, 0, 0, 0, 0, 0, 2], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0, 2]], // Level 15: Double cross [[0, 2, 0, 2, 0, 2, 0], [2, 2, 2, 2, 2, 2, 2], [0, 2, 0, 2, 0, 2, 0], [2, 2, 2, 2, 2, 2, 2], [0, 2, 0, 2, 0, 2, 0]], // Level 16: X shape [[3, 0, 0, 0, 0, 0, 3], [0, 3, 0, 0, 0, 3, 0], [0, 0, 3, 0, 3, 0, 0], [0, 3, 0, 0, 0, 3, 0], [3, 0, 0, 0, 0, 0, 3]], // Level 17: Center diamond [[0, 0, 1, 0, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 2, 2, 2, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 0, 1, 0, 0]], // Level 18: Top and bottom [[1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1]], // Level 19: Alternating blocks [[1, 0, 2, 0, 3, 0, 1], [0, 2, 0, 3, 0, 1, 0], [2, 0, 3, 0, 1, 0, 2], [0, 3, 0, 1, 0, 2, 0], [3, 0, 1, 0, 2, 0, 3]], // Level 20: Dense grid [[1, 2, 3, 1, 2, 3, 1], [2, 3, 1, 2, 3, 1, 2], [3, 1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3, 1], [2, 3, 1, 2, 3, 1, 2]]]; var currentLevel = 0; var MAX_LEVEL = LEVEL_PATTERNS.length; // Helper: Create blocks function createBlocks() { // Remove old blocks for (var i = 0; i < blocks.length; i++) { blocks[i].destroy(); } blocks = []; // Calculate block size and spacing var blockAsset = LK.getAsset('block', { anchorX: 0.5, anchorY: 0.5 }); var blockW = blockAsset.width; var blockH = blockAsset.height; var totalW = BLOCK_COLS * blockW + (BLOCK_COLS - 1) * BLOCK_MARGIN_X; var startX = (GAME_WIDTH - totalW) / 2 + blockW / 2; // Use pattern for current level var pattern = LEVEL_PATTERNS[currentLevel % LEVEL_PATTERNS.length]; // Add more rows as level increases (up to 8) var extraRows = Math.min(Math.floor(currentLevel / 2), 3); for (var row = 0; row < BLOCK_ROWS + extraRows; row++) { for (var col = 0; col < BLOCK_COLS; col++) { var type = pattern[row] && pattern[row][col] ? pattern[row][col] : 0; if (type === 0) continue; var b = new Block(); b.blockType = type; // Remove any previous children (for safety) b.removeChildren(); // Assign a random colorId for each block for more color variety var colorIds = ['block', 'block2', 'block3']; var colorId; if (typeof b.blockType === "number" && b.blockType >= 1 && b.blockType <= 3) { // Pick a random color, but prefer the type's color colorId = colorIds[Math.floor(Math.random() * colorIds.length)]; } else { colorId = colorIds[Math.floor(Math.random() * colorIds.length)]; } b.attachAsset(colorId, { anchorX: 0.5, anchorY: 0.5 }); b.x = startX + col * (blockW + BLOCK_MARGIN_X); b.y = BLOCK_TOP_OFFSET + row * (blockH + BLOCK_MARGIN_Y); game.addChild(b); blocks.push(b); } } } // Helper: Reset game state function resetGame() { score = 0; lives = 3; currentLevel = 0; LK.setScore(0); if (scoreTxt) scoreTxt.setText('0'); if (livesTxt) livesTxt.setText('♥♥♥'); createBlocks(); // Increase ball speed with level (capped for sanity) BALL_SPEED = 18 + currentLevel * 2; if (BALL_SPEED > 40) BALL_SPEED = 40; // Reduce platform width as level increases (min 200) platform.width = 400 - currentLevel * 20; if (platform.width < 200) platform.width = 200; resetBall(); } // Helper: Update lives display function updateLives() { var s = ''; for (var i = 0; i < lives; i++) s += '♥'; livesTxt.setText(s); } // Helper: Ball-Block collision function ballBlockCollision(ball, block) { // AABB collision var dx = Math.abs(ball.x - block.x); var dy = Math.abs(ball.y - block.y); var bw = block.width / 2; var bh = block.height / 2; var br = ball.radius; if (dx > bw + br) return false; if (dy > bh + br) return false; // Find overlap var overlapX = bw + br - dx; var overlapY = bh + br - dy; if (overlapX > 0 && overlapY > 0) { // Determine collision side: reflect ball accordingly if (overlapX < overlapY) { ball.vx = -ball.vx; } else { ball.vy = -ball.vy; } // After bounce, normalize speed to keep it constant var angle = Math.atan2(ball.vy, ball.vx); ball.vx = BALL_SPEED * Math.cos(angle); ball.vy = BALL_SPEED * Math.sin(angle); return true; } return false; } // Helper: Ball-Platform collision function ballPlatformCollision(ball, platform) { // AABB collision var dx = Math.abs(ball.x - platform.x); var dy = Math.abs(ball.y - platform.y); var pw = platform.width / 2; var ph = platform.height / 2; var br = ball.radius; if (dx > pw + br) return false; if (dy > ph + br) return false; // Only reflect if ball is moving down if (ball.vy > 0) { // Calculate hit position (-1 left, 0 center, 1 right) var hit = (ball.x - platform.x) / pw; // Clamp hit hit = clamp(hit, -1, 1); // Reflect angle: 150deg (left) to 30deg (right) var angle = Math.PI - Math.PI / 3 * (hit + 1) / 2; // 150 to 30 deg ball.vx = BALL_SPEED * Math.cos(angle); ball.vy = -BALL_SPEED * Math.sin(angle); // After bounce, normalize speed to keep it constant var norm = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy); if (norm !== 0) { ball.vx = BALL_SPEED * (ball.vx / norm); ball.vy = BALL_SPEED * (ball.vy / norm); } } return true; } // Helper: Ball-Wall collision function ballWallCollision(ball) { // Left wall if (ball.x - ball.radius < 0) { ball.x = ball.radius; // Calculate current angle var angle = Math.atan2(ball.vy, -ball.vx); // Clamp angle to avoid too shallow (force more vertical) if (Math.abs(angle) < BALL_MIN_ANGLE) { angle = BALL_MIN_ANGLE * (ball.vy < 0 ? -1 : 1); } ball.vx = BALL_SPEED * Math.cos(angle); ball.vy = BALL_SPEED * Math.sin(angle); } // Right wall if (ball.x + ball.radius > GAME_WIDTH) { ball.x = GAME_WIDTH - ball.radius; // Calculate current angle var angle = Math.atan2(ball.vy, -ball.vx); // Clamp angle to avoid too shallow (force more vertical) if (Math.abs(angle) < BALL_MIN_ANGLE) { angle = BALL_MIN_ANGLE * (ball.vy < 0 ? -1 : 1); } ball.vx = BALL_SPEED * Math.cos(angle); ball.vy = BALL_SPEED * Math.sin(angle); } // Top wall if (ball.y - ball.radius < 0) { ball.y = ball.radius; ball.vy = -ball.vy; } } // Helper: Ball out of bounds function ballOutOfBounds(ball) { return ball.y - ball.radius > GAME_HEIGHT; } // GUI: Score scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // GUI: Lives livesTxt = new Text2('♥♥♥', { size: 100, fill: 0xE74C3C }); livesTxt.anchor.set(1, 0); LK.gui.topRight.addChild(livesTxt); // Create platform platform = new Platform(); platform.x = GAME_WIDTH / 2; platform.y = PLATFORM_Y; game.addChild(platform); // Create ball ball = new Ball(); resetBall(); game.addChild(ball); // Create blocks createBlocks(); // Input: Drag platform game.down = function (x, y, obj) { // Only allow drag if touch is near platform if (Math.abs(y - platform.y) < 200) { dragPlatform = true; lastTouchX = x; // If ball not launched, move ball with platform if (!isBallLaunched) { ball.x = platform.x; } } }; game.move = function (x, y, obj) { if (dragPlatform) { // Move platform horizontally, clamp to screen platform.x = clamp(x, platform.width / 2, GAME_WIDTH - platform.width / 2); // If ball not launched, move ball with platform if (!isBallLaunched) { ball.x = platform.x; } } }; game.up = function (x, y, obj) { if (dragPlatform) { // On release, if ball not launched, launch it if (!isBallLaunched) { launchBall(); } dragPlatform = false; } }; // Main game loop game.update = function () { // Ball movement if (isBallLaunched) { ball.update(); ballWallCollision(ball); // Platform collision ballPlatformCollision(ball, platform); // Block collisions for (var i = blocks.length - 1; i >= 0; i--) { if (ballBlockCollision(ball, blocks[i])) { // Decrement hit points blocks[i].hitPoints--; if (blocks[i].hitPoints > 0) { // Update visual feedback if (typeof blocks[i].updateBlockVisual === "function") { blocks[i].updateBlockVisual(); } } else { // Powerup drop chance decreases as level increases (min 5%) var powerupChance = 0.25 - currentLevel * 0.02; if (powerupChance < 0.05) powerupChance = 0.05; if (Math.random() < powerupChance) { var p = new Powerup(); p.x = blocks[i].x; p.y = blocks[i].y; game.addChild(p); powerups.push(p); } blocks[i].destroy(); blocks.splice(i, 1); score += 10; LK.setScore(score); scoreTxt.setText(score); } break; // Only one block per frame } } // Powerup logic for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; p.update(); // If powerup intersects platform, apply effect if (p.intersects(platform)) { // Activate powerup effect if (p.type === 'enlarge') { // Enlarge platform for 10 seconds var originalWidth = platform.width; platform.width *= 1.5; if (platform.width > 800) platform.width = 800; // Schedule shrink after 10 seconds LK.setTimeout(function () { // Only shrink if platform is still enlarged if (platform.width > originalWidth) { platform.width = originalWidth; } }, 10000); } else if (p.type === 'shrink') { // Shrink platform for 10 seconds var originalWidth = platform.width; platform.width *= 0.6; if (platform.width < 120) platform.width = 120; LK.setTimeout(function () { if (platform.width < originalWidth) { platform.width = originalWidth; } }, 10000); } else if (p.type === 'life') { // Add a life (max 5) if (lives < 5) { lives++; updateLives(); } } else if (p.type === 'slow') { // Slow down ball for 8 seconds var oldSpeed = BALL_SPEED; BALL_SPEED = Math.max(10, BALL_SPEED * 0.6); // Adjust ball velocity to new speed var angle = Math.atan2(ball.vy, ball.vx); ball.vx = BALL_SPEED * Math.cos(angle); ball.vy = BALL_SPEED * Math.sin(angle); LK.setTimeout(function () { BALL_SPEED = oldSpeed; // Re-adjust ball velocity to restored speed var angle2 = Math.atan2(ball.vy, ball.vx); ball.vx = BALL_SPEED * Math.cos(angle2); ball.vy = BALL_SPEED * Math.sin(angle2); }, 8000); } else if (p.type === 'fast') { // Speed up ball for 8 seconds var oldSpeed = BALL_SPEED; BALL_SPEED = Math.min(50, BALL_SPEED * 1.5); var angle = Math.atan2(ball.vy, ball.vx); ball.vx = BALL_SPEED * Math.cos(angle); ball.vy = BALL_SPEED * Math.sin(angle); LK.setTimeout(function () { BALL_SPEED = oldSpeed; var angle2 = Math.atan2(ball.vy, ball.vx); ball.vx = BALL_SPEED * Math.cos(angle2); ball.vy = BALL_SPEED * Math.sin(angle2); }, 8000); } p.destroy(); powerups.splice(i, 1); continue; } // Remove if out of bounds if (p.y > GAME_HEIGHT + 100) { p.destroy(); powerups.splice(i, 1); } } // Win condition: all blocks destroyed if (blocks.length === 0) { currentLevel++; if (currentLevel >= MAX_LEVEL) { LK.showYouWin(); return; } else { createBlocks(); resetBall(); return; } } // Ball out of bounds if (ballOutOfBounds(ball)) { lives--; updateLives(); if (lives <= 0) { LK.showGameOver(); return; } resetBall(); } } }; // --- Level Selection Screen --- var levelSelectContainers = []; function showLevelSelect() { // Remove any previous containers for (var i = 0; i < levelSelectContainers.length; i++) { levelSelectContainers[i].destroy(); } levelSelectContainers = []; // Title var title = new Text2("Bölüm Seç", { size: 180, fill: "#fff" }); title.anchor.set(0.5, 0); title.x = GAME_WIDTH / 2; title.y = 300; game.addChild(title); levelSelectContainers.push(title); // Level buttons (arrange in 4 rows of 5) var btnW = 320, btnH = 180, gapX = 80, gapY = 80; var totalW = 5 * btnW + 4 * gapX; var startX = (GAME_WIDTH - totalW) / 2 + btnW / 2; var startY = 700; for (var i = 0; i < MAX_LEVEL; i++) { (function (levelIdx) { var btn = new Container(); var bg = LK.getAsset('block', { anchorX: 0.5, anchorY: 0.5 }); bg.width = btnW; bg.height = btnH; btn.addChild(bg); // Color variety if (levelIdx % 3 === 1) bg.tint = 0x2ecc71; if (levelIdx % 3 === 2) bg.tint = 0x9b59b6; var txt = new Text2((levelIdx + 1).toString(), { size: 100, fill: "#fff" }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; btn.addChild(txt); // Position (4 rows of 5) btn.x = startX + levelIdx % 5 * (btnW + gapX); btn.y = startY + Math.floor(levelIdx / 5) * (btnH + gapY); // Touch handler btn.down = function (x, y, obj) { hideLevelSelect(); startGameAtLevel(levelIdx); }; game.addChild(btn); levelSelectContainers.push(btn); })(i); } } function hideLevelSelect() { for (var i = 0; i < levelSelectContainers.length; i++) { levelSelectContainers[i].destroy(); } levelSelectContainers = []; } // Start game at selected level function startGameAtLevel(levelIdx) { currentLevel = levelIdx; score = 0; lives = 3; LK.setScore(0); if (scoreTxt) scoreTxt.setText('0'); if (livesTxt) livesTxt.setText('♥♥♥'); createBlocks(); resetBall(); } // --- Override resetGame to show level select --- resetGame = function resetGame() { showLevelSelect(); }; // Show level select on game start showLevelSelect();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Ball Class
var Ball = Container.expand(function () {
var self = Container.call(this);
var ball = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = ball.width / 2;
// Ball velocity
self.vx = 0;
self.vy = 0;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
};
return self;
});
// Block Class
var Block = Container.expand(function () {
var self = Container.call(this);
// Color variety: assign a colorId based on blockType, but also randomize for more variety
var colorIds = ['block', 'block2', 'block3'];
var colorId;
var r = Math.random();
if (r < 0.1) {
self.hitPoints = 3;
colorId = 'block4'; // Unique color for 3-hit blocks
} else if (r < 0.3) {
self.hitPoints = 2;
if (typeof self.blockType === "number" && self.blockType >= 1 && self.blockType <= 3) {
colorId = colorIds[self.blockType - 1];
} else {
colorId = colorIds[Math.floor(Math.random() * colorIds.length)];
}
} else {
self.hitPoints = 1;
if (typeof self.blockType === "number" && self.blockType >= 1 && self.blockType <= 3) {
colorId = colorIds[self.blockType - 1];
} else {
colorId = colorIds[Math.floor(Math.random() * colorIds.length)];
}
}
var block = self.attachAsset(colorId, {
anchorX: 0.5,
anchorY: 0.5
});
self.width = block.width;
self.height = block.height;
self.updateBlockVisual = function () {
// Change tint or alpha based on hitPoints
if (self.hitPoints === 3) {
block.alpha = 1;
} else if (self.hitPoints === 2) {
block.alpha = 0.7;
} else {
block.alpha = 0.4;
}
};
self.updateBlockVisual();
return self;
});
// Platform (Paddle) Class
var Platform = Container.expand(function () {
var self = Container.call(this);
var plat = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = plat.width;
self.height = plat.height;
return self;
});
// Powerup Class
var Powerup = Container.expand(function () {
var self = Container.call(this);
// Define multiple powerup types
var types = [{
type: 'enlarge',
label: 'E',
color: 'block2'
}, {
type: 'shrink',
label: 'S',
color: 'block3'
}, {
type: 'life',
label: '♥',
color: 'block'
}, {
type: 'slow',
label: '⏳',
color: 'block2'
}, {
type: 'fast',
label: '⚡',
color: 'block3'
}];
// Randomly pick a powerup type
var chosen = types[Math.floor(Math.random() * types.length)];
self.type = chosen.type;
// Use different asset color for each powerup type
var asset = self.attachAsset(chosen.color, {
anchorX: 0.5,
anchorY: 0.5
});
asset.width = 100;
asset.height = 60;
// Add a text label for the powerup type
var txt = new Text2(chosen.label, {
size: 60,
fill: "#fff"
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = 0;
self.addChild(txt);
// Set speed
self.vy = 10;
self.update = function () {
self.y += self.vy;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Block (third color for variety)
// Block (second color for variety)
// Block
// Ball
// Platform (paddle)
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLATFORM_Y = GAME_HEIGHT - 200;
var BALL_START_Y = PLATFORM_Y - 80;
var BALL_SPEED = 18;
var BALL_MIN_ANGLE = Math.PI / 8; // ~22.5deg, to avoid too shallow
var BALL_MAX_ANGLE = Math.PI - Math.PI / 8;
var PLATFORM_SPEED = 60; // Not used, as platform is dragged directly
var BLOCK_ROWS = 5;
var BLOCK_COLS = 7;
var BLOCK_MARGIN_X = 30;
var BLOCK_MARGIN_Y = 30;
var BLOCK_TOP_OFFSET = 350;
var BLOCK_TYPES = [1, 2, 3];
// Game state
var platform;
var ball;
var blocks = [];
var powerups = []; // Track falling powerups
var score = 0;
var lives = 3;
var isBallLaunched = false;
var dragPlatform = false;
var lastTouchX = 0;
var scoreTxt;
var livesTxt;
// Helper: Reset ball to platform
function resetBall() {
ball.x = platform.x;
ball.y = BALL_START_Y;
ball.vx = 0;
ball.vy = 0;
isBallLaunched = false;
// Ball speed increases after level 10 for more challenge
if (currentLevel >= 10) {
BALL_SPEED = 24 + (currentLevel - 10) * 2;
if (BALL_SPEED > 50) BALL_SPEED = 50;
} else {
BALL_SPEED = 18 + currentLevel * 2;
if (BALL_SPEED > 40) BALL_SPEED = 40;
}
}
// Helper: Launch ball
function launchBall() {
if (!isBallLaunched) {
// Randomize initial angle between 45 and 135 degrees (upwards)
var angle = Math.PI / 4 + Math.random() * (Math.PI / 2);
ball.vx = BALL_SPEED * Math.cos(angle);
ball.vy = -BALL_SPEED * Math.sin(angle);
isBallLaunched = true;
}
}
// Helper: Clamp value
function clamp(val, min, max) {
if (val < min) return min;
if (val > max) return max;
return val;
}
// Level patterns: 20 unique block layouts (1: block, 0: empty, 2/3: alt color)
var LEVEL_PATTERNS = [
// Level 1: Full grid
[[1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1]],
// Level 2: Checkerboard
[[1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1], [0, 1, 0, 1, 0, 1, 0], [1, 0, 1, 0, 1, 0, 1]],
// Level 3: Pyramid
[[0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0]],
// Level 4: Hollow rectangle
[[2, 2, 2, 2, 2, 2, 2], [2, 0, 0, 0, 0, 0, 2], [2, 0, 0, 0, 0, 0, 2], [2, 0, 0, 0, 0, 0, 2], [2, 2, 2, 2, 2, 2, 2]],
// Level 5: Diagonal
[[3, 0, 0, 0, 0, 0, 3], [0, 3, 0, 0, 0, 3, 0], [0, 0, 3, 0, 3, 0, 0], [0, 0, 0, 3, 0, 0, 0], [0, 0, 3, 0, 3, 0, 0]],
// Level 6: Two triangles
[[1, 0, 0, 0, 0, 0, 1], [1, 1, 0, 0, 0, 1, 1], [1, 1, 1, 0, 1, 1, 1], [1, 1, 0, 0, 0, 1, 1], [1, 0, 0, 0, 0, 0, 1]],
// Level 7: Alternating rows
[[1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1], [2, 1, 2, 1, 2, 1, 2], [1, 2, 1, 2, 1, 2, 1]],
// Level 8: Center cross
[[0, 0, 3, 3, 3, 0, 0], [0, 0, 3, 3, 3, 0, 0], [3, 3, 3, 3, 3, 3, 3], [0, 0, 3, 3, 3, 0, 0], [0, 0, 3, 3, 3, 0, 0]],
// Level 9: Edges only
[[1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [1, 0, 0, 0, 0, 0, 1], [1, 1, 1, 1, 1, 1, 1]],
// Level 10: Zigzag
[[1, 0, 0, 0, 0, 0, 1], [0, 1, 0, 0, 0, 1, 0], [0, 0, 1, 0, 1, 0, 0], [0, 1, 0, 0, 0, 1, 0], [1, 0, 0, 0, 0, 0, 1]],
// Level 11: Dense center
[[0, 0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 2, 2, 2, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 1, 1, 0, 0]],
// Level 12: Alternating columns
[[1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1], [1, 2, 1, 2, 1, 2, 1]],
// Level 13: Arrow
[[0, 0, 0, 3, 0, 0, 0], [0, 0, 3, 3, 3, 0, 0], [0, 3, 3, 3, 3, 3, 0], [3, 3, 3, 3, 3, 3, 3], [0, 0, 0, 0, 0, 0, 0]],
// Level 14: Corners
[[2, 0, 0, 0, 0, 0, 2], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [2, 0, 0, 0, 0, 0, 2]],
// Level 15: Double cross
[[0, 2, 0, 2, 0, 2, 0], [2, 2, 2, 2, 2, 2, 2], [0, 2, 0, 2, 0, 2, 0], [2, 2, 2, 2, 2, 2, 2], [0, 2, 0, 2, 0, 2, 0]],
// Level 16: X shape
[[3, 0, 0, 0, 0, 0, 3], [0, 3, 0, 0, 0, 3, 0], [0, 0, 3, 0, 3, 0, 0], [0, 3, 0, 0, 0, 3, 0], [3, 0, 0, 0, 0, 0, 3]],
// Level 17: Center diamond
[[0, 0, 1, 0, 1, 0, 0], [0, 1, 1, 1, 1, 1, 0], [1, 1, 2, 2, 2, 1, 1], [0, 1, 1, 1, 1, 1, 0], [0, 0, 1, 0, 1, 0, 0]],
// Level 18: Top and bottom
[[1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1, 1]],
// Level 19: Alternating blocks
[[1, 0, 2, 0, 3, 0, 1], [0, 2, 0, 3, 0, 1, 0], [2, 0, 3, 0, 1, 0, 2], [0, 3, 0, 1, 0, 2, 0], [3, 0, 1, 0, 2, 0, 3]],
// Level 20: Dense grid
[[1, 2, 3, 1, 2, 3, 1], [2, 3, 1, 2, 3, 1, 2], [3, 1, 2, 3, 1, 2, 3], [1, 2, 3, 1, 2, 3, 1], [2, 3, 1, 2, 3, 1, 2]]];
var currentLevel = 0;
var MAX_LEVEL = LEVEL_PATTERNS.length;
// Helper: Create blocks
function createBlocks() {
// Remove old blocks
for (var i = 0; i < blocks.length; i++) {
blocks[i].destroy();
}
blocks = [];
// Calculate block size and spacing
var blockAsset = LK.getAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
var blockW = blockAsset.width;
var blockH = blockAsset.height;
var totalW = BLOCK_COLS * blockW + (BLOCK_COLS - 1) * BLOCK_MARGIN_X;
var startX = (GAME_WIDTH - totalW) / 2 + blockW / 2;
// Use pattern for current level
var pattern = LEVEL_PATTERNS[currentLevel % LEVEL_PATTERNS.length];
// Add more rows as level increases (up to 8)
var extraRows = Math.min(Math.floor(currentLevel / 2), 3);
for (var row = 0; row < BLOCK_ROWS + extraRows; row++) {
for (var col = 0; col < BLOCK_COLS; col++) {
var type = pattern[row] && pattern[row][col] ? pattern[row][col] : 0;
if (type === 0) continue;
var b = new Block();
b.blockType = type;
// Remove any previous children (for safety)
b.removeChildren();
// Assign a random colorId for each block for more color variety
var colorIds = ['block', 'block2', 'block3'];
var colorId;
if (typeof b.blockType === "number" && b.blockType >= 1 && b.blockType <= 3) {
// Pick a random color, but prefer the type's color
colorId = colorIds[Math.floor(Math.random() * colorIds.length)];
} else {
colorId = colorIds[Math.floor(Math.random() * colorIds.length)];
}
b.attachAsset(colorId, {
anchorX: 0.5,
anchorY: 0.5
});
b.x = startX + col * (blockW + BLOCK_MARGIN_X);
b.y = BLOCK_TOP_OFFSET + row * (blockH + BLOCK_MARGIN_Y);
game.addChild(b);
blocks.push(b);
}
}
}
// Helper: Reset game state
function resetGame() {
score = 0;
lives = 3;
currentLevel = 0;
LK.setScore(0);
if (scoreTxt) scoreTxt.setText('0');
if (livesTxt) livesTxt.setText('♥♥♥');
createBlocks();
// Increase ball speed with level (capped for sanity)
BALL_SPEED = 18 + currentLevel * 2;
if (BALL_SPEED > 40) BALL_SPEED = 40;
// Reduce platform width as level increases (min 200)
platform.width = 400 - currentLevel * 20;
if (platform.width < 200) platform.width = 200;
resetBall();
}
// Helper: Update lives display
function updateLives() {
var s = '';
for (var i = 0; i < lives; i++) s += '♥';
livesTxt.setText(s);
}
// Helper: Ball-Block collision
function ballBlockCollision(ball, block) {
// AABB collision
var dx = Math.abs(ball.x - block.x);
var dy = Math.abs(ball.y - block.y);
var bw = block.width / 2;
var bh = block.height / 2;
var br = ball.radius;
if (dx > bw + br) return false;
if (dy > bh + br) return false;
// Find overlap
var overlapX = bw + br - dx;
var overlapY = bh + br - dy;
if (overlapX > 0 && overlapY > 0) {
// Determine collision side: reflect ball accordingly
if (overlapX < overlapY) {
ball.vx = -ball.vx;
} else {
ball.vy = -ball.vy;
}
// After bounce, normalize speed to keep it constant
var angle = Math.atan2(ball.vy, ball.vx);
ball.vx = BALL_SPEED * Math.cos(angle);
ball.vy = BALL_SPEED * Math.sin(angle);
return true;
}
return false;
}
// Helper: Ball-Platform collision
function ballPlatformCollision(ball, platform) {
// AABB collision
var dx = Math.abs(ball.x - platform.x);
var dy = Math.abs(ball.y - platform.y);
var pw = platform.width / 2;
var ph = platform.height / 2;
var br = ball.radius;
if (dx > pw + br) return false;
if (dy > ph + br) return false;
// Only reflect if ball is moving down
if (ball.vy > 0) {
// Calculate hit position (-1 left, 0 center, 1 right)
var hit = (ball.x - platform.x) / pw;
// Clamp hit
hit = clamp(hit, -1, 1);
// Reflect angle: 150deg (left) to 30deg (right)
var angle = Math.PI - Math.PI / 3 * (hit + 1) / 2; // 150 to 30 deg
ball.vx = BALL_SPEED * Math.cos(angle);
ball.vy = -BALL_SPEED * Math.sin(angle);
// After bounce, normalize speed to keep it constant
var norm = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
if (norm !== 0) {
ball.vx = BALL_SPEED * (ball.vx / norm);
ball.vy = BALL_SPEED * (ball.vy / norm);
}
}
return true;
}
// Helper: Ball-Wall collision
function ballWallCollision(ball) {
// Left wall
if (ball.x - ball.radius < 0) {
ball.x = ball.radius;
// Calculate current angle
var angle = Math.atan2(ball.vy, -ball.vx);
// Clamp angle to avoid too shallow (force more vertical)
if (Math.abs(angle) < BALL_MIN_ANGLE) {
angle = BALL_MIN_ANGLE * (ball.vy < 0 ? -1 : 1);
}
ball.vx = BALL_SPEED * Math.cos(angle);
ball.vy = BALL_SPEED * Math.sin(angle);
}
// Right wall
if (ball.x + ball.radius > GAME_WIDTH) {
ball.x = GAME_WIDTH - ball.radius;
// Calculate current angle
var angle = Math.atan2(ball.vy, -ball.vx);
// Clamp angle to avoid too shallow (force more vertical)
if (Math.abs(angle) < BALL_MIN_ANGLE) {
angle = BALL_MIN_ANGLE * (ball.vy < 0 ? -1 : 1);
}
ball.vx = BALL_SPEED * Math.cos(angle);
ball.vy = BALL_SPEED * Math.sin(angle);
}
// Top wall
if (ball.y - ball.radius < 0) {
ball.y = ball.radius;
ball.vy = -ball.vy;
}
}
// Helper: Ball out of bounds
function ballOutOfBounds(ball) {
return ball.y - ball.radius > GAME_HEIGHT;
}
// GUI: Score
scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// GUI: Lives
livesTxt = new Text2('♥♥♥', {
size: 100,
fill: 0xE74C3C
});
livesTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(livesTxt);
// Create platform
platform = new Platform();
platform.x = GAME_WIDTH / 2;
platform.y = PLATFORM_Y;
game.addChild(platform);
// Create ball
ball = new Ball();
resetBall();
game.addChild(ball);
// Create blocks
createBlocks();
// Input: Drag platform
game.down = function (x, y, obj) {
// Only allow drag if touch is near platform
if (Math.abs(y - platform.y) < 200) {
dragPlatform = true;
lastTouchX = x;
// If ball not launched, move ball with platform
if (!isBallLaunched) {
ball.x = platform.x;
}
}
};
game.move = function (x, y, obj) {
if (dragPlatform) {
// Move platform horizontally, clamp to screen
platform.x = clamp(x, platform.width / 2, GAME_WIDTH - platform.width / 2);
// If ball not launched, move ball with platform
if (!isBallLaunched) {
ball.x = platform.x;
}
}
};
game.up = function (x, y, obj) {
if (dragPlatform) {
// On release, if ball not launched, launch it
if (!isBallLaunched) {
launchBall();
}
dragPlatform = false;
}
};
// Main game loop
game.update = function () {
// Ball movement
if (isBallLaunched) {
ball.update();
ballWallCollision(ball);
// Platform collision
ballPlatformCollision(ball, platform);
// Block collisions
for (var i = blocks.length - 1; i >= 0; i--) {
if (ballBlockCollision(ball, blocks[i])) {
// Decrement hit points
blocks[i].hitPoints--;
if (blocks[i].hitPoints > 0) {
// Update visual feedback
if (typeof blocks[i].updateBlockVisual === "function") {
blocks[i].updateBlockVisual();
}
} else {
// Powerup drop chance decreases as level increases (min 5%)
var powerupChance = 0.25 - currentLevel * 0.02;
if (powerupChance < 0.05) powerupChance = 0.05;
if (Math.random() < powerupChance) {
var p = new Powerup();
p.x = blocks[i].x;
p.y = blocks[i].y;
game.addChild(p);
powerups.push(p);
}
blocks[i].destroy();
blocks.splice(i, 1);
score += 10;
LK.setScore(score);
scoreTxt.setText(score);
}
break; // Only one block per frame
}
}
// Powerup logic
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
p.update();
// If powerup intersects platform, apply effect
if (p.intersects(platform)) {
// Activate powerup effect
if (p.type === 'enlarge') {
// Enlarge platform for 10 seconds
var originalWidth = platform.width;
platform.width *= 1.5;
if (platform.width > 800) platform.width = 800;
// Schedule shrink after 10 seconds
LK.setTimeout(function () {
// Only shrink if platform is still enlarged
if (platform.width > originalWidth) {
platform.width = originalWidth;
}
}, 10000);
} else if (p.type === 'shrink') {
// Shrink platform for 10 seconds
var originalWidth = platform.width;
platform.width *= 0.6;
if (platform.width < 120) platform.width = 120;
LK.setTimeout(function () {
if (platform.width < originalWidth) {
platform.width = originalWidth;
}
}, 10000);
} else if (p.type === 'life') {
// Add a life (max 5)
if (lives < 5) {
lives++;
updateLives();
}
} else if (p.type === 'slow') {
// Slow down ball for 8 seconds
var oldSpeed = BALL_SPEED;
BALL_SPEED = Math.max(10, BALL_SPEED * 0.6);
// Adjust ball velocity to new speed
var angle = Math.atan2(ball.vy, ball.vx);
ball.vx = BALL_SPEED * Math.cos(angle);
ball.vy = BALL_SPEED * Math.sin(angle);
LK.setTimeout(function () {
BALL_SPEED = oldSpeed;
// Re-adjust ball velocity to restored speed
var angle2 = Math.atan2(ball.vy, ball.vx);
ball.vx = BALL_SPEED * Math.cos(angle2);
ball.vy = BALL_SPEED * Math.sin(angle2);
}, 8000);
} else if (p.type === 'fast') {
// Speed up ball for 8 seconds
var oldSpeed = BALL_SPEED;
BALL_SPEED = Math.min(50, BALL_SPEED * 1.5);
var angle = Math.atan2(ball.vy, ball.vx);
ball.vx = BALL_SPEED * Math.cos(angle);
ball.vy = BALL_SPEED * Math.sin(angle);
LK.setTimeout(function () {
BALL_SPEED = oldSpeed;
var angle2 = Math.atan2(ball.vy, ball.vx);
ball.vx = BALL_SPEED * Math.cos(angle2);
ball.vy = BALL_SPEED * Math.sin(angle2);
}, 8000);
}
p.destroy();
powerups.splice(i, 1);
continue;
}
// Remove if out of bounds
if (p.y > GAME_HEIGHT + 100) {
p.destroy();
powerups.splice(i, 1);
}
}
// Win condition: all blocks destroyed
if (blocks.length === 0) {
currentLevel++;
if (currentLevel >= MAX_LEVEL) {
LK.showYouWin();
return;
} else {
createBlocks();
resetBall();
return;
}
}
// Ball out of bounds
if (ballOutOfBounds(ball)) {
lives--;
updateLives();
if (lives <= 0) {
LK.showGameOver();
return;
}
resetBall();
}
}
};
// --- Level Selection Screen ---
var levelSelectContainers = [];
function showLevelSelect() {
// Remove any previous containers
for (var i = 0; i < levelSelectContainers.length; i++) {
levelSelectContainers[i].destroy();
}
levelSelectContainers = [];
// Title
var title = new Text2("Bölüm Seç", {
size: 180,
fill: "#fff"
});
title.anchor.set(0.5, 0);
title.x = GAME_WIDTH / 2;
title.y = 300;
game.addChild(title);
levelSelectContainers.push(title);
// Level buttons (arrange in 4 rows of 5)
var btnW = 320,
btnH = 180,
gapX = 80,
gapY = 80;
var totalW = 5 * btnW + 4 * gapX;
var startX = (GAME_WIDTH - totalW) / 2 + btnW / 2;
var startY = 700;
for (var i = 0; i < MAX_LEVEL; i++) {
(function (levelIdx) {
var btn = new Container();
var bg = LK.getAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
bg.width = btnW;
bg.height = btnH;
btn.addChild(bg);
// Color variety
if (levelIdx % 3 === 1) bg.tint = 0x2ecc71;
if (levelIdx % 3 === 2) bg.tint = 0x9b59b6;
var txt = new Text2((levelIdx + 1).toString(), {
size: 100,
fill: "#fff"
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = 0;
btn.addChild(txt);
// Position (4 rows of 5)
btn.x = startX + levelIdx % 5 * (btnW + gapX);
btn.y = startY + Math.floor(levelIdx / 5) * (btnH + gapY);
// Touch handler
btn.down = function (x, y, obj) {
hideLevelSelect();
startGameAtLevel(levelIdx);
};
game.addChild(btn);
levelSelectContainers.push(btn);
})(i);
}
}
function hideLevelSelect() {
for (var i = 0; i < levelSelectContainers.length; i++) {
levelSelectContainers[i].destroy();
}
levelSelectContainers = [];
}
// Start game at selected level
function startGameAtLevel(levelIdx) {
currentLevel = levelIdx;
score = 0;
lives = 3;
LK.setScore(0);
if (scoreTxt) scoreTxt.setText('0');
if (livesTxt) livesTxt.setText('♥♥♥');
createBlocks();
resetBall();
}
// --- Override resetGame to show level select ---
resetGame = function resetGame() {
showLevelSelect();
};
// Show level select on game start
showLevelSelect();