Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: bomb is not defined' in or related to this line: 'bomb.destroy();' Line Number: 275
Code edit (5 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: bomb is not defined' in or related to this line: 'bomb.destroy();' Line Number: 278
Code edit (10 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: highScore is not defined' in or related to this line: 'if (score > highScore) {' Line Number: 734 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: noun is not defined' in or related to this line: 'explosionGraphics.scaleX = 0.2 + progress * noun;' Line Number: 189
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: _CRYPTO_ is not defined' in or related to this line: 'var dx = _CRYPTO_ - self.x;' Line Number: 80
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'setTimeout is not a function' in or related to this line: 'setTimeout(function () {' Line Number: 497
User prompt
Please fix the bug: 'Graphics is not a constructor' in or related to this line: 'var waveProgressBg = LK.gui.top.addChild(new Graphics());' Line Number: 413
Code edit (1 edits merged)
Please save this source code
User prompt
Grandma Click Fury
Initial prompt
Create a 2D pixel art arcade-style action game titled “Grandma Click Fury”. The main character is Grandma Turbo, a wild old lady riding a rocket-powered shopping cart through chaotic food-themed worlds while battling evil cyber pigeons. Grandma follows the mouse cursor slowly, and all actions are triggered with clicks. Clicking makes her attack, holding click charges a turbo boost, and double-clicking throws a food bomb. The game is fast-paced, full of funny sound effects and over-the-top animations. Grandma has sassy voice lines like “Click me harder, baby!”, “That’s how grandma rolls!”, and “Pigeon trash, back off!”. 🎮 Game Mechanics: Grandma rolls toward the mouse cursor. Click to swing her cane. Hold click to charge a forward turbo boost. Double-click to throw a ketchup bomb. Power-ups appear on the ground and activate with a single click. 🌍 Worlds: Syrup Street – A sticky breakfast world with waffle bridges, toast traps, and syrup waterfalls. Pizza Parade – A lunch-themed level where cheese slows you down, and flying pineapple drones shoot pepperoni lasers. Microwave Mountain – The final world, filled with floating forks, bouncing meatballs, and the evil boss Microwave Overlord. 🦅 Enemies: Cyber pigeons that swoop in quickly. Egg-throwing pigeons that stay at range. Hover drones dropping mustard bombs. Mini-bosses like The Burger Bomber and The Bacon Snake. 💥 Power-Ups: Click-Coffee: Temporarily increases movement speed. Cookie Shield: Blocks the next hit. Bingo Blast: Summons a squad of old ladies who do an area attack with knitting needles. 📦 UI: Health bar: Yarn balls. Energy meter: Fills while holding click. Score: Number of pies collected. Funny text when power-ups activate: “¡Turbo Granny Time!” or “Bingo Blitz Ready!” The art should be vibrant, cartoonish pixel style, with exaggerated squash-and-stretch animations, food explosions, and chaotic action. Add juicy sound effects and a retro-style upbeat soundtrack. The game should be fun, silly, satisfying to click, and visually explosive — designed to be addictive and hilarious.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BossPigeon = Container.expand(function () {
var self = Container.call(this);
var pigeonGraphics = self.attachAsset('cyberPigeon', {
anchorX: 0.5,
anchorY: 0.5
});
pigeonGraphics.scaleX = 2;
pigeonGraphics.scaleY = 2;
pigeonGraphics.tint = 0x8000ff;
self.health = 150 + wave * 30;
self.maxHealth = self.health;
self.speed = 1.2;
self.attackCooldown = 0;
self.specialAttackCooldown = 0;
self.isBoss = true;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
var damageText = new Text2('-' + damage, {
size: 60,
fill: 0xffff00
});
damageText.x = self.x;
damageText.y = self.y - 50;
game.addChild(damageText);
tween(damageText, {
y: damageText.y - 80,
alpha: 0
}, {
duration: 1000,
onComplete: function onComplete() {
damageText.destroy();
}
});
if (self.health <= 0) {
score += 200;
for (var i = 0; i < 4; i++) {
LK.setTimeout(function () {
var explosion = new Explosion();
explosion.x = self.x + (Math.random() - 0.5) * 120;
explosion.y = self.y + (Math.random() - 0.5) * 120;
game.addChild(explosion);
explosions.push(explosion);
LK.getSound('explosion').play();
}, i * 150);
}
for (var i = 0; i < 4; i++) {
spawnPowerUpAt(self.x + (Math.random() - 0.5) * 150, self.y + (Math.random() - 0.5) * 150);
}
return true;
}
return false;
};
self.update = function () {
var dx = grandma.x - self.x;
var dy = 1366 - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 300) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
self.x += Math.cos(LK.ticks * 0.04) * 2.5;
self.y += Math.sin(LK.ticks * 0.04) * 2.5;
}
if (self.specialAttackCooldown <= 0) {
for (var i = 0; i < 4; i++) {
var miniPigeon = new CyberPigeon();
miniPigeon.x = self.x + (Math.random() - 0.5) * 120;
miniPigeon.y = self.y + (Math.random() - 0.5) * 120;
miniPigeon.health = 20;
cyberPigeons.push(miniPigeon);
game.addChild(miniPigeon);
}
self.specialAttackCooldown = 240;
} else {
self.specialAttackCooldown--;
}
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
pigeonGraphics.rotation = Math.atan2(dy, dx);
};
return self;
});
var CyberPigeon = Container.expand(function () {
var self = Container.call(this);
var pigeonGraphics = self.attachAsset('cyberPigeon', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 35 + wave * 6;
self.maxHealth = self.health;
self.speed = 1.8 + wave * 0.4;
self.attackCooldown = 0;
self.type = Math.random() < 0.7 ? 'normal' : 'fast';
if (self.type === 'fast') {
self.speed *= 1.8;
self.health *= 0.6;
pigeonGraphics.tint = 0xff6666;
}
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 150);
var damageText = new Text2('-' + damage, {
size: 40,
fill: 0xff0000
});
damageText.x = self.x;
damageText.y = self.y - 30;
game.addChild(damageText);
tween(damageText, {
y: damageText.y - 60,
alpha: 0
}, {
duration: 800,
onComplete: function onComplete() {
damageText.destroy();
}
});
if (self.health <= 0) {
score += self.type === 'fast' ? 20 : 15;
var explosion = new Explosion();
explosion.x = self.x;
explosion.y = self.y;
game.addChild(explosion);
explosions.push(explosion);
LK.getSound('explosion').play();
if (Math.random() < 0.2) {
spawnPowerUpAt(self.x, self.y);
}
return true;
}
return false;
};
self.update = function () {
var dx = 1024 - self.x;
var dy = 1366 - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var wobble = self.type === 'fast' ? Math.sin(LK.ticks * 0.25) * 25 : 0;
self.x += dx / distance * self.speed + Math.sin(LK.ticks * 0.12) * 0.6;
self.y += dy / distance * self.speed + wobble * 0.12;
}
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
pigeonGraphics.rotation = Math.atan2(dy, dx);
};
return self;
});
var Explosion = Container.expand(function () {
var self = Container.call(this);
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifeTime = 35;
self.radius = 100;
explosionGraphics.scaleX = 0.2;
explosionGraphics.scaleY = 0.2;
self.update = function () {
self.lifeTime--;
var progress = 1 - self.lifeTime / 35;
explosionGraphics.scaleX = 0.2 + progress * 2.8;
explosionGraphics.scaleY = 0.2 + progress * 2.8;
explosionGraphics.alpha = 1 - progress;
explosionGraphics.rotation += 0.15;
return self.lifeTime <= 0;
};
return self;
});
var Grandma = Container.expand(function () {
var self = Container.call(this);
var grandmaGraphics = self.attachAsset('grandma', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 120;
self.maxHealth = 120;
self.caneDamage = 35;
self.caneRange = 140;
self.bombDamage = 60;
self.shotCooldown = 0;
self.speedBoost = 0;
self.damageBoost = 0;
self.rangeBoost = 0;
self.multishot = 0;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 300);
game.x = (Math.random() - 0.5) * 25;
game.y = (Math.random() - 0.5) * 25;
LK.setTimeout(function () {
game.x = 0;
game.y = 0;
}, 120);
if (self.health <= 0) {
LK.showGameOver();
}
};
self.update = function () {
self.x = 1024;
self.y = 1366;
if (self.health < self.maxHealth && LK.ticks % 500 === 0) {
self.health = Math.min(self.health + 2, self.maxHealth);
}
if (self.shotCooldown > 0) {
self.shotCooldown--;
}
};
return self;
});
var KetchupBomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('ketchupBomb', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.lifeTime = 80;
self.damage = grandma.bombDamage + grandma.damageBoost;
self.trail = [];
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifeTime--;
bombGraphics.rotation += 0.25;
self.trail.push({
x: self.x,
y: self.y,
alpha: 1
});
if (self.trail.length > 6) {
self.trail.shift();
}
if (self.lifeTime <= 0) {
var explosion = new Explosion();
explosion.x = self.x;
explosion.y = self.y;
game.addChild(explosion);
explosions.push(explosion);
LK.getSound('explosion').play();
return true;
}
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
});
var types = ['speed', 'health', 'damage', 'range', 'multishot'];
self.type = types[Math.floor(Math.random() * types.length)];
self.lifeTime = 800;
switch (self.type) {
case 'speed':
powerUpGraphics.tint = 0x00ff00;
break;
case 'health':
powerUpGraphics.tint = 0xff0000;
break;
case 'damage':
powerUpGraphics.tint = 0xffaa00;
break;
case 'range':
powerUpGraphics.tint = 0x0088ff;
break;
case 'multishot':
powerUpGraphics.tint = 0xff00ff;
break;
}
self.update = function () {
self.lifeTime--;
self.y += Math.sin(LK.ticks * 0.18) * 1.2;
powerUpGraphics.rotation += 0.06;
powerUpGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.12) * 0.25;
powerUpGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.12) * 0.25;
if (self.lifeTime < 160) {
powerUpGraphics.alpha = Math.sin(LK.ticks * 0.35) * 0.5 + 0.5;
}
return self.lifeTime <= 0;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Set to black to show background image
});
/****
* Game Code
****/
var background = game.addChild(LK.getAsset('background', {
x: 0,
y: 0
}));
/****
* Game Variables
****/
var grandma;
var cyberPigeons = [];
var ketchupBombs = [];
var explosions = [];
var powerUps = [];
var score = 0;
var wave = 1;
var enemiesKilled = 0;
var enemiesThisWave = 0;
var totalEnemiesThisWave = 0;
var lastClickTime = 0;
var comboCounter = 0;
var comboTimer = 0;
var difficulty = 1;
var bossWave = false;
/****
* UI Elements
****/
var scoreText = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
scoreText.x = 50;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
var healthText = new Text2('Health: 120/120', {
size: 50,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 3
});
healthText.anchor.set(1, 0);
LK.gui.topRight.addChild(healthText);
var waveText = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFF00,
stroke: 0x000000,
strokeThickness: 3
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
var comboText = new Text2('', {
size: 60,
fill: 0x00FFFF,
stroke: 0x000000,
strokeThickness: 3
});
comboText.anchor.set(0.5, 0);
comboText.x = 1024;
comboText.y = 200;
game.addChild(comboText);
var instructionText = new Text2('Click: Shoot | Double Click: Ketchup Bomb', {
size: 40,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 2
});
instructionText.anchor.set(0.5, 1);
LK.gui.bottom.addChild(instructionText);
var waveProgressBg = LK.getAsset('chargeBarBg', {
anchorX: 0.5,
anchorY: 0,
scaleX: 1.5,
x: 0,
y: 60
});
LK.gui.top.addChild(waveProgressBg);
var waveProgressBar = LK.getAsset('chargeBar', {
anchorX: 0,
anchorY: 0,
scaleX: 0,
x: -150,
y: 60
});
LK.gui.top.addChild(waveProgressBar);
/****
* Game Functions
****/
function createGrandma() {
grandma = game.addChild(new Grandma());
grandma.x = 1024;
grandma.y = 1366;
}
function caneAttack(targetX, targetY) {
if (grandma.shotCooldown > 0) return;
LK.getSound('attack').play();
LK.effects.flashObject(grandma, 0xffff00, 150);
var shots = grandma.multishot > 0 ? 3 : 1;
var angles = [0];
if (shots > 1) {
angles = [-15, 0, 15]; // Spread shot for multishot
}
for (var i = 0; i < shots; i++) {
var angle = Math.atan2(targetY - grandma.y, targetX - grandma.x) + angles[i] * Math.PI / 180;
var dx = Math.cos(angle);
var dy = Math.sin(angle);
var range = grandma.caneRange + grandma.rangeBoost;
var damage = grandma.caneDamage + grandma.damageBoost;
// Visual effect for shot
var shotEffect = LK.getAsset('cane', {
anchorX: 0.5,
anchorY: 0.5,
x: grandma.x,
y: grandma.y,
rotation: angle
});
game.addChild(shotEffect);
tween(shotEffect, {
x: grandma.x + dx * range,
y: grandma.y + dy * range,
alpha: 0
}, {
duration: 200,
onComplete: function onComplete() {
shotEffect.destroy();
}
});
// Check hits
var enemiesHit = 0;
for (var j = cyberPigeons.length - 1; j >= 0; j--) {
var pigeon = cyberPigeons[j];
var pdx = pigeon.x - grandma.x;
var pdy = pigeon.y - grandma.y;
var distance = Math.sqrt(pdx * pdx + pdy * pdy);
if (distance < range && Math.abs(Math.atan2(pdy, pdx) - angle) < 0.3) {
if (pigeon.takeDamage(damage)) {
pigeon.destroy();
cyberPigeons.splice(j, 1);
enemiesKilled++;
enemiesThisWave++;
enemiesHit++;
}
}
}
for (var j = powerUps.length - 1; j >= 0; j--) {
var powerUp = powerUps[j];
var pdx = powerUp.x - grandma.x;
var pdy = powerUp.y - grandma.y;
var distance = Math.sqrt(pdx * pdx + pdy * pdy);
if (distance < range && Math.abs(Math.atan2(pdy, pdx) - angle) < 0.3) {
collectPowerUp(powerUp);
powerUp.destroy();
powerUps.splice(j, 1);
}
}
if (enemiesHit > 0) {
comboCounter += enemiesHit;
comboTimer = 150;
if (comboCounter >= 3) {
score += comboCounter * 6;
}
}
}
grandma.shotCooldown = 15 - Math.min(grandma.speedBoost, 10);
}
function throwKetchupBomb(targetX, targetY) {
if (grandma.shotCooldown > 0) return;
var bomb = new KetchupBomb();
bomb.x = grandma.x;
bomb.y = grandma.y;
var dx = targetX - grandma.x;
var dy = targetY - grandma.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var speed = 12;
if (distance > 0) {
bomb.velocityX = dx / distance * speed;
bomb.velocityY = dy / distance * speed;
}
ketchupBombs.push(bomb);
game.addChild(bomb);
grandma.shotCooldown = 30 - Math.min(grandma.speedBoost * 2, 20);
}
function spawnEnemies() {
bossWave = wave % 5 === 0;
if (bossWave) {
var boss = new BossPigeon();
boss.x = 1024;
boss.y = -150;
cyberPigeons.push(boss);
game.addChild(boss);
totalEnemiesThisWave = 1;
} else {
var enemiesToSpawn = Math.min(4 + wave, 15);
totalEnemiesThisWave = enemiesToSpawn;
for (var i = 0; i < enemiesToSpawn; i++) {
LK.setTimeout(function () {
var pigeon = new CyberPigeon();
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
pigeon.x = Math.random() * 2048;
pigeon.y = -50;
break;
case 1:
pigeon.x = 2098;
pigeon.y = Math.random() * 2732;
break;
case 2:
pigeon.x = Math.random() * 2048;
pigeon.y = 2782;
break;
case 3:
pigeon.x = -50;
pigeon.y = Math.random() * 2732;
break;
}
cyberPigeons.push(pigeon);
game.addChild(pigeon);
}, i * 400);
}
}
enemiesThisWave = 0;
}
function spawnPowerUpAt(x, y) {
var powerUp = new PowerUp();
powerUp.x = x;
powerUp.y = y;
powerUps.push(powerUp);
game.addChild(powerUp);
}
function collectPowerUp(powerUp) {
LK.getSound('powerup').play();
LK.effects.flashObject(grandma, 0x00ff00, 400);
var bonusText = new Text2('', {
size: 50,
fill: 0x00ff00
});
bonusText.x = grandma.x;
bonusText.y = grandma.y - 60;
game.addChild(bonusText);
switch (powerUp.type) {
case 'speed':
grandma.speedBoost += 2;
bonusText.setText('FIRE RATE UP!');
break;
case 'health':
grandma.health = Math.min(grandma.health + 40, grandma.maxHealth);
bonusText.setText('HEALTH +40!');
break;
case 'damage':
grandma.damageBoost += 12;
bonusText.setText('DAMAGE UP!');
break;
case 'range':
grandma.rangeBoost += 25;
bonusText.setText('RANGE UP!');
break;
case 'multishot':
grandma.multishot = 180; // 3 seconds of multishot
bonusText.setText('MULTISHOT!');
break;
}
tween(bonusText, {
y: bonusText.y - 100,
alpha: 0
}, {
duration: 1200,
onComplete: function onComplete() {
bonusText.destroy();
}
});
}
/****
* Event Handlers
****/
game.down = function (x, y, obj) {
var currentTime = LK.ticks;
var timeSinceLastClick = currentTime - lastClickTime;
if (timeSinceLastClick < 25 && timeSinceLastClick > 5) {
throwKetchupBomb(x, y);
} else {
caneAttack(x, y);
}
lastClickTime = currentTime;
};
/****
* Game Loop
****/
createGrandma();
LK.playMusic('gameMusic');
spawnEnemies();
game.update = function () {
if (comboTimer > 0) {
comboTimer--;
if (comboCounter >= 3) {
comboText.setText('COMBO x' + comboCounter + '!');
} else {
comboText.setText('');
}
} else {
comboCounter = 0;
comboText.setText('');
}
for (var i = cyberPigeons.length - 1; i >= 0; i--) {
var pigeon = cyberPigeons[i];
pigeon.update();
if (pigeon.intersects(grandma) && pigeon.attackCooldown <= 0) {
var damage = pigeon.isBoss ? 25 : 12;
grandma.takeDamage(damage);
pigeon.attackCooldown = 50;
}
if (pigeon.x < -200 || pigeon.x > 2248 || pigeon.y < -200 || pigeon.y > 2932) {
pigeon.destroy();
cyberPigeons.splice(i, 1);
}
}
for (var i = ketchupBombs.length - 1; i >= 0; i--) {
var bomb = ketchupBombs[i];
var shouldRemove = bomb.update();
if (shouldRemove || bomb.x < -100 || bomb.x > 2148 || bomb.y < -100 || bomb.y > 2832) {
bomb.destroy();
ketchupBombs.splice(i, 1);
} else {
for (var j = cyberPigeons.length - 1; j >= 0; j--) {
var pigeon = cyberPigeons[j];
if (bomb.intersects(pigeon)) {
if (pigeon.takeDamage(bomb.damage)) {
pigeon.destroy();
cyberPigeons.splice(j, 1);
enemiesKilled++;
enemiesThisWave++;
}
bomb.destroy();
ketchupBombs.splice(i, 1);
break;
}
}
for (var j = powerUps.length - 1; j >= 0; j--) {
var powerUp = powerUps[j];
if (bomb.intersects(powerUp)) {
collectPowerUp(powerUp);
powerUp.destroy();
powerUps.splice(j, 1);
bomb.destroy();
ketchupBombs.splice(i, 1);
break;
}
}
}
}
for (var i = explosions.length - 1; i >= 0; i--) {
var explosion = explosions[i];
var shouldRemove = explosion.update();
if (shouldRemove) {
explosion.destroy();
explosions.splice(i, 1);
} else {
for (var j = cyberPigeons.length - 1; j >= 0; j--) {
var pigeon = cyberPigeons[j];
var dx = pigeon.x - explosion.x;
var dy = pigeon.y - explosion.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosion.radius) {
var damage = 50 + grandma.damageBoost;
if (pigeon.takeDamage(damage)) {
pigeon.destroy();
cyberPigeons.splice(j, 1);
enemiesKilled++;
enemiesThisWave++;
}
}
}
for (var j = powerUps.length - 1; j >= 0; j--) {
var powerUp = powerUps[j];
var dx = powerUp.x - explosion.x;
var dy = powerUp.y - explosion.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosion.radius) {
collectPowerUp(powerUp);
powerUp.destroy();
powerUps.splice(j, 1);
}
}
}
}
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
var shouldRemove = powerUp.update();
if (shouldRemove) {
powerUp.destroy();
powerUps.splice(i, 1);
}
}
if (grandma.multishot > 0) {
grandma.multishot--;
}
grandma.update();
if (cyberPigeons.length === 0) {
wave++;
difficulty += 0.1;
spawnEnemies();
if (Math.random() < 0.5) {
spawnPowerUpAt(Math.random() * 1600 + 200, Math.random() * 2200 + 200);
}
}
scoreText.setText('Score: ' + score);
healthText.setText('Health: ' + grandma.health + '/' + grandma.maxHealth);
waveText.setText('Wave: ' + wave + (bossWave ? ' (BOSS)' : ''));
var progress = totalEnemiesThisWave > 0 ? enemiesThisWave / totalEnemiesThisWave : 0;
waveProgressBar.scaleX = progress * 1.5;
LK.setScore(score);
if (wave > 20) {
LK.showYouWin();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -11,22 +11,20 @@
var pigeonGraphics = self.attachAsset('cyberPigeon', {
anchorX: 0.5,
anchorY: 0.5
});
- // Boss más grande y diferente color
pigeonGraphics.scaleX = 2;
pigeonGraphics.scaleY = 2;
- pigeonGraphics.tint = 0x8000ff; // Púrpura
- self.health = 100 + wave * 20;
+ pigeonGraphics.tint = 0x8000ff;
+ self.health = 150 + wave * 30;
self.maxHealth = self.health;
- self.speed = 1;
+ self.speed = 1.2;
self.attackCooldown = 0;
self.specialAttackCooldown = 0;
self.isBoss = true;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
- // Texto de daño más grande para boss
var damageText = new Text2('-' + damage, {
size: 60,
fill: 0xffff00
});
@@ -42,53 +40,47 @@
damageText.destroy();
}
});
if (self.health <= 0) {
- score += 100;
- // Explosión más grande
- for (var i = 0; i < 3; i++) {
+ score += 200;
+ for (var i = 0; i < 4; i++) {
LK.setTimeout(function () {
var explosion = new Explosion();
- explosion.x = self.x + (Math.random() - 0.5) * 100;
- explosion.y = self.y + (Math.random() - 0.5) * 100;
+ explosion.x = self.x + (Math.random() - 0.5) * 120;
+ explosion.y = self.y + (Math.random() - 0.5) * 120;
game.addChild(explosion);
explosions.push(explosion);
LK.getSound('explosion').play();
- }, i * 200);
+ }, i * 150);
}
- // Drop garantizado de power-ups
- for (var i = 0; i < 3; i++) {
+ for (var i = 0; i < 4; i++) {
spawnPowerUpAt(self.x + (Math.random() - 0.5) * 150, self.y + (Math.random() - 0.5) * 150);
}
return true;
}
return false;
};
self.update = function () {
- // Movimiento del boss
var dx = grandma.x - self.x;
- var dy = grandma.y - self.y;
+ var dy = 1366 - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance > 200) {
+ if (distance > 300) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
- // Círculo alrededor de grandma
- self.x += Math.cos(LK.ticks * 0.05) * 2;
- self.y += Math.sin(LK.ticks * 0.05) * 2;
+ self.x += Math.cos(LK.ticks * 0.04) * 2.5;
+ self.y += Math.sin(LK.ticks * 0.04) * 2.5;
}
- // Ataque especial cada 5 segundos
if (self.specialAttackCooldown <= 0) {
- // Spawn mini pigeons
- for (var i = 0; i < 3; i++) {
+ for (var i = 0; i < 4; i++) {
var miniPigeon = new CyberPigeon();
- miniPigeon.x = self.x + (Math.random() - 0.5) * 100;
- miniPigeon.y = self.y + (Math.random() - 0.5) * 100;
- miniPigeon.health = 15;
+ miniPigeon.x = self.x + (Math.random() - 0.5) * 120;
+ miniPigeon.y = self.y + (Math.random() - 0.5) * 120;
+ miniPigeon.health = 20;
cyberPigeons.push(miniPigeon);
game.addChild(miniPigeon);
}
- self.specialAttackCooldown = 300; // 5 segundos
+ self.specialAttackCooldown = 240;
} else {
self.specialAttackCooldown--;
}
if (self.attackCooldown > 0) {
@@ -103,31 +95,28 @@
var pigeonGraphics = self.attachAsset('cyberPigeon', {
anchorX: 0.5,
anchorY: 0.5
});
- self.health = 30 + wave * 5; // Más salud por wave
+ self.health = 35 + wave * 6;
self.maxHealth = self.health;
- self.speed = 1.5 + wave * 0.3; // Velocidad aumenta con wave
+ self.speed = 1.8 + wave * 0.4;
self.attackCooldown = 0;
- self.type = Math.random() < 0.8 ? 'normal' : 'fast'; // 20% pigeons rápidos
- // Pigeons especiales
+ self.type = Math.random() < 0.7 ? 'normal' : 'fast';
if (self.type === 'fast') {
- self.speed *= 2;
- self.health *= 0.7;
- pigeonGraphics.tint = 0xff6666; // Tinte rojo para los rápidos
+ self.speed *= 1.8;
+ self.health *= 0.6;
+ pigeonGraphics.tint = 0xff6666;
}
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 150);
- // Efecto de sangre/daño
var damageText = new Text2('-' + damage, {
size: 40,
fill: 0xff0000
});
damageText.x = self.x;
damageText.y = self.y - 30;
game.addChild(damageText);
- // Animar el texto de daño
tween(damageText, {
y: damageText.y - 60,
alpha: 0
}, {
@@ -136,40 +125,34 @@
damageText.destroy();
}
});
if (self.health <= 0) {
- // Puntos variables según tipo
- score += self.type === 'fast' ? 15 : 10;
+ score += self.type === 'fast' ? 20 : 15;
var explosion = new Explosion();
explosion.x = self.x;
explosion.y = self.y;
game.addChild(explosion);
explosions.push(explosion);
LK.getSound('explosion').play();
- // Chance de drop power-up al morir
- if (Math.random() < 0.15) {
+ if (Math.random() < 0.2) {
spawnPowerUpAt(self.x, self.y);
}
return true;
}
return false;
};
self.update = function () {
- // Movimiento más inteligente
- var dx = grandma.x - self.x;
- var dy = grandma.y - self.y;
+ var dx = 1024 - self.x;
+ var dy = 1366 - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
- // Movimiento serpenteante para algunos pigeons
- var wobble = self.type === 'fast' ? Math.sin(LK.ticks * 0.2) * 20 : 0;
- self.x += dx / distance * self.speed + Math.sin(LK.ticks * 0.1) * 0.5;
- self.y += dy / distance * self.speed + wobble * 0.1;
+ var wobble = self.type === 'fast' ? Math.sin(LK.ticks * 0.25) * 25 : 0;
+ self.x += dx / distance * self.speed + Math.sin(LK.ticks * 0.12) * 0.6;
+ self.y += dy / distance * self.speed + wobble * 0.12;
}
- // Attack cooldown
if (self.attackCooldown > 0) {
self.attackCooldown--;
}
- // Rotación hacia grandma
pigeonGraphics.rotation = Math.atan2(dy, dx);
};
return self;
});
@@ -178,19 +161,19 @@
var explosionGraphics = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
- self.lifeTime = 40;
- self.radius = 90;
- explosionGraphics.scaleX = 0.1;
- explosionGraphics.scaleY = 0.1;
+ self.lifeTime = 35;
+ self.radius = 100;
+ explosionGraphics.scaleX = 0.2;
+ explosionGraphics.scaleY = 0.2;
self.update = function () {
self.lifeTime--;
- var progress = 1 - self.lifeTime / 40;
- explosionGraphics.scaleX = 0.1 + progress * 2.5;
- explosionGraphics.scaleY = 0.1 + progress * 2.5;
+ var progress = 1 - self.lifeTime / 35;
+ explosionGraphics.scaleX = 0.2 + progress * 2.8;
+ explosionGraphics.scaleY = 0.2 + progress * 2.8;
explosionGraphics.alpha = 1 - progress;
- explosionGraphics.rotation += 0.2; // Rotación
+ explosionGraphics.rotation += 0.15;
return self.lifeTime <= 0;
};
return self;
});
@@ -199,47 +182,39 @@
var grandmaGraphics = self.attachAsset('grandma', {
anchorX: 0.5,
anchorY: 0.5
});
- self.health = 100;
- self.maxHealth = 100;
- self.targetX = 1024;
- self.targetY = 1366;
- self.speed = 8;
- self.caneDamage = 30;
- self.caneRange = 120;
- self.bombDamage = 50;
- // Mejoras permanentes
+ self.health = 120;
+ self.maxHealth = 120;
+ self.caneDamage = 35;
+ self.caneRange = 140;
+ self.bombDamage = 60;
+ self.shotCooldown = 0;
self.speedBoost = 0;
self.damageBoost = 0;
self.rangeBoost = 0;
+ self.multishot = 0;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 300);
- // Screen shake al recibir daño
- game.x = (Math.random() - 0.5) * 20;
- game.y = (Math.random() - 0.5) * 20;
+ game.x = (Math.random() - 0.5) * 25;
+ game.y = (Math.random() - 0.5) * 25;
LK.setTimeout(function () {
game.x = 0;
game.y = 0;
- }, 100);
+ }, 120);
if (self.health <= 0) {
LK.showGameOver();
}
};
self.update = function () {
- var dx = self.targetX - self.x;
- var dy = self.targetY - self.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- var currentSpeed = self.speed + self.speedBoost;
- if (distance > 5) {
- self.x += dx / distance * currentSpeed;
- self.y += dy / distance * currentSpeed;
+ self.x = 1024;
+ self.y = 1366;
+ if (self.health < self.maxHealth && LK.ticks % 500 === 0) {
+ self.health = Math.min(self.health + 2, self.maxHealth);
}
- // Regeneración lenta de salud
- if (self.health < self.maxHealth && LK.ticks % 600 === 0) {
- // cada 10 segundos
- self.health = Math.min(self.health + 1, self.maxHealth);
+ if (self.shotCooldown > 0) {
+ self.shotCooldown--;
}
};
return self;
});
@@ -250,25 +225,22 @@
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
- self.lifeTime = 100;
+ self.lifeTime = 80;
self.damage = grandma.bombDamage + grandma.damageBoost;
- // Efecto de trail
self.trail = [];
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.lifeTime--;
- // Rotación
- bombGraphics.rotation += 0.3;
- // Trail effect
+ bombGraphics.rotation += 0.25;
self.trail.push({
x: self.x,
y: self.y,
alpha: 1
});
- if (self.trail.length > 5) {
+ if (self.trail.length > 6) {
self.trail.shift();
}
if (self.lifeTime <= 0) {
var explosion = new Explosion();
@@ -290,10 +262,9 @@
anchorY: 0.5
});
var types = ['speed', 'health', 'damage', 'range', 'multishot'];
self.type = types[Math.floor(Math.random() * types.length)];
- self.lifeTime = 900; // 15 segundos
- // Color según tipo
+ self.lifeTime = 800;
switch (self.type) {
case 'speed':
powerUpGraphics.tint = 0x00ff00;
break;
@@ -311,16 +282,14 @@
break;
}
self.update = function () {
self.lifeTime--;
- // Animación flotante más dramática
- self.y += Math.sin(LK.ticks * 0.15) * 1;
- powerUpGraphics.rotation += 0.05;
- powerUpGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
- powerUpGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.1) * 0.2;
- // Parpadeo cuando está por expirar
- if (self.lifeTime < 180) {
- powerUpGraphics.alpha = Math.sin(LK.ticks * 0.3) * 0.5 + 0.5;
+ self.y += Math.sin(LK.ticks * 0.18) * 1.2;
+ powerUpGraphics.rotation += 0.06;
+ powerUpGraphics.scaleX = 1 + Math.sin(LK.ticks * 0.12) * 0.25;
+ powerUpGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.12) * 0.25;
+ if (self.lifeTime < 160) {
+ powerUpGraphics.alpha = Math.sin(LK.ticks * 0.35) * 0.5 + 0.5;
}
return self.lifeTime <= 0;
};
return self;
@@ -329,14 +298,18 @@
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0x87ceeb
+ backgroundColor: 0x000000 // Set to black to show background image
});
/****
* Game Code
****/
+var background = game.addChild(LK.getAsset('background', {
+ x: 0,
+ y: 0
+}));
/****
* Game Variables
****/
var grandma;
@@ -365,9 +338,9 @@
});
scoreText.x = 50;
scoreText.y = 50;
LK.gui.topLeft.addChild(scoreText);
-var healthText = new Text2('Health: 100/100', {
+var healthText = new Text2('Health: 120/120', {
size: 50,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 3
@@ -391,9 +364,16 @@
comboText.anchor.set(0.5, 0);
comboText.x = 1024;
comboText.y = 200;
game.addChild(comboText);
-// Barra de progreso de wave
+var instructionText = new Text2('Click: Shoot | Double Click: Ketchup Bomb', {
+ size: 40,
+ fill: 0xFFFFFF,
+ stroke: 0x000000,
+ strokeThickness: 2
+});
+instructionText.anchor.set(0.5, 1);
+LK.gui.bottom.addChild(instructionText);
var waveProgressBg = LK.getAsset('chargeBarBg', {
anchorX: 0.5,
anchorY: 0,
scaleX: 1.5,
@@ -416,96 +396,134 @@
grandma = game.addChild(new Grandma());
grandma.x = 1024;
grandma.y = 1366;
}
-function caneAttack() {
+function caneAttack(targetX, targetY) {
+ if (grandma.shotCooldown > 0) return;
LK.getSound('attack').play();
- LK.effects.flashObject(grandma, 0xffff00, 200);
- var enemiesHit = 0;
- var range = grandma.caneRange + grandma.rangeBoost;
- var damage = grandma.caneDamage + grandma.damageBoost;
- for (var i = cyberPigeons.length - 1; i >= 0; i--) {
- var pigeon = cyberPigeons[i];
- var dx = pigeon.x - grandma.x;
- var dy = pigeon.y - grandma.y;
- var distance = Math.sqrt(dx * dx + dy * dy);
- if (distance < range) {
- if (pigeon.takeDamage(damage)) {
- pigeon.destroy();
- cyberPigeons.splice(i, 1);
- enemiesKilled++;
- enemiesThisWave++;
- enemiesHit++;
+ LK.effects.flashObject(grandma, 0xffff00, 150);
+ var shots = grandma.multishot > 0 ? 3 : 1;
+ var angles = [0];
+ if (shots > 1) {
+ angles = [-15, 0, 15]; // Spread shot for multishot
+ }
+ for (var i = 0; i < shots; i++) {
+ var angle = Math.atan2(targetY - grandma.y, targetX - grandma.x) + angles[i] * Math.PI / 180;
+ var dx = Math.cos(angle);
+ var dy = Math.sin(angle);
+ var range = grandma.caneRange + grandma.rangeBoost;
+ var damage = grandma.caneDamage + grandma.damageBoost;
+ // Visual effect for shot
+ var shotEffect = LK.getAsset('cane', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: grandma.x,
+ y: grandma.y,
+ rotation: angle
+ });
+ game.addChild(shotEffect);
+ tween(shotEffect, {
+ x: grandma.x + dx * range,
+ y: grandma.y + dy * range,
+ alpha: 0
+ }, {
+ duration: 200,
+ onComplete: function onComplete() {
+ shotEffect.destroy();
}
+ });
+ // Check hits
+ var enemiesHit = 0;
+ for (var j = cyberPigeons.length - 1; j >= 0; j--) {
+ var pigeon = cyberPigeons[j];
+ var pdx = pigeon.x - grandma.x;
+ var pdy = pigeon.y - grandma.y;
+ var distance = Math.sqrt(pdx * pdx + pdy * pdy);
+ if (distance < range && Math.abs(Math.atan2(pdy, pdx) - angle) < 0.3) {
+ if (pigeon.takeDamage(damage)) {
+ pigeon.destroy();
+ cyberPigeons.splice(j, 1);
+ enemiesKilled++;
+ enemiesThisWave++;
+ enemiesHit++;
+ }
+ }
}
- }
- // Sistema de combo
- if (enemiesHit > 0) {
- comboCounter += enemiesHit;
- comboTimer = 180; // 3 segundos
- if (comboCounter >= 3) {
- score += comboCounter * 5; // Bonus por combo
+ for (var j = powerUps.length - 1; j >= 0; j--) {
+ var powerUp = powerUps[j];
+ var pdx = powerUp.x - grandma.x;
+ var pdy = powerUp.y - grandma.y;
+ var distance = Math.sqrt(pdx * pdx + pdy * pdy);
+ if (distance < range && Math.abs(Math.atan2(pdy, pdx) - angle) < 0.3) {
+ collectPowerUp(powerUp);
+ powerUp.destroy();
+ powerUps.splice(j, 1);
+ }
}
+ if (enemiesHit > 0) {
+ comboCounter += enemiesHit;
+ comboTimer = 150;
+ if (comboCounter >= 3) {
+ score += comboCounter * 6;
+ }
+ }
}
+ grandma.shotCooldown = 15 - Math.min(grandma.speedBoost, 10);
}
function throwKetchupBomb(targetX, targetY) {
+ if (grandma.shotCooldown > 0) return;
var bomb = new KetchupBomb();
bomb.x = grandma.x;
bomb.y = grandma.y;
var dx = targetX - grandma.x;
var dy = targetY - grandma.y;
var distance = Math.sqrt(dx * dx + dy * dy);
- var speed = 10;
+ var speed = 12;
if (distance > 0) {
bomb.velocityX = dx / distance * speed;
bomb.velocityY = dy / distance * speed;
}
ketchupBombs.push(bomb);
game.addChild(bomb);
+ grandma.shotCooldown = 30 - Math.min(grandma.speedBoost * 2, 20);
}
function spawnEnemies() {
- bossWave = wave % 5 === 0; // Boss cada 5 waves
+ bossWave = wave % 5 === 0;
if (bossWave) {
- // Spawn boss
var boss = new BossPigeon();
boss.x = 1024;
- boss.y = -100;
+ boss.y = -150;
cyberPigeons.push(boss);
game.addChild(boss);
totalEnemiesThisWave = 1;
} else {
- // Enemigos normales
- var enemiesToSpawn = Math.min(3 + wave, 12);
+ var enemiesToSpawn = Math.min(4 + wave, 15);
totalEnemiesThisWave = enemiesToSpawn;
for (var i = 0; i < enemiesToSpawn; i++) {
LK.setTimeout(function () {
var pigeon = new CyberPigeon();
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
- // Top
pigeon.x = Math.random() * 2048;
pigeon.y = -50;
break;
case 1:
- // Right
pigeon.x = 2098;
pigeon.y = Math.random() * 2732;
break;
case 2:
- // Bottom
pigeon.x = Math.random() * 2048;
pigeon.y = 2782;
break;
case 3:
- // Left
pigeon.x = -50;
pigeon.y = Math.random() * 2732;
break;
}
cyberPigeons.push(pigeon);
game.addChild(pigeon);
- }, i * 500); // Spawn escalonado
+ }, i * 400);
}
}
enemiesThisWave = 0;
}
@@ -517,9 +535,9 @@
game.addChild(powerUp);
}
function collectPowerUp(powerUp) {
LK.getSound('powerup').play();
- LK.effects.flashObject(grandma, 0x00ff00, 500);
+ LK.effects.flashObject(grandma, 0x00ff00, 400);
var bonusText = new Text2('', {
size: 50,
fill: 0x00ff00
});
@@ -527,53 +545,48 @@
bonusText.y = grandma.y - 60;
game.addChild(bonusText);
switch (powerUp.type) {
case 'speed':
- grandma.speedBoost += 1;
- bonusText.setText('SPEED UP!');
+ grandma.speedBoost += 2;
+ bonusText.setText('FIRE RATE UP!');
break;
case 'health':
- grandma.health = Math.min(grandma.health + 30, grandma.maxHealth);
- bonusText.setText('HEALTH +30!');
+ grandma.health = Math.min(grandma.health + 40, grandma.maxHealth);
+ bonusText.setText('HEALTH +40!');
break;
case 'damage':
- grandma.damageBoost += 10;
+ grandma.damageBoost += 12;
bonusText.setText('DAMAGE UP!');
break;
case 'range':
- grandma.rangeBoost += 20;
+ grandma.rangeBoost += 25;
bonusText.setText('RANGE UP!');
break;
case 'multishot':
- // Mejora temporal implementada en el ataque
+ grandma.multishot = 180; // 3 seconds of multishot
bonusText.setText('MULTISHOT!');
break;
}
tween(bonusText, {
y: bonusText.y - 100,
alpha: 0
}, {
- duration: 1500,
+ duration: 1200,
onComplete: function onComplete() {
bonusText.destroy();
}
});
}
/****
* Event Handlers
****/
-game.move = function (x, y, obj) {
- grandma.targetX = x;
- grandma.targetY = y;
-};
game.down = function (x, y, obj) {
var currentTime = LK.ticks;
var timeSinceLastClick = currentTime - lastClickTime;
- if (timeSinceLastClick < 20) {
- // Double click más sensible
+ if (timeSinceLastClick < 25 && timeSinceLastClick > 5) {
throwKetchupBomb(x, y);
} else {
- caneAttack();
+ caneAttack(x, y);
}
lastClickTime = currentTime;
};
/****
@@ -582,9 +595,8 @@
createGrandma();
LK.playMusic('gameMusic');
spawnEnemies();
game.update = function () {
- // Update combo timer
if (comboTimer > 0) {
comboTimer--;
if (comboCounter >= 3) {
comboText.setText('COMBO x' + comboCounter + '!');
@@ -594,33 +606,28 @@
} else {
comboCounter = 0;
comboText.setText('');
}
- // Update pigeons
for (var i = cyberPigeons.length - 1; i >= 0; i--) {
var pigeon = cyberPigeons[i];
pigeon.update();
- // Collision with grandma
if (pigeon.intersects(grandma) && pigeon.attackCooldown <= 0) {
- var damage = pigeon.isBoss ? 20 : 10;
+ var damage = pigeon.isBoss ? 25 : 12;
grandma.takeDamage(damage);
- pigeon.attackCooldown = 60;
+ pigeon.attackCooldown = 50;
}
- // Remove if off screen
if (pigeon.x < -200 || pigeon.x > 2248 || pigeon.y < -200 || pigeon.y > 2932) {
pigeon.destroy();
cyberPigeons.splice(i, 1);
}
}
- // Update ketchup bombs
for (var i = ketchupBombs.length - 1; i >= 0; i--) {
var bomb = ketchupBombs[i];
var shouldRemove = bomb.update();
if (shouldRemove || bomb.x < -100 || bomb.x > 2148 || bomb.y < -100 || bomb.y > 2832) {
bomb.destroy();
ketchupBombs.splice(i, 1);
} else {
- // Check collision with enemies
for (var j = cyberPigeons.length - 1; j >= 0; j--) {
var pigeon = cyberPigeons[j];
if (bomb.intersects(pigeon)) {
if (pigeon.takeDamage(bomb.damage)) {
@@ -633,68 +640,82 @@
ketchupBombs.splice(i, 1);
break;
}
}
+ for (var j = powerUps.length - 1; j >= 0; j--) {
+ var powerUp = powerUps[j];
+ if (bomb.intersects(powerUp)) {
+ collectPowerUp(powerUp);
+ powerUp.destroy();
+ powerUps.splice(j, 1);
+ bomb.destroy();
+ ketchupBombs.splice(i, 1);
+ break;
+ }
+ }
}
}
- // Update explosions
for (var i = explosions.length - 1; i >= 0; i--) {
var explosion = explosions[i];
var shouldRemove = explosion.update();
if (shouldRemove) {
explosion.destroy();
explosions.splice(i, 1);
} else {
- // Explosion damage
for (var j = cyberPigeons.length - 1; j >= 0; j--) {
var pigeon = cyberPigeons[j];
var dx = pigeon.x - explosion.x;
var dy = pigeon.y - explosion.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosion.radius) {
- var damage = 40 + grandma.damageBoost;
+ var damage = 50 + grandma.damageBoost;
if (pigeon.takeDamage(damage)) {
pigeon.destroy();
cyberPigeons.splice(j, 1);
enemiesKilled++;
enemiesThisWave++;
}
}
}
+ for (var j = powerUps.length - 1; j >= 0; j--) {
+ var powerUp = powerUps[j];
+ var dx = powerUp.x - explosion.x;
+ var dy = powerUp.y - explosion.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < explosion.radius) {
+ collectPowerUp(powerUp);
+ powerUp.destroy();
+ powerUps.splice(j, 1);
+ }
+ }
}
}
- // Update power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
var shouldRemove = powerUp.update();
if (shouldRemove) {
powerUp.destroy();
powerUps.splice(i, 1);
- } else if (powerUp.intersects(grandma)) {
- collectPowerUp(powerUp);
- powerUp.destroy();
- powerUps.splice(i, 1);
}
}
- // Wave management
+ if (grandma.multishot > 0) {
+ grandma.multishot--;
+ }
+ grandma.update();
if (cyberPigeons.length === 0) {
wave++;
+ difficulty += 0.1;
spawnEnemies();
- // Chance de power-up al completar wave
- if (Math.random() < 0.4) {
+ if (Math.random() < 0.5) {
spawnPowerUpAt(Math.random() * 1600 + 200, Math.random() * 2200 + 200);
}
}
- // Update UI
scoreText.setText('Score: ' + score);
healthText.setText('Health: ' + grandma.health + '/' + grandma.maxHealth);
waveText.setText('Wave: ' + wave + (bossWave ? ' (BOSS)' : ''));
- // Wave progress bar
var progress = totalEnemiesThisWave > 0 ? enemiesThisWave / totalEnemiesThisWave : 0;
waveProgressBar.scaleX = progress * 1.5;
- // Update LK score
LK.setScore(score);
- // Victory condition
if (wave > 20) {
LK.showYouWin();
}
};
\ No newline at end of file
Pixel art sprite of a fierce old lady wearing sunglasses and a scarf, riding a rocket-powered shopping cart. She’s holding a glowing cane like a weapon. Side view, colorful retro 2D style. PNG. In-Game asset. 2d. High contrast. No shadows
Pixel art of an evil pigeon with robotic parts, red glowing eyes, and tiny armor. Flying pose, side view, 2D pixel sprite for an arcade game. In-Game asset. 2d. High contrast. No shadows
Pixel art of a red ketchup bottle turned into a bomb, with a fuse and tomato sauce leaking out. Small item, cartoonish and fun, pixel style. In-Game asset. 2d. High contrast. No shadows
pixel art dog. In-Game asset. 2d. High contrast. No shadows
explosion. In-Game asset. 2d. High contrast. No shadows
background pixel art cielo azul. In-Game asset. 2d. High contrast. No shadows
Pixel art of a smaller robotic pigeon with jet wings and a streamlined shape. Fast enemy type in a 2D arcade game. Side view, green metal feathers. In-Game asset. 2d. High contrast. No shadows
Pixel art of a purple power-up icon with a spiked fist symbol or explosion inside. Represents bonus attack damage in a retro game. In-Game asset. 2d. High contrast. No shadows
Pixel art of a dark purple robotic pigeon spinning in midair, wings blurred in motion. Enemy type in a 2D arcade game, side view. In-Game asset. 2d. High contrast. No shadows
Pixel art of a green power-up icon with a heart or medical cross symbol inside. Represents healing in a 2D pixel arcade game. Glowing green, square icon. In-Game asset. 2d. High contrast. No shadows
Pixel art of a red power-up icon with a bold lightning bolt symbol inside. Represents a temporary speed boost in a retro-style arcade game. Glowing red, square icon. In-Game asset. 2d. High contrast. No shadows
Pixel art of a violet power-up icon with three small arrows or projectiles spreading outward. Represents multishot power in a retro-style game. Glowing, pixelated square icon. In-Game asset. 2d. High contrast. No shadows