User prompt
HP yazısını stage yazısının 2 satır altına taşı.
User prompt
Oyunda HP sistemi olsun. Düşen topların sayısı kadar HP azalsın. Mesela 3 sayılı top geçerse, 3 can azalsın. Gibi.
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle.
User prompt
Topları gönderdikten sonra kendimiz de tıklama yaparak top gönderebilelim. Normal topun hasarının %50 daha düşük olsun.
User prompt
Add combo multiplier visual effects with dynamic scaling ✅ Add magnetized ball class that attracts projectiles ✅ Add critical hit visual effects and damage multiplier ✅ Add magnet ball spawning to level generation ✅ Add special weapon combo system ✅ Add magnet ball collision and attraction effects ✅ Add special victory conditions and epic win effects ✅ Add power-up combo system to track active effects ✅ Add special ball destruction tracking for achievements 🔄 Add lucky shot tracking from long distance ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle.
User prompt
Create the image file behind the achievements button and the achievements text in it.
User prompt
Hız artırma bölgeleri ile ilgili herşeyi sil. Olmasın oyunda.
User prompt
Başarımların olduğu buton ekle ve birbirinden farklı, oyun özelliklerinden oluşan 50 başarım ekle. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle.
User prompt
Add combo multiplier display and visual feedback ✅ Add rainbow ball special enemy type ✅ Add bomb ball that explodes on impact ✅ Add spawning for rainbow and bomb balls ✅ Add special handling for rainbow and bomb balls in collision ✅ Add double shot power-up ✅ Add double shot spawning and variables ✅ Add double shot variables and update ✅ Add double shot update loop ✅ Add double shot movement ✅ Add double shot collision and effect ✅ Add double shot timer update ✅ Modify fireProjectiles to support double shot ✅ Add critical hit visual indicator ✅ Add perfect shot bonus ✅ Add speed boost zones visual indicator 🔄 Add projectile speed boost in zones
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle.
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage['99balls_save'] = savedData;' Line Number: 1191
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle. (alevli top, büyük top, çarpınca parçalanan top, çarpınca çoğalan top vs.)
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle.
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var savedData = storage.get('99balls_save') || {};' Line Number: 353 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage['99balls_save'] = savedData;' Line Number: 919
User prompt
Sorunu çöz
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'var savedData = storage.get('99balls_save') || {};' Line Number: 353 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Oluşturduğun özelliğin kodlamasına devam et. Yarım kaldı.
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'weaponText.style.fill = 0xFFFFFF;' Line Number: 758
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak özellik ekle.
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'call')' in or related to this line: 'AddBallButton.prototype.up.call(addBallButton, x, y, obj);' Line Number: 229
User prompt
3 top arka arkaya hizalı şekilde gitsin ve her seviye sonrası artsın. Bu sayıyı artırmak için buton ekle.
/****
* 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 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 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;
});
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 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.5; // 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;
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;
}
};
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
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;
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: 60,
fill: 0xFFD700
});
comboText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(comboText);
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 perfectStageBonus = false;
var rainbowBalls = [];
var bombBalls = [];
var doubleShotPowerups = [];
var doubleShotActive = false;
var doubleShotTimer = 0;
var achievements = {
firstWin: false,
combo10: false,
score1000: false,
allWeapons: false,
bossKiller: false,
perfectStage: false,
shieldMaster: false
};
// 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
if (savedData.firstWin !== undefined) {
achievements.firstWin = savedData.firstWin;
}
if (savedData.combo10 !== undefined) {
achievements.combo10 = savedData.combo10;
}
if (savedData.score1000 !== undefined) {
achievements.score1000 = savedData.score1000;
}
if (savedData.allWeapons !== undefined) {
achievements.allWeapons = savedData.allWeapons;
}
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;
// Add speed boost zones
var leftZone = game.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 1366,
scaleX: 5,
scaleY: 20,
alpha: 0.1,
tint: 0x00ff00
});
var rightZone = game.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
x: 1848,
y: 1366,
scaleX: 5,
scaleY: 20,
alpha: 0.1,
tint: 0x00ff00
});
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.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.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);
}
}
// 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;
}
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);
}
// Create shockwave effect for chain reactions
if (chainReactionActive && count > 15) {
var shockwave = game.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 0.1,
scaleY: 0.1,
alpha: 0.8,
tint: color
});
tween(shockwave, {
scaleX: 5,
scaleY: 5,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
shockwave.destroy();
}
});
}
// Screen shake for explosive weapons
if (currentWeapon === 'explosive' && count > 15) {
var shakeAmount = 20;
var originalX = game.x;
var originalY = game.y;
tween(game, {
x: originalX + (Math.random() - 0.5) * shakeAmount,
y: originalY + (Math.random() - 0.5) * shakeAmount
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: originalX + (Math.random() - 0.5) * shakeAmount * 0.5,
y: originalY + (Math.random() - 0.5) * shakeAmount * 0.5
}, {
duration: 50,
onFinish: function onFinish() {
tween(game, {
x: originalX,
y: originalY
}, {
duration: 50
});
}
});
}
});
}
}
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) {
var comboFlash = new Text2('AMAZING!', {
size: 80,
fill: 0xFFD700
});
comboFlash.anchor.set(0.5, 0.5);
comboFlash.y = -100;
comboFlash.alpha = 0;
LK.gui.center.addChild(comboFlash);
tween(comboFlash, {
alpha: 1,
y: -150
}, {
duration: 300,
onFinish: function onFinish() {
tween(comboFlash, {
alpha: 0
}, {
duration: 500,
delay: 200,
onFinish: function onFinish() {
comboFlash.destroy();
}
});
}
});
}
}
}
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);
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
});
}
}
// 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 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
for (var i = 0; i < balls.length; i++) {
balls[i].y += ballSpeed * gameSpeed;
if (balls[i].update) {
balls[i].update();
}
}
for (var i = 0; i < powerups.length; i++) {
powerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < stars.length; i++) {
stars[i].y += ballSpeed * gameSpeed;
if (stars[i].update) {
stars[i].update();
}
}
for (var i = 0; i < slowMotionPowerups.length; i++) {
slowMotionPowerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < multiballPowerups.length; i++) {
multiballPowerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < fireballPowerups.length; i++) {
fireballPowerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < giantBallPowerups.length; i++) {
giantBallPowerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < splitBallPowerups.length; i++) {
splitBallPowerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < laserPowerups.length; i++) {
laserPowerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < shieldPowerups.length; i++) {
shieldPowerups[i].y += ballSpeed * gameSpeed;
}
for (var i = 0; i < doubleShotPowerups.length; i++) {
doubleShotPowerups[i].y += ballSpeed * gameSpeed;
}
// 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;
// Speed boost zones
if (projectile.x < 300 || projectile.x > 1748) {
projectile.velocityY *= 1.5;
// Add speed trail
if (Math.random() < 0.5) {
var speedTrail = projectile.attachAsset('projectile', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.6,
tint: 0x00ff00
});
tween(speedTrail, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 200,
onFinish: function onFinish() {
speedTrail.destroy();
}
});
}
}
// 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;
}
}
}
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);
// 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 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);
LK.effects.flashScreen(0xff0000, 300);
// Damage all balls in explosion radius
for (var k = balls.length - 1; k >= 0; k--) {
var nearbyBall = balls[k];
if (checkCollision(bombBall, nearbyBall, 200, nearbyBall.radius)) {
for (var d = 0; d < 3; d++) {
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);
break;
}
}
}
}
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;
// Handle explosive projectiles
if (projectile.type === 'explosive') {
createExplosion(ball.x, ball.y, 0xff4444, 20);
// Damage nearby balls
for (var k = balls.length - 1; k >= 0; k--) {
var otherBall = balls[k];
if (checkCollision(ball, otherBall, 150, otherBall.radius)) {
if (otherBall.takeDamage()) {
LK.getSound('destroy').play();
LK.setScore(LK.getScore() + Math.floor(stage * scoreMultiplier));
createExplosion(otherBall.x, otherBall.y, 0xffff00, 10);
otherBall.destroy();
balls.splice(k, 1);
}
}
}
}
if (ball.takeDamage()) {
LK.getSound('destroy').play();
consecutiveHits++;
if (consecutiveHits >= 3) {
chainReactionActive = true;
}
var points = Math.floor(stage * scoreMultiplier * (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
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);
}
// Handle projectile behavior after hit
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');
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 star collisions
for (var j = stars.length - 1; j >= 0; j--) {
var star = stars[j];
if (checkCollision(projectile, star, projectile.radius, star.radius)) {
LK.getSound('collect').play();
// Random bonus effect
var randomEffect = Math.random();
if (randomEffect < 0.3) {
magnetActive = true;
magnetTimer = 180; // 3 seconds
powerUpIndicator.setText('MAGNET ACTIVE');
} else if (randomEffect < 0.6) {
projectileCount += 2;
projectileCountText.setText('x' + projectileCount);
} else {
// 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;
}
}
// 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);
}
}
}
// 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;
// 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() {
tween(bonusText, {
alpha: 0
}, {
duration: 500,
delay: 500,
onFinish: function onFinish() {
bonusText.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;
}
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 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
@@ -65,8 +65,47 @@
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,
@@ -127,8 +166,27 @@
});
self.rotation = 0;
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,
@@ -251,8 +309,47 @@
}
};
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,
@@ -529,8 +626,13 @@
var freezeActive = false;
var freezeTimer = 0;
var criticalHitChance = 0.1;
var perfectStageBonus = false;
+var rainbowBalls = [];
+var bombBalls = [];
+var doubleShotPowerups = [];
+var doubleShotActive = false;
+var doubleShotTimer = 0;
var achievements = {
firstWin: false,
combo10: false,
score1000: false,
@@ -588,8 +690,16 @@
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,
@@ -610,8 +720,29 @@
aimLine = game.addChild(new AimLine());
aimLine.x = cannon.x;
aimLine.y = cannon.y;
aimLine.visible = false;
+ // Add speed boost zones
+ var leftZone = game.attachAsset('ball', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 200,
+ y: 1366,
+ scaleX: 5,
+ scaleY: 20,
+ alpha: 0.1,
+ tint: 0x00ff00
+ });
+ var rightZone = game.attachAsset('ball', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1848,
+ y: 1366,
+ scaleX: 5,
+ scaleY: 20,
+ alpha: 0.1,
+ tint: 0x00ff00
+ });
spawnBallRow();
}
function spawnBallRow() {
var spacing = 2048 / (ballsPerRow + 1);
@@ -676,9 +807,29 @@
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.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);
}
}
// Spawn boss every 5 stages
bossSpawnCounter++;
@@ -724,8 +875,12 @@
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;
@@ -888,8 +1043,11 @@
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
}, {
@@ -902,8 +1060,36 @@
duration: 200
});
}
});
+ // Combo milestone effects
+ if (combo === 10 || combo === 20 || combo === 30) {
+ var comboFlash = new Text2('AMAZING!', {
+ size: 80,
+ fill: 0xFFD700
+ });
+ comboFlash.anchor.set(0.5, 0.5);
+ comboFlash.y = -100;
+ comboFlash.alpha = 0;
+ LK.gui.center.addChild(comboFlash);
+ tween(comboFlash, {
+ alpha: 1,
+ y: -150
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ tween(comboFlash, {
+ alpha: 0
+ }, {
+ duration: 500,
+ delay: 200,
+ onFinish: function onFinish() {
+ comboFlash.destroy();
+ }
+ });
+ }
+ });
+ }
}
}
function moveRow() {
chainReactionActive = false;
@@ -1035,8 +1221,19 @@
}
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 boss balls
for (var i = 0; i < bossBalls.length; i++) {
if (bossBalls[i].update) {
bossBalls[i].update();
@@ -1079,8 +1276,25 @@
}
for (var i = 0; i < shieldPowerups.length; i++) {
shieldPowerups[i].y += ballSpeed * gameSpeed;
}
+ for (var i = 0; i < doubleShotPowerups.length; i++) {
+ doubleShotPowerups[i].y += ballSpeed * gameSpeed;
+ }
+ // 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
@@ -1094,8 +1308,33 @@
continue;
}
projectile.velocityX = oldVelX;
projectile.velocityY = oldVelY;
+ // Speed boost zones
+ if (projectile.x < 300 || projectile.x > 1748) {
+ projectile.velocityY *= 1.5;
+ // Add speed trail
+ if (Math.random() < 0.5) {
+ var speedTrail = projectile.attachAsset('projectile', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.5,
+ scaleY: 0.5,
+ alpha: 0.6,
+ tint: 0x00ff00
+ });
+ tween(speedTrail, {
+ alpha: 0,
+ scaleX: 0,
+ scaleY: 0
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ speedTrail.destroy();
+ }
+ });
+ }
+ }
// Apply magnet effect
if (magnetActive) {
var closestBall = null;
var closestDist = 200;
@@ -1150,8 +1389,29 @@
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();
@@ -1175,8 +1435,76 @@
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);
+ // 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 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);
+ LK.effects.flashScreen(0xff0000, 300);
+ // Damage all balls in explosion radius
+ for (var k = balls.length - 1; k >= 0; k--) {
+ var nearbyBall = balls[k];
+ if (checkCollision(bombBall, nearbyBall, 200, nearbyBall.radius)) {
+ for (var d = 0; d < 3; d++) {
+ 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);
+ break;
+ }
+ }
+ }
+ }
+ 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)) {
@@ -1273,9 +1601,40 @@
break;
}
}
}
- if (hitBall) continue;else {
+ 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
@@ -1390,8 +1749,21 @@
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 star collisions
for (var j = stars.length - 1; j >= 0; j--) {
var star = stars[j];
if (checkCollision(projectile, star, projectile.radius, star.radius)) {
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