Code edit (6 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
yazı hala sığmıyor %10 daha büyütelim pop-up'ı. Congratulations yazını daha belirgin yapalım , beyaz rengi ile görünmesi zor oluyor, belki gölgelendirme ekleyebiliriz sana bırakıyorum ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Congratulations yazısı pop-up içerisine sığmıyor , pop-up'ın çerçevesini %10 daha büyüt
User prompt
Çıkan pop-up'ları %20 oranında büyüt
User prompt
Oyun içi tüm metinleri ingilizceye çevir
User prompt
10.level bittiğinde level sonu pop up'ı çıkmasın. Oyun sonu pop-up'ı çıksın
User prompt
if level = 10 yapalım
User prompt
Pop-up çıktığında sağ üstteki yenileme butonu gizlensin. Levele başladığımda geri gelsin
User prompt
Leveli yeniden oynadığımda toplam skora eklediği puanı çıkartalım
/**** * Classes ****/ // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletAsset = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.radius = bulletAsset.width / 2; self.vx = 0; self.vy = 0; self.lastX = 0; self.lastY = 0; self.update = function () { self.lastX = self.x; self.lastY = self.y; self.x += self.vx; self.y += self.vy; // Rotate bullet to match its direction if (self.vx !== 0 || self.vy !== 0) { bulletAsset.rotation = Math.atan2(self.vy, self.vx); } // Wall bounce if (self.x - self.radius <= ARENA_X && self.lastX - self.radius > ARENA_X) { self.x = ARENA_X + self.radius; self.vx *= -1; // No sound for left wall } if (self.x + self.radius >= ARENA_X + ARENA_SIZE && self.lastX + self.radius < ARENA_X + ARENA_SIZE) { self.x = ARENA_X + ARENA_SIZE - self.radius; self.vx *= -1; // No sound for right wall } // No sound for top wall if (self.y - self.radius <= ARENA_Y && self.lastY - self.radius > ARENA_Y) { self.y = ARENA_Y + self.radius; self.vy *= -1; } // No sound for bottom wall if (self.y + self.radius >= ARENA_Y + ARENA_SIZE && self.lastY + self.radius < ARENA_Y + ARENA_SIZE) { self.y = ARENA_Y + ARENA_SIZE - self.radius; self.vy *= -1; } }; return self; }); // Obstacle class var Obstacle = Container.expand(function () { var self = Container.call(this); var obsAsset = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.width = obsAsset.width; self.height = obsAsset.height; // Crack state: 0 = no crack, 1 = small crack, 2 = big crack, 3 = broken self.crackLevel = 0; self.crackAsset = null; // Show crack overlay self.showCrack = function (level) { // Remove previous crack asset if any if (self.crackAsset) { self.crackAsset.destroy(); self.crackAsset = null; } if (level === 1) { // Small crack self.crackAsset = self.attachAsset('obstacle_crack1', { anchorX: 0.5, anchorY: 0.5 }); } else if (level === 2) { // Big crack self.crackAsset = self.attachAsset('obstacle_crack2', { anchorX: 0.5, anchorY: 0.5 }); } // If level 0 or 3, no crack overlay }; // Break wall (remove from game) self.breakWall = function () { // Play break sound var breakSound = LK.getSound && LK.getSound('break'); if (breakSound) { breakSound.play(); } // Remove crack asset if any if (self.crackAsset) { self.crackAsset.destroy(); self.crackAsset = null; } // Remove self from game self.destroy(); }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerAsset = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.radius = playerAsset.width / 2; return self; }); // Target class var Target = Container.expand(function () { var self = Container.call(this); var targetAsset = self.attachAsset('target', { anchorX: 0.5, anchorY: 0.5 }); self.radius = targetAsset.width / 2; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Add background image to the game scene // Small crack overlay // Big crack overlay // Wall break sound var backgroundImg = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, width: 2048, height: 2732 }); game.addChild(backgroundImg); // Arena and gameplay variables var ARENA_SIZE = 1800; // Square arena, fits well in 2048x2732 var ARENA_X = (2048 - ARENA_SIZE) / 2; var ARENA_Y = (2732 - ARENA_SIZE) / 2; // Add visible arena border using a white rectangle shape var borderThickness = 16; var borderColor = 0xffffff; var arenaBorder = LK.getAsset('arenaBorder', { anchorX: 0, anchorY: 0, x: ARENA_X - borderThickness / 2, y: ARENA_Y - borderThickness / 2, width: ARENA_SIZE + borderThickness, height: ARENA_SIZE + borderThickness, color: borderColor, shape: 'box' }); game.addChild(arenaBorder); // Arena and gameplay variables var ARENA_SIZE = 1800; // Square arena, fits well in 2048x2732 var ARENA_X = (2048 - ARENA_SIZE) / 2; var ARENA_Y = (2732 - ARENA_SIZE) / 2; var player = null; var target = null; var bullets = []; var obstacles = []; var level = 1; var isAiming = false; var aimLine = null; var aimStart = null; var aimEnd = null; var blockAimForOneFrame = false; // Prevents shooting right after popup closes // Store X positions for each level so they are consistent on restart var levelPositions = {}; // Level score: calculated as number of obstacles * 100 at level start var levelScore = 0; // Total score: sum of all level scores, resets to 0 at game start var totalScore = 0; function setupLevel(lvl) { // If starting a new game (level 1), reset totalScore to 0 and update text if (lvl === 1) { totalScore = 0; if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) { totalScoreTxt.setText('Toplam Skor: ' + totalScore); } } // Always ensure arena border is above background and below gameplay elements if (arenaBorder && arenaBorder.parent) { arenaBorder.parent.removeChild(arenaBorder); } game.addChild(arenaBorder); // Clear previous if (player) { player.destroy(); } if (target) { target.destroy(); } for (var i = 0; i < bullets.length; ++i) { bullets[i].destroy(); } bullets = []; for (var i = 0; i < obstacles.length; ++i) { obstacles[i].destroy(); } obstacles = []; // Player at random X along bottom, but keep same X for same level player = new Player(); var playerMinX = ARENA_X + player.radius + 60; var playerMaxX = ARENA_X + ARENA_SIZE - player.radius - 60; if (!levelPositions[lvl]) { levelPositions[lvl] = {}; levelPositions[lvl].playerX = playerMinX + Math.random() * (playerMaxX - playerMinX); } player.x = levelPositions[lvl].playerX; player.y = ARENA_Y + ARENA_SIZE - 120; game.addChild(player); // Set player asset rotation to default (facing up) if (typeof player.children !== "undefined" && player.children.length > 0) { var playerAsset = player.children[0]; playerAsset.rotation = -Math.PI / 2; } // Target at random X along top, but keep same X for same level target = new Target(); var targetMinX = ARENA_X + target.radius + 60; var targetMaxX = ARENA_X + ARENA_SIZE - target.radius - 60; if (!levelPositions[lvl].targetX) { levelPositions[lvl].targetX = targetMinX + Math.random() * (targetMaxX - targetMinX); } target.x = levelPositions[lvl].targetX; target.y = ARENA_Y + 120; game.addChild(target); // Obstacles for all levels, always at least 1 between player and target var obsCount = Math.max(1, lvl * 2); if (!levelPositions[lvl].obstacles) { levelPositions[lvl].obstacles = []; // Always place the first obstacle between player and target (on the line between them) var obsDummy = new Obstacle(); var margin = 200; var t = 0.5 + (Math.random() - 0.5) * 0.2; // t in [0.4,0.6] for some randomness var betweenX = levelPositions[lvl].playerX * (1 - t) + levelPositions[lvl].targetX * t; // Clamp X to arena betweenX = Math.max(ARENA_X + margin + obsDummy.width / 2, Math.min(ARENA_X + ARENA_SIZE - margin - obsDummy.width / 2, betweenX)); var betweenY = ARENA_Y + ARENA_SIZE / 2 + (Math.random() - 0.5) * 200; // Center-ish, some vertical randomness levelPositions[lvl].obstacles.push({ x: betweenX, y: betweenY }); obsDummy.destroy(); // Place additional obstacles for all levels for (var i = 1; i < obsCount; ++i) { var obsDummy2 = new Obstacle(); var posType = i % 3; var xPos; var maxTries = 20; var tryCount = 0; do { if (posType === 0) { // Left third xPos = ARENA_X + margin + obsDummy2.width / 2 + Math.random() * (ARENA_SIZE / 3 - margin - obsDummy2.width); } else if (posType === 1) { // Right third xPos = ARENA_X + 2 * ARENA_SIZE / 3 + margin + obsDummy2.width / 2 + Math.random() * (ARENA_SIZE / 3 - margin - obsDummy2.width); } else { // Center third xPos = ARENA_X + ARENA_SIZE / 3 + margin + obsDummy2.width / 2 + Math.random() * (ARENA_SIZE / 3 - 2 * margin - obsDummy2.width); } tryCount++; } while ((Math.abs(xPos - levelPositions[lvl].playerX) < obsDummy2.width || Math.abs(xPos - levelPositions[lvl].targetX) < obsDummy2.width || levelPositions[lvl].obstacles.some(function (o) { return Math.abs(xPos - o.x) < obsDummy2.width && Math.abs(o.y - (ARENA_Y + ARENA_SIZE / (obsCount + 1) * (i + 1))) < obsDummy2.height; })) && tryCount < maxTries); // Y position: spread vertically, but randomize a bit var yBase = ARENA_Y + ARENA_SIZE / (obsCount + 1) * (i + 1); var yRand = Math.random() * 120 - 60; // -60 to +60 px var yPos = yBase + yRand; // Prevent obstacles from being below the player or above the target // Player is always at bottom, target is always at top // Clamp yPos so that it is not below the player or above the target var minY = Math.min(levelPositions[lvl].playerY || ARENA_Y + ARENA_SIZE - 120) - obsDummy2.height / 2 - 40; var maxY = Math.max(levelPositions[lvl].targetY || ARENA_Y + 120) + obsDummy2.height / 2 + 40; if (yPos > minY) { yPos = minY; } if (yPos < maxY) { yPos = maxY; } levelPositions[lvl].obstacles.push({ x: xPos, y: yPos }); obsDummy2.destroy(); } } for (var i = 0; i < levelPositions[lvl].obstacles.length; ++i) { var obs = new Obstacle(); obs.x = levelPositions[lvl].obstacles[i].x; obs.y = levelPositions[lvl].obstacles[i].y; game.addChild(obs); obstacles.push(obs); } // Set levelScore: number of obstacles * 100 levelScore = obstacles.length * 100; } setupLevel(level); // Level counter text var levelTxt = new Text2('Level: ' + level + ' / 10', { size: 100, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); // Place at top center, but not in the top left 100x100 area LK.gui.top.addChild(levelTxt); // Total score text, placed between level and level score var totalScoreTxt = new Text2('Toplam Skor: ' + totalScore, { size: 80, fill: 0x00FFFF }); totalScoreTxt.anchor.set(0.5, 0); totalScoreTxt.x = 0; totalScoreTxt.y = 90; // 90px below the top (between level and level score, with extra space above and below) levelTxt.addChild(totalScoreTxt); // Level score text, placed below the total score text var levelScoreTxt = new Text2('Skor: ' + levelScore, { size: 80, fill: 0xFFFF00 }); levelScoreTxt.anchor.set(0.5, 0); levelScoreTxt.x = 0; levelScoreTxt.y = 190; // 190px below the top (with extra space below total score) levelTxt.addChild(levelScoreTxt); // Add a button to restart the current level (without resetting level number) var retryBtn = new Text2('↺', { size: 120, fill: 0xFFFFFF }); retryBtn.anchor.set(0.5, 0.5); // Place at top left, just below the restart button, still below the 100x100 reserved area retryBtn.x = 600; retryBtn.y = 100; retryBtn.interactive = true; retryBtn.buttonMode = true; // Store the last level score to allow subtraction on retry if (typeof lastLevelScore === "undefined") { var lastLevelScore = 0; } retryBtn.down = function (x, y, obj) { // Subtract the last level's score from totalScore before retrying if (typeof lastLevelScore !== "undefined") { totalScore = Math.max(0, totalScore - lastLevelScore); if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) { totalScoreTxt.setText('Toplam Skor: ' + totalScore); } } setupLevel(level); if (levelTxt) { levelTxt.setText('Level: ' + level + ' / 10'); } if (levelScoreTxt) { levelScoreTxt.setText('Skor: ' + levelScore); } }; LK.gui.top.addChild(retryBtn); // Aiming and shooting game.down = function (x, y, obj) { // Prevent aiming if a popup is visible (by checking for popupBg, nextBtn, or retryBtn2 on stage) if (typeof popupBg !== "undefined" && popupBg && popupBg.parent || typeof nextBtn !== "undefined" && nextBtn && nextBtn.parent || typeof retryBtn2 !== "undefined" && retryBtn2 && retryBtn2.parent) { // Ignore down event if popup is visible return; } // Block aiming until a new tap after popup closes // (blockAimForOneFrame logic removed to allow immediate aiming after popup) // Only allow aiming if no bullet is in play if (bullets.length === 0) { isAiming = true; aimStart = { x: player.x, y: player.y }; aimEnd = { x: x, y: y }; } }; game.move = function (x, y, obj) { if (isAiming) { aimEnd = { x: x, y: y }; // Rotate player asset to match the aiming direction if (aimEnd && player) { var dx = aimEnd.x - player.x; var dy = aimEnd.y - player.y; if (typeof player.children !== "undefined" && player.children.length > 0) { // playerAsset is the first child var playerAsset = player.children[0]; playerAsset.rotation = Math.atan2(dy, dx); } } } }; game.up = function (x, y, obj) { if (isAiming) { // Fire bullet var dx = aimEnd.x - player.x; var dy = aimEnd.y - player.y; var len = Math.sqrt(dx * dx + dy * dy); if (len > 10) { var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y; var speed = 30; bullet.vx = dx / len * speed; bullet.vy = dy / len * speed; bullets.push(bullet); game.addChild(bullet); } isAiming = false; aimStart = null; aimEnd = null; // Reset player asset rotation to default (facing up) if (typeof player.children !== "undefined" && player.children.length > 0) { var playerAsset = player.children[0]; playerAsset.rotation = -Math.PI / 2; } } }; // Main update loop game.update = function () { // Prevent aim line and aiming logic if popup is visible // Draw aim line if aiming if (isAiming && aimStart && aimEnd) { if (!aimLine) { aimLine = LK.getAsset('aimLine', { anchorX: 0, anchorY: 0 }); game.addChild(aimLine); } // Set aimLine position and size var dx = aimEnd.x - aimStart.x; var dy = aimEnd.y - aimStart.y; var len = Math.sqrt(dx * dx + dy * dy); aimLine.x = aimStart.x; aimLine.y = aimStart.y; aimLine.width = len; aimLine.height = 10; aimLine.rotation = Math.atan2(dy, dx); } else if (aimLine) { aimLine.destroy(); aimLine = null; } // Update bullets var _loop = function _loop() { b = bullets[i]; b.update(); // Check collision with target if (target) { dx = b.x - target.x; dy = b.y - target.y; dist = Math.sqrt(dx * dx + dy * dy); if (dist < b.radius + target.radius) { var removePopup = function removePopup() { if (popupBg && popupBg.parent) { popupBg.parent.removeChild(popupBg); } if (popupText && popupText.parent) { popupText.parent.removeChild(popupText); } if (nextBtn && nextBtn.parent) { nextBtn.parent.removeChild(nextBtn); } if (retryBtn2 && retryBtn2.parent) { retryBtn2.parent.removeChild(retryBtn2); } if (brokenTarget && brokenTarget.parent) { brokenTarget.parent.removeChild(brokenTarget); } }; // Play special sound for hitting the target targetHitSound = LK.getSound && LK.getSound('targethit'); if (targetHitSound) { targetHitSound.play(); } // Show broken target image brokenTarget = LK.getAsset('target_broken', { anchorX: 0.5, anchorY: 0.5, x: target.x, y: target.y }); game.addChild(brokenTarget); // Remove bullet and target b.destroy(); bullets.splice(i, 1); if (target) { target.destroy(); target = null; } // Add levelScore to totalScore and update totalScoreTxt if (typeof lastLevelScore === "undefined") { var lastLevelScore = 0; } lastLevelScore = levelScore; totalScore += levelScore; if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) { totalScoreTxt.setText('Toplam Skor: ' + totalScore); } // Show popup with Next Level and Retry buttons // Add popup background image first (behind all popup elements) popupBgImg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 735, //{37} // 700 * 1.05 = 735 height: 735 }); popupBgImg.alpha = 0.7; popupBg = LK.getAsset('arenaBorder', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 735, //{3d} // 700 * 1.05 = 735 height: 735, color: 0x222222, shape: 'box' }); popupBg.alpha = 0.96; popupText = new Text2('Tebrikler!', { size: 120, fill: 0xFFFFFF }); popupText.anchor.set(0.5, 0); popupText.x = 2048 / 2; popupText.y = 2732 / 2 - 320; // Level score text in popup, now between 'Tebrikler!' and 'Sıradaki Level' var popupScoreText = new Text2('Level Skoru: ' + levelScore, { size: 90, fill: 0xFFFF00 }); popupScoreText.anchor.set(0.5, 0); popupScoreText.x = 2048 / 2; popupScoreText.y = 2732 / 2 - 60; // 20px more space below "Tebrikler!" // Total score text in popup, below level score with extra spacing var popupTotalScoreText = new Text2('Toplam Skor: ' + totalScore, { size: 90, fill: 0x00FFFF }); popupTotalScoreText.anchor.set(0.5, 0); popupTotalScoreText.x = 2048 / 2; popupTotalScoreText.y = 2732 / 2 + 40; // 30px more space below level score // Use text buttons for Next Level and Retry, placed side by side, more centered and further down, and 10% larger var btnY = 2732 / 2 + 270; // move buttons further down var btnSpacing = 40; // reduced spacing to bring buttons closer to center var btnWidth = 320 * 1.1; // 10% larger var btnHeight = 120 * 1.1; // 10% larger nextBtn = new Text2('▷', { size: 110, //{3p} // 10% larger fill: 0x00FF00 }); nextBtn.anchor.set(0.5, 0.5); // Next Level button on the right, closer to center nextBtn.x = 2048 / 2 + btnWidth / 2 + btnSpacing / 2; nextBtn.y = btnY; nextBtn.interactive = true; nextBtn.buttonMode = true; retryBtn2 = new Text2('↺', { size: 110, //{3r} // 10% larger fill: 0xFF3333 }); retryBtn2.anchor.set(0.5, 0.5); // Retry button on the left, closer to center retryBtn2.x = 2048 / 2 - btnWidth / 2 - btnSpacing / 2; retryBtn2.y = btnY; retryBtn2.interactive = true; retryBtn2.buttonMode = true; nextBtn.down = function (x, y, obj) { removePopup(); level += 1; if (level > 10) { // Show final popup: Oyun Bitti, toplam skor, and restart button // Remove any remaining gameplay elements if (player) { player.destroy(); player = null; } if (target) { target.destroy(); target = null; } for (var i = 0; i < bullets.length; ++i) { bullets[i].destroy(); } bullets = []; for (var i = 0; i < obstacles.length; ++i) { obstacles[i].destroy(); } obstacles = []; // Final popup background var finalPopupBgImg = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 735, height: 735 }); finalPopupBgImg.alpha = 0.7; var finalPopupBg = LK.getAsset('arenaBorder', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 735, height: 735, color: 0x222222, shape: 'box' }); finalPopupBg.alpha = 0.96; var finalPopupText = new Text2('Oyun Bitti!', { size: 120, fill: 0xFFFFFF }); finalPopupText.anchor.set(0.5, 0); finalPopupText.x = 2048 / 2; finalPopupText.y = 2732 / 2 - 320; var finalPopupTotalScoreText = new Text2('Toplam Skor: ' + totalScore, { size: 100, fill: 0x00FFFF }); finalPopupTotalScoreText.anchor.set(0.5, 0); finalPopupTotalScoreText.x = 2048 / 2; finalPopupTotalScoreText.y = 2732 / 2 - 60; // Restart button var finalRestartBtn = new Text2('Baştan Başla', { size: 110, fill: 0x00FF00 }); finalRestartBtn.anchor.set(0.5, 0.5); finalRestartBtn.x = 2048 / 2; finalRestartBtn.y = 2732 / 2 + 200; finalRestartBtn.interactive = true; finalRestartBtn.buttonMode = true; finalRestartBtn.down = function (x, y, obj) { // Remove popup if (finalPopupBgImg && finalPopupBgImg.parent) finalPopupBgImg.parent.removeChild(finalPopupBgImg); if (finalPopupBg && finalPopupBg.parent) finalPopupBg.parent.removeChild(finalPopupBg); if (finalPopupText && finalPopupText.parent) finalPopupText.parent.removeChild(finalPopupText); if (finalPopupTotalScoreText && finalPopupTotalScoreText.parent) finalPopupTotalScoreText.parent.removeChild(finalPopupTotalScoreText); if (finalRestartBtn && finalRestartBtn.parent) finalRestartBtn.parent.removeChild(finalRestartBtn); // Reset game level = 1; setupLevel(level); if (levelTxt) { levelTxt.setText('Level: ' + level + ' / 10'); } if (levelScoreTxt) { levelScoreTxt.setText('Skor: ' + levelScore); } if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) { totalScoreTxt.setText('Toplam Skor: ' + totalScore); } isAiming = false; aimStart = null; aimEnd = null; }; game.addChild(finalPopupBgImg); game.addChild(finalPopupBg); game.addChild(finalPopupText); game.addChild(finalPopupTotalScoreText); game.addChild(finalRestartBtn); return; } setupLevel(level); if (levelTxt) { levelTxt.setText('Level: ' + level + ' / 10'); } if (levelScoreTxt) { levelScoreTxt.setText('Skor: ' + levelScore); } if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) { totalScoreTxt.setText('Toplam Skor: ' + totalScore); } isAiming = false; aimStart = null; aimEnd = null; // blockAimForOneFrame removed to allow immediate aiming after popup }; retryBtn2.down = function (x, y, obj) { // Subtract the last level's score from totalScore before retrying if (typeof lastLevelScore !== "undefined") { totalScore = Math.max(0, totalScore - lastLevelScore); if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) { totalScoreTxt.setText('Toplam Skor: ' + totalScore); } } removePopup(); setupLevel(level); if (levelTxt) { levelTxt.setText('Level: ' + level + ' / 10'); } if (levelScoreTxt) { levelScoreTxt.setText('Skor: ' + levelScore); } if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) { totalScoreTxt.setText('Toplam Skor: ' + totalScore); } isAiming = false; aimStart = null; aimEnd = null; // blockAimForOneFrame removed to allow immediate aiming after popup }; // Only show retryBtn2 if not on final level (level < 10) game.addChild(popupBgImg); game.addChild(popupBg); game.addChild(popupText); game.addChild(popupScoreText); game.addChild(popupTotalScoreText); game.addChild(nextBtn); if (level < 10) { game.addChild(retryBtn2); } return { v: void 0 }; } } // end if (target) // Check collision with obstacles for (j = obstacles.length - 1; j >= 0; --j) { obs = obstacles[j]; left = obs.x - obs.width / 2; right = obs.x + obs.width / 2; top = obs.y - obs.height / 2; bottom = obs.y + obs.height / 2; // Simple AABB collision if (b.x + b.radius > left && b.x - b.radius < right && b.y + b.radius > top && b.y - b.radius < bottom) { // Reflect bullet: pick axis of minimum penetration overlapX = Math.min(Math.abs(b.x + b.radius - left), Math.abs(b.x - b.radius - right)); overlapY = Math.min(Math.abs(b.y + b.radius - top), Math.abs(b.y - b.radius - bottom)); if (overlapX < overlapY) { b.vx *= -1; } else { b.vy *= -1; } // Crack and break logic if (typeof obs.crackLevel === "undefined") { obs.crackLevel = 0; } obs.crackLevel++; // Decrease levelScore by 20 for each obstacle hit, but not below 0 levelScore = Math.max(0, levelScore - 20); if (levelScoreTxt) { levelScoreTxt.setText('Level Skoru: ' + levelScore); } // Play break sound for every hit, break3 on 3rd hit if (obs.crackLevel === 3) { break3Sound = LK.getSound && LK.getSound('break3'); if (break3Sound) { break3Sound.play(); } } else { breakSound = LK.getSound && LK.getSound('break'); if (breakSound) { breakSound.play(); } } if (obs.crackLevel === 1) { if (typeof obs.showCrack === "function") { obs.showCrack(1); } } else if (obs.crackLevel === 2) { if (typeof obs.showCrack === "function") { obs.showCrack(2); } } else if (obs.crackLevel >= 3) { if (typeof obs.breakWall === "function") { obs.breakWall(); } obstacles.splice(j, 1); } } } // Remove bullet if out of arena for too long (failsafe) if (b.x < ARENA_X - 200 || b.x > ARENA_X + ARENA_SIZE + 200 || b.y < ARENA_Y - 200 || b.y > ARENA_Y + ARENA_SIZE + 200) { b.destroy(); bullets.splice(i, 1); } }, b, dx, dy, dist, targetHitSound, brokenTarget, popupBg, popupText, nextBtn, retryBtn2, j, obs, left, right, top, bottom, overlapX, overlapY, break3Sound, breakSound, _ret; for (var i = bullets.length - 1; i >= 0; --i) { _ret = _loop(); if (_ret) { return _ret.v; } } };
/****
* Classes
****/
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletAsset = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = bulletAsset.width / 2;
self.vx = 0;
self.vy = 0;
self.lastX = 0;
self.lastY = 0;
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
self.x += self.vx;
self.y += self.vy;
// Rotate bullet to match its direction
if (self.vx !== 0 || self.vy !== 0) {
bulletAsset.rotation = Math.atan2(self.vy, self.vx);
}
// Wall bounce
if (self.x - self.radius <= ARENA_X && self.lastX - self.radius > ARENA_X) {
self.x = ARENA_X + self.radius;
self.vx *= -1;
// No sound for left wall
}
if (self.x + self.radius >= ARENA_X + ARENA_SIZE && self.lastX + self.radius < ARENA_X + ARENA_SIZE) {
self.x = ARENA_X + ARENA_SIZE - self.radius;
self.vx *= -1;
// No sound for right wall
}
// No sound for top wall
if (self.y - self.radius <= ARENA_Y && self.lastY - self.radius > ARENA_Y) {
self.y = ARENA_Y + self.radius;
self.vy *= -1;
}
// No sound for bottom wall
if (self.y + self.radius >= ARENA_Y + ARENA_SIZE && self.lastY + self.radius < ARENA_Y + ARENA_SIZE) {
self.y = ARENA_Y + ARENA_SIZE - self.radius;
self.vy *= -1;
}
};
return self;
});
// Obstacle class
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obsAsset = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = obsAsset.width;
self.height = obsAsset.height;
// Crack state: 0 = no crack, 1 = small crack, 2 = big crack, 3 = broken
self.crackLevel = 0;
self.crackAsset = null;
// Show crack overlay
self.showCrack = function (level) {
// Remove previous crack asset if any
if (self.crackAsset) {
self.crackAsset.destroy();
self.crackAsset = null;
}
if (level === 1) {
// Small crack
self.crackAsset = self.attachAsset('obstacle_crack1', {
anchorX: 0.5,
anchorY: 0.5
});
} else if (level === 2) {
// Big crack
self.crackAsset = self.attachAsset('obstacle_crack2', {
anchorX: 0.5,
anchorY: 0.5
});
}
// If level 0 or 3, no crack overlay
};
// Break wall (remove from game)
self.breakWall = function () {
// Play break sound
var breakSound = LK.getSound && LK.getSound('break');
if (breakSound) {
breakSound.play();
}
// Remove crack asset if any
if (self.crackAsset) {
self.crackAsset.destroy();
self.crackAsset = null;
}
// Remove self from game
self.destroy();
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerAsset = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = playerAsset.width / 2;
return self;
});
// Target class
var Target = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = targetAsset.width / 2;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Add background image to the game scene
// Small crack overlay
// Big crack overlay
// Wall break sound
var backgroundImg = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2732
});
game.addChild(backgroundImg);
// Arena and gameplay variables
var ARENA_SIZE = 1800; // Square arena, fits well in 2048x2732
var ARENA_X = (2048 - ARENA_SIZE) / 2;
var ARENA_Y = (2732 - ARENA_SIZE) / 2;
// Add visible arena border using a white rectangle shape
var borderThickness = 16;
var borderColor = 0xffffff;
var arenaBorder = LK.getAsset('arenaBorder', {
anchorX: 0,
anchorY: 0,
x: ARENA_X - borderThickness / 2,
y: ARENA_Y - borderThickness / 2,
width: ARENA_SIZE + borderThickness,
height: ARENA_SIZE + borderThickness,
color: borderColor,
shape: 'box'
});
game.addChild(arenaBorder);
// Arena and gameplay variables
var ARENA_SIZE = 1800; // Square arena, fits well in 2048x2732
var ARENA_X = (2048 - ARENA_SIZE) / 2;
var ARENA_Y = (2732 - ARENA_SIZE) / 2;
var player = null;
var target = null;
var bullets = [];
var obstacles = [];
var level = 1;
var isAiming = false;
var aimLine = null;
var aimStart = null;
var aimEnd = null;
var blockAimForOneFrame = false; // Prevents shooting right after popup closes
// Store X positions for each level so they are consistent on restart
var levelPositions = {};
// Level score: calculated as number of obstacles * 100 at level start
var levelScore = 0;
// Total score: sum of all level scores, resets to 0 at game start
var totalScore = 0;
function setupLevel(lvl) {
// If starting a new game (level 1), reset totalScore to 0 and update text
if (lvl === 1) {
totalScore = 0;
if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) {
totalScoreTxt.setText('Toplam Skor: ' + totalScore);
}
}
// Always ensure arena border is above background and below gameplay elements
if (arenaBorder && arenaBorder.parent) {
arenaBorder.parent.removeChild(arenaBorder);
}
game.addChild(arenaBorder);
// Clear previous
if (player) {
player.destroy();
}
if (target) {
target.destroy();
}
for (var i = 0; i < bullets.length; ++i) {
bullets[i].destroy();
}
bullets = [];
for (var i = 0; i < obstacles.length; ++i) {
obstacles[i].destroy();
}
obstacles = [];
// Player at random X along bottom, but keep same X for same level
player = new Player();
var playerMinX = ARENA_X + player.radius + 60;
var playerMaxX = ARENA_X + ARENA_SIZE - player.radius - 60;
if (!levelPositions[lvl]) {
levelPositions[lvl] = {};
levelPositions[lvl].playerX = playerMinX + Math.random() * (playerMaxX - playerMinX);
}
player.x = levelPositions[lvl].playerX;
player.y = ARENA_Y + ARENA_SIZE - 120;
game.addChild(player);
// Set player asset rotation to default (facing up)
if (typeof player.children !== "undefined" && player.children.length > 0) {
var playerAsset = player.children[0];
playerAsset.rotation = -Math.PI / 2;
}
// Target at random X along top, but keep same X for same level
target = new Target();
var targetMinX = ARENA_X + target.radius + 60;
var targetMaxX = ARENA_X + ARENA_SIZE - target.radius - 60;
if (!levelPositions[lvl].targetX) {
levelPositions[lvl].targetX = targetMinX + Math.random() * (targetMaxX - targetMinX);
}
target.x = levelPositions[lvl].targetX;
target.y = ARENA_Y + 120;
game.addChild(target);
// Obstacles for all levels, always at least 1 between player and target
var obsCount = Math.max(1, lvl * 2);
if (!levelPositions[lvl].obstacles) {
levelPositions[lvl].obstacles = [];
// Always place the first obstacle between player and target (on the line between them)
var obsDummy = new Obstacle();
var margin = 200;
var t = 0.5 + (Math.random() - 0.5) * 0.2; // t in [0.4,0.6] for some randomness
var betweenX = levelPositions[lvl].playerX * (1 - t) + levelPositions[lvl].targetX * t;
// Clamp X to arena
betweenX = Math.max(ARENA_X + margin + obsDummy.width / 2, Math.min(ARENA_X + ARENA_SIZE - margin - obsDummy.width / 2, betweenX));
var betweenY = ARENA_Y + ARENA_SIZE / 2 + (Math.random() - 0.5) * 200; // Center-ish, some vertical randomness
levelPositions[lvl].obstacles.push({
x: betweenX,
y: betweenY
});
obsDummy.destroy();
// Place additional obstacles for all levels
for (var i = 1; i < obsCount; ++i) {
var obsDummy2 = new Obstacle();
var posType = i % 3;
var xPos;
var maxTries = 20;
var tryCount = 0;
do {
if (posType === 0) {
// Left third
xPos = ARENA_X + margin + obsDummy2.width / 2 + Math.random() * (ARENA_SIZE / 3 - margin - obsDummy2.width);
} else if (posType === 1) {
// Right third
xPos = ARENA_X + 2 * ARENA_SIZE / 3 + margin + obsDummy2.width / 2 + Math.random() * (ARENA_SIZE / 3 - margin - obsDummy2.width);
} else {
// Center third
xPos = ARENA_X + ARENA_SIZE / 3 + margin + obsDummy2.width / 2 + Math.random() * (ARENA_SIZE / 3 - 2 * margin - obsDummy2.width);
}
tryCount++;
} while ((Math.abs(xPos - levelPositions[lvl].playerX) < obsDummy2.width || Math.abs(xPos - levelPositions[lvl].targetX) < obsDummy2.width || levelPositions[lvl].obstacles.some(function (o) {
return Math.abs(xPos - o.x) < obsDummy2.width && Math.abs(o.y - (ARENA_Y + ARENA_SIZE / (obsCount + 1) * (i + 1))) < obsDummy2.height;
})) && tryCount < maxTries);
// Y position: spread vertically, but randomize a bit
var yBase = ARENA_Y + ARENA_SIZE / (obsCount + 1) * (i + 1);
var yRand = Math.random() * 120 - 60; // -60 to +60 px
var yPos = yBase + yRand;
// Prevent obstacles from being below the player or above the target
// Player is always at bottom, target is always at top
// Clamp yPos so that it is not below the player or above the target
var minY = Math.min(levelPositions[lvl].playerY || ARENA_Y + ARENA_SIZE - 120) - obsDummy2.height / 2 - 40;
var maxY = Math.max(levelPositions[lvl].targetY || ARENA_Y + 120) + obsDummy2.height / 2 + 40;
if (yPos > minY) {
yPos = minY;
}
if (yPos < maxY) {
yPos = maxY;
}
levelPositions[lvl].obstacles.push({
x: xPos,
y: yPos
});
obsDummy2.destroy();
}
}
for (var i = 0; i < levelPositions[lvl].obstacles.length; ++i) {
var obs = new Obstacle();
obs.x = levelPositions[lvl].obstacles[i].x;
obs.y = levelPositions[lvl].obstacles[i].y;
game.addChild(obs);
obstacles.push(obs);
}
// Set levelScore: number of obstacles * 100
levelScore = obstacles.length * 100;
}
setupLevel(level);
// Level counter text
var levelTxt = new Text2('Level: ' + level + ' / 10', {
size: 100,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
// Place at top center, but not in the top left 100x100 area
LK.gui.top.addChild(levelTxt);
// Total score text, placed between level and level score
var totalScoreTxt = new Text2('Toplam Skor: ' + totalScore, {
size: 80,
fill: 0x00FFFF
});
totalScoreTxt.anchor.set(0.5, 0);
totalScoreTxt.x = 0;
totalScoreTxt.y = 90; // 90px below the top (between level and level score, with extra space above and below)
levelTxt.addChild(totalScoreTxt);
// Level score text, placed below the total score text
var levelScoreTxt = new Text2('Skor: ' + levelScore, {
size: 80,
fill: 0xFFFF00
});
levelScoreTxt.anchor.set(0.5, 0);
levelScoreTxt.x = 0;
levelScoreTxt.y = 190; // 190px below the top (with extra space below total score)
levelTxt.addChild(levelScoreTxt);
// Add a button to restart the current level (without resetting level number)
var retryBtn = new Text2('↺', {
size: 120,
fill: 0xFFFFFF
});
retryBtn.anchor.set(0.5, 0.5);
// Place at top left, just below the restart button, still below the 100x100 reserved area
retryBtn.x = 600;
retryBtn.y = 100;
retryBtn.interactive = true;
retryBtn.buttonMode = true;
// Store the last level score to allow subtraction on retry
if (typeof lastLevelScore === "undefined") {
var lastLevelScore = 0;
}
retryBtn.down = function (x, y, obj) {
// Subtract the last level's score from totalScore before retrying
if (typeof lastLevelScore !== "undefined") {
totalScore = Math.max(0, totalScore - lastLevelScore);
if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) {
totalScoreTxt.setText('Toplam Skor: ' + totalScore);
}
}
setupLevel(level);
if (levelTxt) {
levelTxt.setText('Level: ' + level + ' / 10');
}
if (levelScoreTxt) {
levelScoreTxt.setText('Skor: ' + levelScore);
}
};
LK.gui.top.addChild(retryBtn);
// Aiming and shooting
game.down = function (x, y, obj) {
// Prevent aiming if a popup is visible (by checking for popupBg, nextBtn, or retryBtn2 on stage)
if (typeof popupBg !== "undefined" && popupBg && popupBg.parent || typeof nextBtn !== "undefined" && nextBtn && nextBtn.parent || typeof retryBtn2 !== "undefined" && retryBtn2 && retryBtn2.parent) {
// Ignore down event if popup is visible
return;
}
// Block aiming until a new tap after popup closes
// (blockAimForOneFrame logic removed to allow immediate aiming after popup)
// Only allow aiming if no bullet is in play
if (bullets.length === 0) {
isAiming = true;
aimStart = {
x: player.x,
y: player.y
};
aimEnd = {
x: x,
y: y
};
}
};
game.move = function (x, y, obj) {
if (isAiming) {
aimEnd = {
x: x,
y: y
};
// Rotate player asset to match the aiming direction
if (aimEnd && player) {
var dx = aimEnd.x - player.x;
var dy = aimEnd.y - player.y;
if (typeof player.children !== "undefined" && player.children.length > 0) {
// playerAsset is the first child
var playerAsset = player.children[0];
playerAsset.rotation = Math.atan2(dy, dx);
}
}
}
};
game.up = function (x, y, obj) {
if (isAiming) {
// Fire bullet
var dx = aimEnd.x - player.x;
var dy = aimEnd.y - player.y;
var len = Math.sqrt(dx * dx + dy * dy);
if (len > 10) {
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y;
var speed = 30;
bullet.vx = dx / len * speed;
bullet.vy = dy / len * speed;
bullets.push(bullet);
game.addChild(bullet);
}
isAiming = false;
aimStart = null;
aimEnd = null;
// Reset player asset rotation to default (facing up)
if (typeof player.children !== "undefined" && player.children.length > 0) {
var playerAsset = player.children[0];
playerAsset.rotation = -Math.PI / 2;
}
}
};
// Main update loop
game.update = function () {
// Prevent aim line and aiming logic if popup is visible
// Draw aim line if aiming
if (isAiming && aimStart && aimEnd) {
if (!aimLine) {
aimLine = LK.getAsset('aimLine', {
anchorX: 0,
anchorY: 0
});
game.addChild(aimLine);
}
// Set aimLine position and size
var dx = aimEnd.x - aimStart.x;
var dy = aimEnd.y - aimStart.y;
var len = Math.sqrt(dx * dx + dy * dy);
aimLine.x = aimStart.x;
aimLine.y = aimStart.y;
aimLine.width = len;
aimLine.height = 10;
aimLine.rotation = Math.atan2(dy, dx);
} else if (aimLine) {
aimLine.destroy();
aimLine = null;
}
// Update bullets
var _loop = function _loop() {
b = bullets[i];
b.update();
// Check collision with target
if (target) {
dx = b.x - target.x;
dy = b.y - target.y;
dist = Math.sqrt(dx * dx + dy * dy);
if (dist < b.radius + target.radius) {
var removePopup = function removePopup() {
if (popupBg && popupBg.parent) {
popupBg.parent.removeChild(popupBg);
}
if (popupText && popupText.parent) {
popupText.parent.removeChild(popupText);
}
if (nextBtn && nextBtn.parent) {
nextBtn.parent.removeChild(nextBtn);
}
if (retryBtn2 && retryBtn2.parent) {
retryBtn2.parent.removeChild(retryBtn2);
}
if (brokenTarget && brokenTarget.parent) {
brokenTarget.parent.removeChild(brokenTarget);
}
};
// Play special sound for hitting the target
targetHitSound = LK.getSound && LK.getSound('targethit');
if (targetHitSound) {
targetHitSound.play();
}
// Show broken target image
brokenTarget = LK.getAsset('target_broken', {
anchorX: 0.5,
anchorY: 0.5,
x: target.x,
y: target.y
});
game.addChild(brokenTarget);
// Remove bullet and target
b.destroy();
bullets.splice(i, 1);
if (target) {
target.destroy();
target = null;
}
// Add levelScore to totalScore and update totalScoreTxt
if (typeof lastLevelScore === "undefined") {
var lastLevelScore = 0;
}
lastLevelScore = levelScore;
totalScore += levelScore;
if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) {
totalScoreTxt.setText('Toplam Skor: ' + totalScore);
}
// Show popup with Next Level and Retry buttons
// Add popup background image first (behind all popup elements)
popupBgImg = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 735,
//{37} // 700 * 1.05 = 735
height: 735
});
popupBgImg.alpha = 0.7;
popupBg = LK.getAsset('arenaBorder', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 735,
//{3d} // 700 * 1.05 = 735
height: 735,
color: 0x222222,
shape: 'box'
});
popupBg.alpha = 0.96;
popupText = new Text2('Tebrikler!', {
size: 120,
fill: 0xFFFFFF
});
popupText.anchor.set(0.5, 0);
popupText.x = 2048 / 2;
popupText.y = 2732 / 2 - 320;
// Level score text in popup, now between 'Tebrikler!' and 'Sıradaki Level'
var popupScoreText = new Text2('Level Skoru: ' + levelScore, {
size: 90,
fill: 0xFFFF00
});
popupScoreText.anchor.set(0.5, 0);
popupScoreText.x = 2048 / 2;
popupScoreText.y = 2732 / 2 - 60; // 20px more space below "Tebrikler!"
// Total score text in popup, below level score with extra spacing
var popupTotalScoreText = new Text2('Toplam Skor: ' + totalScore, {
size: 90,
fill: 0x00FFFF
});
popupTotalScoreText.anchor.set(0.5, 0);
popupTotalScoreText.x = 2048 / 2;
popupTotalScoreText.y = 2732 / 2 + 40; // 30px more space below level score
// Use text buttons for Next Level and Retry, placed side by side, more centered and further down, and 10% larger
var btnY = 2732 / 2 + 270; // move buttons further down
var btnSpacing = 40; // reduced spacing to bring buttons closer to center
var btnWidth = 320 * 1.1; // 10% larger
var btnHeight = 120 * 1.1; // 10% larger
nextBtn = new Text2('▷', {
size: 110,
//{3p} // 10% larger
fill: 0x00FF00
});
nextBtn.anchor.set(0.5, 0.5);
// Next Level button on the right, closer to center
nextBtn.x = 2048 / 2 + btnWidth / 2 + btnSpacing / 2;
nextBtn.y = btnY;
nextBtn.interactive = true;
nextBtn.buttonMode = true;
retryBtn2 = new Text2('↺', {
size: 110,
//{3r} // 10% larger
fill: 0xFF3333
});
retryBtn2.anchor.set(0.5, 0.5);
// Retry button on the left, closer to center
retryBtn2.x = 2048 / 2 - btnWidth / 2 - btnSpacing / 2;
retryBtn2.y = btnY;
retryBtn2.interactive = true;
retryBtn2.buttonMode = true;
nextBtn.down = function (x, y, obj) {
removePopup();
level += 1;
if (level > 10) {
// Show final popup: Oyun Bitti, toplam skor, and restart button
// Remove any remaining gameplay elements
if (player) {
player.destroy();
player = null;
}
if (target) {
target.destroy();
target = null;
}
for (var i = 0; i < bullets.length; ++i) {
bullets[i].destroy();
}
bullets = [];
for (var i = 0; i < obstacles.length; ++i) {
obstacles[i].destroy();
}
obstacles = [];
// Final popup background
var finalPopupBgImg = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 735,
height: 735
});
finalPopupBgImg.alpha = 0.7;
var finalPopupBg = LK.getAsset('arenaBorder', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 735,
height: 735,
color: 0x222222,
shape: 'box'
});
finalPopupBg.alpha = 0.96;
var finalPopupText = new Text2('Oyun Bitti!', {
size: 120,
fill: 0xFFFFFF
});
finalPopupText.anchor.set(0.5, 0);
finalPopupText.x = 2048 / 2;
finalPopupText.y = 2732 / 2 - 320;
var finalPopupTotalScoreText = new Text2('Toplam Skor: ' + totalScore, {
size: 100,
fill: 0x00FFFF
});
finalPopupTotalScoreText.anchor.set(0.5, 0);
finalPopupTotalScoreText.x = 2048 / 2;
finalPopupTotalScoreText.y = 2732 / 2 - 60;
// Restart button
var finalRestartBtn = new Text2('Baştan Başla', {
size: 110,
fill: 0x00FF00
});
finalRestartBtn.anchor.set(0.5, 0.5);
finalRestartBtn.x = 2048 / 2;
finalRestartBtn.y = 2732 / 2 + 200;
finalRestartBtn.interactive = true;
finalRestartBtn.buttonMode = true;
finalRestartBtn.down = function (x, y, obj) {
// Remove popup
if (finalPopupBgImg && finalPopupBgImg.parent) finalPopupBgImg.parent.removeChild(finalPopupBgImg);
if (finalPopupBg && finalPopupBg.parent) finalPopupBg.parent.removeChild(finalPopupBg);
if (finalPopupText && finalPopupText.parent) finalPopupText.parent.removeChild(finalPopupText);
if (finalPopupTotalScoreText && finalPopupTotalScoreText.parent) finalPopupTotalScoreText.parent.removeChild(finalPopupTotalScoreText);
if (finalRestartBtn && finalRestartBtn.parent) finalRestartBtn.parent.removeChild(finalRestartBtn);
// Reset game
level = 1;
setupLevel(level);
if (levelTxt) {
levelTxt.setText('Level: ' + level + ' / 10');
}
if (levelScoreTxt) {
levelScoreTxt.setText('Skor: ' + levelScore);
}
if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) {
totalScoreTxt.setText('Toplam Skor: ' + totalScore);
}
isAiming = false;
aimStart = null;
aimEnd = null;
};
game.addChild(finalPopupBgImg);
game.addChild(finalPopupBg);
game.addChild(finalPopupText);
game.addChild(finalPopupTotalScoreText);
game.addChild(finalRestartBtn);
return;
}
setupLevel(level);
if (levelTxt) {
levelTxt.setText('Level: ' + level + ' / 10');
}
if (levelScoreTxt) {
levelScoreTxt.setText('Skor: ' + levelScore);
}
if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) {
totalScoreTxt.setText('Toplam Skor: ' + totalScore);
}
isAiming = false;
aimStart = null;
aimEnd = null;
// blockAimForOneFrame removed to allow immediate aiming after popup
};
retryBtn2.down = function (x, y, obj) {
// Subtract the last level's score from totalScore before retrying
if (typeof lastLevelScore !== "undefined") {
totalScore = Math.max(0, totalScore - lastLevelScore);
if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) {
totalScoreTxt.setText('Toplam Skor: ' + totalScore);
}
}
removePopup();
setupLevel(level);
if (levelTxt) {
levelTxt.setText('Level: ' + level + ' / 10');
}
if (levelScoreTxt) {
levelScoreTxt.setText('Skor: ' + levelScore);
}
if (typeof totalScoreTxt !== "undefined" && totalScoreTxt) {
totalScoreTxt.setText('Toplam Skor: ' + totalScore);
}
isAiming = false;
aimStart = null;
aimEnd = null;
// blockAimForOneFrame removed to allow immediate aiming after popup
};
// Only show retryBtn2 if not on final level (level < 10)
game.addChild(popupBgImg);
game.addChild(popupBg);
game.addChild(popupText);
game.addChild(popupScoreText);
game.addChild(popupTotalScoreText);
game.addChild(nextBtn);
if (level < 10) {
game.addChild(retryBtn2);
}
return {
v: void 0
};
}
} // end if (target)
// Check collision with obstacles
for (j = obstacles.length - 1; j >= 0; --j) {
obs = obstacles[j];
left = obs.x - obs.width / 2;
right = obs.x + obs.width / 2;
top = obs.y - obs.height / 2;
bottom = obs.y + obs.height / 2; // Simple AABB collision
if (b.x + b.radius > left && b.x - b.radius < right && b.y + b.radius > top && b.y - b.radius < bottom) {
// Reflect bullet: pick axis of minimum penetration
overlapX = Math.min(Math.abs(b.x + b.radius - left), Math.abs(b.x - b.radius - right));
overlapY = Math.min(Math.abs(b.y + b.radius - top), Math.abs(b.y - b.radius - bottom));
if (overlapX < overlapY) {
b.vx *= -1;
} else {
b.vy *= -1;
}
// Crack and break logic
if (typeof obs.crackLevel === "undefined") {
obs.crackLevel = 0;
}
obs.crackLevel++;
// Decrease levelScore by 20 for each obstacle hit, but not below 0
levelScore = Math.max(0, levelScore - 20);
if (levelScoreTxt) {
levelScoreTxt.setText('Level Skoru: ' + levelScore);
}
// Play break sound for every hit, break3 on 3rd hit
if (obs.crackLevel === 3) {
break3Sound = LK.getSound && LK.getSound('break3');
if (break3Sound) {
break3Sound.play();
}
} else {
breakSound = LK.getSound && LK.getSound('break');
if (breakSound) {
breakSound.play();
}
}
if (obs.crackLevel === 1) {
if (typeof obs.showCrack === "function") {
obs.showCrack(1);
}
} else if (obs.crackLevel === 2) {
if (typeof obs.showCrack === "function") {
obs.showCrack(2);
}
} else if (obs.crackLevel >= 3) {
if (typeof obs.breakWall === "function") {
obs.breakWall();
}
obstacles.splice(j, 1);
}
}
}
// Remove bullet if out of arena for too long (failsafe)
if (b.x < ARENA_X - 200 || b.x > ARENA_X + ARENA_SIZE + 200 || b.y < ARENA_Y - 200 || b.y > ARENA_Y + ARENA_SIZE + 200) {
b.destroy();
bullets.splice(i, 1);
}
},
b,
dx,
dy,
dist,
targetHitSound,
brokenTarget,
popupBg,
popupText,
nextBtn,
retryBtn2,
j,
obs,
left,
right,
top,
bottom,
overlapX,
overlapY,
break3Sound,
breakSound,
_ret;
for (var i = bullets.length - 1; i >= 0; --i) {
_ret = _loop();
if (_ret) {
return _ret.v;
}
}
};
full blue screen. In-Game asset. 2d. High contrast. No shadows
gülle. In-Game asset. 2d. High contrast. No shadows
castle wall. In-Game asset. 2d. High contrast. No shadows
only the mouth part of the cannon and looking at the vertical. In-Game asset. 2d. High contrast. No shadows
castle. In-Game asset. 2d. High contrast. No shadows
kırık
daha çok kırık
yıkılmış kale
next button , no background. In-Game asset. 2d. High contrast. No shadows