User prompt
**In `spawnEnemy()`**: Instead of `new Enemy()` and then modifying it, use `new Drone()` for wave 2 and `new Robot()` for wave 3 2. **In `updateEnemies()`**: The tower detection logic will work the same way because all enemy classes will have the same interface 3. **Each enemy class** should be self-contained with its own graphics and behavior
User prompt
How do we fix this
User prompt
Fix this please
User prompt
Create the drones in the same way that probedroid is created in wave1
User prompt
Add electriceffect and attach it to drone and robot Make it invisible initially but switch to visible when drone or robot is fired at by towers ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Create method for the electric tower to target the drones and robots
User prompt
Increase the tolerance to 200 pixels
User prompt
Make all enemies act like probedroid so all towers respond the same
User prompt
Change bugzapper firing logic to attack drones and robots
User prompt
Add drones and robots to enemy class
User prompt
Can we please correct this
User prompt
Make player start with $200 cash
User prompt
How do we fix this ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Set _assetId property for electric tower to enable zapping functionality ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
When enemy travels on same line that tower is placed electric tower will use zap3 asset in a prolonged attack electrocuting the enemy Electric tower will zap enemies in range of 800 pixels straight ahead ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
It's still not working
User prompt
Fix this please ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Fix this please ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make zap3 animation visible
User prompt
Ensure bugzapper zap function is working correctly
User prompt
Fix this please
User prompt
Why isn't electric tower zap working
User prompt
Move roboarm right 20
User prompt
Move both wheels right 25
User prompt
Move roboarm down 50
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Button class
var Button = Container.expand(function () {
var self = Container.call(this);
// Button properties
self.text = '';
self.backgroundColor = 0x333333;
self.textColor = 0xffffff;
self.width = 200;
self.height = 80;
self.fontSize = 40;
self.isPressed = false;
// Create button background
self.background = self.attachAsset('notification', {
anchorX: 0.5,
anchorY: 0.5,
tint: self.backgroundColor
});
// Create button text
self.buttonText = new Text2(self.text, {
size: self.fontSize,
fill: self.textColor
});
self.buttonText.anchor.set(0.5, 0.5);
self.buttonText.x = 0;
self.buttonText.y = 0;
self.addChild(self.buttonText);
// Method to set button properties
self.setup = function (options) {
if (options.text !== undefined) {
self.text = options.text;
self.buttonText.setText(self.text);
}
if (options.backgroundColor !== undefined) {
self.backgroundColor = options.backgroundColor;
self.background.tint = self.backgroundColor;
}
if (options.textColor !== undefined) {
self.textColor = options.textColor;
// Recreate text with new color since Text2 doesn't have a modifiable style property
self.removeChild(self.buttonText);
self.buttonText = new Text2(self.text, {
size: self.fontSize,
fill: self.textColor
});
self.buttonText.anchor.set(0.5, 0.5);
self.buttonText.x = 0;
self.buttonText.y = 0;
self.addChild(self.buttonText);
}
if (options.width !== undefined) {
self.width = options.width;
self.background.width = self.width;
}
if (options.height !== undefined) {
self.height = options.height;
self.background.height = self.height;
}
if (options.fontSize !== undefined) {
self.fontSize = options.fontSize;
// Recreate text with new font size since Text2 doesn't have a modifiable style property
self.removeChild(self.buttonText);
self.buttonText = new Text2(self.text, {
size: self.fontSize,
fill: self.textColor
});
self.buttonText.anchor.set(0.5, 0.5);
self.buttonText.x = 0;
self.buttonText.y = 0;
self.addChild(self.buttonText);
}
};
// Touch down event
self.down = function (x, y, obj) {
self.isPressed = true;
// Visual feedback - darken button
self.background.alpha = 0.7;
// Call custom down handler if defined
if (self.onDown) {
self.onDown(x, y, obj);
}
};
// Touch up event
self.up = function (x, y, obj) {
if (self.isPressed) {
self.isPressed = false;
// Reset visual state
self.background.alpha = 1.0;
// Call custom up handler if defined
if (self.onUp) {
self.onUp(x, y, obj);
}
// Call click handler if defined
if (self.onClick) {
self.onClick(x, y, obj);
}
}
};
return self;
});
// Defense class
var Defense = Container.expand(function () {
var self = Container.call(this);
var defenseGraphics = self.attachAsset('defense', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Defense logic goes here
};
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Attach probedroid as the main enemy graphic
var enemyGraphics = self.attachAsset('Probedroid', {
anchorX: 0.5,
anchorY: 0.5
});
// Add flashing lights to probe droid
var light1 = self.attachAsset('rangeCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: -85,
scaleX: 0.03,
scaleY: 0.03,
tint: 0xff0000,
alpha: 0.5
});
var light2 = self.attachAsset('rangeCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 50,
y: -80,
scaleX: 0.03,
scaleY: 0.03,
tint: 0x00ff00,
alpha: 0.5
});
var light3 = self.attachAsset('rangeCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -100,
scaleX: 0.02,
scaleY: 0.02,
tint: 0x0000ff,
alpha: 0.5
});
// Add electric effect to probe droid
var electricEffect = self.attachAsset('Electriceffect', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -50,
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.7,
visible: false
});
// Start flashing animations for the lights
function startLightFlashing() {
// Red light flashing
tween(light1, {
alpha: 0.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(light1, {
alpha: 0.6
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: startLightFlashing
});
}
});
// Green light flashing (offset timing)
LK.setTimeout(function () {
tween(light2, {
alpha: 0.1
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(light2, {
alpha: 0.6
}, {
duration: 600,
easing: tween.easeInOut
});
}
});
}, 300);
// Blue light flashing (different timing)
LK.setTimeout(function () {
tween(light3, {
alpha: 0.15
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(light3, {
alpha: 0.6
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
}, 600);
}
// Start the flashing animation
startLightFlashing();
// Start electric effect animation
function startElectricEffect() {
// Animate electric effect fading in and out
tween(electricEffect, {
alpha: 0.2
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(electricEffect, {
alpha: 0.9
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: startElectricEffect
});
}
});
}
// Store electric effect reference
self.electricEffect = electricEffect;
// Function to make electric effect visible
self.showElectricEffect = function () {
if (!self.electricEffectVisible) {
self.electricEffectVisible = true;
self.electricEffect.visible = true;
}
};
// Start the electric effect animation
startElectricEffect();
// Initialize enemy properties
self.speed = -2; // Default movement speed
self.health = 100; // Default health
self.maxHealth = 100; // Default max health
self.pathLine = 1; // Default path line
self.lastX = undefined; // Track last X position
self.electricEffectVisible = false; // Track if electric effect is visible
// Add number text
self.numberText = new Text2('1', {
size: 60,
fill: 0x000000
});
self.numberText.anchor.set(0.5, 0.5);
self.numberText.x = 0;
self.numberText.y = 0;
self.addChild(self.numberText);
// Add health bar
var healthBarOutline = self.attachAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -150
});
var healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -150,
tint: 0x00ff00
});
self.updateHealthBar = function () {
var healthPercentage = self.health / self.maxHealth;
healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
healthBar.tint = 0xffff00; // Yellow
} else {
healthBar.tint = 0xff0000; // Red
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
self.updateHealthBar();
};
self.update = function () {
// Initialize lastX if not set
if (self.lastX === undefined) self.lastX = self.x;
// Update health bar
self.updateHealthBar();
};
return self;
});
// Assets will be automatically created and loaded by the LK engine
// Tower class
var Tower = Container.expand(function () {
var self = Container.call(this);
var towerGraphics = self.attachAsset('tower', {
anchorX: 0.5,
anchorY: 0.5
});
// Initialize tower health
self.health = 100;
self.maxHealth = 100;
self.isBeingDamaged = false;
self.lastDamageTime = 0;
// Method to take damage
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
}
};
self.update = function () {
// Tower logic goes here
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
// Game update loop
game.update = function () {
if (!gameStarted) return;
// Spawn enemies
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnInterval) {
spawnEnemy();
enemySpawnTimer = 0;
}
// Update fan tower cooldowns
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
// Check if this is a fan tower
if (tower.blades) {
tower.cooldownTimer++;
// Check if cooldown should start
if (tower.isRunning && tower.cooldownTimer >= tower.cooldownDuration) {
// Start cooldown - stop fan
tower.cooldownActive = true;
tower.isRunning = false;
tower.cooldownTimer = 0;
// Stop blade spinning
if (tower.blades) {
tween.stop(tower.blades);
}
// Flash fan red to indicate cooldown
LK.effects.flashObject(tower, 0xff0000, 1000);
}
// Check if cooldown should end (10 seconds cooldown)
if (tower.cooldownActive && tower.cooldownTimer >= 10 * 60) {
// End cooldown - restart fan
tower.cooldownActive = false;
tower.isRunning = true;
tower.cooldownTimer = 0;
// Resume blade spinning
var _spinBlades2 = function spinBlades() {
if (tower.blades && tower.isRunning) {
tween(tower.blades, {
rotation: tower.blades.rotation + Math.PI * 2
}, {
duration: 500,
easing: tween.linear,
onFinish: _spinBlades2
});
}
};
_spinBlades2();
// Flash fan green to indicate restart
LK.effects.flashObject(tower, 0x00ff00, 500);
}
}
}
// Handle plasma tower attacks
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
if (tower.plasma) {
handlePlasmaAttack(tower);
}
}
// Update enemies
updateEnemies();
// Check wave 1 completion
if (currentWave === 1 && wave1EnemiesCompleted >= 10) {
// Award player $50 for completing wave 1
playerCash += 50;
cashText.setText('Cash: $' + playerCash);
// Initialize wave 2
currentWave = 2;
enemiesSpawned = 0;
enemySpawnTimer = 0;
maxEnemiesInWave = 30; // Wave 2 has 30 drones
enemySpawnInterval = 180; // 3 seconds between spawns at 60fps
// Fade in wave2 asset in middle of screen
var wave2Asset = game.addChild(LK.getAsset('Wave2', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Fade in wave2 asset
tween(wave2Asset, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Keep wave2 visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(wave2Asset, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
wave2Asset.destroy();
}
});
}, 2000);
}
});
}
// Check wave 2 completion and initialize wave 3
if (currentWave === 2 && wave2EnemiesCompleted >= 30) {
// Award player $100 for completing wave 2
playerCash += 100;
cashText.setText('Cash: $' + playerCash);
// Initialize wave 3
currentWave = 3;
enemiesSpawned = 0;
enemySpawnTimer = 0;
maxEnemiesInWave = 20; // Wave 3 has 20 robots
enemySpawnInterval = 180; // 3 seconds between spawns at 60fps
// Fade in wave3 asset in middle of screen
var wave3Asset = game.addChild(LK.getAsset('Wave3', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Fade in wave3 asset
tween(wave3Asset, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Keep wave3 visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(wave3Asset, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
wave3Asset.destroy();
}
});
}, 2000);
}
});
}
// Check wave 3 completion (win condition)
if (currentWave === 3 && enemiesSpawned >= maxEnemiesInWave && enemies.length === 0) {
LK.showYouWin();
}
// Final check - destroy all towers with 0 or less health at end of update cycle
for (var i = towers.length - 1; i >= 0; i--) {
var tower = towers[i];
if (tower.health <= 0) {
// Remove health bar components
if (tower.healthBarOutline) {
tower.healthBarOutline.destroy();
}
if (tower.healthBar) {
tower.healthBar.destroy();
}
// Remove blades if this is a fan tower
if (tower.blades) {
tower.blades.destroy();
}
// Remove plasma if this is a plasma tower
if (tower.plasma) {
tower.plasma.destroy();
}
// Remove plasma rays if this is a plasma tower
if (tower.plasmaRays) {
for (var rayIndex = 0; rayIndex < tower.plasmaRays.length; rayIndex++) {
tower.plasmaRays[rayIndex].destroy();
}
tower.plasmaRays = [];
}
// Remove active zap if this is an electric tower
if (tower.activeZap) {
tower.activeZap.destroy();
tower.activeZap = null;
}
// Remove tower from the game
tower.destroy();
towers.splice(i, 1);
}
}
};
// Mouse move handler for tower preview
game.move = function (x, y, obj) {
if (isPlacingTower && towerPreview) {
towerPreview.x = x;
// Snap preview to nearest guideline Y position
var snappedY = getNearestGuidelineY(y);
towerPreview.y = snappedY;
// Update blades position if fan preview has blades
if (towerPreview.blades) {
towerPreview.blades.x = towerPreview.x + 50;
towerPreview.blades.y = towerPreview.y - 40 - 100 + 25 + 25;
}
// Update plasma position if plasma preview has plasma
if (towerPreview.plasma) {
towerPreview.plasma.x = towerPreview.x;
towerPreview.plasma.y = towerPreview.y - 20;
}
}
};
var enemies = [];
var towers = [];
var gameStarted = false;
var enemySpawnTimer = 0;
var enemySpawnInterval = 600; // Spawn every 10 seconds at 60fps
var enemiesSpawned = 0;
var maxEnemiesInWave = 10; // Wave 1 has exactly 10 probedroids
var currentWave = 1; // Track current wave number
var wave1EnemiesCompleted = 0; // Track completed enemies in wave 1
var wave2EnemiesCompleted = 0; // Track completed enemies in wave 2
var playerCash = 200; // Player starts with $200
var playerLives = 3; // Player starts with 3 lives
var playerScore = 0; // Player starts with 0 score
var livesText = null; // Global reference to lives text display
var isPlacingTower = false;
var selectedTowerType = null;
var towerPreview = null;
var guidelines = [];
var cashText = null;
var confirmButton = null;
var enemyNumber = 1; // Track enemy numbers for display
// Define path positions for different lines
var pathPositions = {
line6: 2732 / 7 * 6 - 310 + 50,
// Line 6 position
line2: 2732 / 7 * 2 + 320 + 50,
// Line 2 position
line3: 2732 / 7 * 3 + 150 + 50,
// Line 3 position
line4: 2732 / 7 * 4 + 10 + 50,
// Line 4 position
line5: 2732 / 7 * 5 - 150 + 50,
// Line 5 position
line1: 2732 / 7 * 1 + 480 + 50 // Line 1 position
};
// Helper function to get nearest guideline Y position
function getNearestGuidelineY(y) {
var nearestY = y;
var minDistance = Infinity;
for (var i = 0; i < guidelines.length; i++) {
var guideline = guidelines[i];
var distance = Math.abs(guideline.y - y);
if (distance < minDistance) {
minDistance = distance;
nearestY = guideline.y;
}
}
return nearestY;
}
// Helper function to check if tower position is too close to existing towers
function canPlaceTowerAt(x, y) {
var minDistance = 200; // Minimum distance between towers
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
var distance = Math.sqrt(Math.pow(x - tower.x, 2) + Math.pow(y - tower.y, 2));
if (distance < minDistance) {
return false;
}
}
return true;
}
// Tower defense functions
function startTowerDefenseWave1() {
gameStarted = true;
enemySpawnTimer = 0;
enemiesSpawned = 0;
// Add score display to top of screen
var scoreText = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.x = 2048 / 2;
scoreText.y = 50;
game.addChild(scoreText);
// Store scoreText reference globally for updating
window.scoreText = scoreText;
// Add cash display to top of screen
cashText = new Text2('Cash: $' + playerCash, {
size: 80,
fill: 0xFFD700
});
cashText.anchor.set(0.5, 0);
cashText.x = 2048 / 2 + 300 + 200;
cashText.y = 50;
game.addChild(cashText);
// Add lives display to top of screen
livesText = new Text2('Lives: ' + playerLives, {
size: 80,
fill: 0xFF4444
});
livesText.anchor.set(0.5, 0);
livesText.x = 2048 / 2 - 300 - 200;
livesText.y = 50;
game.addChild(livesText);
// Add skip wave button to top of screen
var skipWaveButton = new Text2('SKIP WAVE', {
size: 60,
fill: 0xFFFFFF
});
skipWaveButton.anchor.set(0.5, 0);
skipWaveButton.x = 2048 / 2;
skipWaveButton.y = 150;
game.addChild(skipWaveButton);
// Add touch event to skip wave button
skipWaveButton.down = function (x, y, obj) {
// Skip to next wave immediately
if (currentWave === 1) {
// Skip to wave 2
// Award player $50 for completing wave 1
playerCash += 50;
cashText.setText('Cash: $' + playerCash);
// Initialize wave 2
currentWave = 2;
enemiesSpawned = 0;
enemySpawnTimer = 0;
maxEnemiesInWave = 30; // Wave 2 has 30 drones
enemySpawnInterval = 180; // 3 seconds between spawns at 60fps
wave1EnemiesCompleted = 10; // Mark wave 1 as completed
// Clear existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
// Fade in wave2 asset in middle of screen
var wave2Asset = game.addChild(LK.getAsset('Wave2', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Fade in wave2 asset
tween(wave2Asset, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Keep wave2 visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(wave2Asset, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
wave2Asset.destroy();
}
});
}, 2000);
}
});
} else if (currentWave === 2) {
// Skip to wave 3
// Award player $100 for completing wave 2
playerCash += 100;
cashText.setText('Cash: $' + playerCash);
// Initialize wave 3
currentWave = 3;
enemiesSpawned = 0;
enemySpawnTimer = 0;
maxEnemiesInWave = 20; // Wave 3 has 20 robots
enemySpawnInterval = 180; // 3 seconds between spawns at 60fps
wave2EnemiesCompleted = 30; // Mark wave 2 as completed
// Clear existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
// Fade in wave3 asset in middle of screen
var wave3Asset = game.addChild(LK.getAsset('Wave3', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Fade in wave3 asset
tween(wave3Asset, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Keep wave3 visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(wave3Asset, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
wave3Asset.destroy();
}
});
}, 2000);
}
});
}
};
// Add Gasbutton to bottom of game scene
var gasButton = game.addChild(LK.getAsset('Gasbutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 426.67 + 50 + 50,
y: 2732 - 350
}));
// Add Waterbutton to bottom left of game scene
var waterButton = game.addChild(LK.getAsset('Waterbutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 50,
y: 2732 - 350
}));
// Water button click handler
waterButton.down = function (x, y, obj) {
// Check if player has enough cash
if (playerCash >= 10) {
// Start tower placement mode
isPlacingTower = true;
selectedTowerType = 'water';
// Create tower preview
if (towerPreview) {
towerPreview.destroy();
}
towerPreview = game.addChild(LK.getAsset('Tower1', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.5
}));
// Create green tick button for confirming placement
if (confirmButton) {
confirmButton.destroy();
}
confirmButton = game.addChild(new Button());
confirmButton.setup({
text: '✓',
backgroundColor: 0x00FF00,
textColor: 0xFFFFFF,
width: 120,
height: 120,
fontSize: 80
});
confirmButton.x = 2048 - 150;
confirmButton.y = 2732 / 2;
confirmButton.onClick = function () {
// Place tower at current preview position
if (towerPreview) {
// Align tower Y position to nearest guideline
var alignedY = getNearestGuidelineY(towerPreview.y);
// Check if tower can be placed at this position
if (!canPlaceTowerAt(towerPreview.x, alignedY)) {
// Flash red to indicate invalid placement
LK.effects.flashObject(towerPreview, 0xff0000, 500);
return;
}
var newTower = game.addChild(LK.getAsset('Tower1', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x,
y: alignedY,
alpha: 1
}));
newTower._assetId = 'Tower1'; // Mark this as a water tower
newTower.health = 100;
newTower.maxHealth = 100;
newTower.isBeingDamaged = false;
newTower.lastDamageTime = 0;
newTower.lastFireTime = 0; // Initialize fire rate tracking
// Add health bar to tower
var healthBarOutline = game.addChild(LK.getAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 120
}));
var healthBar = game.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 120,
tint: 0x00ff00
}));
newTower.healthBarOutline = healthBarOutline;
newTower.healthBar = healthBar;
newTower.takeDamage = function (damage) {
newTower.health -= damage;
if (newTower.health <= 0) {
newTower.health = 0;
}
// Update health bar
var healthPercentage = newTower.health / newTower.maxHealth;
newTower.healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
newTower.healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
newTower.healthBar.tint = 0xffff00; // Yellow
} else {
newTower.healthBar.tint = 0xff0000; // Red
}
};
towers.push(newTower);
// Check for enemies in range immediately after placing
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - newTower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 700 pixels
if (enemy.x > newTower.x && enemy.x - newTower.x < 700) {
// Fire immediately
newTower.lastFireTime = LK.ticks;
// Create water squirt visual
var waterSquirt = game.addChild(LK.getAsset('Water', {
anchorX: 0,
anchorY: 0.5,
x: newTower.x,
y: newTower.y,
scaleX: 0.3,
scaleY: 0.1,
alpha: 0.7,
tint: 0x4169E1
}));
// Animate water squirt
tween(waterSquirt, {
scaleX: 0.35,
alpha: 0.3
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
waterSquirt.destroy();
}
});
// Deal damage to enemy
enemy.takeDamage(8);
// Make electric effect visible when hit by water
enemy.showElectricEffect();
// Robot fires back when hit by water tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(newTower);
}
break; // Found an enemy in range
}
}
}
// Sort all towers by Y position (higher Y values should be in front)
towers.sort(function (a, b) {
return a.y - b.y;
});
// Re-add towers to game in sorted order
for (var i = 0; i < towers.length; i++) {
game.removeChild(towers[i]);
game.addChild(towers[i]);
}
// Deduct cost and update display
playerCash -= 10;
cashText.setText('Cash: $' + playerCash);
// Clean up placement mode
isPlacingTower = false;
selectedTowerType = null;
towerPreview.destroy();
towerPreview = null;
confirmButton.destroy();
confirmButton = null;
}
};
}
};
// Gas button click handler
gasButton.down = function (x, y, obj) {
// Check if player has enough cash
if (playerCash >= 20) {
// Start tower placement mode
isPlacingTower = true;
selectedTowerType = 'gas';
// Create tower preview
if (towerPreview) {
towerPreview.destroy();
}
towerPreview = game.addChild(LK.getAsset('Dog', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.5
}));
// Create green tick button for confirming placement
if (confirmButton) {
confirmButton.destroy();
}
confirmButton = game.addChild(new Button());
confirmButton.setup({
text: '✓',
backgroundColor: 0x00FF00,
textColor: 0xFFFFFF,
width: 120,
height: 120,
fontSize: 80
});
confirmButton.x = 2048 - 150;
confirmButton.y = 2732 / 2;
confirmButton.onClick = function () {
// Place tower at current preview position
if (towerPreview) {
// Align tower Y position to nearest guideline
var alignedY = getNearestGuidelineY(towerPreview.y);
// Check if tower can be placed at this position
if (!canPlaceTowerAt(towerPreview.x, alignedY)) {
// Flash red to indicate invalid placement
LK.effects.flashObject(towerPreview, 0xff0000, 500);
return;
}
var newTower = game.addChild(LK.getAsset('Dog', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x,
y: alignedY,
alpha: 1
}));
newTower._assetId = 'Dog'; // Mark this as a gas tower
newTower.health = 100;
newTower.maxHealth = 100;
newTower.isBeingDamaged = false;
newTower.lastDamageTime = 0;
newTower.lastFireTime = 0; // Initialize fire rate tracking
// Add health bar to tower
var healthBarOutline = game.addChild(LK.getAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 120
}));
var healthBar = game.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 120,
tint: 0x00ff00
}));
newTower.healthBarOutline = healthBarOutline;
newTower.healthBar = healthBar;
newTower.takeDamage = function (damage) {
newTower.health -= damage;
if (newTower.health <= 0) {
newTower.health = 0;
}
// Update health bar
var healthPercentage = newTower.health / newTower.maxHealth;
newTower.healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
newTower.healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
newTower.healthBar.tint = 0xffff00; // Yellow
} else {
newTower.healthBar.tint = 0xff0000; // Red
}
};
towers.push(newTower);
// Check for enemies in range immediately after placing
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - newTower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 600 pixels
if (enemy.x > newTower.x && enemy.x - newTower.x < 600) {
// Fire immediately
newTower.lastFireTime = LK.ticks;
// Switch dog asset to dog1 for fart animation
var fartingDog = game.addChild(LK.getAsset('Dog1', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y,
alpha: 1
}));
// Copy tower properties to the new farting dog
fartingDog._assetId = 'Dog';
fartingDog.health = newTower.health;
fartingDog.maxHealth = newTower.maxHealth;
fartingDog.isBeingDamaged = newTower.isBeingDamaged;
fartingDog.lastDamageTime = newTower.lastDamageTime;
fartingDog.lastFireTime = newTower.lastFireTime;
fartingDog.healthBarOutline = newTower.healthBarOutline;
fartingDog.healthBar = newTower.healthBar;
fartingDog.takeDamage = newTower.takeDamage;
// Replace tower in towers array
for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
if (towers[towerIndex] === newTower) {
towers[towerIndex] = fartingDog;
break;
}
}
// Remove original tower
newTower.destroy();
// Create gas cloud visual
var gasCloud = game.addChild(LK.getAsset('GasCloud', {
anchorX: 0.5,
anchorY: 0.5,
x: fartingDog.x + 150,
y: fartingDog.y,
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.6,
tint: 0x90EE90
}));
// Animate gas cloud expanding and fading
tween(gasCloud, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0.2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
gasCloud.destroy();
}
});
// Switch back to normal dog after 500ms
LK.setTimeout(function () {
fartingDog.destroy();
var normalDog = game.addChild(LK.getAsset('Dog', {
anchorX: 0.5,
anchorY: 0.5,
x: fartingDog.x,
y: fartingDog.y,
alpha: 1
}));
// Copy properties back to normal dog
normalDog._assetId = 'Dog';
normalDog.health = fartingDog.health;
normalDog.maxHealth = fartingDog.maxHealth;
normalDog.isBeingDamaged = fartingDog.isBeingDamaged;
normalDog.lastDamageTime = fartingDog.lastDamageTime;
normalDog.lastFireTime = fartingDog.lastFireTime;
normalDog.healthBarOutline = fartingDog.healthBarOutline;
normalDog.healthBar = fartingDog.healthBar;
normalDog.takeDamage = fartingDog.takeDamage;
// Replace in towers array
for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
if (towers[towerIndex] === fartingDog) {
towers[towerIndex] = normalDog;
break;
}
}
}, 500);
// Deal damage to enemy if affected by gas
var isAffectedByGas = true;
if (enemy.attachedAssets && enemy.attachedAssets.length > 0) {
var enemyAssetId = enemy.attachedAssets[0].assetId;
if (enemyAssetId === 'Robot' || enemyAssetId === 'Drone' || enemyAssetId === 'SpaceDrone' || enemyAssetId === 'Probedroid') {
isAffectedByGas = false;
}
}
if (isAffectedByGas) {
enemy.takeDamage(2);
// Robot fires back when hit by gas tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(fartingDog);
}
}
break; // Found an enemy in range
}
}
}
// Sort all towers by Y position (higher Y values should be in front)
towers.sort(function (a, b) {
return a.y - b.y;
});
// Re-add towers to game in sorted order
for (var i = 0; i < towers.length; i++) {
game.removeChild(towers[i]);
game.addChild(towers[i]);
}
// Deduct cost and update display
playerCash -= 20;
cashText.setText('Cash: $' + playerCash);
// Clean up placement mode
isPlacingTower = false;
selectedTowerType = null;
towerPreview.destroy();
towerPreview = null;
confirmButton.destroy();
confirmButton = null;
}
};
}
};
// Add Airbutton to the right side of gasbutton
var airButton = game.addChild(LK.getAsset('Airbutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 426.67 + 50 + 420 + 50 + 50,
y: 2732 - 350
}));
// Air button click handler
airButton.down = function (x, y, obj) {
// Check if player has enough cash
if (playerCash >= 30) {
// Start tower placement mode
isPlacingTower = true;
selectedTowerType = 'air';
// Create tower preview
if (towerPreview) {
towerPreview.destroy();
}
towerPreview = game.addChild(LK.getAsset('Fan', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.5
}));
// Add blades to fan preview
var previewBlades = game.addChild(LK.getAsset('Blades', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x + 50,
y: towerPreview.y - 40 - 100 + 25 + 25,
alpha: 0.5
}));
// Store blades reference in tower preview
towerPreview.blades = previewBlades;
// Create green tick button for confirming placement
if (confirmButton) {
confirmButton.destroy();
}
confirmButton = game.addChild(new Button());
confirmButton.setup({
text: '✓',
backgroundColor: 0x00FF00,
textColor: 0xFFFFFF,
width: 120,
height: 120,
fontSize: 80
});
confirmButton.x = 2048 - 150;
confirmButton.y = 2732 / 2;
confirmButton.onClick = function () {
// Place tower at current preview position
if (towerPreview) {
// Align tower Y position to nearest guideline
var alignedY = getNearestGuidelineY(towerPreview.y);
// Check if tower can be placed at this position
if (!canPlaceTowerAt(towerPreview.x, alignedY)) {
// Flash red to indicate invalid placement
LK.effects.flashObject(towerPreview, 0xff0000, 500);
return;
}
// Create spinning animation for blades
var _spinBlades = function spinBlades() {
tween(blades, {
rotation: blades.rotation + Math.PI * 2
}, {
duration: 500,
easing: tween.linear,
onFinish: _spinBlades
});
};
var newTower = game.addChild(LK.getAsset('Fan', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x,
y: alignedY,
alpha: 1
}));
// Add blades asset to fan tower
var blades = game.addChild(LK.getAsset('Blades', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x + 50,
y: newTower.y - 40 - 100 + 25 + 25
}));
_spinBlades();
// Store blades reference in tower
newTower.blades = blades;
newTower.health = 100;
newTower.maxHealth = 100;
newTower.isBeingDamaged = false;
newTower.lastDamageTime = 0;
// Add cooldown properties for fan
newTower.cooldownTimer = 0;
newTower.cooldownDuration = 20 * 60; // 20 seconds at 60fps
newTower.cooldownActive = false;
newTower.isRunning = true;
// Add health bar to tower
var healthBarOutline = game.addChild(LK.getAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 170
}));
var healthBar = game.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 170,
tint: 0x00ff00
}));
newTower.healthBarOutline = healthBarOutline;
newTower.healthBar = healthBar;
newTower.takeDamage = function (damage) {
newTower.health -= damage;
if (newTower.health <= 0) {
newTower.health = 0;
}
// Update health bar
var healthPercentage = newTower.health / newTower.maxHealth;
newTower.healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
newTower.healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
newTower.healthBar.tint = 0xffff00; // Yellow
} else {
newTower.healthBar.tint = 0xff0000; // Red
}
};
towers.push(newTower);
// Sort all towers by Y position (higher Y values should be in front)
towers.sort(function (a, b) {
return a.y - b.y;
});
// Re-add towers to game in sorted order
for (var i = 0; i < towers.length; i++) {
game.removeChild(towers[i]);
game.addChild(towers[i]);
// Re-add blades if this tower has them to ensure they render in front
if (towers[i].blades) {
game.removeChild(towers[i].blades);
game.addChild(towers[i].blades);
}
}
// Deduct cost and update display
playerCash -= 30;
cashText.setText('Cash: $' + playerCash);
// Clean up placement mode
isPlacingTower = false;
selectedTowerType = null;
// Destroy preview blades if they exist
if (towerPreview.blades) {
towerPreview.blades.destroy();
}
// Destroy preview plasma if it exists
if (towerPreview.plasma) {
towerPreview.plasma.destroy();
}
towerPreview.destroy();
towerPreview = null;
confirmButton.destroy();
confirmButton = null;
}
};
}
};
// Add Firebutton to the right side of airbutton
var fireButton = game.addChild(LK.getAsset('Firebutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 426.67 + 50 + 420 + 50 + 426 + 50 + 50,
y: 2732 - 350
}));
// Fire button click handler
fireButton.down = function (x, y, obj) {
// Check if player has enough cash
if (playerCash >= 40) {
// Start tower placement mode
isPlacingTower = true;
selectedTowerType = 'fire';
// Create tower preview
if (towerPreview) {
towerPreview.destroy();
}
towerPreview = game.addChild(LK.getAsset('Fireworks', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.5
}));
// Create green tick button for confirming placement
if (confirmButton) {
confirmButton.destroy();
}
confirmButton = game.addChild(new Button());
confirmButton.setup({
text: '✓',
backgroundColor: 0x00FF00,
textColor: 0xFFFFFF,
width: 120,
height: 120,
fontSize: 80
});
confirmButton.x = 2048 - 150;
confirmButton.y = 2732 / 2;
confirmButton.onClick = function () {
// Place tower at current preview position
if (towerPreview) {
// Align tower Y position to nearest guideline
var alignedY = getNearestGuidelineY(towerPreview.y);
// Check if tower can be placed at this position
if (!canPlaceTowerAt(towerPreview.x, alignedY)) {
// Flash red to indicate invalid placement
LK.effects.flashObject(towerPreview, 0xff0000, 500);
return;
}
var newTower = game.addChild(LK.getAsset('Fireworks', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x,
y: alignedY,
alpha: 1
}));
newTower._assetId = 'Fireworks'; // Mark this as a fire tower
newTower.health = 100;
newTower.maxHealth = 100;
newTower.isBeingDamaged = false;
newTower.lastDamageTime = 0;
// Add health bar to tower
var healthBarOutline = game.addChild(LK.getAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 210
}));
var healthBar = game.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 210,
tint: 0x00ff00
}));
newTower.healthBarOutline = healthBarOutline;
newTower.healthBar = healthBar;
newTower.takeDamage = function (damage) {
newTower.health -= damage;
if (newTower.health <= 0) {
newTower.health = 0;
}
// Update health bar
var healthPercentage = newTower.health / newTower.maxHealth;
newTower.healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
newTower.healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
newTower.healthBar.tint = 0xffff00; // Yellow
} else {
newTower.healthBar.tint = 0xff0000; // Red
}
};
towers.push(newTower);
// Check for enemies in range immediately after placing
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - newTower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 1000 pixels
if (enemy.x > newTower.x && enemy.x - newTower.x < 1000) {
// Fire immediately
newTower.lastFireTime = LK.ticks;
// Create fireball projectile
var fireball = game.addChild(LK.getAsset('Fireball', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x + 50,
y: newTower.y,
scaleX: 0.5,
scaleY: 0.5,
rotation: 35 * Math.PI / 180
}));
fireball.targetX = enemy.x;
fireball.targetY = enemy.y;
fireball.speed = 8;
fireball.damage = 15;
// Calculate direction to enemy
var deltaX = enemy.x - fireball.x;
var deltaY = enemy.y - fireball.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
fireball.velocityX = deltaX / distance * fireball.speed;
fireball.velocityY = deltaY / distance * fireball.speed;
// Animate fireball movement
var fireballInterval = LK.setInterval(function () {
fireball.x += fireball.velocityX;
fireball.y += fireball.velocityY;
// Check if fireball hit any enemy
for (var enemyIndex = 0; enemyIndex < enemies.length; enemyIndex++) {
var targetEnemy = enemies[enemyIndex];
var fireballDistance = Math.sqrt(Math.pow(fireball.x - targetEnemy.x, 2) + Math.pow(fireball.y - targetEnemy.y, 2));
if (fireballDistance < 80) {
// Hit enemy - deal damage
targetEnemy.takeDamage(fireball.damage);
// Robot fires back when hit by fire tower
if (targetEnemy.fireBackAtTower) {
targetEnemy.fireBackAtTower(newTower);
}
// Remove fireball
LK.clearInterval(fireballInterval);
fireball.destroy();
return;
}
}
// Check if fireball went off screen
if (fireball.x > 2048 + 100 || fireball.x < -100 || fireball.y > 2732 + 100 || fireball.y < -100) {
LK.clearInterval(fireballInterval);
fireball.destroy();
}
}, 16);
break; // Found an enemy in range
}
}
}
// Sort all towers by Y position (higher Y values should be in front)
towers.sort(function (a, b) {
return a.y - b.y;
});
// Re-add towers to game in sorted order
for (var i = 0; i < towers.length; i++) {
game.removeChild(towers[i]);
game.addChild(towers[i]);
}
// Deduct cost and update display
playerCash -= 40;
cashText.setText('Cash: $' + playerCash);
// Clean up placement mode
isPlacingTower = false;
selectedTowerType = null;
towerPreview.destroy();
towerPreview = null;
confirmButton.destroy();
confirmButton = null;
}
};
}
};
// Add mystery button under air button
var mysteryButton1 = game.addChild(LK.getAsset('Mysterybutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 426.67 + 50 + 420 + 50 + 50,
y: 2732 - 350 + 200 + 20
}));
// Add Electricbutton to bottom of screen under water button
var electricButton = game.addChild(LK.getAsset('Electricbutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 50,
y: 2732 - 350 + 200 + 20
}));
// Electric button click handler
electricButton.down = function (x, y, obj) {
// Check if player has enough cash
if (playerCash >= 50) {
// Start tower placement mode
isPlacingTower = true;
selectedTowerType = 'electric';
// Create tower preview
if (towerPreview) {
towerPreview.destroy();
}
towerPreview = game.addChild(LK.getAsset('Bugzapper', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.5
}));
// Create green tick button for confirming placement
if (confirmButton) {
confirmButton.destroy();
}
confirmButton = game.addChild(new Button());
confirmButton.setup({
text: '✓',
backgroundColor: 0x00FF00,
textColor: 0xFFFFFF,
width: 120,
height: 120,
fontSize: 80
});
confirmButton.x = 2048 - 150;
confirmButton.y = 2732 / 2;
confirmButton.onClick = function () {
// Place tower at current preview position
if (towerPreview) {
// Align tower Y position to nearest guideline
var alignedY = getNearestGuidelineY(towerPreview.y);
// Check if tower can be placed at this position
if (!canPlaceTowerAt(towerPreview.x, alignedY)) {
// Flash red to indicate invalid placement
LK.effects.flashObject(towerPreview, 0xff0000, 500);
return;
}
var newTower = game.addChild(LK.getAsset('Bugzapper', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x,
y: alignedY,
alpha: 1
}));
newTower._assetId = 'Bugzapper'; // Mark this as an electric tower
newTower.health = 100;
newTower.maxHealth = 100;
newTower.isBeingDamaged = false;
newTower.lastDamageTime = 0;
// Add health bar to tower
var healthBarOutline = game.addChild(LK.getAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 210
}));
var healthBar = game.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 210,
tint: 0x00ff00
}));
newTower.healthBarOutline = healthBarOutline;
newTower.healthBar = healthBar;
newTower.takeDamage = function (damage) {
newTower.health -= damage;
if (newTower.health <= 0) {
newTower.health = 0;
}
// Update health bar
var healthPercentage = newTower.health / newTower.maxHealth;
newTower.healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
newTower.healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
newTower.healthBar.tint = 0xffff00; // Yellow
} else {
newTower.healthBar.tint = 0xff0000; // Red
}
};
towers.push(newTower);
// Check for enemies in range immediately after placing
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - newTower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 800 pixels
if (enemy.x > newTower.x && enemy.x - newTower.x < 800) {
// Fire immediately
newTower.activeZap = null;
newTower.zapStartTime = LK.ticks;
// Create prolonged zap3 visual
newTower.activeZap = game.addChild(LK.getAsset('Zap3', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x + 400,
y: newTower.y,
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.9,
tint: 0x00FFFF
}));
// Deal damage to enemy
enemy.takeDamage(20);
// Make electric effect visible when hit by electricity
enemy.showElectricEffect();
// Robot fires back when hit by electric tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(newTower);
}
break; // Found an enemy in range
}
}
}
// Sort all towers by Y position (higher Y values should be in front)
towers.sort(function (a, b) {
return a.y - b.y;
});
// Re-add towers to game in sorted order
for (var i = 0; i < towers.length; i++) {
game.removeChild(towers[i]);
game.addChild(towers[i]);
}
// Deduct cost and update display
playerCash -= 50;
cashText.setText('Cash: $' + playerCash);
// Clean up placement mode
isPlacingTower = false;
selectedTowerType = null;
towerPreview.destroy();
towerPreview = null;
confirmButton.destroy();
confirmButton = null;
}
};
}
};
// Add Plasmabutton to bottom of screen under gas button
var plasmaButton = game.addChild(LK.getAsset('Plasmabutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 426.67 + 50 + 50,
y: 2732 - 350 + 200 + 20
}));
// Plasma button click handler
plasmaButton.down = function (x, y, obj) {
// Check if player has enough cash
if (playerCash >= 60) {
// Start tower placement mode
isPlacingTower = true;
selectedTowerType = 'plasma';
// Create tower preview
if (towerPreview) {
towerPreview.destroy();
}
towerPreview = game.addChild(LK.getAsset('Plasmaball', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.5
}));
// Add plasma asset to plasma tower preview and render it in front
var previewPlasma = game.addChild(LK.getAsset('Plasma', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x,
y: towerPreview.y - 20,
alpha: 0.5
}));
// Store plasma reference in tower preview
towerPreview.plasma = previewPlasma;
// Start plasma animation for preview
animatePlasma(previewPlasma);
// Create green tick button for confirming placement
if (confirmButton) {
confirmButton.destroy();
}
confirmButton = game.addChild(new Button());
confirmButton.setup({
text: '✓',
backgroundColor: 0x00FF00,
textColor: 0xFFFFFF,
width: 120,
height: 120,
fontSize: 80
});
confirmButton.x = 2048 - 150;
confirmButton.y = 2732 / 2;
confirmButton.onClick = function () {
// Place tower at current preview position
if (towerPreview) {
// Align tower Y position to nearest guideline
var alignedY = getNearestGuidelineY(towerPreview.y);
// Check if tower can be placed at this position
if (!canPlaceTowerAt(towerPreview.x, alignedY)) {
// Flash red to indicate invalid placement
LK.effects.flashObject(towerPreview, 0xff0000, 500);
return;
}
var newTower = game.addChild(LK.getAsset('Plasmaball', {
anchorX: 0.5,
anchorY: 0.5,
x: towerPreview.x,
y: alignedY,
alpha: 1
}));
// Add plasma asset to plasmaball tower and render it in front
var plasma = game.addChild(LK.getAsset('Plasma', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 20,
alpha: 1
}));
// Store plasma reference in tower
newTower.plasma = plasma;
// Start plasma animation
animatePlasma(plasma);
newTower.health = 100;
newTower.maxHealth = 100;
newTower.isBeingDamaged = false;
newTower.lastDamageTime = 0;
// Add health bar to tower
var healthBarOutline = game.addChild(LK.getAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 150
}));
var healthBar = game.addChild(LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: newTower.x,
y: newTower.y - 150,
tint: 0x00ff00
}));
newTower.healthBarOutline = healthBarOutline;
newTower.healthBar = healthBar;
newTower.takeDamage = function (damage) {
newTower.health -= damage;
if (newTower.health <= 0) {
newTower.health = 0;
}
// Update health bar
var healthPercentage = newTower.health / newTower.maxHealth;
newTower.healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
newTower.healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
newTower.healthBar.tint = 0xffff00; // Yellow
} else {
newTower.healthBar.tint = 0xff0000; // Red
}
};
towers.push(newTower);
// Check for enemies in range immediately after placing
var enemiesInRange = [];
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - newTower.x, 2) + Math.pow(enemy.y - newTower.y, 2));
if (distance <= 800) {
enemiesInRange.push(enemy);
}
}
// If enemies are in range, start attack immediately
if (enemiesInRange.length > 0) {
newTower.plasmaAttackActive = true;
newTower.plasmaAttackStartTime = LK.ticks;
newTower.plasmaRays = [];
// Create 10 plasma ray assets
for (var j = 0; j < 10; j++) {
var angle = j * 36 * Math.PI / 180;
var rayX = newTower.x + Math.cos(angle) * 150;
var rayY = newTower.y + Math.sin(angle) * 150;
var plasmaRay = game.addChild(LK.getAsset('Plasmaray1', {
anchorX: 0.5,
anchorY: 0.5,
x: rayX,
y: rayY,
rotation: angle + Math.PI / 2,
alpha: 0.8,
scaleX: 0.8,
scaleY: 0.8
}));
newTower.plasmaRays.push(plasmaRay);
}
// Deal damage to enemies in range
for (var i = 0; i < enemiesInRange.length; i++) {
var enemy = enemiesInRange[i];
enemy.takeDamage(30);
// Make electric effect visible when hit by plasma
enemy.showElectricEffect();
// Robot fires back when hit by plasma tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(newTower);
}
}
}
// Sort all towers by Y position (higher Y values should be in front)
towers.sort(function (a, b) {
return a.y - b.y;
});
// Re-add towers to game in sorted order
for (var i = 0; i < towers.length; i++) {
game.removeChild(towers[i]);
game.addChild(towers[i]);
// Re-add plasma if this tower has it to ensure it renders in front
if (towers[i].plasma) {
game.removeChild(towers[i].plasma);
game.addChild(towers[i].plasma);
// Restart plasma animation after re-adding
animatePlasma(towers[i].plasma);
}
}
// Deduct cost and update display
playerCash -= 60;
cashText.setText('Cash: $' + playerCash);
// Clean up placement mode
isPlacingTower = false;
selectedTowerType = null;
// Destroy preview plasma if it exists
if (towerPreview.plasma) {
towerPreview.plasma.destroy();
}
towerPreview.destroy();
towerPreview = null;
confirmButton.destroy();
confirmButton = null;
}
};
}
};
// Add mystery button under fire button
var mysteryButton2 = game.addChild(LK.getAsset('Mysterybutton', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 4 - 250 + 426.67 + 50 + 420 + 50 + 426 + 50 + 50,
y: 2732 - 350 + 200 + 20
}));
}
function spawnEnemy() {
if (enemiesSpawned >= maxEnemiesInWave) return;
var enemy;
if (currentWave === 1) {
enemy = game.addChild(new Enemy());
} else if (currentWave === 2) {
// Create drone enemy for wave 2 using Enemy class
enemy = game.addChild(new Enemy());
// Remove the probedroid graphics and replace with drone graphics
enemy.removeChild(enemy.children[0]); // Remove probedroid graphics
// Attach drone asset
var droneGraphics = enemy.attachAsset('Drone', {
anchorX: 0.5,
anchorY: 0.5
});
// Remove the probedroid lights and replace with drone lights
while (enemy.children.length > 2) {
// Keep only drone graphics and number text
enemy.removeChild(enemy.children[1]);
}
// Add flashing lights to drone
var droneLight1 = enemy.attachAsset('rangeCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: -30,
y: 5,
scaleX: 0.025,
scaleY: 0.025,
tint: 0xff0000,
alpha: 0.6
});
var droneLight2 = enemy.attachAsset('squareLight', {
anchorX: 0.5,
anchorY: 0.5,
x: 40,
y: 0,
scaleX: 0.7,
scaleY: 0.7,
tint: 0x00ff00,
alpha: 0.6
});
var droneLight3 = enemy.attachAsset('rangeCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -90,
scaleX: 0.02,
scaleY: 0.02,
tint: 0x0000ff,
alpha: 0.6
});
// Start flashing animations for drone lights
var _startDroneLightFlashing = function startDroneLightFlashing() {
// Red light flashing
tween(droneLight1, {
alpha: 0.1
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(droneLight1, {
alpha: 0.7
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: _startDroneLightFlashing
});
}
});
// Green light flashing (offset timing)
LK.setTimeout(function () {
tween(droneLight2, {
alpha: 0.15
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(droneLight2, {
alpha: 0.7
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
}, 200);
// Blue light flashing (different timing)
LK.setTimeout(function () {
tween(droneLight3, {
alpha: 0.2
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(droneLight3, {
alpha: 0.7
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
}, 400);
}; // Start the flashing animation
_startDroneLightFlashing();
// Update drone properties
enemy.speed = -5; // Much faster than probedroids
enemy.health = 80; // Less health than probedroids
enemy.maxHealth = 80;
enemy.pathLine = 1;
enemy.lastX = undefined;
// Add laser fire back attack for drone when hit
enemy.fireBackAtTower = function (attackingTower) {
// Create laser fire back projectile
var laser = game.addChild(LK.getAsset('Laserfire', {
anchorX: 0.5,
anchorY: 0.5,
x: enemy.x - 200,
y: enemy.y,
alpha: 0.9
}));
// Calculate direction to attacking tower
var deltaX = attackingTower.x - laser.x;
var deltaY = attackingTower.y - laser.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
var speed = 6;
laser.velocityX = deltaX / distance * speed;
laser.velocityY = deltaY / distance * speed;
laser.damage = 15;
// Animate laser movement
var laserInterval = LK.setInterval(function () {
laser.x += laser.velocityX;
laser.y += laser.velocityY;
// Check if laser hit the attacking tower
var laserDistance = Math.sqrt(Math.pow(laser.x - attackingTower.x, 2) + Math.pow(laser.y - attackingTower.y, 2));
if (laserDistance < 100) {
// Hit tower - deal damage
attackingTower.takeDamage(laser.damage);
LK.effects.flashObject(attackingTower, 0xff0000, 300);
// Remove laser
LK.clearInterval(laserInterval);
laser.destroy();
return;
}
// Check if laser went off screen
if (laser.x > 2048 + 100 || laser.x < -100 || laser.y > 2732 + 100 || laser.y < -100) {
LK.clearInterval(laserInterval);
laser.destroy();
}
}, 16);
};
} else if (currentWave === 3) {
// Create robot enemy for wave 3
enemy = game.addChild(new Container());
// Attach robot asset
var robotGraphics = enemy.attachAsset('Robot', {
anchorX: 0.5,
anchorY: 0.5
});
// Add wheel to robot
var wheel = enemy.attachAsset('Wheel', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: 100,
scaleX: 0.8,
scaleY: 0.8
});
// Add second wheel to robot
var wheel2 = enemy.attachAsset('wheel2', {
anchorX: 0.5,
anchorY: 0.5,
x: 25,
y: 100,
scaleX: 0.8,
scaleY: 0.8
});
// Add roboarm to robot
var roboarm = enemy.attachAsset('Roboarm', {
anchorX: 0.5,
anchorY: 0.5,
x: -5,
y: 0,
scaleX: 0.6,
scaleY: 0.6
});
// Initialize robot properties
enemy.speed = -6; // Faster speed
enemy.health = 120; // High health
enemy.maxHealth = 120;
enemy.pathLine = 1;
enemy.lastX = undefined;
// Add health bar
var healthBarOutline = enemy.attachAsset('healthBarOutline', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -200
});
var healthBar = enemy.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -200,
tint: 0x00ff00
});
enemy.updateHealthBar = function () {
var healthPercentage = enemy.health / enemy.maxHealth;
healthBar.scaleX = healthPercentage;
if (healthPercentage > 0.6) {
healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
healthBar.tint = 0xffff00; // Yellow
} else {
healthBar.tint = 0xff0000; // Red
}
};
enemy.takeDamage = function (damage) {
enemy.health -= damage;
if (enemy.health <= 0) {
enemy.health = 0;
}
enemy.updateHealthBar();
};
// Number text removed from wave 3 robots
// Add laser fire back attack for robot when hit
enemy.fireBackAtTower = function (attackingTower) {
// Create laser fire back projectile
var laser = game.addChild(LK.getAsset('Laserfire', {
anchorX: 0.5,
anchorY: 0.5,
x: enemy.x - 200,
y: enemy.y,
alpha: 0.9
}));
// Calculate direction to attacking tower
var deltaX = attackingTower.x - laser.x;
var deltaY = attackingTower.y - laser.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
var speed = 6;
laser.velocityX = deltaX / distance * speed;
laser.velocityY = deltaY / distance * speed;
laser.damage = 15;
// Animate laser movement
var laserInterval = LK.setInterval(function () {
laser.x += laser.velocityX;
laser.y += laser.velocityY;
// Check if laser hit the attacking tower
var laserDistance = Math.sqrt(Math.pow(laser.x - attackingTower.x, 2) + Math.pow(laser.y - attackingTower.y, 2));
if (laserDistance < 100) {
// Hit tower - deal damage
attackingTower.takeDamage(laser.damage);
LK.effects.flashObject(attackingTower, 0xff0000, 300);
// Remove laser
LK.clearInterval(laserInterval);
laser.destroy();
return;
}
// Check if laser went off screen
if (laser.x > 2048 + 100 || laser.x < -100 || laser.y > 2732 + 100 || laser.y < -100) {
LK.clearInterval(laserInterval);
laser.destroy();
}
}, 16);
};
// Add showElectricEffect function for wave 3 robots
enemy.showElectricEffect = function () {
// Wave 3 robots don't have electric effect visuals, so this is a no-op
};
enemy.update = function () {
if (enemy.lastX === undefined) enemy.lastX = enemy.x;
enemy.updateHealthBar();
// Rotate wheel slowly anticlockwise
if (wheel) {
tween(wheel, {
rotation: wheel.rotation - Math.PI / 8
}, {
duration: 200,
easing: tween.linear
});
}
// Rotate second wheel slowly anticlockwise
if (wheel2) {
tween(wheel2, {
rotation: wheel2.rotation - Math.PI / 8
}, {
duration: 200,
easing: tween.linear
});
}
};
}
// Position enemy at the right side of the screen
enemy.x = 2048 - 50; // Start from right side
// Randomly assign path from all 6 available lines
var availableLines = [1, 2, 3, 4, 5, 6];
var randomLineIndex = Math.floor(Math.random() * availableLines.length);
var selectedLine = availableLines[randomLineIndex];
// Set enemy position based on randomly selected line
if (selectedLine === 1) {
enemy.y = pathPositions.line1;
enemy.pathLine = 1;
} else if (selectedLine === 2) {
enemy.y = pathPositions.line2;
enemy.pathLine = 2;
} else if (selectedLine === 3) {
enemy.y = pathPositions.line3;
enemy.pathLine = 3;
} else if (selectedLine === 4) {
enemy.y = pathPositions.line4;
enemy.pathLine = 4;
} else if (selectedLine === 5) {
enemy.y = pathPositions.line5;
enemy.pathLine = 5;
} else if (selectedLine === 6) {
enemy.y = pathPositions.line6;
enemy.pathLine = 6;
}
enemy.health = 100;
enemy.maxHealth = 100;
enemy.speed = -2; // Negative speed to move left
enemy.pathIndex = 0;
enemy.lastPathIndex = -1;
// Set enemy number (only if numberText exists)
if (enemy.numberText) {
enemy.numberText.setText(enemyNumber.toString());
}
enemies.push(enemy);
enemiesSpawned++;
}
function updateEnemies() {
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
// Move enemy using its speed (negative for left movement)
enemy.x += enemy.speed;
// Check if enemy reached the left side of the screen (goal)
if (enemy.lastX >= 0 && enemy.x < 0) {
// Enemy reached the goal - player loses a life
playerLives -= 1;
// Update lives display using direct reference
if (livesText) {
livesText.setText('Lives: ' + playerLives);
}
// Check if player has no lives left
if (playerLives <= 0) {
// Game over - show game over screen
LK.showGameOver();
return;
}
// Track wave 1 completion
if (currentWave === 1) {
wave1EnemiesCompleted++;
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
// Enemy reached the left side - remove it
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check each tower type separately (no early exits)
for (var j = 0; j < towers.length; j++) {
var tower = towers[j];
// Check if tower is a water tower (Tower1 asset)
if (tower._assetId === 'Tower1') {
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - tower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 700 pixels
if (enemy.x > tower.x && enemy.x - tower.x < 700) {
// Initialize fire rate tracking for this tower
if (!tower.lastFireTime) {
tower.lastFireTime = 0;
}
// Fire every 30 ticks (0.5 seconds at 60fps)
if (LK.ticks - tower.lastFireTime >= 30) {
tower.lastFireTime = LK.ticks;
// Create water squirt visual
var waterSquirt = game.addChild(LK.getAsset('Water', {
anchorX: 0,
anchorY: 0.5,
x: tower.x,
y: tower.y,
scaleX: 0.3,
scaleY: 0.1,
alpha: 0.7,
tint: 0x4169E1
})); // Animate water squirt
tween(waterSquirt, {
scaleX: 0.35,
alpha: 0.3
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
waterSquirt.destroy();
}
});
// Deal damage to enemy
enemy.takeDamage(8);
// Make electric effect visible when hit by water
enemy.showElectricEffect();
// Robot fires back when hit by water tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(tower);
}
// Check if enemy is destroyed
if (enemy.health <= 0) {
// Create explosion effect when probedroid is destroyed by water
var waterExplosion = game.addChild(LK.getAsset('Explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: enemy.x,
y: enemy.y,
scaleX: 0.3,
scaleY: 0.3
})); // Animate explosion with tween
tween(waterExplosion, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
waterExplosion.destroy();
}
});
enemy.destroy();
enemies.splice(i, 1);
// Give player money for destroying enemy
playerCash += 5;
cashText.setText('Cash: $' + playerCash);
// Award 50 points for kill
playerScore += 50;
LK.setScore(playerScore);
if (window.scoreText) {
window.scoreText.setText('Score: ' + playerScore);
}
// Track wave 1 completion
if (currentWave === 1) {
wave1EnemiesCompleted++;
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
i--; // Adjust index since we removed an enemy
return; // Exit function for this enemy
}
}
}
}
}
// Check if tower is a gas tower (Dog asset)
if (tower._assetId === 'Dog') {
// Check tower health before any firing logic - if dead, skip all processing
if (tower.health <= 0) {
continue; // Skip to next tower
}
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - tower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 600 pixels
if (enemy.x > tower.x && enemy.x - tower.x < 600) {
// Initialize fire rate tracking for this tower
if (!tower.lastFireTime) {
tower.lastFireTime = 0;
}
// Fire every 45 ticks (0.75 seconds at 60fps)
if (LK.ticks - tower.lastFireTime >= 45) {
tower.lastFireTime = LK.ticks;
// Switch dog asset to dog1 for fart animation
tower.destroy();
var fartingDog = game.addChild(LK.getAsset('Dog1', {
anchorX: 0.5,
anchorY: 0.5,
x: tower.x,
y: tower.y,
alpha: 1
})); // Copy tower properties to the new farting dog
fartingDog._assetId = 'Dog';
fartingDog.health = tower.health;
fartingDog.maxHealth = tower.maxHealth;
fartingDog.isBeingDamaged = tower.isBeingDamaged;
fartingDog.lastDamageTime = tower.lastDamageTime;
fartingDog.lastFireTime = tower.lastFireTime;
fartingDog.healthBarOutline = tower.healthBarOutline;
fartingDog.healthBar = tower.healthBar;
fartingDog.takeDamage = function (damage) {
fartingDog.health -= damage;
if (fartingDog.health <= 0) {
fartingDog.health = 0;
}
// Update health bar
var healthPercentage = fartingDog.health / fartingDog.maxHealth;
fartingDog.healthBar.scaleX = healthPercentage;
// Change color based on health
if (healthPercentage > 0.6) {
fartingDog.healthBar.tint = 0x00ff00; // Green
} else if (healthPercentage > 0.3) {
fartingDog.healthBar.tint = 0xffff00; // Yellow
} else {
fartingDog.healthBar.tint = 0xff0000; // Red
}
};
// Replace tower in towers array
for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
if (towers[towerIndex] === tower) {
towers[towerIndex] = fartingDog;
break;
}
}
// Create gas cloud visual
var gasCloud = game.addChild(LK.getAsset('GasCloud', {
anchorX: 0.5,
anchorY: 0.5,
x: tower.x + 150,
// Position gas cloud 100 pixels further left when dog farts
y: tower.y,
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.6,
tint: 0x90EE90
})); // Animate gas cloud expanding and fading
tween(gasCloud, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0.2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
gasCloud.destroy();
}
});
// Switch back to normal dog after 500ms
LK.setTimeout(function () {
// Check if farting dog is still alive before replacing
if (fartingDog.health <= 0) {
// Farting dog is dead, don't replace it, just destroy it
// Remove health bar components
if (fartingDog.healthBarOutline) {
fartingDog.healthBarOutline.destroy();
}
if (fartingDog.healthBar) {
fartingDog.healthBar.destroy();
}
fartingDog.destroy();
// Remove from towers array
for (var towerIndex = towers.length - 1; towerIndex >= 0; towerIndex--) {
if (towers[towerIndex] === fartingDog) {
towers.splice(towerIndex, 1);
break;
}
}
return;
}
// Check if fartingDog still exists in towers array before replacing
var fartingDogExists = false;
for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
if (towers[towerIndex] === fartingDog) {
fartingDogExists = true;
break;
}
}
if (!fartingDogExists) {
// Farting dog was already destroyed, don't create replacement
return;
}
fartingDog.destroy();
var normalDog = game.addChild(LK.getAsset('Dog', {
anchorX: 0.5,
anchorY: 0.5,
x: fartingDog.x,
y: fartingDog.y,
alpha: 1
}));
// Copy properties back to normal dog
normalDog._assetId = 'Dog';
normalDog.health = fartingDog.health;
normalDog.maxHealth = fartingDog.maxHealth;
normalDog.isBeingDamaged = fartingDog.isBeingDamaged;
normalDog.lastDamageTime = fartingDog.lastDamageTime;
normalDog.lastFireTime = fartingDog.lastFireTime;
normalDog.healthBarOutline = fartingDog.healthBarOutline;
normalDog.healthBar = fartingDog.healthBar;
normalDog.takeDamage = fartingDog.takeDamage;
// Check if normal dog should be destroyed immediately after replacement
if (normalDog.health <= 0) {
// Remove health bar components
if (normalDog.healthBarOutline) {
normalDog.healthBarOutline.destroy();
}
if (normalDog.healthBar) {
normalDog.healthBar.destroy();
}
normalDog.destroy();
// Remove from towers array
for (var towerIndex = towers.length - 1; towerIndex >= 0; towerIndex--) {
if (towers[towerIndex] === fartingDog) {
towers.splice(towerIndex, 1);
break;
}
}
return;
}
// Replace in towers array
for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
if (towers[towerIndex] === fartingDog) {
towers[towerIndex] = normalDog;
break;
}
}
}, 500);
// Check if enemy is affected by gas (farts don't affect robots, drones, or probe droids)
var isAffectedByGas = true; // Check enemy asset ID to determine if it's a robot/mechanical enemy
if (enemy.attachedAssets && enemy.attachedAssets.length > 0) {
var enemyAssetId = enemy.attachedAssets[0].assetId;
if (enemyAssetId === 'Robot' || enemyAssetId === 'Drone' || enemyAssetId === 'SpaceDrone' || enemyAssetId === 'Probedroid') {
isAffectedByGas = false;
}
}
// Only deal damage if enemy is affected by gas
if (isAffectedByGas) {
// Deal damage to enemy
enemy.takeDamage(2);
// Robot fires back when hit by gas tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(fartingDog);
}
// Check if enemy is destroyed
if (enemy.health <= 0) {
enemy.destroy();
enemies.splice(i, 1);
// Give player money for destroying enemy
playerCash += 5;
cashText.setText('Cash: $' + playerCash);
// Award 50 points for kill
playerScore += 50;
LK.setScore(playerScore);
if (window.scoreText) {
window.scoreText.setText('Score: ' + playerScore);
}
// Track wave 1 completion
if (currentWave === 1) {
wave1EnemiesCompleted++;
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
i--; // Adjust index since we removed an enemy
return; // Exit function for this enemy
}
}
}
}
}
}
// Check if tower is a bug zapper (electric tower)
if (tower._assetId === 'Bugzapper') {
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - tower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 800 pixels
if (enemy.x > tower.x && enemy.x - tower.x < 800) {
// Initialize zap tracking for this tower
if (!tower.activeZap) {
tower.activeZap = null;
tower.zapStartTime = 0;
}
// Start prolonged zap attack if not already active
if (!tower.activeZap) {
// Start zap animation
var _animateZap = function animateZap() {
if (tower.activeZap) {
tween(tower.activeZap, {
alpha: 0.3
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (tower.activeZap) {
tween(tower.activeZap, {
alpha: 0.9
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: _animateZap
});
}
}
});
}
};
tower.zapStartTime = LK.ticks;
// Create prolonged zap3 visual
tower.activeZap = game.addChild(LK.getAsset('Zap3', {
anchorX: 0.5,
anchorY: 0.5,
x: tower.x + 400,
y: tower.y,
scaleX: 1.0,
scaleY: 1.0,
alpha: 0.9,
tint: 0x00FFFF
}));
_animateZap();
}
// Deal damage continuously every 15 ticks while zapping
if (tower.activeZap && LK.ticks - tower.zapStartTime >= 15 && (LK.ticks - tower.zapStartTime) % 15 === 0) {
// Deal damage to enemy
enemy.takeDamage(20);
// Make electric effect visible when hit by electricity
enemy.showElectricEffect();
// Robot fires back when hit by electric tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(tower);
}
// Check if enemy is destroyed
if (enemy.health <= 0) {
// Create explosive effect when probedroid is destroyed by bugzapper
var bugzapperExplosion = game.addChild(LK.getAsset('Explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: enemy.x,
y: enemy.y,
scaleX: 0.3,
scaleY: 0.3
}));
// Animate explosion with tween
tween(bugzapperExplosion, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
bugzapperExplosion.destroy();
}
});
enemy.destroy();
enemies.splice(i, 1);
// Give player money for destroying enemy
playerCash += 5;
cashText.setText('Cash: $' + playerCash);
// Award 50 points for kill
playerScore += 50;
LK.setScore(playerScore);
if (window.scoreText) {
window.scoreText.setText('Score: ' + playerScore);
}
// Track wave 1 completion
if (currentWave === 1) {
wave1EnemiesCompleted++;
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
i--; // Adjust index since we removed an enemy
return; // Exit function for this enemy
}
}
} else {
// Enemy is not in range, stop zap attack
if (tower.activeZap) {
tower.activeZap.destroy();
tower.activeZap = null;
tower.zapStartTime = 0;
}
}
} else {
// Enemy is not on same line, stop zap attack
if (tower.activeZap) {
tower.activeZap.destroy();
tower.activeZap = null;
tower.zapStartTime = 0;
}
}
}
// Check if tower is a fire tower (Fireworks asset)
if (tower._assetId === 'Fireworks') {
// Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
if (Math.abs(enemy.y - tower.y) < 50) {
// Check if enemy is to the right of the tower and within range of 1000 pixels
if (enemy.x > tower.x && enemy.x - tower.x < 1000) {
// Initialize fire rate tracking for this tower
if (!tower.lastFireTime) {
tower.lastFireTime = 0;
}
// Fire every 60 ticks (1 second at 60fps)
if (LK.ticks - tower.lastFireTime >= 60) {
// Store fireball properties
// Add fire animation to fireball
var animateFireball = function animateFireball(fireball) {
// Pulsing scale animation
function startFireballPulse() {
tween(fireball, {
scaleX: 0.6,
scaleY: 0.6,
alpha: 0.8
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(fireball, {
scaleX: 0.5,
scaleY: 0.5,
alpha: 1.0
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: startFireballPulse
});
}
});
}
// Flickering alpha animation
function startFireballFlicker() {
tween(fireball, {
alpha: 0.7
}, {
duration: 150,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(fireball, {
alpha: 1.0
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
LK.setTimeout(function () {
if (fireball && fireball.parent) {
startFireballFlicker();
}
}, Math.random() * 300 + 100);
}
});
}
});
}
// Start all fire animations
startFireballPulse();
startFireballFlicker();
}; // Start fire animation for this fireball
tower.lastFireTime = LK.ticks;
// Create fireball projectile
var fireball = game.addChild(LK.getAsset('Fireball', {
anchorX: 0.5,
anchorY: 0.5,
x: tower.x + 50,
y: tower.y,
scaleX: 0.5,
scaleY: 0.5,
rotation: 35 * Math.PI / 180 // Rotate 35 degrees to the right
}));
animateFireball(fireball);
fireball.targetX = enemy.x;
fireball.targetY = enemy.y;
fireball.speed = 8;
fireball.damage = 15;
// Calculate direction to enemy
var deltaX = enemy.x - fireball.x;
var deltaY = enemy.y - fireball.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
fireball.velocityX = deltaX / distance * fireball.speed;
fireball.velocityY = deltaY / distance * fireball.speed;
// Animate fireball movement
var fireballInterval = LK.setInterval(function () {
fireball.x += fireball.velocityX;
fireball.y += fireball.velocityY;
// Check if fireball hit any enemy
for (var enemyIndex = 0; enemyIndex < enemies.length; enemyIndex++) {
var targetEnemy = enemies[enemyIndex];
var fireballDistance = Math.sqrt(Math.pow(fireball.x - targetEnemy.x, 2) + Math.pow(fireball.y - targetEnemy.y, 2));
if (fireballDistance < 80) {
// Hit enemy - deal damage
targetEnemy.takeDamage(fireball.damage);
// Robot fires back when hit by fire tower
if (targetEnemy.fireBackAtTower) {
targetEnemy.fireBackAtTower(tower);
}
// Create explosion effect
var explosion = game.addChild(LK.getAsset('Explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: fireball.x,
y: fireball.y,
scaleX: 0.3,
scaleY: 0.3
}));
// Animate explosion
tween(explosion, {
scaleX: 0.8,
scaleY: 0.8,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
explosion.destroy();
}
});
// Check if enemy is destroyed
if (targetEnemy.health <= 0) {
// Check if this is a mechanical enemy that should have explosion effect
var isMechanicalEnemy = false;
if (targetEnemy.attachedAssets && targetEnemy.attachedAssets.length > 0) {
var enemyAssetId = targetEnemy.attachedAssets[0].assetId;
if (enemyAssetId === 'Robot' || enemyAssetId === 'Drone' || enemyAssetId === 'SpaceDrone' || enemyAssetId === 'Probedroid' || enemyAssetId === 'UFO') {
isMechanicalEnemy = true;
}
}
// For probe droids (current enemy type), always show explosion
if (!isMechanicalEnemy) {
// Check if this is a probe droid by checking the asset used
var enemyChildren = targetEnemy.children;
for (var childIndex = 0; childIndex < enemyChildren.length; childIndex++) {
var child = enemyChildren[childIndex];
if (child.assetId === 'Probedroid') {
isMechanicalEnemy = true;
break;
}
}
}
// Create explosion effect for mechanical enemies
if (isMechanicalEnemy) {
var mechanicalExplosion = game.addChild(LK.getAsset('Explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: targetEnemy.x,
y: targetEnemy.y,
scaleX: 0.2,
scaleY: 0.2
}));
// Animate explosion with tween
tween(mechanicalExplosion, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
mechanicalExplosion.destroy();
}
});
}
targetEnemy.destroy();
enemies.splice(enemyIndex, 1);
// Give player money for destroying enemy
playerCash += 5;
cashText.setText('Cash: $' + playerCash);
// Award 50 points for kill
playerScore += 50;
LK.setScore(playerScore);
if (window.scoreText) {
window.scoreText.setText('Score: ' + playerScore);
}
// Track wave 1 completion
if (currentWave === 1) {
wave1EnemiesCompleted++;
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
}
// Remove fireball
LK.clearInterval(fireballInterval);
fireball.destroy();
return;
}
}
// Check if fireball went off screen
if (fireball.x > 2048 + 100 || fireball.x < -100 || fireball.y > 2732 + 100 || fireball.y < -100) {
LK.clearInterval(fireballInterval);
fireball.destroy();
}
}, 16); // ~60fps
break; // Found an enemy in range, no need to check other towers of this type
}
}
}
}
}
// Check collision with fan blades first (before tower collision)
for (var k = 0; k < towers.length; k++) {
var tower = towers[k];
// Check if this tower has blades (fan tower) and is running (not in cooldown)
if (tower.blades && tower.isRunning && !tower.cooldownActive) {
// Initialize blade collision tracking for this enemy-tower pair
if (!enemy.collidingBlades) {
enemy.collidingBlades = {};
}
// Check if enemy intersects with fan blades
var enemyWidth = 150; // Half width of probedroid
var enemyHeight = 183; // Half height of probedroid
var bladeWidth = 75; // Half width of blades
var bladeHeight = 75; // Half height of blades
var isCollidingWithBlades = Math.abs(enemy.x - tower.blades.x) < (enemyWidth + bladeWidth) / 2 && Math.abs(enemy.y - tower.blades.y) < (enemyHeight + bladeHeight) / 2;
// Track blade collision state transitions
var wasCollidingWithBlades = enemy.collidingBlades[k] || false;
// Handle blade collision start
if (!wasCollidingWithBlades && isCollidingWithBlades) {
// Collision with blades just started
enemy.collidingBlades[k] = true;
// Push enemy back 400 pixels to the right
var pushbackDistance = 400;
var targetX = enemy.x + pushbackDistance;
// Make sure enemy doesn't go off screen
if (targetX > 2048 - 50) {
targetX = 2048 - 50;
}
// Animate pushback using tween
tween(enemy, {
x: targetX
}, {
duration: 500,
easing: tween.easeOut
});
// Inflict damage to enemy
enemy.takeDamage(25);
// Flash enemy to show damage
LK.effects.flashObject(enemy, 0x0088ff, 300);
// Robot fires back when hit by fan tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(tower);
}
// Check if enemy is destroyed
if (enemy.health <= 0) {
enemy.destroy();
enemies.splice(i, 1);
// Give player money for destroying enemy
playerCash += 5;
cashText.setText('Cash: $' + playerCash);
// Award 50 points for kill
playerScore += 50;
LK.setScore(playerScore);
if (window.scoreText) {
window.scoreText.setText('Score: ' + playerScore);
}
// Track wave 1 completion
if (currentWave === 1) {
wave1EnemiesCompleted++;
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
i--; // Adjust index since we removed an enemy
break; // Exit tower loop for this enemy
}
} else if (!isCollidingWithBlades && wasCollidingWithBlades) {
// Collision with blades just ended
enemy.collidingBlades[k] = false;
}
}
}
// Check if enemy is colliding with any tower
for (var k = 0; k < towers.length; k++) {
var tower = towers[k];
// Initialize collision tracking for this enemy-tower pair
if (!enemy.collidingTowers) {
enemy.collidingTowers = {};
}
// Check if enemy intersects with tower (use proper collision detection)
var enemyWidth = 150; // Half width of probedroid
var enemyHeight = 183; // Half height of probedroid
var towerWidth = 100; // Half width of tower
var towerHeight = 100; // Half height of tower
var isColliding = Math.abs(enemy.x - tower.x) < (enemyWidth + towerWidth) / 2 && Math.abs(enemy.y - tower.y) < (enemyHeight + towerHeight) / 2;
// Track collision state transitions
var wasColliding = enemy.collidingTowers[k] || false;
// Handle collision start
if (!wasColliding && isColliding) {
// Collision just started
enemy.collidingTowers[k] = true;
// Stop enemy movement
enemy.speed = 0;
// Mark tower as being damaged
tower.isBeingDamaged = true;
tower.lastDamageTime = LK.ticks;
// Flash both objects to show collision
LK.effects.flashObject(enemy, 0xffff00, 200);
LK.effects.flashObject(tower, 0xff0000, 200);
}
// Handle ongoing collision
if (isColliding) {
// Deal damage every 30 ticks (0.5 seconds at 60fps)
if (tower.isBeingDamaged && LK.ticks - tower.lastDamageTime >= 30) {
// Flash tower red to show damage
LK.effects.flashObject(tower, 0xff0000, 300);
// Deal damage to tower
tower.takeDamage(10);
tower.lastDamageTime = LK.ticks;
// Check if tower is destroyed - mark for destruction but don't destroy here
if (tower.health <= 0) {
// Resume enemy movement after destroying tower
enemy.speed = -2;
// Clear collision tracking for this tower
delete enemy.collidingTowers[k];
// Flash enemy green to show it can continue
LK.effects.flashObject(enemy, 0x00ff00, 500);
}
}
} else {
// No longer colliding
if (wasColliding) {
// Collision just ended
enemy.collidingTowers[k] = false;
tower.isBeingDamaged = false;
// Resume enemy movement if not colliding with any towers
var stillColliding = false;
for (var key in enemy.collidingTowers) {
if (enemy.collidingTowers[key]) {
stillColliding = true;
break;
}
}
if (!stillColliding) {
enemy.speed = -2;
}
}
}
}
// Update last position for next frame
enemy.lastX = enemy.x;
}
}
// Display the title - They Came For Our WiFi
// Import tween plugin
var titleImage = game.addChild(LK.getAsset('Title', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 1400
}));
// Add skip intro button to top of title screen
var skipButton = new Text2('SKIP INTRO', {
size: 60,
fill: 0xFFFFFF
});
skipButton.anchor.set(0.5, 0);
skipButton.x = 2048 / 2;
skipButton.y = 150;
game.addChild(skipButton);
// Function to animate plasma pulsation and flicker
function animatePlasma(plasma) {
if (!plasma) return;
// Create pulsation animation - scale up and down
function startPulsation() {
tween(plasma, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(plasma, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: startPulsation
});
}
});
}
// Create flicker animation - alpha changes
function startFlicker() {
tween(plasma, {
alpha: 0.5
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(plasma, {
alpha: 1.0
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Random delay before next flicker
LK.setTimeout(function () {
startFlicker();
}, Math.random() * 1000 + 200);
}
});
}
});
}
// Start both animations
startPulsation();
startFlicker();
}
// Function to handle plasma tower prolonged attack
function handlePlasmaAttack(tower) {
// Check if this tower has plasma (is a plasma tower)
if (!tower.plasma) return;
// Initialize plasma attack tracking
if (!tower.plasmaAttackActive) {
tower.plasmaAttackActive = false;
tower.plasmaRays = [];
tower.plasmaAttackStartTime = 0;
}
// Check for enemies within 800 pixels radius
var enemiesInRange = [];
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var distance = Math.sqrt(Math.pow(enemy.x - tower.x, 2) + Math.pow(enemy.y - tower.y, 2));
if (distance <= 800) {
enemiesInRange.push(enemy);
}
}
// If enemies are in range and attack is not active, start attack
if (enemiesInRange.length > 0 && !tower.plasmaAttackActive) {
tower.plasmaAttackActive = true;
tower.plasmaAttackStartTime = LK.ticks;
// Create 10 plasma ray assets
var _loop2 = function _loop2() {
angle = j * 36 * Math.PI / 180; // 360 degrees / 10 rays = 36 degrees each
rayX = tower.x + Math.cos(angle) * 150;
rayY = tower.y + Math.sin(angle) * 150;
plasmaRay = game.addChild(LK.getAsset('Plasmaray1', {
anchorX: 0.5,
anchorY: 0.5,
x: rayX,
y: rayY,
rotation: angle + Math.PI / 2,
// Rotate to point outward
alpha: 0.8,
scaleX: 0.8,
scaleY: 0.8
}));
tower.plasmaRays.push(plasmaRay);
// Animate plasma ray with pulsing effect
function animatePlasmaRay(ray) {
tween(ray, {
alpha: 0.4,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(ray, {
alpha: 0.9,
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 400,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (tower.plasmaAttackActive) {
animatePlasmaRay(ray);
}
}
});
}
});
}
animatePlasmaRay(plasmaRay);
},
angle,
rayX,
rayY,
plasmaRay;
for (var j = 0; j < 10; j++) {
_loop2();
}
}
// If attack is active, deal damage to enemies in range
if (tower.plasmaAttackActive && enemiesInRange.length > 0) {
// Deal damage every 20 ticks
if ((LK.ticks - tower.plasmaAttackStartTime) % 20 === 0) {
// Plasmaball loses health every time it uses plasmaray1 attack
tower.takeDamage(3);
// Flash tower to show it's taking damage from using plasma attack
LK.effects.flashObject(tower, 0xff8800, 200);
for (var i = 0; i < enemiesInRange.length; i++) {
var enemy = enemiesInRange[i];
enemy.takeDamage(30);
// Make electric effect visible when hit by plasma
enemy.showElectricEffect();
// Robot fires back when hit by plasma tower
if (enemy.fireBackAtTower) {
enemy.fireBackAtTower(tower);
}
// Check if enemy is destroyed
if (enemy.health <= 0) {
// Create explosion effect
var plasmaExplosion = game.addChild(LK.getAsset('Explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: enemy.x,
y: enemy.y,
scaleX: 0.3,
scaleY: 0.3
}));
// Animate explosion
tween(plasmaExplosion, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
plasmaExplosion.destroy();
}
});
enemy.destroy();
for (var k = 0; k < enemies.length; k++) {
if (enemies[k] === enemy) {
enemies.splice(k, 1);
break;
}
}
// Give player money for destroying enemy
playerCash += 5;
cashText.setText('Cash: $' + playerCash);
// Award 50 points for kill
playerScore += 50;
LK.setScore(playerScore);
if (window.scoreText) {
window.scoreText.setText('Score: ' + playerScore);
}
// Track wave 1 completion
if (currentWave === 1) {
wave1EnemiesCompleted++;
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
}
}
}
}
// If no enemies in range and attack is active, stop attack
if (enemiesInRange.length === 0 && tower.plasmaAttackActive) {
tower.plasmaAttackActive = false;
// Remove all plasma rays
for (var j = 0; j < tower.plasmaRays.length; j++) {
tower.plasmaRays[j].destroy();
}
tower.plasmaRays = [];
}
}
// Function to skip directly to backdrop scene
function skipToBackdrop() {
// Stop all tweens
tween.stop(titleImage);
tween.stop(flybyImage);
// Remove title and flyby
titleImage.destroy();
flybyImage.destroy();
skipButton.destroy();
// Add backdrop asset to game
var backdropAsset = game.addChild(LK.getAsset('backdrop', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 1,
scaleX: 0.5,
scaleY: 0.5
}));
// Add flyby asset to backdrop
var backdropFlyby = game.addChild(LK.getAsset('Flyby', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 800,
alpha: 1,
scaleX: 0.1,
scaleY: 0.1
}));
// Zoom in flyby to final size
tween(backdropFlyby, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 2000,
easing: tween.easeInOut
});
// Store the original Y position for backdrop flyby
var backdropFlybyOriginalY = backdropFlyby.y;
// Make flyby move off the right side of backdrop scene
tween(backdropFlyby, {
x: 2048 + 375
}, {
duration: 6000,
easing: tween.linear,
onFinish: function onFinish() {
// After flyby has left the backdrop scene, fade in wave1 asset
var wave1Asset = game.addChild(LK.getAsset('Wave1', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Fade in wave1 asset
tween(wave1Asset, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Keep wave1 visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(wave1Asset, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
wave1Asset.destroy();
// Start first wave of tower defense game
startTowerDefenseWave1();
}
});
}, 2000);
}
});
}
});
// Add 6 horizontal guide lines immediately
var lineSpacing = 2732 / 7;
for (var i = 1; i <= 6; i++) {
var yPosition = lineSpacing * i;
if (i === 1) {
yPosition += 480 + 50; // Move guideline 1 down by 480 pixels
} else if (i === 2) {
yPosition += 320 + 50; // Move guideline 2 down by 320 pixels
} else if (i === 3) {
yPosition += 150 + 50; // Move guideline 3 down by 150 pixels
} else if (i === 4) {
yPosition += 10 + 50; // Move guideline 4 down by 10 pixels
} else if (i === 5) {
yPosition -= 150 - 50; // Move guideline 5 up by 150 pixels
} else if (i === 6) {
yPosition -= 310 - 50; // Move guideline 6 up by 310 pixels
}
var guideLine = game.addChild(LK.getAsset('guideLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: yPosition,
alpha: 0
}));
// Store guideline reference and add click handler
guidelines.push(guideLine);
guideLine.lineNumber = i;
guideLine.down = function (x, y, obj) {
if (isPlacingTower && towerPreview) {
// Move tower preview to clicked position on guideline
// x and y are already in the local coordinate space of the guideline
towerPreview.x = x;
towerPreview.y = this.y; // Use the guideline's Y position
}
};
}
}
// Add touch event to skip button
skipButton.down = function (x, y, obj) {
skipToBackdrop();
};
// Add flyby asset to title - start at right side of screen
var flybyImage = game.addChild(LK.getAsset('Flyby', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 + 375,
y: 2732 / 2 + 1400 - 500
}));
// Store the original Y position for flyby
var flybyOriginalY = flybyImage.y;
// Create hover animation function
function startFlybyHover() {
// Tween up 50 pixels over 2 seconds
tween(flybyImage, {
y: flybyOriginalY - 50
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Tween down 50 pixels over 2 seconds
tween(flybyImage, {
y: flybyOriginalY + 50
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Start the cycle again
startFlybyHover();
}
});
}
});
}
// Start the hover animation
startFlybyHover();
// Start flyby movement from right to left
tween(flybyImage, {
x: -375
}, {
duration: 8000,
easing: tween.linear,
onFinish: function onFinish() {
// After flyby has left the screen, slowly scroll title up
tween(titleImage, {
y: titleImage.y - titleImage.height
}, {
duration: 20000,
easing: tween.easeOut
});
// Stop the title scrolling after 5 seconds
LK.setTimeout(function () {
tween.stop(titleImage, {
y: true
});
// Fade in intro asset in the middle of the screen
var introAsset = game.addChild(LK.getAsset('intro', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Add wifi asset to intro
var wifiAsset = game.addChild(LK.getAsset('WiFi', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 200,
y: 2732 / 2 + 200,
alpha: 0
}));
// Tween alpha from 0 to 1 for fade-in effect
tween(introAsset, {
alpha: 1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Also fade in wifi asset
tween(wifiAsset, {
alpha: 1
}, {
duration: 2000,
easing: tween.easeInOut
});
// After intro has faded in, make flyby move from left to right
flybyImage.x = -375; // Reset flyby to left side
flybyImage.y = 2732 / 2; // Center vertically
tween(flybyImage, {
x: 2048 + 375
}, {
duration: 6000,
easing: tween.linear,
onFinish: function onFinish() {
// After flyby has left the screen, fade out intro and fade in backdrop
tween(introAsset, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeInOut
});
// Also fade out wifi asset
tween(wifiAsset, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeInOut
});
// Add backdrop asset to game
var backdropAsset = game.addChild(LK.getAsset('backdrop', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}));
// Add flyby asset to backdrop
var backdropFlyby = game.addChild(LK.getAsset('Flyby', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 800,
alpha: 1,
scaleX: 0.1,
scaleY: 0.1
}));
// Store the original Y position for backdrop flyby
var backdropFlybyOriginalY = backdropFlyby.y;
// Make flyby move off the right side of backdrop scene
function startBackdropFlybyHover() {
tween(backdropFlyby, {
x: 2048 + 375
}, {
duration: 6000,
easing: tween.linear,
onFinish: function onFinish() {
// After flyby has left the backdrop scene, fade in wave1 asset
var wave1Asset = game.addChild(LK.getAsset('Wave1', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Fade in wave1 asset
tween(wave1Asset, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Keep wave1 visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(wave1Asset, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
wave1Asset.destroy();
// Start first wave of tower defense game
startTowerDefenseWave1();
}
});
}, 2000);
}
});
}
});
}
// Fade in backdrop
tween(backdropAsset, {
alpha: 1
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Zoom in backdrop flyby
tween(backdropFlyby, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Start flyby movement to right side after zoom in
startBackdropFlybyHover();
}
});
// Add 6 horizontal guide lines after backdrop fades in
var lineSpacing = 2732 / 7; // Divide screen height by 7 to get 6 lines with margins
for (var i = 1; i <= 6; i++) {
var yPosition = lineSpacing * i;
if (i === 1) {
yPosition += 480 + 50; // Move guideline 1 down by 480 pixels
} else if (i === 2) {
yPosition += 320 + 50; // Move guideline 2 down by 320 pixels
} else if (i === 3) {
yPosition += 150 + 50; // Move guideline 3 down by 150 pixels
} else if (i === 4) {
yPosition += 10 + 50; // Move guideline 4 down by 10 pixels
} else if (i === 5) {
yPosition -= 150 - 50; // Move guideline 5 up by 150 pixels
} else if (i === 6) {
yPosition -= 310 - 50; // Move guideline 6 up by 310 pixels
}
var guideLine = game.addChild(LK.getAsset('guideLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: yPosition,
alpha: 0
}));
}
}
});
}
});
}
});
}, 5000);
}
});
; ===================================================================
--- original.js
+++ change.js
@@ -2209,389 +2209,277 @@
enemy.destroy();
enemies.splice(i, 1);
continue;
}
- // Check for water towers on the same line
- var _loop = function _loop() {
- tower = towers[j]; // Check if tower is a water tower (Tower1 asset) by checking the asset's id
- if (tower._assetId === 'Tower1') {
- // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
- if (Math.abs(enemy.y - tower.y) < 50) {
- // Check if enemy is to the right of the tower and within range of 700 pixels
- if (enemy.x > tower.x && enemy.x - tower.x < 700) {
- // Initialize fire rate tracking for this tower
- if (!tower.lastFireTime) {
- tower.lastFireTime = 0;
+ // Check each tower type separately (no early exits)
+ for (var j = 0; j < towers.length; j++) {
+ var tower = towers[j];
+ // Check if tower is a water tower (Tower1 asset)
+ if (tower._assetId === 'Tower1') {
+ // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
+ if (Math.abs(enemy.y - tower.y) < 50) {
+ // Check if enemy is to the right of the tower and within range of 700 pixels
+ if (enemy.x > tower.x && enemy.x - tower.x < 700) {
+ // Initialize fire rate tracking for this tower
+ if (!tower.lastFireTime) {
+ tower.lastFireTime = 0;
+ }
+ // Fire every 30 ticks (0.5 seconds at 60fps)
+ if (LK.ticks - tower.lastFireTime >= 30) {
+ tower.lastFireTime = LK.ticks;
+ // Create water squirt visual
+ var waterSquirt = game.addChild(LK.getAsset('Water', {
+ anchorX: 0,
+ anchorY: 0.5,
+ x: tower.x,
+ y: tower.y,
+ scaleX: 0.3,
+ scaleY: 0.1,
+ alpha: 0.7,
+ tint: 0x4169E1
+ })); // Animate water squirt
+ tween(waterSquirt, {
+ scaleX: 0.35,
+ alpha: 0.3
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ waterSquirt.destroy();
+ }
+ });
+ // Deal damage to enemy
+ enemy.takeDamage(8);
+ // Make electric effect visible when hit by water
+ enemy.showElectricEffect();
+ // Robot fires back when hit by water tower
+ if (enemy.fireBackAtTower) {
+ enemy.fireBackAtTower(tower);
}
- // Fire every 30 ticks (0.5 seconds at 60fps)
- if (LK.ticks - tower.lastFireTime >= 30) {
- tower.lastFireTime = LK.ticks;
- // Create water squirt visual
- var waterSquirt = game.addChild(LK.getAsset('Water', {
- anchorX: 0,
+ // Check if enemy is destroyed
+ if (enemy.health <= 0) {
+ // Create explosion effect when probedroid is destroyed by water
+ var waterExplosion = game.addChild(LK.getAsset('Explosion', {
+ anchorX: 0.5,
anchorY: 0.5,
- x: tower.x,
- y: tower.y,
+ x: enemy.x,
+ y: enemy.y,
scaleX: 0.3,
- scaleY: 0.1,
- alpha: 0.7,
- tint: 0x4169E1
- })); // Animate water squirt
- tween(waterSquirt, {
- scaleX: 0.35,
- alpha: 0.3
+ scaleY: 0.3
+ })); // Animate explosion with tween
+ tween(waterExplosion, {
+ scaleX: 1.2,
+ scaleY: 1.2,
+ alpha: 0
}, {
- duration: 500,
+ duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
- waterSquirt.destroy();
+ waterExplosion.destroy();
}
});
- // Deal damage to enemy
- enemy.takeDamage(8);
- // Make electric effect visible when hit by water
- enemy.showElectricEffect();
- // Robot fires back when hit by water tower
- if (enemy.fireBackAtTower) {
- enemy.fireBackAtTower(tower);
+ enemy.destroy();
+ enemies.splice(i, 1);
+ // Give player money for destroying enemy
+ playerCash += 5;
+ cashText.setText('Cash: $' + playerCash);
+ // Award 50 points for kill
+ playerScore += 50;
+ LK.setScore(playerScore);
+ if (window.scoreText) {
+ window.scoreText.setText('Score: ' + playerScore);
}
- // Check if enemy is destroyed
- if (enemy.health <= 0) {
- // Create explosion effect when probedroid is destroyed by water
- waterExplosion = game.addChild(LK.getAsset('Explosion', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: enemy.x,
- y: enemy.y,
- scaleX: 0.3,
- scaleY: 0.3
- })); // Animate explosion with tween
- tween(waterExplosion, {
- scaleX: 1.2,
- scaleY: 1.2,
- alpha: 0
- }, {
- duration: 1000,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- waterExplosion.destroy();
- }
- });
- enemy.destroy();
- enemies.splice(i, 1);
- // Give player money for destroying enemy
- playerCash += 5;
- cashText.setText('Cash: $' + playerCash);
- // Award 50 points for kill
- playerScore += 50;
- LK.setScore(playerScore);
- if (window.scoreText) {
- window.scoreText.setText('Score: ' + playerScore);
- }
- // Track wave 1 completion
- if (currentWave === 1) {
- wave1EnemiesCompleted++;
- } else if (currentWave === 2) {
- wave2EnemiesCompleted++;
- }
- i--; // Adjust index since we removed an enemy
- return 0; // break
- // Exit tower loop for this enemy
+ // Track wave 1 completion
+ if (currentWave === 1) {
+ wave1EnemiesCompleted++;
+ } else if (currentWave === 2) {
+ wave2EnemiesCompleted++;
}
+ i--; // Adjust index since we removed an enemy
+ return; // Exit function for this enemy
}
}
}
}
- // Check if tower is a gas tower (Dog asset)
- else if (tower._assetId === 'Dog') {
- // Check tower health before any firing logic - if dead, skip all processing
- if (tower.health <= 0) {
- return 0; // continue - tower is dead, don't process further
- }
- // Check tower health before any firing logic - if dead, skip all processing
- if (tower.health <= 0) {
- return 0; // break - tower is dead, don't process further
- }
- // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
- if (Math.abs(enemy.y - tower.y) < 50) {
- // Check if enemy is to the right of the tower and within range of 600 pixels
- if (enemy.x > tower.x && enemy.x - tower.x < 600) {
- // Initialize fire rate tracking for this tower
- if (!tower.lastFireTime) {
- tower.lastFireTime = 0;
+ }
+ // Check if tower is a gas tower (Dog asset)
+ if (tower._assetId === 'Dog') {
+ // Check tower health before any firing logic - if dead, skip all processing
+ if (tower.health <= 0) {
+ continue; // Skip to next tower
+ }
+ // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
+ if (Math.abs(enemy.y - tower.y) < 50) {
+ // Check if enemy is to the right of the tower and within range of 600 pixels
+ if (enemy.x > tower.x && enemy.x - tower.x < 600) {
+ // Initialize fire rate tracking for this tower
+ if (!tower.lastFireTime) {
+ tower.lastFireTime = 0;
+ }
+ // Fire every 45 ticks (0.75 seconds at 60fps)
+ if (LK.ticks - tower.lastFireTime >= 45) {
+ tower.lastFireTime = LK.ticks;
+ // Switch dog asset to dog1 for fart animation
+ tower.destroy();
+ var fartingDog = game.addChild(LK.getAsset('Dog1', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: tower.x,
+ y: tower.y,
+ alpha: 1
+ })); // Copy tower properties to the new farting dog
+ fartingDog._assetId = 'Dog';
+ fartingDog.health = tower.health;
+ fartingDog.maxHealth = tower.maxHealth;
+ fartingDog.isBeingDamaged = tower.isBeingDamaged;
+ fartingDog.lastDamageTime = tower.lastDamageTime;
+ fartingDog.lastFireTime = tower.lastFireTime;
+ fartingDog.healthBarOutline = tower.healthBarOutline;
+ fartingDog.healthBar = tower.healthBar;
+ fartingDog.takeDamage = function (damage) {
+ fartingDog.health -= damage;
+ if (fartingDog.health <= 0) {
+ fartingDog.health = 0;
+ }
+ // Update health bar
+ var healthPercentage = fartingDog.health / fartingDog.maxHealth;
+ fartingDog.healthBar.scaleX = healthPercentage;
+ // Change color based on health
+ if (healthPercentage > 0.6) {
+ fartingDog.healthBar.tint = 0x00ff00; // Green
+ } else if (healthPercentage > 0.3) {
+ fartingDog.healthBar.tint = 0xffff00; // Yellow
+ } else {
+ fartingDog.healthBar.tint = 0xff0000; // Red
+ }
+ };
+ // Replace tower in towers array
+ for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
+ if (towers[towerIndex] === tower) {
+ towers[towerIndex] = fartingDog;
+ break;
+ }
}
- // Fire every 45 ticks (0.75 seconds at 60fps)
- if (LK.ticks - tower.lastFireTime >= 45) {
- tower.lastFireTime = LK.ticks;
- // Switch dog asset to dog1 for fart animation
- tower.destroy();
- fartingDog = game.addChild(LK.getAsset('Dog1', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: tower.x,
- y: tower.y,
- alpha: 1
- })); // Copy tower properties to the new farting dog
- fartingDog._assetId = 'Dog';
- fartingDog.health = tower.health;
- fartingDog.maxHealth = tower.maxHealth;
- fartingDog.isBeingDamaged = tower.isBeingDamaged;
- fartingDog.lastDamageTime = tower.lastDamageTime;
- fartingDog.lastFireTime = tower.lastFireTime;
- fartingDog.healthBarOutline = tower.healthBarOutline;
- fartingDog.healthBar = tower.healthBar;
- fartingDog.takeDamage = function (damage) {
- fartingDog.health -= damage;
- if (fartingDog.health <= 0) {
- fartingDog.health = 0;
+ // Create gas cloud visual
+ var gasCloud = game.addChild(LK.getAsset('GasCloud', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: tower.x + 150,
+ // Position gas cloud 100 pixels further left when dog farts
+ y: tower.y,
+ scaleX: 1.5,
+ scaleY: 1.5,
+ alpha: 0.6,
+ tint: 0x90EE90
+ })); // Animate gas cloud expanding and fading
+ tween(gasCloud, {
+ scaleX: 2.5,
+ scaleY: 2.5,
+ alpha: 0.2
+ }, {
+ duration: 1000,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ gasCloud.destroy();
+ }
+ });
+ // Switch back to normal dog after 500ms
+ LK.setTimeout(function () {
+ // Check if farting dog is still alive before replacing
+ if (fartingDog.health <= 0) {
+ // Farting dog is dead, don't replace it, just destroy it
+ // Remove health bar components
+ if (fartingDog.healthBarOutline) {
+ fartingDog.healthBarOutline.destroy();
}
- // Update health bar
- var healthPercentage = fartingDog.health / fartingDog.maxHealth;
- fartingDog.healthBar.scaleX = healthPercentage;
- // Change color based on health
- if (healthPercentage > 0.6) {
- fartingDog.healthBar.tint = 0x00ff00; // Green
- } else if (healthPercentage > 0.3) {
- fartingDog.healthBar.tint = 0xffff00; // Yellow
- } else {
- fartingDog.healthBar.tint = 0xff0000; // Red
+ if (fartingDog.healthBar) {
+ fartingDog.healthBar.destroy();
}
- };
- // Replace tower in towers array
- for (towerIndex = 0; towerIndex < towers.length; towerIndex++) {
- if (towers[towerIndex] === tower) {
- towers[towerIndex] = fartingDog;
+ fartingDog.destroy();
+ // Remove from towers array
+ for (var towerIndex = towers.length - 1; towerIndex >= 0; towerIndex--) {
+ if (towers[towerIndex] === fartingDog) {
+ towers.splice(towerIndex, 1);
+ break;
+ }
+ }
+ return;
+ }
+ // Check if fartingDog still exists in towers array before replacing
+ var fartingDogExists = false;
+ for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
+ if (towers[towerIndex] === fartingDog) {
+ fartingDogExists = true;
break;
}
}
- // Create gas cloud visual
- gasCloud = game.addChild(LK.getAsset('GasCloud', {
+ if (!fartingDogExists) {
+ // Farting dog was already destroyed, don't create replacement
+ return;
+ }
+ fartingDog.destroy();
+ var normalDog = game.addChild(LK.getAsset('Dog', {
anchorX: 0.5,
anchorY: 0.5,
- x: tower.x + 150,
- // Position gas cloud 100 pixels further left when dog farts
- y: tower.y,
- scaleX: 1.5,
- scaleY: 1.5,
- alpha: 0.6,
- tint: 0x90EE90
- })); // Animate gas cloud expanding and fading
- tween(gasCloud, {
- scaleX: 2.5,
- scaleY: 2.5,
- alpha: 0.2
- }, {
- duration: 1000,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- gasCloud.destroy();
+ x: fartingDog.x,
+ y: fartingDog.y,
+ alpha: 1
+ }));
+ // Copy properties back to normal dog
+ normalDog._assetId = 'Dog';
+ normalDog.health = fartingDog.health;
+ normalDog.maxHealth = fartingDog.maxHealth;
+ normalDog.isBeingDamaged = fartingDog.isBeingDamaged;
+ normalDog.lastDamageTime = fartingDog.lastDamageTime;
+ normalDog.lastFireTime = fartingDog.lastFireTime;
+ normalDog.healthBarOutline = fartingDog.healthBarOutline;
+ normalDog.healthBar = fartingDog.healthBar;
+ normalDog.takeDamage = fartingDog.takeDamage;
+ // Check if normal dog should be destroyed immediately after replacement
+ if (normalDog.health <= 0) {
+ // Remove health bar components
+ if (normalDog.healthBarOutline) {
+ normalDog.healthBarOutline.destroy();
}
- });
- // Switch back to normal dog after 500ms
- LK.setTimeout(function () {
- // Check if farting dog is still alive before replacing
- if (fartingDog.health <= 0) {
- // Farting dog is dead, don't replace it, just destroy it
- // Remove health bar components
- if (fartingDog.healthBarOutline) {
- fartingDog.healthBarOutline.destroy();
- }
- if (fartingDog.healthBar) {
- fartingDog.healthBar.destroy();
- }
- fartingDog.destroy();
- // Remove from towers array
- for (var towerIndex = towers.length - 1; towerIndex >= 0; towerIndex--) {
- if (towers[towerIndex] === fartingDog) {
- towers.splice(towerIndex, 1);
- break;
- }
- }
- return;
+ if (normalDog.healthBar) {
+ normalDog.healthBar.destroy();
}
- // Check if fartingDog still exists in towers array before replacing
- var fartingDogExists = false;
- for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
+ normalDog.destroy();
+ // Remove from towers array
+ for (var towerIndex = towers.length - 1; towerIndex >= 0; towerIndex--) {
if (towers[towerIndex] === fartingDog) {
- fartingDogExists = true;
+ towers.splice(towerIndex, 1);
break;
}
}
- if (!fartingDogExists) {
- // Farting dog was already destroyed, don't create replacement
- return;
- }
- fartingDog.destroy();
- var normalDog = game.addChild(LK.getAsset('Dog', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: fartingDog.x,
- y: fartingDog.y,
- alpha: 1
- }));
- // Copy properties back to normal dog
- normalDog._assetId = 'Dog';
- normalDog.health = fartingDog.health;
- normalDog.maxHealth = fartingDog.maxHealth;
- normalDog.isBeingDamaged = fartingDog.isBeingDamaged;
- normalDog.lastDamageTime = fartingDog.lastDamageTime;
- normalDog.lastFireTime = fartingDog.lastFireTime;
- normalDog.healthBarOutline = fartingDog.healthBarOutline;
- normalDog.healthBar = fartingDog.healthBar;
- normalDog.takeDamage = fartingDog.takeDamage;
- // Check if normal dog should be destroyed immediately after replacement
- if (normalDog.health <= 0) {
- // Remove health bar components
- if (normalDog.healthBarOutline) {
- normalDog.healthBarOutline.destroy();
- }
- if (normalDog.healthBar) {
- normalDog.healthBar.destroy();
- }
- normalDog.destroy();
- // Remove from towers array
- for (var towerIndex = towers.length - 1; towerIndex >= 0; towerIndex--) {
- if (towers[towerIndex] === fartingDog) {
- towers.splice(towerIndex, 1);
- break;
- }
- }
- return;
- }
- // Replace in towers array
- for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
- if (towers[towerIndex] === fartingDog) {
- towers[towerIndex] = normalDog;
- break;
- }
- }
- }, 500);
- // Check if enemy is affected by gas (farts don't affect robots, drones, or probe droids)
- isAffectedByGas = true; // Check enemy asset ID to determine if it's a robot/mechanical enemy
- if (enemy.attachedAssets && enemy.attachedAssets.length > 0) {
- enemyAssetId = enemy.attachedAssets[0].assetId;
- if (enemyAssetId === 'Robot' || enemyAssetId === 'Drone' || enemyAssetId === 'SpaceDrone' || enemyAssetId === 'Probedroid') {
- isAffectedByGas = false;
- }
+ return;
}
- // Only deal damage if enemy is affected by gas
- if (isAffectedByGas) {
- // Deal damage to enemy
- enemy.takeDamage(2);
- // Robot fires back when hit by gas tower
- if (enemy.fireBackAtTower) {
- enemy.fireBackAtTower(fartingDog);
+ // Replace in towers array
+ for (var towerIndex = 0; towerIndex < towers.length; towerIndex++) {
+ if (towers[towerIndex] === fartingDog) {
+ towers[towerIndex] = normalDog;
+ break;
}
- // Check if enemy is destroyed
- if (enemy.health <= 0) {
- enemy.destroy();
- enemies.splice(i, 1);
- // Give player money for destroying enemy
- playerCash += 5;
- cashText.setText('Cash: $' + playerCash);
- // Award 50 points for kill
- playerScore += 50;
- LK.setScore(playerScore);
- if (window.scoreText) {
- window.scoreText.setText('Score: ' + playerScore);
- }
- // Track wave 1 completion
- if (currentWave === 1) {
- wave1EnemiesCompleted++;
- } else if (currentWave === 2) {
- wave2EnemiesCompleted++;
- }
- i--; // Adjust index since we removed an enemy
- return 0; // break
- // Exit tower loop for this enemy
- }
}
+ }, 500);
+ // Check if enemy is affected by gas (farts don't affect robots, drones, or probe droids)
+ var isAffectedByGas = true; // Check enemy asset ID to determine if it's a robot/mechanical enemy
+ if (enemy.attachedAssets && enemy.attachedAssets.length > 0) {
+ var enemyAssetId = enemy.attachedAssets[0].assetId;
+ if (enemyAssetId === 'Robot' || enemyAssetId === 'Drone' || enemyAssetId === 'SpaceDrone' || enemyAssetId === 'Probedroid') {
+ isAffectedByGas = false;
+ }
}
- }
- }
- }
- // Check if tower is a bug zapper (electric tower)
- else if (tower._assetId === 'Bugzapper') {
- // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
- if (Math.abs(enemy.y - tower.y) < 50) {
- // Check if enemy is to the right of the tower and within range of 800 pixels
- if (enemy.x > tower.x && enemy.x - tower.x < 800) {
- // Initialize zap tracking for this tower
- if (!tower.activeZap) {
- tower.activeZap = null;
- tower.zapStartTime = 0;
- }
- // Start prolonged zap attack if not already active
- if (!tower.activeZap) {
- // Start zap animation
- var _animateZap = function animateZap() {
- if (tower.activeZap) {
- tween(tower.activeZap, {
- alpha: 0.3
- }, {
- duration: 200,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- if (tower.activeZap) {
- tween(tower.activeZap, {
- alpha: 0.9
- }, {
- duration: 200,
- easing: tween.easeInOut,
- onFinish: _animateZap
- });
- }
- }
- });
- }
- };
- tower.zapStartTime = LK.ticks;
- // Create prolonged zap3 visual
- tower.activeZap = game.addChild(LK.getAsset('Zap3', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: tower.x + 400,
- y: tower.y,
- scaleX: 1.0,
- scaleY: 1.0,
- alpha: 0.9,
- tint: 0x00FFFF
- }));
- _animateZap();
- }
- // Deal damage continuously every 15 ticks while zapping
- if (tower.activeZap && LK.ticks - tower.zapStartTime >= 15 && (LK.ticks - tower.zapStartTime) % 15 === 0) {
+ // Only deal damage if enemy is affected by gas
+ if (isAffectedByGas) {
// Deal damage to enemy
- enemy.takeDamage(20);
- // Make electric effect visible when hit by electricity
- enemy.showElectricEffect();
- // Robot fires back when hit by electric tower
+ enemy.takeDamage(2);
+ // Robot fires back when hit by gas tower
if (enemy.fireBackAtTower) {
- enemy.fireBackAtTower(tower);
+ enemy.fireBackAtTower(fartingDog);
}
// Check if enemy is destroyed
if (enemy.health <= 0) {
- // Create explosive effect when probedroid is destroyed by bugzapper
- var bugzapperExplosion = game.addChild(LK.getAsset('Explosion', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: enemy.x,
- y: enemy.y,
- scaleX: 0.3,
- scaleY: 0.3
- }));
- // Animate explosion with tween
- tween(bugzapperExplosion, {
- scaleX: 1.2,
- scaleY: 1.2,
- alpha: 0
- }, {
- duration: 1000,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- bugzapperExplosion.destroy();
- }
- });
enemy.destroy();
enemies.splice(i, 1);
// Give player money for destroying enemy
playerCash += 5;
@@ -2608,251 +2496,338 @@
} else if (currentWave === 2) {
wave2EnemiesCompleted++;
}
i--; // Adjust index since we removed an enemy
- return 0; // break
- // Exit tower loop for this enemy
+ return; // Exit function for this enemy
}
}
- } else {
- // Enemy is not in range, stop zap attack
- if (tower.activeZap) {
- tower.activeZap.destroy();
- tower.activeZap = null;
- tower.zapStartTime = 0;
- }
}
- } else {
- // Enemy is not on same line, stop zap attack
- if (tower.activeZap) {
- tower.activeZap.destroy();
+ }
+ }
+ }
+ // Check if tower is a bug zapper (electric tower)
+ if (tower._assetId === 'Bugzapper') {
+ // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
+ if (Math.abs(enemy.y - tower.y) < 50) {
+ // Check if enemy is to the right of the tower and within range of 800 pixels
+ if (enemy.x > tower.x && enemy.x - tower.x < 800) {
+ // Initialize zap tracking for this tower
+ if (!tower.activeZap) {
tower.activeZap = null;
tower.zapStartTime = 0;
}
- }
- }
- // Check if tower is a fire tower (Fireworks asset)
- else if (tower._assetId === 'Fireworks') {
- // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
- if (Math.abs(enemy.y - tower.y) < 50) {
- // Check if enemy is to the right of the tower and within range of 1000 pixels
- if (enemy.x > tower.x && enemy.x - tower.x < 1000) {
- // Initialize fire rate tracking for this tower
- if (!tower.lastFireTime) {
- tower.lastFireTime = 0;
- }
- // Fire every 60 ticks (1 second at 60fps)
- if (LK.ticks - tower.lastFireTime >= 60) {
- // Store fireball properties
- // Add fire animation to fireball
- var animateFireball = function animateFireball(fireball) {
- // Pulsing scale animation
- function startFireballPulse() {
- tween(fireball, {
- scaleX: 0.6,
- scaleY: 0.6,
- alpha: 0.8
- }, {
- duration: 200,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(fireball, {
- scaleX: 0.5,
- scaleY: 0.5,
- alpha: 1.0
+ // Start prolonged zap attack if not already active
+ if (!tower.activeZap) {
+ // Start zap animation
+ var _animateZap = function animateZap() {
+ if (tower.activeZap) {
+ tween(tower.activeZap, {
+ alpha: 0.3
+ }, {
+ duration: 200,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ if (tower.activeZap) {
+ tween(tower.activeZap, {
+ alpha: 0.9
}, {
duration: 200,
easing: tween.easeInOut,
- onFinish: startFireballPulse
+ onFinish: _animateZap
});
}
- });
- }
- // Flickering alpha animation
- function startFireballFlicker() {
- tween(fireball, {
- alpha: 0.7
- }, {
- duration: 150,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(fireball, {
- alpha: 1.0
- }, {
- duration: 100,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- LK.setTimeout(function () {
- if (fireball && fireball.parent) {
- startFireballFlicker();
- }
- }, Math.random() * 300 + 100);
- }
- });
- }
- });
- }
- // Start all fire animations
- startFireballPulse();
- startFireballFlicker();
- }; // Start fire animation for this fireball
- tower.lastFireTime = LK.ticks;
- // Create fireball projectile
- fireball = game.addChild(LK.getAsset('Fireball', {
+ }
+ });
+ }
+ };
+ tower.zapStartTime = LK.ticks;
+ // Create prolonged zap3 visual
+ tower.activeZap = game.addChild(LK.getAsset('Zap3', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: tower.x + 400,
+ y: tower.y,
+ scaleX: 1.0,
+ scaleY: 1.0,
+ alpha: 0.9,
+ tint: 0x00FFFF
+ }));
+ _animateZap();
+ }
+ // Deal damage continuously every 15 ticks while zapping
+ if (tower.activeZap && LK.ticks - tower.zapStartTime >= 15 && (LK.ticks - tower.zapStartTime) % 15 === 0) {
+ // Deal damage to enemy
+ enemy.takeDamage(20);
+ // Make electric effect visible when hit by electricity
+ enemy.showElectricEffect();
+ // Robot fires back when hit by electric tower
+ if (enemy.fireBackAtTower) {
+ enemy.fireBackAtTower(tower);
+ }
+ // Check if enemy is destroyed
+ if (enemy.health <= 0) {
+ // Create explosive effect when probedroid is destroyed by bugzapper
+ var bugzapperExplosion = game.addChild(LK.getAsset('Explosion', {
anchorX: 0.5,
anchorY: 0.5,
- x: tower.x + 50,
- y: tower.y,
- scaleX: 0.5,
- scaleY: 0.5,
- rotation: 35 * Math.PI / 180 // Rotate 35 degrees to the right
+ x: enemy.x,
+ y: enemy.y,
+ scaleX: 0.3,
+ scaleY: 0.3
}));
- animateFireball(fireball);
- fireball.targetX = enemy.x;
- fireball.targetY = enemy.y;
- fireball.speed = 8;
- fireball.damage = 15;
- // Calculate direction to enemy
- deltaX = enemy.x - fireball.x;
- deltaY = enemy.y - fireball.y;
- distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
- fireball.velocityX = deltaX / distance * fireball.speed;
- fireball.velocityY = deltaY / distance * fireball.speed;
- // Animate fireball movement
- fireballInterval = LK.setInterval(function () {
- fireball.x += fireball.velocityX;
- fireball.y += fireball.velocityY;
- // Check if fireball hit any enemy
- for (var enemyIndex = 0; enemyIndex < enemies.length; enemyIndex++) {
- var targetEnemy = enemies[enemyIndex];
- var fireballDistance = Math.sqrt(Math.pow(fireball.x - targetEnemy.x, 2) + Math.pow(fireball.y - targetEnemy.y, 2));
- if (fireballDistance < 80) {
- // Hit enemy - deal damage
- targetEnemy.takeDamage(fireball.damage);
- // Robot fires back when hit by fire tower
- if (targetEnemy.fireBackAtTower) {
- targetEnemy.fireBackAtTower(tower);
- }
- // Create explosion effect
- var explosion = game.addChild(LK.getAsset('Explosion', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: fireball.x,
- y: fireball.y,
- scaleX: 0.3,
- scaleY: 0.3
- }));
- // Animate explosion
- tween(explosion, {
- scaleX: 0.8,
- scaleY: 0.8,
- alpha: 0
+ // Animate explosion with tween
+ tween(bugzapperExplosion, {
+ scaleX: 1.2,
+ scaleY: 1.2,
+ alpha: 0
+ }, {
+ duration: 1000,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ bugzapperExplosion.destroy();
+ }
+ });
+ enemy.destroy();
+ enemies.splice(i, 1);
+ // Give player money for destroying enemy
+ playerCash += 5;
+ cashText.setText('Cash: $' + playerCash);
+ // Award 50 points for kill
+ playerScore += 50;
+ LK.setScore(playerScore);
+ if (window.scoreText) {
+ window.scoreText.setText('Score: ' + playerScore);
+ }
+ // Track wave 1 completion
+ if (currentWave === 1) {
+ wave1EnemiesCompleted++;
+ } else if (currentWave === 2) {
+ wave2EnemiesCompleted++;
+ }
+ i--; // Adjust index since we removed an enemy
+ return; // Exit function for this enemy
+ }
+ }
+ } else {
+ // Enemy is not in range, stop zap attack
+ if (tower.activeZap) {
+ tower.activeZap.destroy();
+ tower.activeZap = null;
+ tower.zapStartTime = 0;
+ }
+ }
+ } else {
+ // Enemy is not on same line, stop zap attack
+ if (tower.activeZap) {
+ tower.activeZap.destroy();
+ tower.activeZap = null;
+ tower.zapStartTime = 0;
+ }
+ }
+ }
+ // Check if tower is a fire tower (Fireworks asset)
+ if (tower._assetId === 'Fireworks') {
+ // Check if enemy is on the same horizontal line as the tower (within 50 pixels tolerance)
+ if (Math.abs(enemy.y - tower.y) < 50) {
+ // Check if enemy is to the right of the tower and within range of 1000 pixels
+ if (enemy.x > tower.x && enemy.x - tower.x < 1000) {
+ // Initialize fire rate tracking for this tower
+ if (!tower.lastFireTime) {
+ tower.lastFireTime = 0;
+ }
+ // Fire every 60 ticks (1 second at 60fps)
+ if (LK.ticks - tower.lastFireTime >= 60) {
+ // Store fireball properties
+ // Add fire animation to fireball
+ var animateFireball = function animateFireball(fireball) {
+ // Pulsing scale animation
+ function startFireballPulse() {
+ tween(fireball, {
+ scaleX: 0.6,
+ scaleY: 0.6,
+ alpha: 0.8
+ }, {
+ duration: 200,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(fireball, {
+ scaleX: 0.5,
+ scaleY: 0.5,
+ alpha: 1.0
}, {
- duration: 500,
- easing: tween.easeOut,
+ duration: 200,
+ easing: tween.easeInOut,
+ onFinish: startFireballPulse
+ });
+ }
+ });
+ }
+ // Flickering alpha animation
+ function startFireballFlicker() {
+ tween(fireball, {
+ alpha: 0.7
+ }, {
+ duration: 150,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(fireball, {
+ alpha: 1.0
+ }, {
+ duration: 100,
+ easing: tween.easeInOut,
onFinish: function onFinish() {
- explosion.destroy();
+ LK.setTimeout(function () {
+ if (fireball && fireball.parent) {
+ startFireballFlicker();
+ }
+ }, Math.random() * 300 + 100);
}
});
- // Check if enemy is destroyed
- if (targetEnemy.health <= 0) {
- // Check if this is a mechanical enemy that should have explosion effect
- var isMechanicalEnemy = false;
- if (targetEnemy.attachedAssets && targetEnemy.attachedAssets.length > 0) {
- var enemyAssetId = targetEnemy.attachedAssets[0].assetId;
- if (enemyAssetId === 'Robot' || enemyAssetId === 'Drone' || enemyAssetId === 'SpaceDrone' || enemyAssetId === 'Probedroid' || enemyAssetId === 'UFO') {
+ }
+ });
+ }
+ // Start all fire animations
+ startFireballPulse();
+ startFireballFlicker();
+ }; // Start fire animation for this fireball
+ tower.lastFireTime = LK.ticks;
+ // Create fireball projectile
+ var fireball = game.addChild(LK.getAsset('Fireball', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: tower.x + 50,
+ y: tower.y,
+ scaleX: 0.5,
+ scaleY: 0.5,
+ rotation: 35 * Math.PI / 180 // Rotate 35 degrees to the right
+ }));
+ animateFireball(fireball);
+ fireball.targetX = enemy.x;
+ fireball.targetY = enemy.y;
+ fireball.speed = 8;
+ fireball.damage = 15;
+ // Calculate direction to enemy
+ var deltaX = enemy.x - fireball.x;
+ var deltaY = enemy.y - fireball.y;
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ fireball.velocityX = deltaX / distance * fireball.speed;
+ fireball.velocityY = deltaY / distance * fireball.speed;
+ // Animate fireball movement
+ var fireballInterval = LK.setInterval(function () {
+ fireball.x += fireball.velocityX;
+ fireball.y += fireball.velocityY;
+ // Check if fireball hit any enemy
+ for (var enemyIndex = 0; enemyIndex < enemies.length; enemyIndex++) {
+ var targetEnemy = enemies[enemyIndex];
+ var fireballDistance = Math.sqrt(Math.pow(fireball.x - targetEnemy.x, 2) + Math.pow(fireball.y - targetEnemy.y, 2));
+ if (fireballDistance < 80) {
+ // Hit enemy - deal damage
+ targetEnemy.takeDamage(fireball.damage);
+ // Robot fires back when hit by fire tower
+ if (targetEnemy.fireBackAtTower) {
+ targetEnemy.fireBackAtTower(tower);
+ }
+ // Create explosion effect
+ var explosion = game.addChild(LK.getAsset('Explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: fireball.x,
+ y: fireball.y,
+ scaleX: 0.3,
+ scaleY: 0.3
+ }));
+ // Animate explosion
+ tween(explosion, {
+ scaleX: 0.8,
+ scaleY: 0.8,
+ alpha: 0
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ explosion.destroy();
+ }
+ });
+ // Check if enemy is destroyed
+ if (targetEnemy.health <= 0) {
+ // Check if this is a mechanical enemy that should have explosion effect
+ var isMechanicalEnemy = false;
+ if (targetEnemy.attachedAssets && targetEnemy.attachedAssets.length > 0) {
+ var enemyAssetId = targetEnemy.attachedAssets[0].assetId;
+ if (enemyAssetId === 'Robot' || enemyAssetId === 'Drone' || enemyAssetId === 'SpaceDrone' || enemyAssetId === 'Probedroid' || enemyAssetId === 'UFO') {
+ isMechanicalEnemy = true;
+ }
+ }
+ // For probe droids (current enemy type), always show explosion
+ if (!isMechanicalEnemy) {
+ // Check if this is a probe droid by checking the asset used
+ var enemyChildren = targetEnemy.children;
+ for (var childIndex = 0; childIndex < enemyChildren.length; childIndex++) {
+ var child = enemyChildren[childIndex];
+ if (child.assetId === 'Probedroid') {
isMechanicalEnemy = true;
+ break;
}
}
- // For probe droids (current enemy type), always show explosion
- if (!isMechanicalEnemy) {
- // Check if this is a probe droid by checking the asset used
- var enemyChildren = targetEnemy.children;
- for (var childIndex = 0; childIndex < enemyChildren.length; childIndex++) {
- var child = enemyChildren[childIndex];
- if (child.assetId === 'Probedroid') {
- isMechanicalEnemy = true;
- break;
- }
+ }
+ // Create explosion effect for mechanical enemies
+ if (isMechanicalEnemy) {
+ var mechanicalExplosion = game.addChild(LK.getAsset('Explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: targetEnemy.x,
+ y: targetEnemy.y,
+ scaleX: 0.2,
+ scaleY: 0.2
+ }));
+ // Animate explosion with tween
+ tween(mechanicalExplosion, {
+ scaleX: 1.0,
+ scaleY: 1.0,
+ alpha: 0
+ }, {
+ duration: 800,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ mechanicalExplosion.destroy();
}
- }
- // Create explosion effect for mechanical enemies
- if (isMechanicalEnemy) {
- var mechanicalExplosion = game.addChild(LK.getAsset('Explosion', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: targetEnemy.x,
- y: targetEnemy.y,
- scaleX: 0.2,
- scaleY: 0.2
- }));
- // Animate explosion with tween
- tween(mechanicalExplosion, {
- scaleX: 1.0,
- scaleY: 1.0,
- alpha: 0
- }, {
- duration: 800,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- mechanicalExplosion.destroy();
- }
- });
- }
- targetEnemy.destroy();
- enemies.splice(enemyIndex, 1);
- // Give player money for destroying enemy
- playerCash += 5;
- cashText.setText('Cash: $' + playerCash);
- // Award 50 points for kill
- playerScore += 50;
- LK.setScore(playerScore);
- if (window.scoreText) {
- window.scoreText.setText('Score: ' + playerScore);
- }
- // Track wave 1 completion
- if (currentWave === 1) {
- wave1EnemiesCompleted++;
- } else if (currentWave === 2) {
- wave2EnemiesCompleted++;
- }
+ });
}
- // Remove fireball
- LK.clearInterval(fireballInterval);
- fireball.destroy();
- return;
+ targetEnemy.destroy();
+ enemies.splice(enemyIndex, 1);
+ // Give player money for destroying enemy
+ playerCash += 5;
+ cashText.setText('Cash: $' + playerCash);
+ // Award 50 points for kill
+ playerScore += 50;
+ LK.setScore(playerScore);
+ if (window.scoreText) {
+ window.scoreText.setText('Score: ' + playerScore);
+ }
+ // Track wave 1 completion
+ if (currentWave === 1) {
+ wave1EnemiesCompleted++;
+ } else if (currentWave === 2) {
+ wave2EnemiesCompleted++;
+ }
}
- }
- // Check if fireball went off screen
- if (fireball.x > 2048 + 100 || fireball.x < -100 || fireball.y > 2732 + 100 || fireball.y < -100) {
+ // Remove fireball
LK.clearInterval(fireballInterval);
fireball.destroy();
+ return;
}
- }, 16); // ~60fps
- return 0; // break
- // Found an enemy in range
- }
+ }
+ // Check if fireball went off screen
+ if (fireball.x > 2048 + 100 || fireball.x < -100 || fireball.y > 2732 + 100 || fireball.y < -100) {
+ LK.clearInterval(fireballInterval);
+ fireball.destroy();
+ }
+ }, 16); // ~60fps
+ break; // Found an enemy in range, no need to check other towers of this type
}
}
}
- },
- tower,
- waterSquirt,
- waterExplosion,
- fartingDog,
- towerIndex,
- gasCloud,
- isAffectedByGas,
- enemyAssetId,
- fireball,
- deltaX,
- deltaY,
- distance,
- fireballInterval,
- _ret;
- for (var j = 0; j < towers.length; j++) {
- _ret = _loop();
- if (_ret === 0) break;
+ }
}
// Check collision with fan blades first (before tower collision)
for (var k = 0; k < towers.length; k++) {
var tower = towers[k];
White circle with two eyes, seen from above.. In-Game asset. 2d. High contrast. No shadows
White simple circular enemy seen from above, black outline. Black eyes, with a single shield in-font of it. Black and white only. Blue background.
White circle with black outline. Blue background.. In-Game asset. 2d. High contrast. No shadows
Fire hydrant. In-Game asset. 2d. High contrast. No shadows
Water spraying forward In-Game asset. 2d. High contrast. No shadows
Fan blades symmetrical. In-Game asset. 2d. High contrast. No shadows
Plasma ball. In-Game asset. 2d. High contrast. No shadows
Make picture transparent
Bug zapper on a pole. In-Game asset. 2d. High contrast. No shadows
Probe droid. In-Game asset. 2d. High contrast. No shadows
Space drone. In-Game asset. 2d. High contrast. No shadows
Remove propellers and make them symmetrical
Add more rows to gris
Make this picture with more night sky above the city skyline
Change text to say wave 1
Make button grey and say ??????
Make it say Wave 2
Make it say wave 3
Make it say wave 4
WiFi symbol. In-Game asset. 2d. High contrast. No shadows
explosion effect In-Game asset. 2d. High contrast. No shadows
Make it say wave 5
Remove laser beam
Make button hot pink and say 'Reflect $20'
Make button blue and change text to say 'Water $10' in a retro style font
Make button green and change test to say 'Gas $20'
Make button orange and change test to say 'Fire $40'
Make button very light blue and change test to say 'Air $30'
Make button gold and change text to say 'Electric $50'
Make button purple and change test to say 'Plasma $60'
Make button Teal and change test to say 'Slingshot $100'
Make button silver and change test to say 'WiFi $150'
Remove little kick so it's just a smooth oval shape
Make grid 6x8
Hand should be holding the gun by the Handle
Place laser cannon in both hands holding it like a shotgun
Make it stand still
Remove the words 5g
Make sure spelling in speech bubble is correct "We have found the earthlings weakness"
Fix the spelling of the word Planet
Slingshot. In-Game asset. 2d. High contrast. No shadows
Red button with a 'X' on it. In-Game asset. 2d. High contrast. No shadows
Green button with a tick on it
Fix the spelling of word saw
Display icon that says score sci fi comic style font. In-Game asset. 2d. High contrast. No shadows
Display icon that says cash sci fi comic style font. In-Game asset. 2d. High contrast. No shadows
Display icon that says X2 speed sci fi comic style font. In-Game asset. 2d. High contrast. No shadows
Make it say x1 speed and make the x1 blue
Canvasser
Sound effect
Alien1
Sound effect
Alien2
Sound effect
Alien3
Sound effect
Intro
Music
Probedroid
Sound effect
Probedroid2
Sound effect
Towerselect
Sound effect
Water
Sound effect
Explosion
Sound effect
Confirm
Sound effect
Fart
Sound effect
Electric
Sound effect
Fireball
Sound effect