User prompt
Bütün balon boyutlarını aynı boyutta yap
User prompt
20 farklı çeşit balon resimi oluştur.
User prompt
Her stage yükselişinde MaxHP +10 değil, +20 artsın.
User prompt
combo ve altında çıkan lucy tarzı yazının konumlarını 2 satır sola kaydır.
User prompt
Giant Ball türünü oyundan kaldır.
User prompt
arkaplan müziğini resmine basınca durdur veya oynat.
User prompt
Arkaplan müziğinin resim dosyasını Archievements butonunun altına yerleştir.
User prompt
Oyuna arkaplan müziği ekle ve dosyasını oluştur.
User prompt
Lucy Shot ve Amazing yazılarını çeşitlendir. Farklı farklı yazılar çıksın.
User prompt
Bunu görünmez yap
User prompt
combo ve amazing yazılarını 2 satır sola kaydır.
User prompt
Combo yazısını Score yazısının 1 satır soluna taşı. Amazing yazısını bunun 1 satır altına taşı ve boyutları Balls Left yazı boyutu ile aynı olsun.
User prompt
HP yazısının boyutunu Next Stage ile aynı fontta yap.
User prompt
Ekranın sağ alt köşesine ''Reset'' butonu ekle. Basınca, bütün ilerlemeler ve herşey sıfırlansın. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Archievements panel içerisini, başarımları yana doğru 3 sıra ve alta doğru 5 sıra olacak şekilde yeniden düzenle, panele 1-2-3 şeklinde butonlar ekle ve paneli bu şekilde sayfalara ayır.
User prompt
Archievements panel içerisinde ki bütün yazıları ''Balls Left'' yazı boyutu olacak kadar büyüt ve paneli de aynı şekilde hizalı olacak şekilde büyüt.
User prompt
Shockwave efekti bunu oyundan kaldır.
User prompt
Her stage sonrası MaxHP +10 artsın.
User prompt
Stage yükseltmesi için kalan süre, Hp'nin altında yazsın.
User prompt
Her 2 dakikada 1, Stage yükseltmesi sağlansın.
User prompt
Explosive topa değince, oyunda bazı toplar kalıyor. Ne vurabiliyorum, ne yok edebiliyorum. Bug gibi ekranda kalıyor öylece. Bunu tamamen çözmeni istiyorum.
User prompt
Explosive topa değince, oyunda bazı toplar kalıyor. Ne vurabiliyorum, ne yok edebiliyorum. Bug gibi ekranda kalıyor öylece. Bunu tamamen çözmeni istiyorum.
User prompt
Hala oyunda kalan toplar var. Sorunu çözmemişsin.
User prompt
Mermi gönderdikten sonra ve mermiler tamamen yok olduktan sonra yeni bir mermi gönderemiyoruz. Sorun var. Çöz.
User prompt
Şimdi mermi döngüsünde, mermi gönderilmiyor.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AimLine = Container.expand(function () { var self = Container.call(this); for (var i = 0; i < 10; i++) { var dot = self.attachAsset('aimline', { anchorX: 0.5, anchorY: 0.5, y: -i * 30, alpha: 0.5 - i * 0.05 }); } return self; }); var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.numberText = new Text2('1', { size: 40, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.hits = 1; self.radius = 40; self.velocityX = 0; self.velocityY = 0; self.setNumber = function (num) { self.hits = num; self.numberText.setText(num.toString()); var scale = 1 + num / 50 * 0.5; ballGraphics.scale.set(scale); self.radius = 40 * scale; }; self.takeDamage = function () { self.hits--; if (self.hits <= 0) { return true; } self.numberText.setText(self.hits.toString()); tween(ballGraphics, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100, onFinish: function onFinish() { tween(ballGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); return false; }; return self; }); var BombBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, tint: 0x333333, scaleX: 1.3, scaleY: 1.3 }); self.numberText = new Text2('💣', { size: 40, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.hits = 5; self.radius = 50; self.velocityX = 0; self.velocityY = 0; self.pulseTimer = 0; self.isBomb = true; self.takeDamage = function () { self.hits--; if (self.hits <= 0) { return true; } self.numberText.setText(self.hits.toString()); ballGraphics.tint = self.hits <= 2 ? 0xff0000 : 0x333333; return false; }; self.update = function () { self.pulseTimer += 0.15; if (self.hits <= 2) { var pulse = 1 + Math.sin(self.pulseTimer) * 0.2; ballGraphics.scale.set(1.3 * pulse); } }; return self; }); var BossBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, tint: 0xff1744, scaleX: 2, scaleY: 2 }); self.numberText = new Text2('BOSS', { size: 50, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.hits = 50; self.radius = 80; self.velocityX = 2; self.moveTimer = 0; self.isBoss = true; self.takeDamage = function () { self.hits--; if (self.hits <= 0) { return true; } self.numberText.setText(self.hits.toString()); ballGraphics.tint = Math.random() > 0.5 ? 0xff1744 : 0xff6600; tween(ballGraphics, { scaleX: 1.8, scaleY: 1.8 }, { duration: 100, onFinish: function onFinish() { tween(ballGraphics, { scaleX: 2, scaleY: 2 }, { duration: 100 }); } }); return false; }; self.update = function () { self.moveTimer += 0.05; self.x += self.velocityX; if (self.x <= self.radius || self.x >= 2048 - self.radius) { self.velocityX *= -1; } ballGraphics.rotation += 0.02; }; return self; }); var Cannon = Container.expand(function () { var self = Container.call(this); var cannonGraphics = self.attachAsset('cannon', { anchorX: 0.5, anchorY: 0.8 }); self.rotation = 0; return self; }); var ChainReactionPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0xff8800, scaleX: 1.4, scaleY: 1.4 }); self.radius = 35; self.chainTimer = 0; self.update = function () { self.chainTimer += 0.2; var scale = 1.4 + Math.sin(self.chainTimer) * 0.2; powerupGraphics.scale.set(scale); // Chain effect if (Math.random() < 0.2) { var chain = self.attachAsset('aimline', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, tint: 0xff8800, alpha: 0.6, rotation: Math.random() * Math.PI * 2 }); tween(chain, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 400, onFinish: function onFinish() { chain.destroy(); } }); } }; return self; }); var DoubleShotPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0xffff00, scaleX: 1.2, scaleY: 1.2 }); self.radius = 30; self.bounceTimer = 0; self.update = function () { self.bounceTimer += 0.08; var scale = 1.2 + Math.sin(self.bounceTimer * 2) * 0.1; powerupGraphics.scale.set(scale); powerupGraphics.rotation -= 0.03; }; return self; }); var FireBallPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0xff6600 }); self.radius = 25; self.flameTimer = 0; self.update = function () { self.flameTimer += 0.15; var scale = 1 + Math.sin(self.flameTimer) * 0.4; powerupGraphics.scale.set(scale); powerupGraphics.alpha = 0.7 + Math.sin(self.flameTimer * 2) * 0.3; }; return self; }); var FreezeBombPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ccff, scaleX: 1.3, scaleY: 1.3 }); self.radius = 30; self.iceTimer = 0; self.update = function () { self.iceTimer += 0.15; powerupGraphics.alpha = 0.6 + Math.sin(self.iceTimer) * 0.4; powerupGraphics.rotation += 0.02; // Ice particle effect if (Math.random() < 0.1) { var iceParticle = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, tint: 0x00ffff, alpha: 0.8 }); iceParticle.x = (Math.random() - 0.5) * 40; iceParticle.y = (Math.random() - 0.5) * 40; tween(iceParticle, { y: iceParticle.y - 20, alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 500, onFinish: function onFinish() { iceParticle.destroy(); } }); } }; return self; }); var GhostBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, tint: 0x8888ff, alpha: 0.5 }); self.numberText = new Text2('G', { size: 40, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.hits = 7; self.radius = 40; self.phaseTimer = 0; self.isPhased = false; self.isGhost = true; self.takeDamage = function () { if (self.isPhased) return false; self.hits--; if (self.hits <= 0) { return true; } self.numberText.setText(self.hits.toString()); return false; }; self.update = function () { self.phaseTimer += 0.1; self.isPhased = Math.sin(self.phaseTimer) > 0; ballGraphics.alpha = self.isPhased ? 0.2 : 0.8; self.numberText.alpha = self.isPhased ? 0.2 : 1; }; return self; }); var GiantBallPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ff00, scaleX: 1.5, scaleY: 1.5 }); self.radius = 35; self.bounceTimer = 0; self.update = function () { self.bounceTimer += 0.1; var scale = 1.5 + Math.sin(self.bounceTimer) * 0.3; powerupGraphics.scale.set(scale); }; return self; }); // HeartBall: Ball with heart icon, gives +10 HP when collected var HeartBall = Container.expand(function () { var self = Container.call(this); var heartGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5, tint: 0xff3366, scaleX: 1.1, scaleY: 1.1 }); self.radius = 28; self.heartText = new Text2('♥', { size: 38, fill: 0xffffff }); self.heartText.anchor.set(0.5, 0.5); self.addChild(self.heartText); self.update = function () { heartGraphics.rotation += 0.04; self.heartText.scale.set(1 + Math.sin(LK.ticks * 0.15) * 0.1); }; return self; }); var LaserPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ffff }); self.radius = 25; self.glowTimer = 0; self.update = function () { self.glowTimer += 0.2; powerupGraphics.alpha = 0.5 + Math.sin(self.glowTimer) * 0.5; }; return self; }); var LightningPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0x9966ff }); self.radius = 25; self.sparkTimer = 0; self.update = function () { self.sparkTimer += 0.3; powerupGraphics.alpha = 0.4 + Math.random() * 0.6; powerupGraphics.scale.set(1 + Math.sin(self.sparkTimer) * 0.3); }; return self; }); var MagnetBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, tint: 0x0066cc, scaleX: 1.3, scaleY: 1.3 }); self.numberText = new Text2('MAG', { size: 35, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.hits = 20; self.radius = 50; self.magnetRadius = 200; self.isMagnet = true; self.magnetTimer = 0; self.takeDamage = function () { self.hits--; if (self.hits <= 0) { return true; } self.numberText.setText(self.hits.toString()); // Pulse effect on hit tween(ballGraphics, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, onFinish: function onFinish() { tween(ballGraphics, { scaleX: 1.3, scaleY: 1.3 }, { duration: 100 }); } }); return false; }; self.update = function () { self.magnetTimer += 0.1; // Magnetic field visual effect if (Math.random() < 0.2) { var field = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.1, scaleY: 0.1, tint: 0x0099ff, alpha: 0.3 }); var angle = Math.random() * Math.PI * 2; var radius = Math.random() * self.magnetRadius; field.x = Math.cos(angle) * radius; field.y = Math.sin(angle) * radius; tween(field, { scaleX: 0.5, scaleY: 0.5, alpha: 0, x: field.x * 0.5, y: field.y * 0.5 }, { duration: 1000, onFinish: function onFinish() { field.destroy(); } }); } ballGraphics.rotation = self.magnetTimer * 0.5; }; return self; }); var MirrorBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, tint: 0xc0c0c0, scaleX: 1.2, scaleY: 1.2 }); self.numberText = new Text2('M', { size: 40, fill: 0x000000 }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.hits = 15; self.radius = 45; self.velocityX = 0; self.velocityY = 0; self.isMirror = true; self.reflectTimer = 0; self.takeDamage = function () { self.hits--; if (self.hits <= 0) { return true; } self.numberText.setText(self.hits.toString()); // Flash effect on hit tween(ballGraphics, { tint: 0xffffff }, { duration: 100, onFinish: function onFinish() { tween(ballGraphics, { tint: 0xc0c0c0 }, { duration: 100 }); } }); return false; }; self.update = function () { self.reflectTimer += 0.1; ballGraphics.alpha = 0.7 + Math.sin(self.reflectTimer * 2) * 0.3; // Shine effect if (Math.random() < 0.05) { var shine = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, tint: 0xffffff, alpha: 0.8 }); shine.x = (Math.random() - 0.5) * 40; shine.y = (Math.random() - 0.5) * 40; tween(shine, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, onFinish: function onFinish() { shine.destroy(); } }); } }; return self; }); var MultiballPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0xe74c3c }); self.radius = 25; self.rotationSpeed = 0.05; self.update = function () { powerupGraphics.rotation += self.rotationSpeed; var scale = 1 + Math.sin(LK.ticks * 0.1) * 0.3; powerupGraphics.scale.set(scale); }; return self; }); var Particle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.lifetime = 30; self.fadeSpeed = 0.03; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; self.velocityY += 0.075; // gravity self.lifetime--; self.alpha -= self.fadeSpeed; if (self.lifetime <= 0 || self.alpha <= 0) { return true; // destroy } return false; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 20; return self; }); var Projectile = Container.expand(function () { var self = Container.call(this); var projectileGraphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.speed = 15; self.radius = 10; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Apply gravity (0.75% per frame) self.velocityY += 0.075; if (self.x <= self.radius || self.x >= 2048 - self.radius) { self.velocityX *= -1; self.x = Math.max(self.radius, Math.min(2048 - self.radius, self.x)); } if (self.y <= self.radius) { self.velocityY *= -1; self.y = self.radius; } }; return self; }); var RainbowBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); self.numberText = new Text2('★', { size: 50, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.hits = 10; self.radius = 60; self.velocityX = 0; self.velocityY = 0; self.colorTimer = 0; self.isRainbow = true; self.takeDamage = function () { self.hits--; if (self.hits <= 0) { return true; } self.numberText.setText(self.hits.toString()); return false; }; self.update = function () { self.colorTimer += 0.1; var hue = (Math.sin(self.colorTimer) + 1) * 0.5; var r = Math.floor(Math.sin(hue * Math.PI * 2) * 127 + 128); var g = Math.floor(Math.sin((hue + 0.33) * Math.PI * 2) * 127 + 128); var b = Math.floor(Math.sin((hue + 0.67) * Math.PI * 2) * 127 + 128); ballGraphics.tint = r << 16 | g << 8 | b; ballGraphics.rotation += 0.05; }; return self; }); var ShieldPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0x3498db }); self.radius = 25; self.shieldTimer = 0; self.update = function () { self.shieldTimer += 0.1; var scale = 1 + Math.sin(self.shieldTimer * 2) * 0.2; powerupGraphics.scale.set(scale); powerupGraphics.rotation += 0.05; }; return self; }); var SlowMotionPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0x9b59b6 }); self.radius = 30; self.pulseTimer = 0; self.update = function () { self.pulseTimer += 0.1; var scale = 1 + Math.sin(self.pulseTimer) * 0.2; powerupGraphics.scale.set(scale); }; return self; }); var SpecialProjectile = Container.expand(function () { var self = Container.call(this); self.type = 'normal'; self.velocityX = 0; self.velocityY = 0; self.speed = 15; self.radius = 10; self.piercing = 0; self.bounces = 999; var projectileGraphics = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5 }); self.setType = function (type) { self.type = type; switch (type) { case 'piercing': projectileGraphics.tint = 0xff00ff; self.piercing = 3; projectileGraphics.scale.set(1.5); self.radius = 15; break; case 'explosive': projectileGraphics.tint = 0xff4444; projectileGraphics.scale.set(2); self.radius = 20; self.speed = 10; break; case 'rapid': projectileGraphics.tint = 0x44ff44; projectileGraphics.scale.set(0.7); self.radius = 7; self.speed = 25; break; case 'fireball': projectileGraphics.tint = 0xff6600; projectileGraphics.scale.set(1.8); self.radius = 18; self.speed = 12; self.piercing = 999; break; case 'giant': projectileGraphics.tint = 0x00ff00; projectileGraphics.scale.set(3); self.radius = 30; self.speed = 8; break; case 'split': projectileGraphics.tint = 0xff00ff; projectileGraphics.scale.set(1.2); self.radius = 12; self.speed = 15; break; case 'laser': projectileGraphics.tint = 0x00ffff; projectileGraphics.scale.set(0.5); self.radius = 5; self.speed = 30; self.piercing = 999; break; case 'lightning': projectileGraphics.tint = 0x9966ff; projectileGraphics.scale.set(1.5); self.radius = 15; self.speed = 20; self.piercing = 1; break; } }; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Apply gravity (0.75% per frame) if (self.gravity === undefined) self.gravity = 0.075; self.velocityY += self.gravity; if (self.x <= self.radius || self.x >= 2048 - self.radius) { self.velocityX *= -1; self.x = Math.max(self.radius, Math.min(2048 - self.radius, self.x)); self.bounces--; } if (self.y <= self.radius) { self.velocityY *= -1; self.y = self.radius; self.bounces--; } if (self.type === 'rapid') { // Add trail effect if (Math.random() < 0.3) { var trail = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, alpha: 0.5, tint: 0x44ff44 }); tween(trail, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 300, onFinish: function onFinish() { trail.destroy(); } }); } } else if (self.type === 'fireball') { // Add flame trail if (Math.random() < 0.5) { var flame = self.attachAsset('projectile', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, alpha: 0.8, tint: Math.random() > 0.5 ? 0xff6600 : 0xffaa00 }); tween(flame, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 200, onFinish: function onFinish() { flame.destroy(); } }); } } else if (self.type === 'laser') { // Add laser glow projectileGraphics.alpha = 0.8 + Math.sin(LK.ticks * 0.3) * 0.2; } return self.bounces <= 0; }; return self; }); var SplitBallPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0xff00ff }); self.radius = 25; self.rotationSpeed = 0.1; self.update = function () { powerupGraphics.rotation += self.rotationSpeed; }; return self; }); var Star = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5 }); self.radius = 25; starGraphics.rotation = Math.PI / 4; self.update = function () { starGraphics.rotation += 0.02; }; return self; }); var TeleportPowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5, tint: 0x8000ff, scaleX: 1.2, scaleY: 1.2 }); self.radius = 30; self.teleportTimer = 0; self.update = function () { self.teleportTimer += 0.3; powerupGraphics.alpha = 0.3 + Math.abs(Math.sin(self.teleportTimer)) * 0.7; // Portal effect if (powerupGraphics.alpha < 0.4) { powerupGraphics.x = (Math.random() - 0.5) * 10; powerupGraphics.y = (Math.random() - 0.5) * 10; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } var cannon; var aimLine; var balls = []; var projectiles = []; var powerups = []; var stars = []; var isAiming = false; var canShoot = true; var projectileCount = 1; var stage = 1; var ballsPerRow = 6; var ballSpeed = 0.5; var gameActive = true; // HP system var maxHP = 20; var hp = maxHP; var hpText = new Text2('HP: ' + hp, { size: 35, fill: 0xff4444 }); hpText.anchor.set(0, 0); hpText.x = 20 + 2 * 80; hpText.y = 20; LK.gui.topLeft.addChild(hpText); // Stage timer text (below HP) var stageTimerText = new Text2('Next Stage: 2:00', { size: 35, fill: 0x00CCFF }); stageTimerText.anchor.set(0, 0); stageTimerText.x = 20 + 2 * 80; stageTimerText.y = 80; LK.gui.topLeft.addChild(stageTimerText); // Remaining balls count text (above stage text) var ballsLeftText = new Text2('Balls Left: 0', { size: 28, fill: 0xCCCCCC }); ballsLeftText.anchor.set(0.5, 0); ballsLeftText.y = 0; LK.gui.top.addChild(ballsLeftText); var stageText = new Text2('Stage 1', { size: 60, fill: 0xFFFFFF }); stageText.anchor.set(0.5, 0); stageText.y = 20; LK.gui.top.addChild(stageText); var projectileCountText = new Text2('x1', { size: 50, fill: 0x4ECDC4 }); projectileCountText.anchor.set(0.5, 0); projectileCountText.y = 100; LK.gui.top.addChild(projectileCountText); var scoreText = new Text2('Score: 0', { size: 40, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); scoreText.x = -20; scoreText.y = 20; LK.gui.topRight.addChild(scoreText); var combo = 0; var comboTimer = 0; var scoreMultiplier = 1; var comboText = new Text2('', { size: 28, fill: 0xFFD700 }); comboText.anchor.set(1, 0); comboText.x = -220; comboText.y = 20; LK.gui.topRight.addChild(comboText); var amazingText = new Text2('', { size: 28, fill: 0xFFD700 }); amazingText.anchor.set(1, 0); amazingText.x = -220; amazingText.y = 50; LK.gui.topRight.addChild(amazingText); var particles = []; var currentWeapon = 'normal'; var weaponUnlocks = { piercing: false, explosive: false, rapid: false }; var slowMotionActive = false; var slowMotionTimer = 0; var gameSpeed = 1; var magnetActive = false; var magnetTimer = 0; var specialEffects = []; var chainReactionActive = false; var lastBallDestroyed = null; var consecutiveHits = 0; var slowMotionPowerups = []; var multiballPowerups = []; var multiballActive = false; var fireballPowerups = []; var giantBallPowerups = []; var splitBallPowerups = []; var laserPowerups = []; var fireballActive = false; var giantBallActive = false; var splitBallActive = false; var laserActive = false; var shieldPowerups = []; var shieldActive = false; var shieldTimer = 0; var bossBalls = []; var bossSpawnCounter = 0; var freezeActive = false; var freezeTimer = 0; var criticalHitChance = 0.1; var magnetBalls = []; var perfectStageBonus = false; var rainbowBalls = []; var bombBalls = []; var doubleShotPowerups = []; var doubleShotActive = false; var doubleShotTimer = 0; var lightningPowerups = []; var lightningActive = false; var ghostBalls = []; var reverseGravityActive = false; var reverseGravityTimer = 0; var scoreBoostActive = false; var scoreBoostTimer = 0; var scoreBoostMultiplier = 1; var autoAimActive = false; var autoAimTimer = 0; var freezeBombPowerups = []; var freezeBombActive = false; var mirrorBalls = []; var chainReactionPowerups = []; var chainReactionBombActive = false; var teleportPowerups = []; var teleportActive = false; var ballsDestroyed = 0; var perfectHits = 0; var missedShots = 0; var powerupsCollected = 0; var maxCombo = 0; var timePlayed = 0; var achievements = { // Basic achievements firstWin: false, combo10: false, score1000: false, allWeapons: false, bossKiller: false, perfectStage: false, shieldMaster: false, lightningMaster: false, ghostHunter: false, reverseGravity: false, // New achievements stage10: false, stage25: false, stage50: false, score5000: false, score10000: false, score50000: false, combo20: false, combo50: false, multiKill5: false, multiKill10: false, projectiles50: false, projectiles100: false, fireballKills: false, laserKills: false, explosiveKills: false, piercingKills: false, rapidKills: false, splitKills: false, giantKills: false, lightningChain: false, bombExpert: false, rainbowHunter: false, starCollector: false, powerupMaster: false, dodgeMaster: false, speedDemon: false, slowMotionPro: false, magnetMaster: false, freezeMaster: false, doubleTrouble: false, tripleCombo: false, chainReactionPro: false, perfectAccuracy: false, luckyShot: false, survivor: false, pacifist: false, aggressive: false, versatile: false, persistent: false, flawless: false, comeback: false, closeCall: false, longShot: false, richPlayer: false, masterOfAll: false }; var achievementDescriptions = { firstWin: "Clear your first stage", combo10: "Achieve a 10x combo", score1000: "Score 1,000 points", allWeapons: "Unlock all basic weapons", bossKiller: "Defeat a boss", perfectStage: "Clear a stage with only 1 projectile", shieldMaster: "Use a shield power-up", lightningMaster: "Use lightning power-up", ghostHunter: "Defeat a ghost ball", reverseGravity: "Use reverse gravity", stage10: "Reach stage 10", stage25: "Reach stage 25", stage50: "Reach stage 50", score5000: "Score 5,000 points", score10000: "Score 10,000 points", score50000: "Score 50,000 points", combo20: "Achieve a 20x combo", combo50: "Achieve a 50x combo", multiKill5: "Destroy 5 balls with one shot", multiKill10: "Destroy 10 balls with one shot", projectiles50: "Collect 50 projectiles total", projectiles100: "Collect 100 projectiles total", fireballKills: "Destroy 100 balls with fireball", laserKills: "Destroy 100 balls with laser", explosiveKills: "Destroy 100 balls with explosive", piercingKills: "Destroy 100 balls with piercing", rapidKills: "Destroy 100 balls with rapid fire", splitKills: "Destroy 100 balls with split shot", giantKills: "Destroy 100 balls with giant ball", lightningChain: "Chain lightning to 5 balls", bombExpert: "Trigger 10 bomb explosions", rainbowHunter: "Destroy 20 rainbow balls", starCollector: "Collect 50 stars", powerupMaster: "Use 100 power-ups", dodgeMaster: "Survive with balls at bottom 10 times", speedDemon: "Clear a stage in under 30 seconds", slowMotionPro: "Use slow motion 20 times", magnetMaster: "Use magnet 20 times", freezeMaster: "Use freeze 20 times", doubleTrouble: "Use double shot 20 times", tripleCombo: "Get 3 different power-ups active", chainReactionPro: "Trigger 50 chain reactions", perfectAccuracy: "Hit 100 balls without missing", luckyShot: "Hit a ball from max distance", survivor: "Survive for 10 minutes", pacifist: "Clear a stage without power-ups", aggressive: "Clear a stage in under 10 shots", versatile: "Use all weapon types in one game", persistent: "Play 100 games", flawless: "Clear 5 stages without taking damage", comeback: "Win with 1 projectile left", closeCall: "Survive with shield save 5 times", longShot: "Hit a ball from bottom to top", richPlayer: "Have 10+ projectiles at once", masterOfAll: "Unlock all 50 achievements" }; var achievementProgress = { fireballKills: 0, laserKills: 0, explosiveKills: 0, piercingKills: 0, rapidKills: 0, splitKills: 0, giantKills: 0, bombExpert: 0, rainbowHunter: 0, starCollector: 0, powerupMaster: 0, dodgeMaster: 0, slowMotionPro: 0, magnetMaster: 0, freezeMaster: 0, doubleTrouble: 0, chainReactionPro: 0, perfectAccuracy: 0, persistent: 0, flawless: 0, closeCall: 0 }; // Load saved data var savedData = storage['99balls_save'] || {}; if (savedData.highScore) { var highScoreText = new Text2('Best: ' + savedData.highScore, { size: 30, fill: 0xFFD700 }); highScoreText.anchor.set(1, 0); highScoreText.x = -20; highScoreText.y = 70; LK.gui.topRight.addChild(highScoreText); } // Load achievements from flattened structure for (var key in achievements) { if (savedData[key] !== undefined) { achievements[key] = savedData[key]; } } // Load achievement progress for (var key in achievementProgress) { if (savedData[key + 'Progress'] !== undefined) { achievementProgress[key] = savedData[key + 'Progress']; } } var weaponText = new Text2('Normal', { size: 40, fill: 0xFFFFFF }); weaponText.anchor.set(0.5, 1); weaponText.y = -20; LK.gui.bottom.addChild(weaponText); var slowMotionOverlay = new Container(); var slowMotionBg = slowMotionOverlay.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 50, scaleY: 50, alpha: 0, tint: 0x9b59b6 }); LK.gui.center.addChild(slowMotionOverlay); var powerUpIndicator = new Text2('', { size: 50, fill: 0xFFFFFF }); powerUpIndicator.anchor.set(0, 0); powerUpIndicator.x = 20; powerUpIndicator.y = 200; LK.gui.topLeft.addChild(powerUpIndicator); var doubleShotIndicator = new Text2('', { size: 40, fill: 0xffff00 }); doubleShotIndicator.anchor.set(0, 0); doubleShotIndicator.x = 20; doubleShotIndicator.y = 260; LK.gui.topLeft.addChild(doubleShotIndicator); var shieldIndicator = new Container(); var shieldBg = shieldIndicator.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3, alpha: 0, tint: 0x3498db }); game.addChild(shieldIndicator); function initializeLevel() { // Reset game state gameActive = true; canShoot = true; isAiming = false; cannon = game.addChild(new Cannon()); cannon.x = 1024; cannon.y = 2600; aimLine = game.addChild(new AimLine()); aimLine.x = cannon.x; aimLine.y = cannon.y; aimLine.visible = false; spawnBallRow(); } function spawnBallRow() { var spacing = 2048 / (ballsPerRow + 1); for (var i = 0; i < ballsPerRow; i++) { if (Math.random() < 0.8) { var ball = new Ball(); ball.x = spacing * (i + 1); ball.y = -50; ball.setNumber(Math.floor(Math.random() * stage * 5) + stage); balls.push(ball); game.addChild(ball); if (Math.random() < 0.15) { var powerup = new PowerUp(); powerup.x = ball.x; powerup.y = ball.y; powerups.push(powerup); game.addChild(powerup); } else if (Math.random() < 0.07) { // 7% chance for heart ball var heartBall = new HeartBall(); heartBall.x = ball.x; heartBall.y = ball.y; stars.push(heartBall); // Use stars array for easy y-movement and removal game.addChild(heartBall); } else if (Math.random() < 0.1) { var star = new Star(); star.x = ball.x; star.y = ball.y; stars.push(star); game.addChild(star); } else if (Math.random() < 0.05 && stage > 2) { var slowPowerup = new SlowMotionPowerUp(); slowPowerup.x = ball.x; slowPowerup.y = ball.y; slowMotionPowerups.push(slowPowerup); game.addChild(slowPowerup); } else if (Math.random() < 0.04 && stage > 3) { var multiballPowerup = new MultiballPowerUp(); multiballPowerup.x = ball.x; multiballPowerup.y = ball.y; multiballPowerups.push(multiballPowerup); game.addChild(multiballPowerup); } else if (Math.random() < 0.04 && stage > 1) { var fireballPowerup = new FireBallPowerUp(); fireballPowerup.x = ball.x; fireballPowerup.y = ball.y; fireballPowerups.push(fireballPowerup); game.addChild(fireballPowerup); } else if (Math.random() < 0.03 && stage > 2) { var giantBallPowerup = new GiantBallPowerUp(); giantBallPowerup.x = ball.x; giantBallPowerup.y = ball.y; giantBallPowerups.push(giantBallPowerup); game.addChild(giantBallPowerup); } else if (Math.random() < 0.03 && stage > 4) { var splitBallPowerup = new SplitBallPowerUp(); splitBallPowerup.x = ball.x; splitBallPowerup.y = ball.y; splitBallPowerups.push(splitBallPowerup); game.addChild(splitBallPowerup); } else if (Math.random() < 0.02 && stage > 5) { var laserPowerup = new LaserPowerUp(); laserPowerup.x = ball.x; laserPowerup.y = ball.y; laserPowerups.push(laserPowerup); game.addChild(laserPowerup); } else if (Math.random() < 0.03 && stage > 3) { var shieldPowerup = new ShieldPowerUp(); shieldPowerup.x = ball.x; shieldPowerup.y = ball.y; shieldPowerups.push(shieldPowerup); game.addChild(shieldPowerup); } else if (Math.random() < 0.04 && stage > 2) { var doubleShotPowerup = new DoubleShotPowerUp(); doubleShotPowerup.x = ball.x; doubleShotPowerup.y = ball.y; doubleShotPowerups.push(doubleShotPowerup); game.addChild(doubleShotPowerup); } else if (Math.random() < 0.03 && stage > 4) { var lightningPowerup = new LightningPowerUp(); lightningPowerup.x = ball.x; lightningPowerup.y = ball.y; lightningPowerups.push(lightningPowerup); game.addChild(lightningPowerup); } } else if (Math.random() < 0.05 && stage > 3) { // Spawn rainbow ball var rainbowBall = new RainbowBall(); rainbowBall.x = ball.x; rainbowBall.y = ball.y; rainbowBalls.push(rainbowBall); game.addChild(rainbowBall); } else if (Math.random() < 0.04 && stage > 4) { // Spawn bomb ball var bombBall = new BombBall(); bombBall.x = ball.x; bombBall.y = ball.y; bombBalls.push(bombBall); game.addChild(bombBall); } else if (Math.random() < 0.03 && stage > 5) { // Spawn ghost ball var ghostBall = new GhostBall(); ghostBall.x = ball.x; ghostBall.y = ball.y; ghostBalls.push(ghostBall); game.addChild(ghostBall); } else if (Math.random() < 0.02 && stage > 6) { // Spawn mirror ball var mirrorBall = new MirrorBall(); mirrorBall.x = ball.x; mirrorBall.y = ball.y; mirrorBalls.push(mirrorBall); game.addChild(mirrorBall); } else if (Math.random() < 0.03 && stage > 4) { // Spawn freeze bomb power-up var freezeBombPowerup = new FreezeBombPowerUp(); freezeBombPowerup.x = ball.x; freezeBombPowerup.y = ball.y; freezeBombPowerups.push(freezeBombPowerup); game.addChild(freezeBombPowerup); } else if (Math.random() < 0.02 && stage > 5) { // Spawn chain reaction power-up var chainReactionPowerup = new ChainReactionPowerUp(); chainReactionPowerup.x = ball.x; chainReactionPowerup.y = ball.y; chainReactionPowerups.push(chainReactionPowerup); game.addChild(chainReactionPowerup); } else if (Math.random() < 0.02 && stage > 7) { // Spawn teleport power-up var teleportPowerup = new TeleportPowerUp(); teleportPowerup.x = ball.x; teleportPowerup.y = ball.y; teleportPowerups.push(teleportPowerup); game.addChild(teleportPowerup); } else if (Math.random() < 0.03 && stage > 6) { // Spawn magnet ball var magnetBall = new MagnetBall(); magnetBall.x = ball.x; magnetBall.y = ball.y; magnetBalls.push(magnetBall); game.addChild(magnetBall); } } // Spawn boss every 5 stages bossSpawnCounter++; if (stage > 0 && stage % 5 === 0 && bossSpawnCounter === 1) { var boss = new BossBall(); boss.x = 1024; boss.y = 200; bossBalls.push(boss); game.addChild(boss); var bossWarning = new Text2('BOSS INCOMING!', { size: 100, fill: 0xff1744 }); bossWarning.anchor.set(0.5, 0.5); bossWarning.alpha = 0; LK.gui.center.addChild(bossWarning); tween(bossWarning, { alpha: 1, scaleX: 1.5, scaleY: 1.5 }, { duration: 500, onFinish: function onFinish() { tween(bossWarning, { alpha: 0 }, { duration: 500, delay: 1000, onFinish: function onFinish() { bossWarning.destroy(); } }); } }); } else if (stage % 5 !== 0) { bossSpawnCounter = 0; } } function fireProjectiles(angle) { var shotCount = projectileCount; var delay = 100; var weaponType = currentWeapon; if (currentWeapon === 'rapid') { shotCount = Math.min(projectileCount * 3, 15); delay = 30; } // Double shot modifier if (doubleShotActive) { shotCount *= 2; } // Check for active power-ups if (fireballActive) { weaponType = 'fireball'; fireballActive = false; } else if (giantBallActive) { weaponType = 'giant'; giantBallActive = false; } else if (splitBallActive) { weaponType = 'split'; splitBallActive = false; } else if (laserActive) { weaponType = 'laser'; laserActive = false; shotCount = 1; } else if (lightningActive) { weaponType = 'lightning'; lightningActive = false; } // Add cannon fire effect var muzzleFlash = cannon.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, y: -40, scaleX: 0.5, scaleY: 0.5, alpha: 0.8, tint: weaponType === 'fireball' ? 0xff6600 : weaponType === 'laser' ? 0x00ffff : 0xffffff }); // Special combo effects for weapon combinations var activeEffects = 0; if (fireballActive) activeEffects++; if (giantBallActive) activeEffects++; if (splitBallActive) activeEffects++; if (laserActive) activeEffects++; if (lightningActive) activeEffects++; if (multiballActive) activeEffects++; if (doubleShotActive) activeEffects++; if (activeEffects >= 3) { // Triple combo effect var comboFlash = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: cannon.x, y: cannon.y, scaleX: 0.1, scaleY: 0.1, alpha: 0.8, tint: 0xff00ff }); tween(comboFlash, { scaleX: 10, scaleY: 10, alpha: 0, rotation: Math.PI * 4 }, { duration: 1000, onFinish: function onFinish() { comboFlash.destroy(); } }); checkAchievement('tripleCombo'); } tween(muzzleFlash, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 200, onFinish: function onFinish() { muzzleFlash.destroy(); } }); if (multiballActive) { // Fire in multiple directions var angles = [-0.3, -0.15, 0, 0.15, 0.3]; for (var a = 0; a < angles.length; a++) { (function (angleOffset) { LK.setTimeout(function () { var projectile = new SpecialProjectile(); projectile.x = cannon.x; projectile.y = cannon.y - 40; projectile.setType(weaponType); projectile.velocityX = Math.cos(angle + angleOffset) * projectile.speed; projectile.velocityY = Math.sin(angle + angleOffset) * projectile.speed; projectiles.push(projectile); game.addChild(projectile); }, a * 50); })(angles[a]); } multiballActive = false; return; } for (var i = 0; i < shotCount; i++) { LK.setTimeout(function () { var projectile = new SpecialProjectile(); projectile.x = cannon.x; projectile.y = cannon.y - 40; projectile.setType(weaponType); if (weaponType === 'rapid') { var spread = (Math.random() - 0.5) * 0.2; projectile.velocityX = Math.cos(angle + spread) * projectile.speed; projectile.velocityY = Math.sin(angle + spread) * projectile.speed; } else if (weaponType === 'laser') { // Laser goes straight up projectile.velocityX = 0; projectile.velocityY = -projectile.speed; } else { projectile.velocityX = Math.cos(angle) * projectile.speed; projectile.velocityY = Math.sin(angle) * projectile.speed; } projectiles.push(projectile); game.addChild(projectile); LK.getSound('shoot').play(); }, i * delay); } } function checkCollision(obj1, obj2, radius1, radius2) { var dx = obj1.x - obj2.x; var dy = obj1.y - obj2.y; var distance = Math.sqrt(dx * dx + dy * dy); return distance < radius1 + radius2; } function createExplosion(x, y, color, count) { for (var i = 0; i < count; i++) { var particle = new Particle(); particle.x = x; particle.y = y; var angle = Math.random() * Math.PI * 2; var speed = Math.random() * 10 + 5; particle.velocityX = Math.cos(angle) * speed; particle.velocityY = Math.sin(angle) * speed; particle.tint = color; particles.push(particle); game.addChild(particle); } } var currentAchievementPage = 1; var achievementsPerPage = 15; // 3x5 grid function updateAchievementDisplay() { // Clear existing achievement displays for (var i = achievementPanel.children.length - 1; i >= 0; i--) { var child = achievementPanel.children[i]; if (child !== panelBg && child !== achievementTitle && child !== closeButton) { child.destroy(); } } // Convert achievements object to array for easier pagination var achievementKeys = []; for (var key in achievements) { achievementKeys.push(key); } var totalPages = Math.ceil(achievementKeys.length / achievementsPerPage); // Make sure current page is valid if (currentAchievementPage > totalPages) currentAchievementPage = totalPages; if (currentAchievementPage < 1) currentAchievementPage = 1; var unlocked = 0; var total = achievementKeys.length; // Count unlocked achievements for (var i = 0; i < achievementKeys.length; i++) { if (achievements[achievementKeys[i]]) unlocked++; } // Display achievements for current page var startIndex = (currentAchievementPage - 1) * achievementsPerPage; var endIndex = Math.min(startIndex + achievementsPerPage, achievementKeys.length); var row = 0; var col = 0; var xSpacing = 400; var ySpacing = 250; var xOffset = -xSpacing; var yOffset = -550; for (var i = startIndex; i < endIndex; i++) { var key = achievementKeys[i]; var achContainer = new Container(); var achBg = achContainer.attachAsset('achievementItemBg', { anchorX: 0.5, anchorY: 0.5, tint: achievements[key] ? 0x27ae60 : 0x7f8c8d, alpha: 0.9, scaleX: 1.4, scaleY: 1.4 }); var achText = new Text2(key.replace(/([A-Z])/g, ' $1').trim(), { size: 28, fill: achievements[key] ? 0xFFFFFF : 0x95a5a6 }); achText.anchor.set(0.5, 0.5); achText.y = -14; achContainer.addChild(achText); var achDesc = new Text2(achievementDescriptions[key] || '', { size: 21, fill: achievements[key] ? 0xecf0f1 : 0x7f8c8d }); achDesc.anchor.set(0.5, 0.5); achDesc.y = 14; achContainer.addChild(achDesc); achContainer.x = xOffset + col * xSpacing; achContainer.y = yOffset + row * ySpacing; achievementPanel.addChild(achContainer); col++; if (col >= 3) { col = 0; row++; } } // Add page buttons var buttonY = 750; for (var p = 1; p <= totalPages; p++) { (function (page) { var pageButton = new Container(); var pageBg = pageButton.attachAsset('addBallButton', { anchorX: 0.5, anchorY: 0.5, tint: page === currentAchievementPage ? 0xFFD700 : 0x3498db, scaleX: 0.8, scaleY: 0.8 }); var pageText = new Text2(page.toString(), { size: 40, fill: page === currentAchievementPage ? 0x000000 : 0xFFFFFF }); pageText.anchor.set(0.5, 0.5); pageButton.addChild(pageText); pageButton.x = -100 + (page - 1) * 100; pageButton.y = buttonY; achievementPanel.addChild(pageButton); pageButton.down = function () { currentAchievementPage = page; updateAchievementDisplay(); }; })(p); } var progressText = new Text2('Progress: ' + unlocked + '/' + total + ' (Page ' + currentAchievementPage + '/' + totalPages + ')', { size: 56, fill: 0xFFD700 }); progressText.anchor.set(0.5, 0.5); progressText.y = 600; achievementPanel.addChild(progressText); } function checkAchievement(key) { if (!achievements[key]) { achievements[key] = true; showAchievement(achievementDescriptions[key] || key, 0xFFD700); saveAchievements(); // Check master achievement var allUnlocked = true; for (var k in achievements) { if (k !== 'masterOfAll' && !achievements[k]) { allUnlocked = false; break; } } if (allUnlocked && !achievements.masterOfAll) { achievements.masterOfAll = true; showAchievement("MASTER OF ALL ACHIEVEMENTS!", 0xFF00FF); } } } function saveAchievements() { savedData.highScore = savedData.highScore || 0; for (var key in achievements) { savedData[key] = achievements[key]; } for (var key in achievementProgress) { savedData[key + 'Progress'] = achievementProgress[key]; } storage['99balls_save'] = savedData; } function showAchievement(text, color) { var achievementText = new Text2('Achievement: ' + text, { size: 60, fill: color }); achievementText.anchor.set(0.5, 0.5); achievementText.y = 200; achievementText.alpha = 0; LK.gui.center.addChild(achievementText); tween(achievementText, { alpha: 1, y: 100 }, { duration: 500, onFinish: function onFinish() { tween(achievementText, { alpha: 0 }, { duration: 1000, delay: 2000, onFinish: function onFinish() { achievementText.destroy(); } }); } }); } function updateCombo() { combo++; comboTimer = 120; // 2 seconds at 60 FPS if (combo >= 5) { scoreMultiplier = Math.min(combo / 5, 5); comboText.setText('Combo x' + Math.floor(scoreMultiplier)); comboText.alpha = 1; // Enhanced visual feedback var colors = [0xFFD700, 0xFF6347, 0x00CED1, 0xFF1493, 0x32CD32]; comboText.tint = colors[Math.min(Math.floor(scoreMultiplier) - 1, 4)]; tween(comboText, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, onFinish: function onFinish() { tween(comboText, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); // Combo milestone effects if (combo === 10 || combo === 20 || combo === 30 || combo === 50 || combo === 100) { var message = combo === 100 ? 'LEGENDARY!' : combo === 50 ? 'UNSTOPPABLE!' : 'AMAZING!'; amazingText.setText(message); amazingText.alpha = 1; amazingText.tint = combo === 100 ? 0xff00ff : 0xFFD700; tween(amazingText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, onFinish: function onFinish() { tween(amazingText, { scaleX: 1, scaleY: 1 }, { duration: 200, onFinish: function onFinish() { LK.setTimeout(function () { tween(amazingText, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { amazingText.setText(''); } }); }, 2000); } }); } }); } } } function moveRow() { chainReactionActive = false; consecutiveHits = 0; spawnBallRow(); } game.down = function (x, y, obj) { if (!canShoot || !gameActive) return; isAiming = true; aimLine.visible = true; }; game.move = function (x, y, obj) { if (!isAiming || !gameActive) return; var dx = x - cannon.x; var dy = y - cannon.y; var angle = Math.atan2(dy, dx); // Auto aim to nearest ball if (autoAimActive && balls.length > 0) { var closestBall = null; var closestDist = 999999; for (var i = 0; i < balls.length; i++) { var ball = balls[i]; var ballDx = ball.x - cannon.x; var ballDy = ball.y - cannon.y; var dist = Math.sqrt(ballDx * ballDx + ballDy * ballDy); if (dist < closestDist && ball.y < cannon.y) { closestDist = dist; closestBall = ball; } } if (closestBall) { dx = closestBall.x - cannon.x; dy = closestBall.y - cannon.y; angle = Math.atan2(dy, dx); } } if (angle > -Math.PI && angle < 0) { cannon.rotation = angle + Math.PI / 2; aimLine.rotation = angle + Math.PI / 2; } }; game.up = function (x, y, obj) { if (!isAiming || !gameActive) return; isAiming = false; aimLine.visible = false; canShoot = false; var dx = x - cannon.x; var dy = y - cannon.y; var angle = Math.atan2(dy, dx); if (angle > -Math.PI && angle < 0) { fireProjectiles(angle); } }; game.update = function () { if (!gameActive) return; // Update slow motion if (slowMotionActive) { slowMotionTimer--; gameSpeed = 0.3; if (slowMotionTimer <= 0) { slowMotionActive = false; gameSpeed = 1; tween(slowMotionBg, { alpha: 0 }, { duration: 300 }); powerUpIndicator.setText(''); } } else { gameSpeed = 1; } // Update magnet effect if (magnetActive) { magnetTimer--; if (magnetTimer <= 0) { magnetActive = false; } } // Update combo timer if (comboTimer > 0) { comboTimer--; if (comboTimer === 0) { combo = 0; scoreMultiplier = 1; consecutiveHits = 0; tween(comboText, { alpha: 0 }, { duration: 300 }); amazingText.setText(''); amazingText.alpha = 0; } } else if (combo > 0) { // Add dynamic combo multiplier visual var comboScale = 1 + Math.sin(LK.ticks * 0.2) * 0.1 * Math.min(combo / 10, 1); comboText.scale.set(comboScale); } // Update particles for (var i = particles.length - 1; i >= 0; i--) { if (particles[i].update()) { particles[i].destroy(); particles.splice(i, 1); } } // Update slow motion powerups for (var i = 0; i < slowMotionPowerups.length; i++) { slowMotionPowerups[i].update(); } // Update multiball powerups for (var i = 0; i < multiballPowerups.length; i++) { multiballPowerups[i].update(); } // Update shield if (shieldActive) { shieldTimer--; shieldIndicator.x = cannon.x; shieldIndicator.y = cannon.y; shieldBg.alpha = 0.3 + Math.sin(LK.ticks * 0.2) * 0.2; shieldBg.rotation += 0.05; if (shieldTimer <= 0) { shieldActive = false; tween(shieldBg, { alpha: 0 }, { duration: 300 }); powerUpIndicator.setText(''); } } // Update freeze if (freezeActive) { freezeTimer--; if (freezeTimer <= 0) { freezeActive = false; gameSpeed = 1; for (var i = 0; i < balls.length; i++) { balls[i].tint = 0xffffff; } } } // Update new power-ups for (var i = 0; i < shieldPowerups.length; i++) { shieldPowerups[i].update(); } for (var i = 0; i < fireballPowerups.length; i++) { fireballPowerups[i].update(); } for (var i = 0; i < giantBallPowerups.length; i++) { giantBallPowerups[i].update(); } for (var i = 0; i < splitBallPowerups.length; i++) { splitBallPowerups[i].update(); } for (var i = 0; i < laserPowerups.length; i++) { laserPowerups[i].update(); } for (var i = 0; i < doubleShotPowerups.length; i++) { doubleShotPowerups[i].update(); } // Update double shot timer if (doubleShotActive) { doubleShotTimer--; if (doubleShotTimer <= 0) { doubleShotActive = false; doubleShotIndicator.setText(''); } } // Update lightning powerups for (var i = 0; i < lightningPowerups.length; i++) { lightningPowerups[i].update(); } // Update ghost balls for (var i = 0; i < ghostBalls.length; i++) { ghostBalls[i].update(); } // Update reverse gravity if (reverseGravityActive) { reverseGravityTimer--; if (reverseGravityTimer <= 0) { reverseGravityActive = false; ballSpeed = Math.abs(ballSpeed); powerUpIndicator.setText(''); } } // Update score boost if (scoreBoostActive) { scoreBoostTimer--; scoreBoostMultiplier = 3; if (scoreBoostTimer <= 0) { scoreBoostActive = false; scoreBoostMultiplier = 1; powerUpIndicator.setText(''); } } else { scoreBoostMultiplier = 1; } // Update auto aim if (autoAimActive) { autoAimTimer--; if (autoAimTimer <= 0) { autoAimActive = false; powerUpIndicator.setText(''); } } // Update freeze bomb powerups for (var i = 0; i < freezeBombPowerups.length; i++) { freezeBombPowerups[i].update(); } // Update mirror balls for (var i = 0; i < mirrorBalls.length; i++) { if (mirrorBalls[i].update) { mirrorBalls[i].update(); } } // Update magnet balls for (var i = 0; i < magnetBalls.length; i++) { if (magnetBalls[i].update) { magnetBalls[i].update(); } } // Update chain reaction powerups for (var i = 0; i < chainReactionPowerups.length; i++) { chainReactionPowerups[i].update(); } // Update teleport powerups for (var i = 0; i < teleportPowerups.length; i++) { teleportPowerups[i].update(); } // Track time played timePlayed++; if (timePlayed % 3600 === 0) { // Every minute var minutes = timePlayed / 3600; if (minutes === 5) checkAchievement('persistent'); } // Update stage timer var timeUntilNextStage = 7200 - timePlayed % 7200; var minutes = Math.floor(timeUntilNextStage / 3600); var seconds = Math.floor(timeUntilNextStage % 3600 / 60); stageTimerText.setText('Next Stage: ' + minutes + ':' + (seconds < 10 ? '0' : '') + seconds); // Auto increase stage every 2 minutes (7200 ticks at 60 FPS) if (timePlayed % 7200 === 0 && timePlayed > 0) { stage++; stageText.setText('Stage ' + stage); ballSpeed += 0.1; // Increase MaxHP by 10 for time-based stage increase maxHP += 10; hp += 10; // Also increase current HP by 10 hpText.setText('HP: ' + hp); // Show stage increase notification var stageUpText = new Text2('Stage ' + stage + ' (Time Bonus)', { size: 100, fill: 0x00FFFF }); stageUpText.anchor.set(0.5, 0.5); stageUpText.alpha = 0; LK.gui.center.addChild(stageUpText); tween(stageUpText, { alpha: 1, y: -100 }, { duration: 500, onFinish: function onFinish() { // Show MaxHP increase notification var hpBonusText = new Text2('Max HP +10!', { size: 60, fill: 0xff3366 }); hpBonusText.anchor.set(0.5, 0.5); hpBonusText.y = 0; hpBonusText.alpha = 0; LK.gui.center.addChild(hpBonusText); tween(hpBonusText, { alpha: 1, y: 50 }, { duration: 300, onFinish: function onFinish() { tween(hpBonusText, { alpha: 0 }, { duration: 500, delay: 800, onFinish: function onFinish() { hpBonusText.destroy(); } }); } }); tween(stageUpText, { alpha: 0 }, { duration: 500, delay: 1000, onFinish: function onFinish() { stageUpText.destroy(); } }); } }); } // Track max combo if (combo > maxCombo) { maxCombo = combo; } // Update balls left text ballsLeftText.setText('Balls Left: ' + balls.length); // Update boss balls for (var i = 0; i < bossBalls.length; i++) { if (bossBalls[i].update) { bossBalls[i].update(); } bossBalls[i].y += ballSpeed * gameSpeed * 0.5; // Boss moves slower } // Update ball falling speed and call update, and destroy if off screen for (var i = balls.length - 1; i >= 0; i--) { balls[i].y += ballSpeed * gameSpeed; if (balls[i].update) { balls[i].update(); } if (balls[i].y > 2732 + 100) { balls[i].destroy(); balls.splice(i, 1); } } for (var i = powerups.length - 1; i >= 0; i--) { powerups[i].y += ballSpeed * gameSpeed; if (powerups[i].y > 2732 + 100) { powerups[i].destroy(); powerups.splice(i, 1); } } for (var i = stars.length - 1; i >= 0; i--) { stars[i].y += ballSpeed * gameSpeed; if (stars[i].update) { stars[i].update(); } if (stars[i].y > 2732 + 100) { stars[i].destroy(); stars.splice(i, 1); } } for (var i = slowMotionPowerups.length - 1; i >= 0; i--) { slowMotionPowerups[i].y += ballSpeed * gameSpeed; if (slowMotionPowerups[i].y > 2732 + 100) { slowMotionPowerups[i].destroy(); slowMotionPowerups.splice(i, 1); } } for (var i = multiballPowerups.length - 1; i >= 0; i--) { multiballPowerups[i].y += ballSpeed * gameSpeed; if (multiballPowerups[i].y > 2732 + 100) { multiballPowerups[i].destroy(); multiballPowerups.splice(i, 1); } } for (var i = fireballPowerups.length - 1; i >= 0; i--) { fireballPowerups[i].y += ballSpeed * gameSpeed; if (fireballPowerups[i].y > 2732 + 100) { fireballPowerups[i].destroy(); fireballPowerups.splice(i, 1); } } for (var i = giantBallPowerups.length - 1; i >= 0; i--) { giantBallPowerups[i].y += ballSpeed * gameSpeed; if (giantBallPowerups[i].y > 2732 + 100) { giantBallPowerups[i].destroy(); giantBallPowerups.splice(i, 1); } } for (var i = splitBallPowerups.length - 1; i >= 0; i--) { splitBallPowerups[i].y += ballSpeed * gameSpeed; if (splitBallPowerups[i].y > 2732 + 100) { splitBallPowerups[i].destroy(); splitBallPowerups.splice(i, 1); } } for (var i = laserPowerups.length - 1; i >= 0; i--) { laserPowerups[i].y += ballSpeed * gameSpeed; if (laserPowerups[i].y > 2732 + 100) { laserPowerups[i].destroy(); laserPowerups.splice(i, 1); } } for (var i = shieldPowerups.length - 1; i >= 0; i--) { shieldPowerups[i].y += ballSpeed * gameSpeed; if (shieldPowerups[i].y > 2732 + 100) { shieldPowerups[i].destroy(); shieldPowerups.splice(i, 1); } } for (var i = doubleShotPowerups.length - 1; i >= 0; i--) { doubleShotPowerups[i].y += ballSpeed * gameSpeed; if (doubleShotPowerups[i].y > 2732 + 100) { doubleShotPowerups[i].destroy(); doubleShotPowerups.splice(i, 1); } } for (var i = lightningPowerups.length - 1; i >= 0; i--) { lightningPowerups[i].y += ballSpeed * gameSpeed; if (lightningPowerups[i].y > 2732 + 100) { lightningPowerups[i].destroy(); lightningPowerups.splice(i, 1); } } for (var i = ghostBalls.length - 1; i >= 0; i--) { ghostBalls[i].y += ballSpeed * gameSpeed; if (ghostBalls[i].y > 2732 + 100) { ghostBalls[i].destroy(); ghostBalls.splice(i, 1); } } for (var i = mirrorBalls.length - 1; i >= 0; i--) { mirrorBalls[i].y += ballSpeed * gameSpeed; if (mirrorBalls[i].y > 2732 + 100) { mirrorBalls[i].destroy(); mirrorBalls.splice(i, 1); } } for (var i = magnetBalls.length - 1; i >= 0; i--) { magnetBalls[i].y += ballSpeed * gameSpeed; if (magnetBalls[i].y > 2732 + 100) { magnetBalls[i].destroy(); magnetBalls.splice(i, 1); } } for (var i = freezeBombPowerups.length - 1; i >= 0; i--) { freezeBombPowerups[i].y += ballSpeed * gameSpeed; if (freezeBombPowerups[i].y > 2732 + 100) { freezeBombPowerups[i].destroy(); freezeBombPowerups.splice(i, 1); } } for (var i = chainReactionPowerups.length - 1; i >= 0; i--) { chainReactionPowerups[i].y += ballSpeed * gameSpeed; if (chainReactionPowerups[i].y > 2732 + 100) { chainReactionPowerups[i].destroy(); chainReactionPowerups.splice(i, 1); } } for (var i = teleportPowerups.length - 1; i >= 0; i--) { teleportPowerups[i].y += ballSpeed * gameSpeed; if (teleportPowerups[i].y > 2732 + 100) { teleportPowerups[i].destroy(); teleportPowerups.splice(i, 1); } } // Update rainbow balls for (var i = 0; i < rainbowBalls.length; i++) { rainbowBalls[i].y += ballSpeed * gameSpeed; if (rainbowBalls[i].update) { rainbowBalls[i].update(); } } // Update bomb balls for (var i = 0; i < bombBalls.length; i++) { bombBalls[i].y += ballSpeed * gameSpeed; if (bombBalls[i].update) { bombBalls[i].update(); } } // Update projectiles for (var i = projectiles.length - 1; i >= 0; i--) { var projectile = projectiles[i]; // Apply game speed to projectile movement var oldVelX = projectile.velocityX; var oldVelY = projectile.velocityY; projectile.velocityX *= gameSpeed; projectile.velocityY *= gameSpeed; if (projectile.update() || projectile.y > 2732 + 50) { projectile.destroy(); projectiles.splice(i, 1); continue; } projectile.velocityX = oldVelX; projectile.velocityY = oldVelY; // Apply magnet effect if (magnetActive) { var closestBall = null; var closestDist = 200; for (var j = 0; j < balls.length; j++) { var ball = balls[j]; var dx = ball.x - projectile.x; var dy = ball.y - projectile.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < closestDist) { closestDist = dist; closestBall = ball; } } if (closestBall) { var dx = closestBall.x - projectile.x; var dy = closestBall.y - projectile.y; var dist = Math.sqrt(dx * dx + dy * dy); projectile.velocityX += dx / dist * 2; projectile.velocityY += dy / dist * 2; var speed = Math.sqrt(projectile.velocityX * projectile.velocityX + projectile.velocityY * projectile.velocityY); if (speed > projectile.speed * 1.5) { projectile.velocityX = projectile.velocityX / speed * projectile.speed * 1.5; projectile.velocityY = projectile.velocityY / speed * projectile.speed * 1.5; } } } // Apply magnet ball attraction for (var m = 0; m < magnetBalls.length; m++) { var magnetBall = magnetBalls[m]; var dx = magnetBall.x - projectile.x; var dy = magnetBall.y - projectile.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < magnetBall.magnetRadius && dist > magnetBall.radius) { // Attract projectile var force = (1 - dist / magnetBall.magnetRadius) * 3; projectile.velocityX += dx / dist * force; projectile.velocityY += dy / dist * force; // Normalize speed var speed = Math.sqrt(projectile.velocityX * projectile.velocityX + projectile.velocityY * projectile.velocityY); if (speed > projectile.speed * 2) { projectile.velocityX = projectile.velocityX / speed * projectile.speed * 2; projectile.velocityY = projectile.velocityY / speed * projectile.speed * 2; } } } var hitBall = false; // Check boss collisions first for (var j = bossBalls.length - 1; j >= 0; j--) { var boss = bossBalls[j]; if (checkCollision(projectile, boss, projectile.radius, boss.radius)) { LK.getSound('hit').play(); updateCombo(); hitBall = true; // Critical hit chance var isCritical = Math.random() < criticalHitChance; var damage = isCritical ? 5 : 1; if (isCritical) { var critText = new Text2('CRITICAL!', { size: 60, fill: 0xffff00 }); critText.anchor.set(0.5, 0.5); critText.x = boss.x; critText.y = boss.y - 100; game.addChild(critText); tween(critText, { y: boss.y - 150, alpha: 0 }, { duration: 1000, onFinish: function onFinish() { critText.destroy(); } }); // Add critical hit effect var critEffect = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: boss.x, y: boss.y, scaleX: 0.1, scaleY: 0.1, alpha: 0.8, tint: 0xffff00 }); tween(critEffect, { scaleX: 3, scaleY: 3, alpha: 0 }, { duration: 500, onFinish: function onFinish() { critEffect.destroy(); } }); } for (var d = 0; d < damage; d++) { if (boss.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + 500); createExplosion(boss.x, boss.y, 0xff1744, 50); boss.destroy(); bossBalls.splice(j, 1); // Boss killed achievement if (!achievements.bossKiller) { achievements.bossKiller = true; showAchievement('Boss Slayer!', 0xff1744); } break; } } // Handle projectile after boss hit if (projectile.type !== 'piercing' && projectile.type !== 'fireball' && projectile.type !== 'laser') { projectile.destroy(); projectiles.splice(i, 1); i--; break; } } } // Check rainbow ball collisions for (var j = rainbowBalls.length - 1; j >= 0; j--) { var rainbowBall = rainbowBalls[j]; if (checkCollision(projectile, rainbowBall, projectile.radius, rainbowBall.radius)) { LK.getSound('hit').play(); updateCombo(); hitBall = true; // Rainbow balls give bonus points var bonus = 50 * scoreMultiplier; if (rainbowBall.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + bonus * 5); createExplosion(rainbowBall.x, rainbowBall.y, 0xffffff, 40); achievementProgress.rainbowHunter++; if (achievementProgress.rainbowHunter >= 20) checkAchievement('rainbowHunter'); // Create rainbow particle effect for (var p = 0; p < 20; p++) { var particle = new Particle(); particle.x = rainbowBall.x; particle.y = rainbowBall.y; var angle = p / 20 * Math.PI * 2; particle.velocityX = Math.cos(angle) * 8; particle.velocityY = Math.sin(angle) * 8; particle.tint = Math.random() * 0xffffff | 0; particles.push(particle); game.addChild(particle); } rainbowBall.destroy(); rainbowBalls.splice(j, 1); } // Projectile continues through rainbow balls } } // Check ghost ball collisions for (var j = ghostBalls.length - 1; j >= 0; j--) { var ghostBall = ghostBalls[j]; if (!ghostBall.isPhased && checkCollision(projectile, ghostBall, projectile.radius, ghostBall.radius)) { LK.getSound('hit').play(); updateCombo(); hitBall = true; if (ghostBall.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + 100 * scoreMultiplier * scoreBoostMultiplier); createExplosion(ghostBall.x, ghostBall.y, 0x8888ff, 30); ghostBall.destroy(); ghostBalls.splice(j, 1); ballsDestroyed++; if (!achievements.ghostHunter) { achievements.ghostHunter = true; showAchievement('Ghost Hunter!', 0x8888ff); } } } } // Check magnet ball collisions for (var j = magnetBalls.length - 1; j >= 0; j--) { var magnetBall = magnetBalls[j]; if (checkCollision(projectile, magnetBall, projectile.radius, magnetBall.radius)) { LK.getSound('hit').play(); updateCombo(); hitBall = true; if (magnetBall.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + 200 * scoreMultiplier * scoreBoostMultiplier); createExplosion(magnetBall.x, magnetBall.y, 0x0066cc, 45); // Create magnetic shockwave var shockwave = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: magnetBall.x, y: magnetBall.y, scaleX: 0.1, scaleY: 0.1, alpha: 0.6, tint: 0x0099ff }); tween(shockwave, { scaleX: 8, scaleY: 8, alpha: 0 }, { duration: 800, onFinish: function onFinish() { shockwave.destroy(); } }); magnetBall.destroy(); magnetBalls.splice(j, 1); ballsDestroyed++; checkAchievement('magnetMaster'); } // Projectile behavior after magnet hit if (projectile.type !== 'laser' && projectile.type !== 'piercing') { projectile.destroy(); projectiles.splice(i, 1); i--; break; } } } // Check mirror ball collisions for (var j = mirrorBalls.length - 1; j >= 0; j--) { var mirrorBall = mirrorBalls[j]; if (checkCollision(projectile, mirrorBall, projectile.radius, mirrorBall.radius)) { LK.getSound('hit').play(); updateCombo(); hitBall = true; // Reflect projectile var dx = projectile.x - mirrorBall.x; var dy = projectile.y - mirrorBall.y; var dist = Math.sqrt(dx * dx + dy * dy); dx /= dist; dy /= dist; projectile.velocityX = dx * projectile.speed * 1.5; projectile.velocityY = dy * projectile.speed * 1.5; // Mirror flash effect var flash = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: mirrorBall.x, y: mirrorBall.y, scaleX: 1, scaleY: 1, alpha: 0.8, tint: 0xffffff }); tween(flash, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, onFinish: function onFinish() { flash.destroy(); } }); if (mirrorBall.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + 150 * scoreMultiplier * scoreBoostMultiplier); createExplosion(mirrorBall.x, mirrorBall.y, 0xc0c0c0, 40); mirrorBall.destroy(); mirrorBalls.splice(j, 1); ballsDestroyed++; } // Projectile bounces off mirror balls if (projectile.type !== 'laser') { break; } } } // Check bomb ball collisions for (var j = bombBalls.length - 1; j >= 0; j--) { var bombBall = bombBalls[j]; if (checkCollision(projectile, bombBall, projectile.radius, bombBall.radius)) { LK.getSound('hit').play(); updateCombo(); hitBall = true; if (bombBall.takeDamage()) { LK.getSound('destroy').play(); // Bomb explosion damages all nearby balls createExplosion(bombBall.x, bombBall.y, 0xff0000, 50); achievementProgress.bombExpert++; if (achievementProgress.bombExpert >= 10) checkAchievement('bombExpert'); // Collect all balls that need explosion damage var ballsToExplode = []; // Check all balls for explosion damage for (var k = 0; k < balls.length; k++) { var nearbyBall = balls[k]; if (checkCollision(bombBall, nearbyBall, 200, nearbyBall.radius)) { ballsToExplode.push(nearbyBall); } } // Now apply damage to all marked balls for (var be = 0; be < ballsToExplode.length; be++) { var explodeBall = ballsToExplode[be]; // Apply up to 3 damage for (var d = 0; d < 3; d++) { if (explodeBall.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + Math.floor(stage * scoreMultiplier * 2)); createExplosion(explodeBall.x, explodeBall.y, 0xffff00, 20); explodeBall.destroy(); // Find and remove from balls array var ballIndex = balls.indexOf(explodeBall); if (ballIndex !== -1) { balls.splice(ballIndex, 1); } break; } } } // Remove the bomb ball bombBall.destroy(); bombBalls.splice(j, 1); } projectile.destroy(); projectiles.splice(i, 1); i--; break; } } // Check ball collisions for (var j = balls.length - 1; j >= 0; j--) { var ball = balls[j]; if (checkCollision(projectile, ball, projectile.radius, ball.radius)) { LK.getSound('hit').play(); updateCombo(); hitBall = true; // Set gravity to 1% per frame after hit if (typeof projectile.gravity === "undefined" || projectile.gravity < 0.1) { projectile.gravity = 0.1; } // Handle explosive projectiles if (projectile.type === 'explosive') { // Create explosion effect at impact point createExplosion(ball.x, ball.y, 0xff4444, 30); LK.effects.flashScreen(0xff4444, 200); // Collect all balls that need to be destroyed var ballsToDestroy = []; // Check all balls for explosion damage for (var k = 0; k < balls.length; k++) { var otherBall = balls[k]; if (checkCollision(ball, otherBall, 150, otherBall.radius)) { // Store reference to ball that needs destruction ballsToDestroy.push(otherBall); } } // Now destroy all marked balls for (var bd = 0; bd < ballsToDestroy.length; bd++) { var destroyBall = ballsToDestroy[bd]; // Apply damage if (destroyBall.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + Math.floor(stage * scoreMultiplier)); createExplosion(destroyBall.x, destroyBall.y, 0xffff00, 15); destroyBall.destroy(); // Find and remove from balls array var ballIndex = balls.indexOf(destroyBall); if (ballIndex !== -1) { balls.splice(ballIndex, 1); } } } // Remove the projectile projectile.destroy(); projectiles.splice(i, 1); i--; break; } // Skip the regular ball damage check for explosive projectiles if (projectile.type !== 'explosive' && ball.takeDamage()) { LK.getSound('destroy').play(); consecutiveHits++; if (consecutiveHits >= 3) { chainReactionActive = true; achievementProgress.chainReactionPro++; if (achievementProgress.chainReactionPro >= 50) checkAchievement('chainReactionPro'); } // Track weapon kills switch (projectile.type) { case 'fireball': achievementProgress.fireballKills++; if (achievementProgress.fireballKills >= 100) checkAchievement('fireballKills'); break; case 'laser': achievementProgress.laserKills++; if (achievementProgress.laserKills >= 100) checkAchievement('laserKills'); break; case 'explosive': achievementProgress.explosiveKills++; if (achievementProgress.explosiveKills >= 100) checkAchievement('explosiveKills'); break; case 'piercing': achievementProgress.piercingKills++; if (achievementProgress.piercingKills >= 100) checkAchievement('piercingKills'); break; case 'rapid': achievementProgress.rapidKills++; if (achievementProgress.rapidKills >= 100) checkAchievement('rapidKills'); break; case 'split': achievementProgress.splitKills++; if (achievementProgress.splitKills >= 100) checkAchievement('splitKills'); break; case 'giant': achievementProgress.giantKills++; if (achievementProgress.giantKills >= 100) checkAchievement('giantKills'); break; } // Track perfect accuracy achievementProgress.perfectAccuracy++; if (achievementProgress.perfectAccuracy >= 100) checkAchievement('perfectAccuracy'); // Check for lucky long distance shot var shotDistance = Math.sqrt(Math.pow(ball.x - cannon.x, 2) + Math.pow(ball.y - cannon.y, 2)); if (shotDistance > 2000) { checkAchievement('luckyShot'); // Lucky shot visual effect var luckyText = new Text2('LUCKY SHOT!', { size: 20, fill: 0xffd700 }); luckyText.anchor.set(0.5, 0.5); luckyText.x = ball.x; luckyText.y = ball.y - 100; game.addChild(luckyText); tween(luckyText, { y: ball.y - 200, alpha: 0 }, { duration: 1500, onFinish: function onFinish() { luckyText.destroy(); } }); } var points = Math.floor(stage * scoreMultiplier * scoreBoostMultiplier * (chainReactionActive ? 2 : 1)); LK.setScore(LK.getScore() + points); scoreText.setText('Score: ' + LK.getScore()); createExplosion(ball.x, ball.y, 0xffff00, chainReactionActive ? 25 : 15); // Chain reaction damage (loop backwards to avoid skipping) if (chainReactionActive) { for (var k = balls.length - 1; k >= 0; k--) { var nearbyBall = balls[k]; if (nearbyBall !== ball && checkCollision(ball, nearbyBall, 100, nearbyBall.radius)) { if (nearbyBall.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + Math.floor(stage * scoreMultiplier * 2)); createExplosion(nearbyBall.x, nearbyBall.y, 0xffff00, 20); nearbyBall.destroy(); balls.splice(k, 1); } } } } ball.destroy(); balls.splice(j, 1); ballsDestroyed++; perfectHits++; } // Handle projectile behavior after hit if (projectile.type === 'lightning') { // Chain to nearby balls var chainTargets = []; for (var k = 0; k < balls.length; k++) { var nearbyBall = balls[k]; if (nearbyBall !== ball && checkCollision(ball, nearbyBall, 150, nearbyBall.radius)) { chainTargets.push(nearbyBall); } } // Create lightning visual effect for (var c = 0; c < Math.min(chainTargets.length, 3); c++) { var target = chainTargets[c]; var lightning = game.attachAsset('aimline', { anchorX: 0.5, anchorY: 0, x: ball.x, y: ball.y, tint: 0x9966ff, alpha: 0.8 }); var dx = target.x - ball.x; var dy = target.y - ball.y; var dist = Math.sqrt(dx * dx + dy * dy); lightning.height = dist; lightning.rotation = Math.atan2(dy, dx) + Math.PI / 2; tween(lightning, { alpha: 0, scaleX: 0.1 }, { duration: 300, onFinish: function onFinish() { lightning.destroy(); } }); // Damage chained balls if (target.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + Math.floor(stage * scoreMultiplier * scoreBoostMultiplier)); createExplosion(target.x, target.y, 0x9966ff, 20); target.destroy(); var idx = balls.indexOf(target); if (idx > -1) balls.splice(idx, 1); } } projectile.destroy(); projectiles.splice(i, 1); i--; break; } else if (projectile.type === 'piercing' && projectile.piercing > 0) { projectile.piercing--; // Continue in same direction } else if (projectile.type === 'explosive') { projectile.destroy(); projectiles.splice(i, 1); i--; break; } else if (projectile.type === 'fireball') { // Fireball burns through everything createExplosion(ball.x, ball.y, 0xff6600, 15); } else if (projectile.type === 'split') { // Split into 3 projectiles for (var s = 0; s < 3; s++) { var splitProjectile = new SpecialProjectile(); splitProjectile.x = projectile.x; splitProjectile.y = projectile.y; splitProjectile.setType('normal'); var splitAngle = Math.atan2(projectile.velocityY, projectile.velocityX) + (s - 1) * 0.5; splitProjectile.velocityX = Math.cos(splitAngle) * splitProjectile.speed; splitProjectile.velocityY = Math.sin(splitAngle) * splitProjectile.speed; projectiles.push(splitProjectile); game.addChild(splitProjectile); } projectile.destroy(); projectiles.splice(i, 1); i--; break; } else if (projectile.type === 'laser') { // Laser continues straight } else { // Normal bounce var dx = projectile.x - ball.x; var dy = projectile.y - ball.y; var dist = Math.sqrt(dx * dx + dy * dy); dx /= dist; dy /= dist; projectile.velocityX = dx * projectile.speed; projectile.velocityY = dy * projectile.speed; } if (!projectile.type || projectile.type === 'normal' || projectile.type === 'rapid' || projectile.type === 'giant') { break; } } } if (hitBall) { // Perfect shot bonus if (consecutiveHits >= 10 && consecutiveHits % 5 === 0) { var perfectBonus = 100 * scoreMultiplier; LK.setScore(LK.getScore() + perfectBonus); var perfectText = new Text2('PERFECT SHOT! +' + perfectBonus, { size: 60, fill: 0x00ff00 }); perfectText.anchor.set(0.5, 0.5); perfectText.alpha = 0; LK.gui.center.addChild(perfectText); tween(perfectText, { alpha: 1, y: -50 }, { duration: 300, onFinish: function onFinish() { tween(perfectText, { alpha: 0 }, { duration: 500, delay: 500, onFinish: function onFinish() { perfectText.destroy(); } }); } }); } continue; } else { chainReactionActive = false; consecutiveHits = 0; } // Check powerup collisions for (var j = powerups.length - 1; j >= 0; j--) { var powerup = powerups[j]; if (checkCollision(projectile, powerup, projectile.radius, powerup.radius)) { LK.getSound('collect').play(); projectileCount++; projectileCountText.setText('x' + projectileCount); createExplosion(powerup.x, powerup.y, 0x4ecdc4, 10); powerup.destroy(); powerups.splice(j, 1); } } // Check slow motion power-up collisions for (var j = slowMotionPowerups.length - 1; j >= 0; j--) { var slowPowerup = slowMotionPowerups[j]; if (checkCollision(projectile, slowPowerup, projectile.radius, slowPowerup.radius)) { LK.getSound('collect').play(); slowMotionActive = true; slowMotionTimer = 300; // 5 seconds at 60 FPS powerUpIndicator.setText('SLOW MOTION'); achievementProgress.slowMotionPro++; achievementProgress.powerupMaster++; if (achievementProgress.slowMotionPro >= 20) checkAchievement('slowMotionPro'); if (achievementProgress.powerupMaster >= 100) checkAchievement('powerupMaster'); tween(slowMotionBg, { alpha: 0.1 }, { duration: 300 }); createExplosion(slowPowerup.x, slowPowerup.y, 0x9b59b6, 20); slowPowerup.destroy(); slowMotionPowerups.splice(j, 1); } } // Check multiball power-up collisions for (var j = multiballPowerups.length - 1; j >= 0; j--) { var multiballPowerup = multiballPowerups[j]; if (checkCollision(projectile, multiballPowerup, projectile.radius, multiballPowerup.radius)) { LK.getSound('collect').play(); multiballActive = true; powerUpIndicator.setText('MULTIBALL!'); createExplosion(multiballPowerup.x, multiballPowerup.y, 0xe74c3c, 25); multiballPowerup.destroy(); multiballPowerups.splice(j, 1); } } // Check fireball power-up collisions for (var j = fireballPowerups.length - 1; j >= 0; j--) { var fireballPowerup = fireballPowerups[j]; if (checkCollision(projectile, fireballPowerup, projectile.radius, fireballPowerup.radius)) { LK.getSound('collect').play(); fireballActive = true; powerUpIndicator.setText('FIREBALL!'); createExplosion(fireballPowerup.x, fireballPowerup.y, 0xff6600, 30); fireballPowerup.destroy(); fireballPowerups.splice(j, 1); } } // Check giant ball power-up collisions for (var j = giantBallPowerups.length - 1; j >= 0; j--) { var giantBallPowerup = giantBallPowerups[j]; if (checkCollision(projectile, giantBallPowerup, projectile.radius, giantBallPowerup.radius)) { LK.getSound('collect').play(); giantBallActive = true; powerUpIndicator.setText('GIANT BALL!'); createExplosion(giantBallPowerup.x, giantBallPowerup.y, 0x00ff00, 35); giantBallPowerup.destroy(); giantBallPowerups.splice(j, 1); } } // Check split ball power-up collisions for (var j = splitBallPowerups.length - 1; j >= 0; j--) { var splitBallPowerup = splitBallPowerups[j]; if (checkCollision(projectile, splitBallPowerup, projectile.radius, splitBallPowerup.radius)) { LK.getSound('collect').play(); splitBallActive = true; powerUpIndicator.setText('SPLIT BALL!'); createExplosion(splitBallPowerup.x, splitBallPowerup.y, 0xff00ff, 30); splitBallPowerup.destroy(); splitBallPowerups.splice(j, 1); } } // Check laser power-up collisions for (var j = laserPowerups.length - 1; j >= 0; j--) { var laserPowerup = laserPowerups[j]; if (checkCollision(projectile, laserPowerup, projectile.radius, laserPowerup.radius)) { LK.getSound('collect').play(); laserActive = true; powerUpIndicator.setText('LASER BEAM!'); createExplosion(laserPowerup.x, laserPowerup.y, 0x00ffff, 40); laserPowerup.destroy(); laserPowerups.splice(j, 1); } } // Check shield power-up collisions for (var j = shieldPowerups.length - 1; j >= 0; j--) { var shieldPowerup = shieldPowerups[j]; if (checkCollision(projectile, shieldPowerup, projectile.radius, shieldPowerup.radius)) { LK.getSound('collect').play(); shieldActive = true; shieldTimer = 600; // 10 seconds powerUpIndicator.setText('SHIELD ACTIVE!'); tween(shieldBg, { alpha: 0.3 }, { duration: 300 }); createExplosion(shieldPowerup.x, shieldPowerup.y, 0x3498db, 30); shieldPowerup.destroy(); shieldPowerups.splice(j, 1); // Shield achievement if (!achievements.shieldMaster) { achievements.shieldMaster = true; showAchievement('Shield Master!', 0x3498db); } } } // Check double shot power-up collisions for (var j = doubleShotPowerups.length - 1; j >= 0; j--) { var doubleShotPowerup = doubleShotPowerups[j]; if (checkCollision(projectile, doubleShotPowerup, projectile.radius, doubleShotPowerup.radius)) { LK.getSound('collect').play(); doubleShotActive = true; doubleShotTimer = 600; // 10 seconds doubleShotIndicator.setText('DOUBLE SHOT!'); createExplosion(doubleShotPowerup.x, doubleShotPowerup.y, 0xffff00, 35); doubleShotPowerup.destroy(); doubleShotPowerups.splice(j, 1); } } // Check lightning power-up collisions for (var j = lightningPowerups.length - 1; j >= 0; j--) { var lightningPowerup = lightningPowerups[j]; if (checkCollision(projectile, lightningPowerup, projectile.radius, lightningPowerup.radius)) { LK.getSound('collect').play(); lightningActive = true; powerUpIndicator.setText('LIGHTNING CHAIN!'); createExplosion(lightningPowerup.x, lightningPowerup.y, 0x9966ff, 40); lightningPowerup.destroy(); lightningPowerups.splice(j, 1); powerupsCollected++; if (!achievements.lightningMaster) { achievements.lightningMaster = true; showAchievement('Lightning Master!', 0x9966ff); } } } // Check freeze bomb power-up collisions for (var j = freezeBombPowerups.length - 1; j >= 0; j--) { var freezeBombPowerup = freezeBombPowerups[j]; if (checkCollision(projectile, freezeBombPowerup, projectile.radius, freezeBombPowerup.radius)) { LK.getSound('collect').play(); // Freeze explosion effect createExplosion(freezeBombPowerup.x, freezeBombPowerup.y, 0x00ccff, 50); LK.effects.flashScreen(0x00ccff, 500); // Freeze all balls in radius (loop backwards to avoid skipping) for (var k = balls.length - 1; k >= 0; k--) { var ball = balls[k]; if (checkCollision(freezeBombPowerup, ball, 300, ball.radius)) { ball.tint = 0x00ccff; // Create ice effect on ball var ice = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: ball.x, y: ball.y, scaleX: 1.2, scaleY: 1.2, alpha: 0.3, tint: 0x00ffff }); tween(ice, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 2000, onFinish: function onFinish() { ice.destroy(); } }); // Damage frozen ball for (var d = 0; d < 5; d++) { if (ball.takeDamage()) { LK.getSound('destroy').play(); LK.setScore(LK.getScore() + Math.floor(stage * scoreMultiplier * 3)); createExplosion(ball.x, ball.y, 0x00ccff, 25); ball.destroy(); balls.splice(k, 1); ballsDestroyed++; break; } } } } freezeBombPowerup.destroy(); freezeBombPowerups.splice(j, 1); powerupsCollected++; } } // Check chain reaction power-up collisions for (var j = chainReactionPowerups.length - 1; j >= 0; j--) { var chainReactionPowerup = chainReactionPowerups[j]; if (checkCollision(projectile, chainReactionPowerup, projectile.radius, chainReactionPowerup.radius)) { LK.getSound('collect').play(); chainReactionBombActive = true; powerUpIndicator.setText('CHAIN BOMB!'); createExplosion(chainReactionPowerup.x, chainReactionPowerup.y, 0xff8800, 40); // Make next hit cause massive chain reaction consecutiveHits = 10; chainReactionActive = true; chainReactionPowerup.destroy(); chainReactionPowerups.splice(j, 1); powerupsCollected++; } } // Check teleport power-up collisions for (var j = teleportPowerups.length - 1; j >= 0; j--) { var teleportPowerup = teleportPowerups[j]; if (checkCollision(projectile, teleportPowerup, projectile.radius, teleportPowerup.radius)) { LK.getSound('collect').play(); // Teleport effect var portal1 = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: projectile.x, y: projectile.y, scaleX: 0.1, scaleY: 0.1, alpha: 0.8, tint: 0x8000ff }); tween(portal1, { scaleX: 2, scaleY: 2, alpha: 0, rotation: Math.PI * 2 }, { duration: 500, onFinish: function onFinish() { portal1.destroy(); } }); // Teleport projectile to random position projectile.x = Math.random() * 1648 + 200; projectile.y = Math.random() * 1000 + 500; // Exit portal effect var portal2 = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: projectile.x, y: projectile.y, scaleX: 2, scaleY: 2, alpha: 0, tint: 0x8000ff }); tween(portal2, { scaleX: 0.1, scaleY: 0.1, alpha: 0.8, rotation: -Math.PI * 2 }, { duration: 500, onFinish: function onFinish() { portal2.destroy(); } }); teleportPowerup.destroy(); teleportPowerups.splice(j, 1); powerupsCollected++; } } // Check star collisions for (var j = stars.length - 1; j >= 0; j--) { var star = stars[j]; // HeartBall: +10 HP, effect, destroy if (star instanceof HeartBall && checkCollision(projectile, star, projectile.radius, star.radius)) { LK.getSound('collect').play(); var oldHP = hp; hp = Math.min(hp + 10, maxHP); // Show +10 HP effect var hpGainText = new Text2('+10 HP', { size: 60, fill: 0xff3366 }); hpGainText.anchor.set(0.5, 0.5); hpGainText.x = star.x; hpGainText.y = star.y; game.addChild(hpGainText); tween(hpGainText, { y: star.y - 100, alpha: 0 }, { duration: 800, onFinish: function onFinish() { hpGainText.destroy(); } }); hpText.setText('HP: ' + hp); createExplosion(star.x, star.y, 0xff3366, 15); star.destroy(); stars.splice(j, 1); continue; } // Normal star if (checkCollision(projectile, star, projectile.radius, star.radius)) { LK.getSound('collect').play(); // Random bonus effect var randomEffect = Math.random(); if (randomEffect < 0.15) { magnetActive = true; magnetTimer = 180; // 3 seconds powerUpIndicator.setText('MAGNET ACTIVE'); } else if (randomEffect < 0.3) { projectileCount += 2; projectileCountText.setText('x' + projectileCount); } else if (randomEffect < 0.45) { // Freeze all balls temporarily freezeActive = true; freezeTimer = 180; // 3 seconds powerUpIndicator.setText('FREEZE!'); for (var k = 0; k < balls.length; k++) { balls[k].tint = 0x00ffff; } } else if (randomEffect < 0.6) { // Reverse gravity reverseGravityActive = true; reverseGravityTimer = 300; // 5 seconds ballSpeed = -Math.abs(ballSpeed); powerUpIndicator.setText('REVERSE GRAVITY!'); LK.effects.flashScreen(0xff00ff, 500); if (!achievements.reverseGravity) { achievements.reverseGravity = true; showAchievement('Gravity Master!', 0xff00ff); } } else if (randomEffect < 0.75) { // Score boost scoreBoostActive = true; scoreBoostTimer = 600; // 10 seconds powerUpIndicator.setText('3X SCORE!'); } else if (randomEffect < 0.9) { // Auto aim autoAimActive = true; autoAimTimer = 300; // 5 seconds powerUpIndicator.setText('AUTO AIM!'); } else { // Random weapon power-up var weapons = ['fireball', 'giant', 'split', 'laser', 'lightning']; var randomWeapon = weapons[Math.floor(Math.random() * weapons.length)]; switch (randomWeapon) { case 'fireball': fireballActive = true; break; case 'giant': giantBallActive = true; break; case 'split': splitBallActive = true; break; case 'laser': laserActive = true; break; case 'lightning': lightningActive = true; break; } powerUpIndicator.setText(randomWeapon.toUpperCase() + '!'); } // Unlock weapons based on score // Check achievements if (combo >= 10 && !achievements.combo10) { achievements.combo10 = true; showAchievement('Combo Master!', 0xFF00FF); } if (LK.getScore() >= 1000 && !achievements.score1000) { achievements.score1000 = true; showAchievement('Score Champion!', 0xFFD700); } if (weaponUnlocks.piercing && weaponUnlocks.explosive && weaponUnlocks.rapid && !achievements.allWeapons) { achievements.allWeapons = true; showAchievement('Weapon Master!', 0x00FF00); } // Save high score if (!savedData.highScore || LK.getScore() > savedData.highScore) { savedData.highScore = LK.getScore(); // Flatten achievements into savedData directly savedData.firstWin = achievements.firstWin; savedData.combo10 = achievements.combo10; savedData.score1000 = achievements.score1000; savedData.allWeapons = achievements.allWeapons; storage['99balls_save'] = savedData; } if (LK.getScore() >= 100 && !weaponUnlocks.piercing) { weaponUnlocks.piercing = true; var unlockText = new Text2('Piercing Weapon Unlocked!', { size: 80, fill: 0xFF00FF }); unlockText.anchor.set(0.5, 0.5); unlockText.alpha = 0; LK.gui.center.addChild(unlockText); tween(unlockText, { alpha: 1, y: -100 }, { duration: 500, onFinish: function onFinish() { tween(unlockText, { alpha: 0 }, { duration: 1000, delay: 1000, onFinish: function onFinish() { unlockText.destroy(); } }); } }); } if (LK.getScore() >= 300 && !weaponUnlocks.explosive) { weaponUnlocks.explosive = true; var unlockText = new Text2('Explosive Weapon Unlocked!', { size: 80, fill: 0xFF4444 }); unlockText.anchor.set(0.5, 0.5); unlockText.alpha = 0; LK.gui.center.addChild(unlockText); tween(unlockText, { alpha: 1, y: -100 }, { duration: 500, onFinish: function onFinish() { tween(unlockText, { alpha: 0 }, { duration: 1000, delay: 1000, onFinish: function onFinish() { unlockText.destroy(); } }); } }); } if (LK.getScore() >= 500 && !weaponUnlocks.rapid) { weaponUnlocks.rapid = true; var unlockText = new Text2('Rapid Fire Unlocked!', { size: 80, fill: 0x44FF44 }); unlockText.anchor.set(0.5, 0.5); unlockText.alpha = 0; LK.gui.center.addChild(unlockText); tween(unlockText, { alpha: 1, y: -100 }, { duration: 500, onFinish: function onFinish() { tween(unlockText, { alpha: 0 }, { duration: 1000, delay: 1000, onFinish: function onFinish() { unlockText.destroy(); } }); } }); } LK.setScore(LK.getScore() + Math.floor(10 * scoreMultiplier)); scoreText.setText('Score: ' + LK.getScore()); createExplosion(star.x, star.y, 0xffd93d, 15); star.destroy(); stars.splice(j, 1); achievementProgress.starCollector++; if (achievementProgress.starCollector >= 50) checkAchievement('starCollector'); } } } // Check if all projectiles are gone if (projectiles.length === 0 && !canShoot) { canShoot = true; moveRow(); if (balls.length === 0) { stage++; stageText.setText('Stage ' + stage); ballSpeed += 0.1; // Increase MaxHP by 10 after each stage maxHP += 10; hp += 10; // Also increase current HP by 10 hpText.setText('HP: ' + hp); // Bonus for clearing stage var bonus = stage * 50; LK.setScore(LK.getScore() + bonus); scoreText.setText('Score: ' + LK.getScore()); var bonusText = new Text2('Stage Clear! +' + bonus, { size: 100, fill: 0x00FF00 }); bonusText.anchor.set(0.5, 0.5); bonusText.alpha = 0; LK.gui.center.addChild(bonusText); // Check if this is first stage clear if (stage === 2 && !achievements.firstWin) { achievements.firstWin = true; showAchievement('First Victory!', 0x00FF00); } // Perfect stage bonus if (projectileCount === 1) { perfectStageBonus = true; var perfectBonus = stage * 100; LK.setScore(LK.getScore() + perfectBonus); showAchievement('Perfect Stage! +' + perfectBonus, 0xFFD700); if (!achievements.perfectStage) { achievements.perfectStage = true; showAchievement('Perfectionist!', 0xFFD700); } } tween(bonusText, { alpha: 1, y: -200 }, { duration: 500, onFinish: function onFinish() { // Show MaxHP increase notification var hpBonusText = new Text2('Max HP +10!', { size: 80, fill: 0xff3366 }); hpBonusText.anchor.set(0.5, 0.5); hpBonusText.y = -100; hpBonusText.alpha = 0; LK.gui.center.addChild(hpBonusText); tween(hpBonusText, { alpha: 1, y: -50 }, { duration: 300, onFinish: function onFinish() { tween(hpBonusText, { alpha: 0 }, { duration: 500, delay: 1000, onFinish: function onFinish() { hpBonusText.destroy(); } }); } }); tween(bonusText, { alpha: 0 }, { duration: 500, delay: 500, onFinish: function onFinish() { bonusText.destroy(); } }); } }); } } // Check time-based achievements if (LK.ticks % 60 === 0) { var seconds = Math.floor(LK.ticks / 60); if (seconds >= 600 && !achievements.survivor) { checkAchievement('survivor'); } } // Check stage achievements if (stage >= 10) checkAchievement('stage10'); if (stage >= 25) checkAchievement('stage25'); if (stage >= 50) checkAchievement('stage50'); // Check score achievements if (LK.getScore() >= 5000) checkAchievement('score5000'); if (LK.getScore() >= 10000) checkAchievement('score10000'); if (LK.getScore() >= 50000) checkAchievement('score50000'); // Check combo achievements if (combo >= 20) checkAchievement('combo20'); if (combo >= 50) checkAchievement('combo50'); // Check projectile achievements if (projectileCount >= 10) checkAchievement('richPlayer'); if (achievementProgress.projectiles50 >= 50) checkAchievement('projectiles50'); if (achievementProgress.projectiles100 >= 100) checkAchievement('projectiles100'); // Special win condition - collect all power-up types in one game var allPowerUpsCollected = fireballActive || giantBallActive || splitBallActive || laserActive || lightningActive || multiballActive || doubleShotActive || slowMotionActive || magnetActive || shieldActive || freezeActive; if (allPowerUpsCollected && powerupsCollected >= 20 && !achievements.versatile) { checkAchievement('versatile'); // Epic win effect var epicWin = new Text2('POWER MASTER!', { size: 120, fill: 0xff00ff }); epicWin.anchor.set(0.5, 0.5); epicWin.alpha = 0; LK.gui.center.addChild(epicWin); tween(epicWin, { alpha: 1, rotation: Math.PI * 2 }, { duration: 1000, onFinish: function onFinish() { tween(epicWin, { alpha: 0, scaleX: 3, scaleY: 3 }, { duration: 1000, onFinish: function onFinish() { epicWin.destroy(); } }); } }); } // Check power-up master achievement if (powerupsCollected >= 100) checkAchievement('powerupMaster'); // Special effects for high combos if (combo > 30 && combo % 10 === 0) { var rainbowFlash = game.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366, scaleX: 0.1, scaleY: 0.1, alpha: 0.5, tint: Math.random() * 0xffffff | 0 }); tween(rainbowFlash, { scaleX: 30, scaleY: 30, alpha: 0, rotation: Math.PI * 4 }, { duration: 1000, onFinish: function onFinish() { rainbowFlash.destroy(); } }); } // Check game over if (gameActive) { for (var i = 0; i < balls.length; i++) { if (balls[i].y > 2400) { if (shieldActive) { // Shield protects from game over once shieldActive = false; shieldTimer = 0; tween(shieldBg, { alpha: 0 }, { duration: 300 }); balls[i].destroy(); balls.splice(i, 1); var shieldSaveText = new Text2('SHIELD SAVED YOU!', { size: 80, fill: 0x3498db }); shieldSaveText.anchor.set(0.5, 0.5); shieldSaveText.alpha = 0; LK.gui.center.addChild(shieldSaveText); tween(shieldSaveText, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { tween(shieldSaveText, { alpha: 0 }, { duration: 500, delay: 1000, onFinish: function onFinish() { shieldSaveText.destroy(); } }); } }); LK.effects.flashScreen(0x3498db, 500); continue; } // HP system: decrease HP by the number on the ball var lostHP = 1; if (typeof balls[i].hits === "number") { lostHP = balls[i].hits; } else if (_typeof(balls[i].numberText) === "object" && balls[i].numberText.text) { var parsed = parseInt(balls[i].numberText.text, 10); if (!isNaN(parsed)) lostHP = parsed; } hp -= lostHP; if (hp < 0) hp = 0; hpText.setText('HP: ' + hp); // Visual feedback for HP loss var hpLossText = new Text2('-' + lostHP + ' HP', { size: 60, fill: 0xff4444 }); hpLossText.anchor.set(0.5, 0.5); hpLossText.x = balls[i].x; hpLossText.y = balls[i].y; game.addChild(hpLossText); tween(hpLossText, { y: balls[i].y - 100, alpha: 0 }, { duration: 800, onFinish: function onFinish() { hpLossText.destroy(); } }); balls[i].destroy(); balls.splice(i, 1); // Game over if HP is 0 or less if (hp <= 0) { gameActive = false; // Save progress before game over if (!savedData.highScore || LK.getScore() > savedData.highScore) { savedData.highScore = LK.getScore(); // Flatten achievements into savedData directly savedData.firstWin = achievements.firstWin; savedData.combo10 = achievements.combo10; savedData.score1000 = achievements.score1000; savedData.allWeapons = achievements.allWeapons; storage['99balls_save'] = savedData; } LK.showGameOver(); break; } } } } }; // Add achievements button var achievementsButton = game.addChild(new Container()); var achievementsBg = achievementsButton.attachAsset('addBallButton', { anchorX: 0.5, anchorY: 0.5, tint: 0xFFD700, scaleX: 1.2, scaleY: 1.2 }); var achievementsButtonText = new Text2('Achievements', { size: 25, fill: 0x000000 }); achievementsButtonText.anchor.set(0.5, 0.5); achievementsButton.addChild(achievementsButtonText); achievementsButton.x = 1924; achievementsButton.y = 200; // Add glow effect to achievements button achievementsButton.update = function () { achievementsBg.alpha = 0.8 + Math.sin(LK.ticks * 0.05) * 0.2; }; // Achievement panel var achievementPanel = new Container(); var panelBg = achievementPanel.attachAsset('achievementPanelBg', { anchorX: 0.5, anchorY: 0.5, alpha: 0.95, scaleX: 1.4, scaleY: 1.4 }); achievementPanel.visible = false; LK.gui.center.addChild(achievementPanel); var achievementTitle = new Text2('ACHIEVEMENTS', { size: 84, fill: 0xFFD700 }); achievementTitle.anchor.set(0.5, 0.5); achievementTitle.y = -840; achievementPanel.addChild(achievementTitle); var closeButton = new Container(); var closeBg = closeButton.attachAsset('addBallButton', { anchorX: 0.5, anchorY: 0.5, tint: 0xff4444, scaleX: 1.4, scaleY: 1.4 }); var closeText = new Text2('X', { size: 56, fill: 0xFFFFFF }); closeText.anchor.set(0.5, 0.5); closeButton.addChild(closeText); closeButton.x = 630; closeButton.y = -840; achievementPanel.addChild(closeButton); closeButton.down = function () { achievementPanel.visible = false; gameActive = true; }; achievementsButton.down = function () { achievementPanel.visible = true; gameActive = false; updateAchievementDisplay(); }; // Add reset button to bottom right var resetButton = new Container(); var resetBg = resetButton.attachAsset('addBallButton', { anchorX: 0.5, anchorY: 0.5, tint: 0xff4444, scaleX: 1.2, scaleY: 1.2 }); var resetText = new Text2('Reset', { size: 35, fill: 0xFFFFFF }); resetText.anchor.set(0.5, 0.5); resetButton.addChild(resetText); resetButton.x = -120; resetButton.y = -120; LK.gui.bottomRight.addChild(resetButton); resetButton.down = function () { // Clear all saved data storage['99balls_save'] = {}; savedData = {}; // Reset all achievements for (var key in achievements) { achievements[key] = false; } // Reset all achievement progress for (var key in achievementProgress) { achievementProgress[key] = 0; } // Reset game state LK.setScore(0); stage = 1; ballSpeed = 0.5; projectileCount = 1; maxHP = 20; hp = maxHP; combo = 0; comboTimer = 0; scoreMultiplier = 1; ballsDestroyed = 0; perfectHits = 0; missedShots = 0; powerupsCollected = 0; maxCombo = 0; timePlayed = 0; // Reset weapon unlocks weaponUnlocks.piercing = false; weaponUnlocks.explosive = false; weaponUnlocks.rapid = false; currentWeapon = 'normal'; // Reset all power-up states slowMotionActive = false; slowMotionTimer = 0; gameSpeed = 1; magnetActive = false; magnetTimer = 0; multiballActive = false; fireballActive = false; giantBallActive = false; splitBallActive = false; laserActive = false; shieldActive = false; shieldTimer = 0; doubleShotActive = false; doubleShotTimer = 0; lightningActive = false; freezeActive = false; freezeTimer = 0; reverseGravityActive = false; reverseGravityTimer = 0; scoreBoostActive = false; scoreBoostTimer = 0; scoreBoostMultiplier = 1; autoAimActive = false; autoAimTimer = 0; freezeBombActive = false; chainReactionBombActive = false; teleportActive = false; chainReactionActive = false; consecutiveHits = 0; perfectStageBonus = false; // Update UI hpText.setText('HP: ' + hp); stageText.setText('Stage 1'); projectileCountText.setText('x1'); scoreText.setText('Score: 0'); weaponText.setText('Normal'); weaponText.tint = 0xFFFFFF; powerUpIndicator.setText(''); doubleShotIndicator.setText(''); comboText.setText(''); comboText.alpha = 0; amazingText.setText(''); amazingText.alpha = 0; ballsLeftText.setText('Balls Left: 0'); // Remove high score text if exists if (LK.gui.topRight.children.length > 1) { LK.gui.topRight.children[1].destroy(); } // Show reset notification var resetNotification = new Text2('All Progress Reset!', { size: 100, fill: 0xff4444 }); resetNotification.anchor.set(0.5, 0.5); resetNotification.alpha = 0; LK.gui.center.addChild(resetNotification); tween(resetNotification, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 500, onFinish: function onFinish() { tween(resetNotification, { alpha: 0 }, { duration: 500, delay: 1000, onFinish: function onFinish() { resetNotification.destroy(); } }); } }); // Flash effect LK.effects.flashScreen(0xff4444, 500); // Restart the game LK.showGameOver(); }; // Add weapon switch button var weaponButton = game.addChild(new Container()); var buttonBg = weaponButton.attachAsset('addBallButton', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2('Switch', { size: 30, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); weaponButton.addChild(buttonText); weaponButton.x = 1024; weaponButton.y = 2400; weaponButton.down = function () { var weapons = ['normal']; if (weaponUnlocks.piercing) weapons.push('piercing'); if (weaponUnlocks.explosive) weapons.push('explosive'); if (weaponUnlocks.rapid) weapons.push('rapid'); var currentIndex = weapons.indexOf(currentWeapon); currentWeapon = weapons[(currentIndex + 1) % weapons.length]; switch (currentWeapon) { case 'normal': weaponText.setText('Normal'); weaponText.tint = 0xFFFFFF; break; case 'piercing': weaponText.setText('Piercing'); weaponText.tint = 0xFF00FF; break; case 'explosive': weaponText.setText('Explosive'); weaponText.tint = 0xFF4444; break; case 'rapid': weaponText.setText('Rapid Fire'); weaponText.tint = 0x44FF44; break; } tween(weaponButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(weaponButton, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; initializeLevel();
===================================================================
--- original.js
+++ change.js
@@ -2563,9 +2563,8 @@
if (bombBall.takeDamage()) {
LK.getSound('destroy').play();
// Bomb explosion damages all nearby balls
createExplosion(bombBall.x, bombBall.y, 0xff0000, 50);
- LK.effects.flashScreen(0xff0000, 300);
achievementProgress.bombExpert++;
if (achievementProgress.bombExpert >= 10) checkAchievement('bombExpert');
// Collect all balls that need explosion damage
var ballsToExplode = [];
Renkli yuvarlak Balon, üstten görünüm, Gerçekçi, yazısız.. In-Game asset. High contrast. No shadows
tek renk top, üstten görünüm, Gerçekçi, yazısız.. In-Game asset. 2d. High contrast. No shadows
tek renk top, üstten görünüm, Gerçekçi, yazısız.. In-Game asset. High contrast. No shadows
tek renk top, üstten görünüm, Gerçekçi, yazısız.. In-Game asset. High contrast. No shadows
tek renk top, üstten görünüm, Gerçekçi, yazısız.. In-Game asset. High contrast. No shadows
tek renk top, üstten görünüm, Gerçekçi, yazısız.. In-Game asset. High contrast. No shadows
tek renk top, üstten görünüm, Gerçekçi, yazısız.. In-Game asset. High contrast. No shadows