/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BossEnemy = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bossEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 300;
self.speed = 2.5; // Increased speed for faster approach
self.damage = 50;
self.waveNumber = currentWave;
self.clawAttackCooldown = 0;
self.clawAttackRange = 150;
self.clawAttackRate = 120; // 2 seconds between claw attacks
self.waveAttackCooldown = 0;
self.waveAttackRange = 400; // Longer range for wave attacks
self.waveAttackRate = 180; // 3 seconds between wave attacks
// Visual effect for claw attack
self.clawEffect = null;
// Animation properties
self.animationOffset = Math.random() * Math.PI * 2;
self.breathingSpeed = 0.08;
self.intimidationFactor = 1;
self.update = function () {
// Add scaling pulse animation - grow and shrink (more intense for boss)
var scalePulse = self.intimidationFactor + Math.sin(LK.ticks * 0.08 + self.animationOffset) * 0.15;
graphics.scaleX = scalePulse;
graphics.scaleY = scalePulse;
// Add color pulsing for menacing effect
var pulseIntensity = Math.sin(LK.ticks * 0.1 + self.animationOffset) * 0.3 + 0.7;
if (graphics.tint === 0xFFFFFF || graphics.tint === undefined) {
graphics.tint = 0xFF0000;
}
if (player) {
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
// Move towards player with increased speed
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
// Claw attack logic
if (self.clawAttackCooldown > 0) {
self.clawAttackCooldown--;
}
// Wave attack logic
if (self.waveAttackCooldown > 0) {
self.waveAttackCooldown--;
}
// Prioritize wave attacks at medium range, claw attacks at close range
if (distanceToPlayer <= self.waveAttackRange && distanceToPlayer > self.clawAttackRange && self.waveAttackCooldown <= 0) {
self.performWaveAttack();
self.waveAttackCooldown = self.waveAttackRate;
} else if (distanceToPlayer <= self.clawAttackRange && self.clawAttackCooldown <= 0) {
self.performClawAttack();
self.clawAttackCooldown = self.clawAttackRate;
}
}
};
self.performWaveAttack = function () {
// Create multiple cutting wave projectiles
var angleToPlayer = Math.atan2(player.y - self.y, player.x - self.x);
// Create 3 waves spread in a cone
for (var i = 0; i < 3; i++) {
var waveAngle = angleToPlayer + (i - 1) * 0.3; // Spread waves in cone
var wave = gameCamera.addChild(new Container());
// Create wave visual
var waveGraphic = wave.attachAsset('waveAttack', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 1.2
});
waveGraphic.tint = 0xFF3333;
waveGraphic.alpha = 0.95;
wave.rotation = waveAngle;
wave.x = self.x;
wave.y = self.y;
wave.velocityX = Math.cos(waveAngle) * 6;
wave.velocityY = Math.sin(waveAngle) * 6;
wave.damage = self.damage * 0.8; // Slightly less damage than claw
wave.lifeTime = 0;
wave.maxLifeTime = 120; // 2 seconds at 60fps
// Add wave to bullets array for collision detection
if (!bossWaves) {
bossWaves = [];
}
bossWaves.push(wave);
// Add pulsing animation to wave
tween(waveGraphic, {
scaleX: 2.5,
alpha: 0.7
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(waveGraphic, {
scaleX: 2,
alpha: 0.9
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
}
// Visual effect at boss position
LK.effects.flashObject(self, 0xFF6666, 300);
LK.getSound('clawAttack').play(); // Reuse claw sound for waves
};
self.performClawAttack = function () {
// Create visual claw effect
if (self.clawEffect) {
self.clawEffect.destroy();
}
self.clawEffect = self.addChild(LK.getAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.5
}));
self.clawEffect.tint = 0xFF4444;
self.clawEffect.alpha = 0.8;
// Animate claw slash effect
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.clawEffect.rotation = angle;
tween(self.clawEffect, {
scaleX: 4,
scaleY: 1,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
if (self.clawEffect) {
self.clawEffect.destroy();
self.clawEffect = null;
}
}
});
// Deal damage to player if still in range
var currentDistance = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (currentDistance <= self.clawAttackRange) {
player.health -= self.damage;
LK.effects.flashObject(player, 0xFF0000, 500);
LK.getSound('clawAttack').play();
}
// Screen shake effect for dramatic impact
LK.effects.flashScreen(0xFF4444, 200);
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.damage = Bullet.prototype.baseDamage || 25;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var Corn = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('corn', {
anchorX: 0.5,
anchorY: 0.5
});
self.scoreValue = 10;
graphics.tint = 0xFFD700; // Golden corn color
// Add floating animation
self.floatOffset = Math.random() * Math.PI * 2;
self.baseY = 0;
self.update = function () {
if (self.baseY === 0) {
self.baseY = self.y;
}
self.y = self.baseY + Math.sin(LK.ticks * 0.1 + self.floatOffset) * 5;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 50;
self.speed = 1.5;
self.damage = 20;
self.waveNumber = currentWave;
// Animation properties
self.animationOffset = Math.random() * Math.PI * 2;
self.rotationSpeed = 0.02 + Math.random() * 0.02;
self.update = function () {
// Add scaling pulse animation - grow and shrink
var scalePulse = 1 + Math.sin(LK.ticks * 0.08 + self.animationOffset) * 0.1;
graphics.scaleX = scalePulse;
graphics.scaleY = scalePulse;
if (player) {
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
}
};
return self;
});
var MiniTurret = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
graphics.tint = 0x00FFFF;
self.shootCooldown = 0;
self.shootRate = 40; // Slower than player
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Auto-shoot at nearest enemy
if (self.shootCooldown <= 0 && enemies.length > 0) {
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var distance = Math.sqrt(Math.pow(enemies[i].x - self.x, 2) + Math.pow(enemies[i].y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemies[i];
}
}
if (nearestEnemy && nearestDistance < 350) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var angle = Math.atan2(nearestEnemy.y - self.y, nearestEnemy.x - self.x);
bullet.velocityX = Math.cos(angle) * 6;
bullet.velocityY = Math.sin(angle) * 6;
bullets.push(bullet);
gameCamera.addChild(bullet);
self.shootCooldown = self.shootRate;
LK.getSound('shoot').play();
}
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 4;
self.shootCooldown = 0;
self.shootRate = 20; // frames between shots
// Animation properties
self.animationOffset = Math.random() * Math.PI * 2;
self.baseY = 0;
self.isAnimating = false;
self.update = function () {
// Add scaling pulse animation - grow and shrink
var scalePulse = 1 + Math.sin(LK.ticks * 0.08 + self.animationOffset) * 0.1;
graphics.scaleX = scalePulse;
graphics.scaleY = scalePulse;
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Auto-shoot at nearest enemy
if (self.shootCooldown <= 0 && enemies.length > 0) {
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var distance = Math.sqrt(Math.pow(enemies[i].x - self.x, 2) + Math.pow(enemies[i].y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemies[i];
}
}
if (nearestEnemy && nearestDistance < 400) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var angle = Math.atan2(nearestEnemy.y - self.y, nearestEnemy.x - self.x);
bullet.velocityX = Math.cos(angle) * 8;
bullet.velocityY = Math.sin(angle) * 8;
bullets.push(bullet);
gameCamera.addChild(bullet);
self.shootCooldown = self.shootRate;
LK.getSound('shoot').play();
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0F1A2E // Dark night blue
});
/****
* Game Code
****/
// Game variables
var player;
var bullets = [];
var enemies = [];
var miniTurrets = [];
var cornDrops = [];
var bossWaves = [];
var currentWave = 1;
var enemiesRemaining = 0;
var waveStartDelay = 0;
var gameStarted = false;
var showingMenu = true;
var menuContainer = null;
var dragTarget = null;
var waveInProgress = false;
var showingPowerUpSelection = false;
var waveTimer = 0;
var waveTimeLimit = 0;
var enemySpawnTimer = 0;
var enemySpawnRate = 0;
var powerUpSelectionUI = null;
// Power-up indicators
var playerHealthIndicator = null;
var playerShootingIndicator = null;
var activePowerUps = {
healthUpgrades: 0,
shootingUpgrades: 0,
turretCount: 0
};
// Camera zoom variables
var gameCamera = null;
var currentZoom = 1;
var targetZoom = 2; // 2x zoom for better detail
var zoomTransitioning = false;
// Player movement variables
var targetPlayerX = 0;
var targetPlayerY = 0;
var playerMoveSpeed = 0.03; // Much slower movement for better control
// Create camera container for zoom functionality
gameCamera = game.addChild(new Container());
// Create nighttime farm scenery in top area
var farmSceneryContainer = gameCamera.addChild(new Container());
// Night sky gradient background
var skyBg = farmSceneryContainer.attachAsset('ground', {
anchorX: 0,
anchorY: 0,
scaleX: 10.24,
scaleY: 2
});
skyBg.x = 0;
skyBg.y = 0;
skyBg.tint = 0x1A2B4A; // Dark night blue
// Add some farm buildings silhouettes
var barn = farmSceneryContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0,
scaleX: 8,
scaleY: 6
});
barn.x = 300;
barn.y = 80;
barn.tint = 0x2C1810; // Dark barn color
var farmhouse = farmSceneryContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0,
scaleX: 6,
scaleY: 4
});
farmhouse.x = 1200;
farmhouse.y = 120;
farmhouse.tint = 0x3D2817; // Dark house color
// Add some trees silhouettes
for (var t = 0; t < 5; t++) {
var tree = farmSceneryContainer.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 1,
scaleX: 2,
scaleY: 3
});
tree.x = 150 + t * 350;
tree.y = 200;
tree.tint = 0x0D1B0D; // Very dark green for tree silhouettes
}
// Add stars
for (var s = 0; s < 20; s++) {
var star = farmSceneryContainer.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
star.x = Math.random() * 2048;
star.y = Math.random() * 180;
star.tint = 0xFFFFAA; // Yellowish white stars
}
// Arena bounds - zoomed in and repositioned for better gameplay
var arenaLeft = 300;
var arenaRight = 1748;
var arenaTop = 450;
var arenaBottom = 2300;
// Create corral ground background
var groundContainer = gameCamera.addChild(new Container());
var groundTileWidth = 200;
var groundTileHeight = 200;
var tilesX = Math.ceil((arenaRight - arenaLeft) / groundTileWidth);
var tilesY = Math.ceil((arenaBottom - arenaTop) / groundTileHeight);
for (var gx = 0; gx < tilesX; gx++) {
for (var gy = 0; gy < tilesY; gy++) {
var groundTile = groundContainer.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
groundTile.x = arenaLeft + gx * groundTileWidth;
groundTile.y = arenaTop + gy * groundTileHeight;
// Add nighttime ground colors
if ((gx + gy) % 2 === 0) {
groundTile.tint = 0x3A5F3A; // Dark nighttime grass green
} else {
groundTile.tint = 0x2F4F2F; // Slightly different dark green
}
}
}
// Create fence borders
var fenceContainer = gameCamera.addChild(new Container());
// Top fence
var topFenceLength = Math.ceil((arenaRight - arenaLeft) / 100);
for (var i = 0; i < topFenceLength; i++) {
var topFence = fenceContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0.5
});
topFence.x = arenaLeft + i * 100;
topFence.y = arenaTop - 10;
}
// Bottom fence
for (var i = 0; i < topFenceLength; i++) {
var bottomFence = fenceContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0.5
});
bottomFence.x = arenaLeft + i * 100;
bottomFence.y = arenaBottom + 10;
}
// Left fence (vertical)
var leftFenceLength = Math.ceil((arenaBottom - arenaTop) / 100);
for (var i = 0; i < leftFenceLength; i++) {
var leftFence = fenceContainer.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0,
scaleX: 0.2,
scaleY: 5
});
leftFence.x = arenaLeft - 10;
leftFence.y = arenaTop + i * 100;
}
// Right fence (vertical)
for (var i = 0; i < leftFenceLength; i++) {
var rightFence = fenceContainer.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0,
scaleX: 0.2,
scaleY: 5
});
rightFence.x = arenaRight + 10;
rightFence.y = arenaTop + i * 100;
}
// Corner posts for authenticity
var corners = [{
x: arenaLeft - 10,
y: arenaTop - 10
}, {
x: arenaRight + 10,
y: arenaTop - 10
}, {
x: arenaLeft - 10,
y: arenaBottom + 10
}, {
x: arenaRight + 10,
y: arenaBottom + 10
}];
for (var c = 0; c < corners.length; c++) {
var cornerPost = fenceContainer.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 2
});
cornerPost.x = corners[c].x;
cornerPost.y = corners[c].y;
cornerPost.tint = 0x2C1810; // Very dark brown for nighttime posts
}
// UI Elements
var healthText = new Text2('Health: 100/100', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 20;
var waveText = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
waveText.y = 20;
// Create corn icon for score display
var cornIcon = LK.getAsset('corn', {
anchorX: 1,
anchorY: 0,
scaleX: 1.5,
scaleY: 1.5
});
cornIcon.tint = 0xFFD700;
LK.gui.topRight.addChild(cornIcon);
cornIcon.x = -120;
cornIcon.y = 20;
var scoreText = new Text2('0', {
size: 60,
fill: 0xFFFF00
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -20;
scoreText.y = 20;
var timerText = new Text2('Time: 30', {
size: 60,
fill: 0x00FFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
timerText.y = 100;
// Initialize player
player = gameCamera.addChild(new Player());
player.x = (arenaLeft + arenaRight) / 2; // Center horizontally in arena
player.y = (arenaTop + arenaBottom) / 2; // Center vertically in arena
// Initialize target position
targetPlayerX = player.x;
targetPlayerY = player.y;
// Create power-up selection UI (initially hidden)
function createPowerUpSelectionUI() {
if (powerUpSelectionUI) {
powerUpSelectionUI.destroy();
}
powerUpSelectionUI = game.addChild(new Container());
// Create gradient background effect with multiple layers
var gradientBg1 = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10.24,
scaleY: 13.66,
alpha: 0.9
});
gradientBg1.x = 1024;
gradientBg1.y = 1366;
gradientBg1.tint = 0x1A0D2E; // Deep purple base
var gradientBg2 = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 10,
alpha: 0.6
});
gradientBg2.x = 1024;
gradientBg2.y = 1366;
gradientBg2.tint = 0x2E1A4A; // Lighter purple middle
// Main content background panel
var mainPanel = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 8,
alpha: 0.95
});
mainPanel.x = 1024;
mainPanel.y = 1366;
mainPanel.tint = 0x0A0A2E; // Dark blue panel
// Decorative border
var borderPanel = powerUpSelectionUI.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 14,
scaleY: 0.5
});
borderPanel.x = 1024;
borderPanel.y = 700;
borderPanel.tint = 0xFFD700; // Gold border
var borderPanel2 = powerUpSelectionUI.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 14,
scaleY: 0.5
});
borderPanel2.x = 1024;
borderPanel2.y = 2000;
borderPanel2.tint = 0xFFD700; // Gold border
// Title with enhanced styling
var titleBg = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 1.2,
alpha: 0.8
});
titleBg.x = 1024;
titleBg.y = 800;
titleBg.tint = 0x4A1A6A; // Purple title background
var titleText = new Text2('CHOOSE POWER-UP', {
size: 90,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
powerUpSelectionUI.addChild(titleText);
// Subtitle
var subtitleText = new Text2('Enhance your abilities to survive longer!', {
size: 50,
fill: 0xCCCCFF
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 870;
powerUpSelectionUI.addChild(subtitleText);
// Power-up options with enhanced visual design
var options = [{
type: 'health',
name: 'Health Boost',
description: '+50 Max Health',
cost: 50,
color: 0xFF4444,
bgColor: 0x4A1A1A,
icon: 'player',
iconTint: 0xFF4444
}, {
type: 'shooting',
name: 'Combat Upgrade',
description: 'Better Damage & Speed',
cost: 100,
color: 0xFFFF44,
bgColor: 0x4A4A1A,
icon: 'bullet',
iconTint: 0xFFFF44
}, {
type: 'turret',
name: 'Ally Turret',
description: 'Auto-Shooting Helper',
cost: 150,
color: 0x44FFFF,
bgColor: 0x1A4A4A,
icon: 'player',
iconTint: 0x44FFFF
}];
for (var i = 0; i < options.length; i++) {
var option = options[i];
var button = powerUpSelectionUI.addChild(new Container());
// Enhanced button background with multiple layers
var buttonShadow = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.2,
scaleY: 1.8,
alpha: 0.5
});
buttonShadow.x = 5;
buttonShadow.y = 5;
buttonShadow.tint = 0x000000; // Shadow
var buttonBg = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 1.7
});
buttonBg.tint = option.bgColor;
var buttonBorder = button.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 0.3
});
buttonBorder.tint = option.color;
buttonBorder.y = -60;
var buttonBorder2 = button.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 0.3
});
buttonBorder2.tint = option.color;
buttonBorder2.y = 60;
// Icon for the power-up
var icon = button.attachAsset(option.icon, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
icon.x = -250;
icon.y = -10;
icon.tint = option.iconTint || option.color;
// Main title text
var buttonTitle = new Text2(option.name, {
size: 60,
fill: option.color
});
buttonTitle.anchor.set(0.5, 0.5);
buttonTitle.x = 50;
buttonTitle.y = -20;
button.addChild(buttonTitle);
// Description text
var buttonDesc = new Text2(option.description, {
size: 40,
fill: 0xCCCCCC
});
buttonDesc.anchor.set(0.5, 0.5);
buttonDesc.x = 50;
buttonDesc.y = 20;
button.addChild(buttonDesc);
// Cost text with coin icon
var costCoin = button.attachAsset('corn', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
costCoin.x = 200;
costCoin.y = 10;
costCoin.tint = 0xFFD700;
var buttonCost = new Text2(option.cost + ' pts', {
size: 45,
fill: 0xFFD700
});
buttonCost.anchor.set(0, 0.5);
buttonCost.x = 230;
buttonCost.y = 10;
button.addChild(buttonCost);
button.x = 1024;
button.y = 1000 + i * 180;
button.powerUpType = option.type;
button.cost = option.cost;
button.originalScale = 1;
button.down = function (x, y, obj) {
if (LK.getScore() >= button.cost) {
// Enhanced visual feedback on successful purchase
tween(button, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
// Flash effect for successful purchase
var flash = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 2,
alpha: 0.8
});
flash.tint = 0x00FF00;
tween(flash, {
alpha: 0,
scaleX: 6,
scaleY: 3
}, {
duration: 400,
onFinish: function onFinish() {
flash.destroy();
}
});
applyPowerUp(button.powerUpType);
LK.setScore(LK.getScore() - button.cost);
scoreText.setText(LK.getScore().toString());
hidePowerUpSelection();
} else {
// Enhanced visual feedback on insufficient funds
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(button, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 100,
onFinish: function onFinish() {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
}
});
// Red flash for insufficient funds
var errorFlash = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.5,
scaleY: 2,
alpha: 0.6
});
errorFlash.tint = 0xFF0000;
tween(errorFlash, {
alpha: 0,
scaleX: 5,
scaleY: 2.5
}, {
duration: 300,
onFinish: function onFinish() {
errorFlash.destroy();
}
});
}
};
// Enhanced hover effect with glow
button.move = function (x, y, obj) {
if (!button.isHovering) {
button.isHovering = true;
// Create glow effect
if (!button.glowEffect) {
button.glowEffect = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.5,
scaleY: 2,
alpha: 0
});
button.glowEffect.tint = option.color;
button.addChildAt(button.glowEffect, 0);
}
tween(button, {
scaleX: 1.08,
scaleY: 1.08
}, {
duration: 200,
easing: tween.easeOut
});
tween(button.glowEffect, {
alpha: 0.3,
scaleX: 5,
scaleY: 2.3
}, {
duration: 200,
easing: tween.easeOut
});
}
};
}
// Enhanced skip button
var skipButton = powerUpSelectionUI.addChild(new Container());
// Skip button background with shadow
var skipShadow = skipButton.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.2,
scaleY: 1.2,
alpha: 0.5
});
skipShadow.x = 3;
skipShadow.y = 3;
skipShadow.tint = 0x000000;
var skipBg = skipButton.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 1
});
skipBg.tint = 0x2A2A2A;
// Skip button border
var skipBorder = skipButton.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 0.2
});
skipBorder.tint = 0x777777;
skipBorder.y = -30;
var skipBorder2 = skipButton.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 0.2
});
skipBorder2.tint = 0x777777;
skipBorder2.y = 30;
var skipText = new Text2('SKIP UPGRADES', {
size: 55,
fill: 0xCCCCCC
});
skipText.anchor.set(0.5, 0.5);
skipButton.addChild(skipText);
skipButton.x = 1024;
skipButton.y = 1750;
skipButton.down = function (x, y, obj) {
tween(skipButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(skipButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 150
});
}
});
hidePowerUpSelection();
};
skipButton.move = function (x, y, obj) {
if (!skipButton.isHovering) {
skipButton.isHovering = true;
tween(skipButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200
});
}
};
powerUpSelectionUI.alpha = 0;
// Enhanced entrance animations with staggered effects
// First fade in the background layers
tween(gradientBg1, {
alpha: 0.9
}, {
duration: 500,
easing: tween.easeOut
});
tween(gradientBg2, {
alpha: 0.6
}, {
duration: 600,
easing: tween.easeOut
});
tween(mainPanel, {
alpha: 0.95
}, {
duration: 700,
easing: tween.easeOut
});
// Animate title with special effect
titleText.scaleX = 0;
titleText.scaleY = 0;
tween(titleText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 400,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
// Animate borders sliding in
borderPanel.scaleX = 0;
borderPanel2.scaleX = 0;
tween(borderPanel, {
scaleX: 14
}, {
duration: 500,
easing: tween.easeOut
});
tween(borderPanel2, {
scaleX: 14
}, {
duration: 500,
easing: tween.easeOut
});
// Animate subtitle fading in
subtitleText.alpha = 0;
LK.setTimeout(function () {
tween(subtitleText, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}, 300);
// Animate power-up buttons with enhanced entrance
for (var k = 0; k < powerUpSelectionUI.children.length; k++) {
var child = powerUpSelectionUI.children[k];
if (child !== gradientBg1 && child !== gradientBg2 && child !== mainPanel && child !== borderPanel && child !== borderPanel2 && child !== titleText && child !== subtitleText) {
child.scaleX = 0;
child.scaleY = 0;
child.alpha = 0;
// Start animation after delay
LK.setTimeout(function (childElement, delay) {
return function () {
tween(childElement, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 1
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(childElement, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
};
}(child, k), 800 + k * 150);
}
}
tween(powerUpSelectionUI, {
alpha: 1
}, {
duration: 400
});
}
function showPowerUpSelection() {
showingPowerUpSelection = true;
createPowerUpSelectionUI();
}
function hidePowerUpSelection() {
showingPowerUpSelection = false;
if (powerUpSelectionUI) {
tween(powerUpSelectionUI, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
powerUpSelectionUI.destroy();
powerUpSelectionUI = null;
startNextWave();
}
});
}
}
function applyPowerUp(type) {
switch (type) {
case 'health':
player.maxHealth += 50;
player.health = player.maxHealth; // Heal to full new max health
activePowerUps.healthUpgrades++;
// Add health indicator if not present
if (!playerHealthIndicator) {
playerHealthIndicator = player.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
});
playerHealthIndicator.x = -30;
playerHealthIndicator.y = -30;
playerHealthIndicator.tint = 0xFF4444;
// Add pulsing animation
tween(playerHealthIndicator, {
scaleX: 0.4,
scaleY: 0.4,
alpha: 0.9
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
var _healthPulse = function healthPulse() {
tween(playerHealthIndicator, {
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(playerHealthIndicator, {
scaleX: 0.4,
scaleY: 0.4,
alpha: 0.9
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: _healthPulse
});
}
});
};
_healthPulse();
}
});
}
break;
case 'shooting':
// Improve shooting: increase damage and fire rate
Bullet.prototype.baseDamage = (Bullet.prototype.baseDamage || 25) + 15;
player.shootRate = Math.max(player.shootRate - 5, 8);
activePowerUps.shootingUpgrades++;
// Add shooting indicator if not present
if (!playerShootingIndicator) {
playerShootingIndicator = player.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.8
});
playerShootingIndicator.x = 30;
playerShootingIndicator.y = -30;
playerShootingIndicator.tint = 0xFFFF44;
// Add rotation animation
tween(playerShootingIndicator, {
rotation: Math.PI * 2
}, {
duration: 2000,
easing: tween.linear,
onFinish: function onFinish() {
var _shootRotate = function shootRotate() {
playerShootingIndicator.rotation = 0;
tween(playerShootingIndicator, {
rotation: Math.PI * 2
}, {
duration: 2000,
easing: tween.linear,
onFinish: _shootRotate
});
};
_shootRotate();
}
});
}
break;
case 'turret':
// Create mini turret at random position
var turret = new MiniTurret();
turret.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
turret.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
miniTurrets.push(turret);
gameCamera.addChild(turret);
activePowerUps.turretCount++;
// Add visual effect to show turret was created
LK.effects.flashObject(turret, 0x44FFFF, 1000);
break;
}
// Update UI immediately after applying power-up
healthText.setText('Health: ' + player.health + '/' + player.maxHealth);
}
function startWave() {
if (waveInProgress) {
return;
}
waveInProgress = {
bossSpawned: false
};
waveTimer = 0;
waveTimeLimit = 60 * 60; // 1 minute for all waves at 60fps
enemySpawnTimer = 0;
enemySpawnRate = Math.max(120 - currentWave * 5, 30); // Spawn every 2-0.5 seconds
console.log('Starting wave ' + currentWave + ' for ' + waveTimeLimit / 60 + ' seconds');
}
function startNextWave() {
waveInProgress = {
bossSpawned: false
};
waveTimer = 0;
waveTimeLimit = 60 * 60; // 1 minute for all waves at 60fps
enemySpawnTimer = 0;
enemySpawnRate = Math.max(120 - currentWave * 5, 30);
console.log('Starting wave ' + currentWave + ' for ' + waveTimeLimit / 60 + ' seconds');
}
function spawnEnemy() {
var enemy = new Enemy();
// Spawn at random edge
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// top
enemy.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
enemy.y = arenaTop - 50;
break;
case 1:
// right
enemy.x = arenaRight + 50;
enemy.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
case 2:
// bottom
enemy.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
enemy.y = arenaBottom + 50;
break;
case 3:
// left
enemy.x = arenaLeft - 50;
enemy.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
}
// Scale enemy with wave - bigger and more resistant
var sizeMultiplier = 1 + (currentWave - 1) * 0.15;
var healthMultiplier = 1 + (currentWave - 1) * 0.5;
enemy.children[0].scaleX = sizeMultiplier;
enemy.children[0].scaleY = sizeMultiplier;
enemy.health = Math.floor(50 * healthMultiplier);
enemy.speed = 1.5 + (currentWave - 1) * 0.1;
enemy.damage = 20 + (currentWave - 1) * 5;
enemy.waveNumber = currentWave;
// Tint stronger enemies
if (currentWave > 5) {
enemy.children[0].tint = 0xFF0000 + currentWave * 0x110000;
}
enemies.push(enemy);
gameCamera.addChild(enemy);
}
function spawnBossEnemy() {
var boss = new BossEnemy();
// Spawn at random edge
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// top
boss.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
boss.y = arenaTop - 80;
break;
case 1:
// right
boss.x = arenaRight + 80;
boss.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
case 2:
// bottom
boss.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
boss.y = arenaBottom + 80;
break;
case 3:
// left
boss.x = arenaLeft - 80;
boss.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
}
// Scale boss with wave - much bigger and more resistant than regular enemies
var sizeMultiplier = 1.5 + (currentWave - 1) * 0.2;
var healthMultiplier = 2 + (currentWave - 1) * 0.8;
boss.children[0].scaleX = sizeMultiplier;
boss.children[0].scaleY = sizeMultiplier;
boss.health = Math.floor(300 * healthMultiplier);
boss.speed = 1 + (currentWave - 1) * 0.05; // Slower than regular enemies
boss.damage = 50 + (currentWave - 1) * 10;
boss.waveNumber = currentWave;
// Special boss tinting - darker red with wave progression
boss.children[0].tint = 0x8B0000 + currentWave * 0x110000;
// Add menacing glow effect
tween(boss.children[0], {
tint: 0xFF0000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(boss.children[0], {
tint: 0x8B0000 + currentWave * 0x110000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Create looping glow effect
var _glowLoop = function glowLoop() {
tween(boss.children[0], {
tint: 0xFF0000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(boss.children[0], {
tint: 0x8B0000 + currentWave * 0x110000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: _glowLoop
});
}
});
};
_glowLoop();
}
});
}
});
enemies.push(boss);
gameCamera.addChild(boss);
// Screen flash to announce boss arrival
LK.effects.flashScreen(0xFF0000, 800);
}
function handleMove(x, y, obj) {
if (dragTarget === player) {
// Convert screen coordinates to camera coordinates
var localX = x;
var localY = y;
if (currentZoom > 1) {
// Convert screen touch to world coordinates
localX = (x - gameCamera.x) / currentZoom;
localY = (y - gameCamera.y) / currentZoom;
}
// Set target position instead of direct movement
targetPlayerX = Math.max(arenaLeft + 40, Math.min(arenaRight - 40, localX));
targetPlayerY = Math.max(arenaTop + 40, Math.min(arenaBottom - 40, localY));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragTarget = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragTarget = null;
};
// Create start menu
function createStartMenu() {
menuContainer = game.addChild(new Container());
// Menu background overlay
var menuBg = menuContainer.attachAsset('ground', {
anchorX: 0,
anchorY: 0,
scaleX: 10.24,
scaleY: 13.66
});
menuBg.tint = 0x0A0A0A;
menuBg.alpha = 0.9;
// Game title
var titleText = new Text2('PUERCA DEFENDER', {
size: 120,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
menuContainer.addChild(titleText);
// Game design preview area
var previewContainer = menuContainer.addChild(new Container());
// Preview background
var previewBg = previewContainer.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 4
});
previewBg.x = 1024;
previewBg.y = 850;
previewBg.tint = 0x3A5F3A;
// Preview elements - show mini versions of game assets
var previewPlayer = previewContainer.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
previewPlayer.x = 924;
previewPlayer.y = 850;
var previewEnemy = previewContainer.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
previewEnemy.x = 1024;
previewEnemy.y = 800;
previewEnemy.tint = 0xFF4444;
var previewBoss = previewContainer.attachAsset('bossEnemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
previewBoss.x = 1124;
previewBoss.y = 820;
previewBoss.tint = 0x8B0000;
var previewCorn = previewContainer.attachAsset('corn', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
previewCorn.x = 1024;
previewCorn.y = 900;
previewCorn.tint = 0xFFD700;
// Add floating animation to preview elements
tween(previewPlayer, {
y: previewPlayer.y - 10
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
var _floatLoop = function floatLoop() {
tween(previewPlayer, {
y: previewPlayer.y + 20
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(previewPlayer, {
y: previewPlayer.y - 20
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: _floatLoop
});
}
});
};
_floatLoop();
}
});
// Start button
var startButton = menuContainer.addChild(new Container());
var buttonBg = startButton.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 1
});
buttonBg.tint = 0x2E8B57;
buttonBg.x = 0;
buttonBg.y = 0;
var buttonText = new Text2('START GAME', {
size: 70,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
startButton.addChild(buttonText);
startButton.x = 1024;
startButton.y = 1200;
// Button interactions
startButton.down = function (x, y, obj) {
tween(startButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 150,
onFinish: function onFinish() {
tween(startButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 150
});
}
});
startGame();
};
// Instructions text
var instructionsText = new Text2('Drag to move player\nCollect corn to buy upgrades\nSurvive 20 waves!', {
size: 50,
fill: 0xCCCCCC
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 1024;
instructionsText.y = 1450;
menuContainer.addChild(instructionsText);
// Animate menu entrance
menuContainer.alpha = 0;
tween(menuContainer, {
alpha: 1
}, {
duration: 1000
});
}
function zoomToDetail() {
if (zoomTransitioning || currentZoom >= targetZoom) {
return;
}
zoomTransitioning = true;
// Calculate center point for zoom (focus on player)
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
// Calculate new camera position to keep player centered
var newCameraX = centerX - player.x * targetZoom;
var newCameraY = centerY - player.y * targetZoom;
// Animate zoom in
tween(gameCamera, {
scaleX: targetZoom,
scaleY: targetZoom,
x: newCameraX,
y: newCameraY
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
currentZoom = targetZoom;
zoomTransitioning = false;
}
});
}
function startGame() {
showingMenu = false;
// Fade out menu
tween(menuContainer, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
menuContainer.destroy();
menuContainer = null;
// Start background music
LK.playMusic('MusicaFondo1');
// Start first wave
LK.setTimeout(function () {
startWave();
gameStarted = true;
// Zoom in for better detail after game starts
LK.setTimeout(function () {
zoomToDetail();
}, 500);
}, 1000);
}
});
}
// Create and show start menu
createStartMenu();
game.update = function () {
if (showingMenu || !gameStarted || showingPowerUpSelection) {
return;
}
// Update player position with smooth interpolation
if (player) {
// Lerp player position toward target position
player.x += (targetPlayerX - player.x) * playerMoveSpeed;
player.y += (targetPlayerY - player.y) * playerMoveSpeed;
// Update camera position to follow player when zoomed
if (currentZoom > 1 && !zoomTransitioning) {
var centerX = 1024;
var centerY = 1366;
gameCamera.x = centerX - player.x * currentZoom;
gameCamera.y = centerY - player.y * currentZoom;
}
}
// Update wave timer and spawn enemies
if (waveInProgress) {
waveTimer++;
enemySpawnTimer++;
// Spawn enemies at intervals
if (enemySpawnTimer >= enemySpawnRate) {
spawnEnemy();
enemySpawnTimer = 0;
}
// Spawn boss enemy when 50% of wave time has passed (once per wave)
var waveProgress = waveTimer / waveTimeLimit;
if (waveProgress >= 0.5 && !waveInProgress.bossSpawned) {
spawnBossEnemy();
waveInProgress.bossSpawned = true;
}
// Update timer display
var timeLeft = Math.max(0, Math.ceil((waveTimeLimit - waveTimer) / 60));
timerText.setText('Time: ' + timeLeft);
// Check wave completion
if (waveTimer >= waveTimeLimit) {
waveInProgress = false;
// Clear remaining enemies
for (var k = enemies.length - 1; k >= 0; k--) {
enemies[k].destroy();
enemies.splice(k, 1);
}
currentWave++;
console.log('Wave ' + (currentWave - 1) + ' completed! Moving to wave ' + currentWave);
if (currentWave > 20) {
LK.showYouWin();
return;
}
waveText.setText('Wave: ' + currentWave);
player.health = player.maxHealth; // Heal to full health between waves
showPowerUpSelection();
return;
}
}
// Update boss wave projectiles
for (var w = bossWaves.length - 1; w >= 0; w--) {
var wave = bossWaves[w];
wave.lifeTime++;
wave.x += wave.velocityX;
wave.y += wave.velocityY;
// Remove waves that are off screen or expired
if (wave.x < 0 || wave.x > 2048 || wave.y < 0 || wave.y > 2732 || wave.lifeTime >= wave.maxLifeTime) {
wave.destroy();
bossWaves.splice(w, 1);
continue;
}
// Check wave-player collision
if (wave.intersects(player)) {
player.health -= wave.damage;
LK.effects.flashObject(player, 0xFF6666, 400);
LK.getSound('enemyHit').play();
wave.destroy();
bossWaves.splice(w, 1);
if (player.health <= 0) {
LK.showGameOver();
return;
}
continue;
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that go off screen
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
enemy.health -= bullet.damage;
LK.effects.flashObject(enemy, 0xFFFFFF, 200);
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
if (enemy.health <= 0) {
// Drop corn at enemy position
var corn = new Corn();
corn.x = enemy.x;
corn.y = enemy.y;
corn.scoreValue = 10 * enemy.waveNumber;
cornDrops.push(corn);
gameCamera.addChild(corn);
enemy.destroy();
enemies.splice(j, 1);
}
break;
}
}
}
// Check player-enemy collisions
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (player.intersects(enemy)) {
player.health -= enemy.damage;
LK.effects.flashObject(player, 0xFF0000, 300);
enemy.destroy();
enemies.splice(i, 1);
if (player.health <= 0) {
LK.showGameOver();
return;
}
}
}
// Update corn drops and check collection
for (var c = cornDrops.length - 1; c >= 0; c--) {
var corn = cornDrops[c];
// Check if player collects corn
if (player.intersects(corn)) {
LK.setScore(LK.getScore() + corn.scoreValue);
scoreText.setText(LK.getScore().toString());
LK.getSound('cornCollect').play();
// Add collection effect
tween(corn, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
corn.destroy();
}
});
cornDrops.splice(c, 1);
continue;
}
// Remove corn that's been on screen too long (30 seconds)
if (corn.lifeTime === undefined) {
corn.lifeTime = 0;
}
corn.lifeTime++;
if (corn.lifeTime > 1800) {
// 30 seconds at 60fps
corn.destroy();
cornDrops.splice(c, 1);
}
}
// Update UI
healthText.setText('Health: ' + player.health + '/' + player.maxHealth);
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BossEnemy = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bossEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 300;
self.speed = 2.5; // Increased speed for faster approach
self.damage = 50;
self.waveNumber = currentWave;
self.clawAttackCooldown = 0;
self.clawAttackRange = 150;
self.clawAttackRate = 120; // 2 seconds between claw attacks
self.waveAttackCooldown = 0;
self.waveAttackRange = 400; // Longer range for wave attacks
self.waveAttackRate = 180; // 3 seconds between wave attacks
// Visual effect for claw attack
self.clawEffect = null;
// Animation properties
self.animationOffset = Math.random() * Math.PI * 2;
self.breathingSpeed = 0.08;
self.intimidationFactor = 1;
self.update = function () {
// Add scaling pulse animation - grow and shrink (more intense for boss)
var scalePulse = self.intimidationFactor + Math.sin(LK.ticks * 0.08 + self.animationOffset) * 0.15;
graphics.scaleX = scalePulse;
graphics.scaleY = scalePulse;
// Add color pulsing for menacing effect
var pulseIntensity = Math.sin(LK.ticks * 0.1 + self.animationOffset) * 0.3 + 0.7;
if (graphics.tint === 0xFFFFFF || graphics.tint === undefined) {
graphics.tint = 0xFF0000;
}
if (player) {
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
// Move towards player with increased speed
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
// Claw attack logic
if (self.clawAttackCooldown > 0) {
self.clawAttackCooldown--;
}
// Wave attack logic
if (self.waveAttackCooldown > 0) {
self.waveAttackCooldown--;
}
// Prioritize wave attacks at medium range, claw attacks at close range
if (distanceToPlayer <= self.waveAttackRange && distanceToPlayer > self.clawAttackRange && self.waveAttackCooldown <= 0) {
self.performWaveAttack();
self.waveAttackCooldown = self.waveAttackRate;
} else if (distanceToPlayer <= self.clawAttackRange && self.clawAttackCooldown <= 0) {
self.performClawAttack();
self.clawAttackCooldown = self.clawAttackRate;
}
}
};
self.performWaveAttack = function () {
// Create multiple cutting wave projectiles
var angleToPlayer = Math.atan2(player.y - self.y, player.x - self.x);
// Create 3 waves spread in a cone
for (var i = 0; i < 3; i++) {
var waveAngle = angleToPlayer + (i - 1) * 0.3; // Spread waves in cone
var wave = gameCamera.addChild(new Container());
// Create wave visual
var waveGraphic = wave.attachAsset('waveAttack', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 1.2
});
waveGraphic.tint = 0xFF3333;
waveGraphic.alpha = 0.95;
wave.rotation = waveAngle;
wave.x = self.x;
wave.y = self.y;
wave.velocityX = Math.cos(waveAngle) * 6;
wave.velocityY = Math.sin(waveAngle) * 6;
wave.damage = self.damage * 0.8; // Slightly less damage than claw
wave.lifeTime = 0;
wave.maxLifeTime = 120; // 2 seconds at 60fps
// Add wave to bullets array for collision detection
if (!bossWaves) {
bossWaves = [];
}
bossWaves.push(wave);
// Add pulsing animation to wave
tween(waveGraphic, {
scaleX: 2.5,
alpha: 0.7
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(waveGraphic, {
scaleX: 2,
alpha: 0.9
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
}
// Visual effect at boss position
LK.effects.flashObject(self, 0xFF6666, 300);
LK.getSound('clawAttack').play(); // Reuse claw sound for waves
};
self.performClawAttack = function () {
// Create visual claw effect
if (self.clawEffect) {
self.clawEffect.destroy();
}
self.clawEffect = self.addChild(LK.getAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.5
}));
self.clawEffect.tint = 0xFF4444;
self.clawEffect.alpha = 0.8;
// Animate claw slash effect
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.clawEffect.rotation = angle;
tween(self.clawEffect, {
scaleX: 4,
scaleY: 1,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
if (self.clawEffect) {
self.clawEffect.destroy();
self.clawEffect = null;
}
}
});
// Deal damage to player if still in range
var currentDistance = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (currentDistance <= self.clawAttackRange) {
player.health -= self.damage;
LK.effects.flashObject(player, 0xFF0000, 500);
LK.getSound('clawAttack').play();
}
// Screen shake effect for dramatic impact
LK.effects.flashScreen(0xFF4444, 200);
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.damage = Bullet.prototype.baseDamage || 25;
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
};
return self;
});
var Corn = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('corn', {
anchorX: 0.5,
anchorY: 0.5
});
self.scoreValue = 10;
graphics.tint = 0xFFD700; // Golden corn color
// Add floating animation
self.floatOffset = Math.random() * Math.PI * 2;
self.baseY = 0;
self.update = function () {
if (self.baseY === 0) {
self.baseY = self.y;
}
self.y = self.baseY + Math.sin(LK.ticks * 0.1 + self.floatOffset) * 5;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 50;
self.speed = 1.5;
self.damage = 20;
self.waveNumber = currentWave;
// Animation properties
self.animationOffset = Math.random() * Math.PI * 2;
self.rotationSpeed = 0.02 + Math.random() * 0.02;
self.update = function () {
// Add scaling pulse animation - grow and shrink
var scalePulse = 1 + Math.sin(LK.ticks * 0.08 + self.animationOffset) * 0.1;
graphics.scaleX = scalePulse;
graphics.scaleY = scalePulse;
if (player) {
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.x += Math.cos(angle) * self.speed;
self.y += Math.sin(angle) * self.speed;
}
};
return self;
});
var MiniTurret = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
graphics.tint = 0x00FFFF;
self.shootCooldown = 0;
self.shootRate = 40; // Slower than player
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Auto-shoot at nearest enemy
if (self.shootCooldown <= 0 && enemies.length > 0) {
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var distance = Math.sqrt(Math.pow(enemies[i].x - self.x, 2) + Math.pow(enemies[i].y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemies[i];
}
}
if (nearestEnemy && nearestDistance < 350) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var angle = Math.atan2(nearestEnemy.y - self.y, nearestEnemy.x - self.x);
bullet.velocityX = Math.cos(angle) * 6;
bullet.velocityY = Math.sin(angle) * 6;
bullets.push(bullet);
gameCamera.addChild(bullet);
self.shootCooldown = self.shootRate;
LK.getSound('shoot').play();
}
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 4;
self.shootCooldown = 0;
self.shootRate = 20; // frames between shots
// Animation properties
self.animationOffset = Math.random() * Math.PI * 2;
self.baseY = 0;
self.isAnimating = false;
self.update = function () {
// Add scaling pulse animation - grow and shrink
var scalePulse = 1 + Math.sin(LK.ticks * 0.08 + self.animationOffset) * 0.1;
graphics.scaleX = scalePulse;
graphics.scaleY = scalePulse;
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
// Auto-shoot at nearest enemy
if (self.shootCooldown <= 0 && enemies.length > 0) {
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var distance = Math.sqrt(Math.pow(enemies[i].x - self.x, 2) + Math.pow(enemies[i].y - self.y, 2));
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemies[i];
}
}
if (nearestEnemy && nearestDistance < 400) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var angle = Math.atan2(nearestEnemy.y - self.y, nearestEnemy.x - self.x);
bullet.velocityX = Math.cos(angle) * 8;
bullet.velocityY = Math.sin(angle) * 8;
bullets.push(bullet);
gameCamera.addChild(bullet);
self.shootCooldown = self.shootRate;
LK.getSound('shoot').play();
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0F1A2E // Dark night blue
});
/****
* Game Code
****/
// Game variables
var player;
var bullets = [];
var enemies = [];
var miniTurrets = [];
var cornDrops = [];
var bossWaves = [];
var currentWave = 1;
var enemiesRemaining = 0;
var waveStartDelay = 0;
var gameStarted = false;
var showingMenu = true;
var menuContainer = null;
var dragTarget = null;
var waveInProgress = false;
var showingPowerUpSelection = false;
var waveTimer = 0;
var waveTimeLimit = 0;
var enemySpawnTimer = 0;
var enemySpawnRate = 0;
var powerUpSelectionUI = null;
// Power-up indicators
var playerHealthIndicator = null;
var playerShootingIndicator = null;
var activePowerUps = {
healthUpgrades: 0,
shootingUpgrades: 0,
turretCount: 0
};
// Camera zoom variables
var gameCamera = null;
var currentZoom = 1;
var targetZoom = 2; // 2x zoom for better detail
var zoomTransitioning = false;
// Player movement variables
var targetPlayerX = 0;
var targetPlayerY = 0;
var playerMoveSpeed = 0.03; // Much slower movement for better control
// Create camera container for zoom functionality
gameCamera = game.addChild(new Container());
// Create nighttime farm scenery in top area
var farmSceneryContainer = gameCamera.addChild(new Container());
// Night sky gradient background
var skyBg = farmSceneryContainer.attachAsset('ground', {
anchorX: 0,
anchorY: 0,
scaleX: 10.24,
scaleY: 2
});
skyBg.x = 0;
skyBg.y = 0;
skyBg.tint = 0x1A2B4A; // Dark night blue
// Add some farm buildings silhouettes
var barn = farmSceneryContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0,
scaleX: 8,
scaleY: 6
});
barn.x = 300;
barn.y = 80;
barn.tint = 0x2C1810; // Dark barn color
var farmhouse = farmSceneryContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0,
scaleX: 6,
scaleY: 4
});
farmhouse.x = 1200;
farmhouse.y = 120;
farmhouse.tint = 0x3D2817; // Dark house color
// Add some trees silhouettes
for (var t = 0; t < 5; t++) {
var tree = farmSceneryContainer.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 1,
scaleX: 2,
scaleY: 3
});
tree.x = 150 + t * 350;
tree.y = 200;
tree.tint = 0x0D1B0D; // Very dark green for tree silhouettes
}
// Add stars
for (var s = 0; s < 20; s++) {
var star = farmSceneryContainer.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
star.x = Math.random() * 2048;
star.y = Math.random() * 180;
star.tint = 0xFFFFAA; // Yellowish white stars
}
// Arena bounds - zoomed in and repositioned for better gameplay
var arenaLeft = 300;
var arenaRight = 1748;
var arenaTop = 450;
var arenaBottom = 2300;
// Create corral ground background
var groundContainer = gameCamera.addChild(new Container());
var groundTileWidth = 200;
var groundTileHeight = 200;
var tilesX = Math.ceil((arenaRight - arenaLeft) / groundTileWidth);
var tilesY = Math.ceil((arenaBottom - arenaTop) / groundTileHeight);
for (var gx = 0; gx < tilesX; gx++) {
for (var gy = 0; gy < tilesY; gy++) {
var groundTile = groundContainer.attachAsset('ground', {
anchorX: 0,
anchorY: 0
});
groundTile.x = arenaLeft + gx * groundTileWidth;
groundTile.y = arenaTop + gy * groundTileHeight;
// Add nighttime ground colors
if ((gx + gy) % 2 === 0) {
groundTile.tint = 0x3A5F3A; // Dark nighttime grass green
} else {
groundTile.tint = 0x2F4F2F; // Slightly different dark green
}
}
}
// Create fence borders
var fenceContainer = gameCamera.addChild(new Container());
// Top fence
var topFenceLength = Math.ceil((arenaRight - arenaLeft) / 100);
for (var i = 0; i < topFenceLength; i++) {
var topFence = fenceContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0.5
});
topFence.x = arenaLeft + i * 100;
topFence.y = arenaTop - 10;
}
// Bottom fence
for (var i = 0; i < topFenceLength; i++) {
var bottomFence = fenceContainer.attachAsset('fence', {
anchorX: 0,
anchorY: 0.5
});
bottomFence.x = arenaLeft + i * 100;
bottomFence.y = arenaBottom + 10;
}
// Left fence (vertical)
var leftFenceLength = Math.ceil((arenaBottom - arenaTop) / 100);
for (var i = 0; i < leftFenceLength; i++) {
var leftFence = fenceContainer.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0,
scaleX: 0.2,
scaleY: 5
});
leftFence.x = arenaLeft - 10;
leftFence.y = arenaTop + i * 100;
}
// Right fence (vertical)
for (var i = 0; i < leftFenceLength; i++) {
var rightFence = fenceContainer.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0,
scaleX: 0.2,
scaleY: 5
});
rightFence.x = arenaRight + 10;
rightFence.y = arenaTop + i * 100;
}
// Corner posts for authenticity
var corners = [{
x: arenaLeft - 10,
y: arenaTop - 10
}, {
x: arenaRight + 10,
y: arenaTop - 10
}, {
x: arenaLeft - 10,
y: arenaBottom + 10
}, {
x: arenaRight + 10,
y: arenaBottom + 10
}];
for (var c = 0; c < corners.length; c++) {
var cornerPost = fenceContainer.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 2
});
cornerPost.x = corners[c].x;
cornerPost.y = corners[c].y;
cornerPost.tint = 0x2C1810; // Very dark brown for nighttime posts
}
// UI Elements
var healthText = new Text2('Health: 100/100', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthText);
healthText.x = 120;
healthText.y = 20;
var waveText = new Text2('Wave: 1', {
size: 60,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
LK.gui.top.addChild(waveText);
waveText.y = 20;
// Create corn icon for score display
var cornIcon = LK.getAsset('corn', {
anchorX: 1,
anchorY: 0,
scaleX: 1.5,
scaleY: 1.5
});
cornIcon.tint = 0xFFD700;
LK.gui.topRight.addChild(cornIcon);
cornIcon.x = -120;
cornIcon.y = 20;
var scoreText = new Text2('0', {
size: 60,
fill: 0xFFFF00
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -20;
scoreText.y = 20;
var timerText = new Text2('Time: 30', {
size: 60,
fill: 0x00FFFF
});
timerText.anchor.set(0.5, 0);
LK.gui.top.addChild(timerText);
timerText.y = 100;
// Initialize player
player = gameCamera.addChild(new Player());
player.x = (arenaLeft + arenaRight) / 2; // Center horizontally in arena
player.y = (arenaTop + arenaBottom) / 2; // Center vertically in arena
// Initialize target position
targetPlayerX = player.x;
targetPlayerY = player.y;
// Create power-up selection UI (initially hidden)
function createPowerUpSelectionUI() {
if (powerUpSelectionUI) {
powerUpSelectionUI.destroy();
}
powerUpSelectionUI = game.addChild(new Container());
// Create gradient background effect with multiple layers
var gradientBg1 = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10.24,
scaleY: 13.66,
alpha: 0.9
});
gradientBg1.x = 1024;
gradientBg1.y = 1366;
gradientBg1.tint = 0x1A0D2E; // Deep purple base
var gradientBg2 = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 10,
alpha: 0.6
});
gradientBg2.x = 1024;
gradientBg2.y = 1366;
gradientBg2.tint = 0x2E1A4A; // Lighter purple middle
// Main content background panel
var mainPanel = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 8,
alpha: 0.95
});
mainPanel.x = 1024;
mainPanel.y = 1366;
mainPanel.tint = 0x0A0A2E; // Dark blue panel
// Decorative border
var borderPanel = powerUpSelectionUI.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 14,
scaleY: 0.5
});
borderPanel.x = 1024;
borderPanel.y = 700;
borderPanel.tint = 0xFFD700; // Gold border
var borderPanel2 = powerUpSelectionUI.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 14,
scaleY: 0.5
});
borderPanel2.x = 1024;
borderPanel2.y = 2000;
borderPanel2.tint = 0xFFD700; // Gold border
// Title with enhanced styling
var titleBg = powerUpSelectionUI.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 1.2,
alpha: 0.8
});
titleBg.x = 1024;
titleBg.y = 800;
titleBg.tint = 0x4A1A6A; // Purple title background
var titleText = new Text2('CHOOSE POWER-UP', {
size: 90,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
powerUpSelectionUI.addChild(titleText);
// Subtitle
var subtitleText = new Text2('Enhance your abilities to survive longer!', {
size: 50,
fill: 0xCCCCFF
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 870;
powerUpSelectionUI.addChild(subtitleText);
// Power-up options with enhanced visual design
var options = [{
type: 'health',
name: 'Health Boost',
description: '+50 Max Health',
cost: 50,
color: 0xFF4444,
bgColor: 0x4A1A1A,
icon: 'player',
iconTint: 0xFF4444
}, {
type: 'shooting',
name: 'Combat Upgrade',
description: 'Better Damage & Speed',
cost: 100,
color: 0xFFFF44,
bgColor: 0x4A4A1A,
icon: 'bullet',
iconTint: 0xFFFF44
}, {
type: 'turret',
name: 'Ally Turret',
description: 'Auto-Shooting Helper',
cost: 150,
color: 0x44FFFF,
bgColor: 0x1A4A4A,
icon: 'player',
iconTint: 0x44FFFF
}];
for (var i = 0; i < options.length; i++) {
var option = options[i];
var button = powerUpSelectionUI.addChild(new Container());
// Enhanced button background with multiple layers
var buttonShadow = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.2,
scaleY: 1.8,
alpha: 0.5
});
buttonShadow.x = 5;
buttonShadow.y = 5;
buttonShadow.tint = 0x000000; // Shadow
var buttonBg = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 1.7
});
buttonBg.tint = option.bgColor;
var buttonBorder = button.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 0.3
});
buttonBorder.tint = option.color;
buttonBorder.y = -60;
var buttonBorder2 = button.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8,
scaleY: 0.3
});
buttonBorder2.tint = option.color;
buttonBorder2.y = 60;
// Icon for the power-up
var icon = button.attachAsset(option.icon, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
icon.x = -250;
icon.y = -10;
icon.tint = option.iconTint || option.color;
// Main title text
var buttonTitle = new Text2(option.name, {
size: 60,
fill: option.color
});
buttonTitle.anchor.set(0.5, 0.5);
buttonTitle.x = 50;
buttonTitle.y = -20;
button.addChild(buttonTitle);
// Description text
var buttonDesc = new Text2(option.description, {
size: 40,
fill: 0xCCCCCC
});
buttonDesc.anchor.set(0.5, 0.5);
buttonDesc.x = 50;
buttonDesc.y = 20;
button.addChild(buttonDesc);
// Cost text with coin icon
var costCoin = button.attachAsset('corn', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
costCoin.x = 200;
costCoin.y = 10;
costCoin.tint = 0xFFD700;
var buttonCost = new Text2(option.cost + ' pts', {
size: 45,
fill: 0xFFD700
});
buttonCost.anchor.set(0, 0.5);
buttonCost.x = 230;
buttonCost.y = 10;
button.addChild(buttonCost);
button.x = 1024;
button.y = 1000 + i * 180;
button.powerUpType = option.type;
button.cost = option.cost;
button.originalScale = 1;
button.down = function (x, y, obj) {
if (LK.getScore() >= button.cost) {
// Enhanced visual feedback on successful purchase
tween(button, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
// Flash effect for successful purchase
var flash = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 2,
alpha: 0.8
});
flash.tint = 0x00FF00;
tween(flash, {
alpha: 0,
scaleX: 6,
scaleY: 3
}, {
duration: 400,
onFinish: function onFinish() {
flash.destroy();
}
});
applyPowerUp(button.powerUpType);
LK.setScore(LK.getScore() - button.cost);
scoreText.setText(LK.getScore().toString());
hidePowerUpSelection();
} else {
// Enhanced visual feedback on insufficient funds
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(button, {
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 100,
onFinish: function onFinish() {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
}
});
// Red flash for insufficient funds
var errorFlash = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.5,
scaleY: 2,
alpha: 0.6
});
errorFlash.tint = 0xFF0000;
tween(errorFlash, {
alpha: 0,
scaleX: 5,
scaleY: 2.5
}, {
duration: 300,
onFinish: function onFinish() {
errorFlash.destroy();
}
});
}
};
// Enhanced hover effect with glow
button.move = function (x, y, obj) {
if (!button.isHovering) {
button.isHovering = true;
// Create glow effect
if (!button.glowEffect) {
button.glowEffect = button.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4.5,
scaleY: 2,
alpha: 0
});
button.glowEffect.tint = option.color;
button.addChildAt(button.glowEffect, 0);
}
tween(button, {
scaleX: 1.08,
scaleY: 1.08
}, {
duration: 200,
easing: tween.easeOut
});
tween(button.glowEffect, {
alpha: 0.3,
scaleX: 5,
scaleY: 2.3
}, {
duration: 200,
easing: tween.easeOut
});
}
};
}
// Enhanced skip button
var skipButton = powerUpSelectionUI.addChild(new Container());
// Skip button background with shadow
var skipShadow = skipButton.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.2,
scaleY: 1.2,
alpha: 0.5
});
skipShadow.x = 3;
skipShadow.y = 3;
skipShadow.tint = 0x000000;
var skipBg = skipButton.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 1
});
skipBg.tint = 0x2A2A2A;
// Skip button border
var skipBorder = skipButton.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 0.2
});
skipBorder.tint = 0x777777;
skipBorder.y = -30;
var skipBorder2 = skipButton.attachAsset('fence', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 0.2
});
skipBorder2.tint = 0x777777;
skipBorder2.y = 30;
var skipText = new Text2('SKIP UPGRADES', {
size: 55,
fill: 0xCCCCCC
});
skipText.anchor.set(0.5, 0.5);
skipButton.addChild(skipText);
skipButton.x = 1024;
skipButton.y = 1750;
skipButton.down = function (x, y, obj) {
tween(skipButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
onFinish: function onFinish() {
tween(skipButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 150
});
}
});
hidePowerUpSelection();
};
skipButton.move = function (x, y, obj) {
if (!skipButton.isHovering) {
skipButton.isHovering = true;
tween(skipButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200
});
}
};
powerUpSelectionUI.alpha = 0;
// Enhanced entrance animations with staggered effects
// First fade in the background layers
tween(gradientBg1, {
alpha: 0.9
}, {
duration: 500,
easing: tween.easeOut
});
tween(gradientBg2, {
alpha: 0.6
}, {
duration: 600,
easing: tween.easeOut
});
tween(mainPanel, {
alpha: 0.95
}, {
duration: 700,
easing: tween.easeOut
});
// Animate title with special effect
titleText.scaleX = 0;
titleText.scaleY = 0;
tween(titleText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 400,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
// Animate borders sliding in
borderPanel.scaleX = 0;
borderPanel2.scaleX = 0;
tween(borderPanel, {
scaleX: 14
}, {
duration: 500,
easing: tween.easeOut
});
tween(borderPanel2, {
scaleX: 14
}, {
duration: 500,
easing: tween.easeOut
});
// Animate subtitle fading in
subtitleText.alpha = 0;
LK.setTimeout(function () {
tween(subtitleText, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}, 300);
// Animate power-up buttons with enhanced entrance
for (var k = 0; k < powerUpSelectionUI.children.length; k++) {
var child = powerUpSelectionUI.children[k];
if (child !== gradientBg1 && child !== gradientBg2 && child !== mainPanel && child !== borderPanel && child !== borderPanel2 && child !== titleText && child !== subtitleText) {
child.scaleX = 0;
child.scaleY = 0;
child.alpha = 0;
// Start animation after delay
LK.setTimeout(function (childElement, delay) {
return function () {
tween(childElement, {
scaleX: 1.1,
scaleY: 1.1,
alpha: 1
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
tween(childElement, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
};
}(child, k), 800 + k * 150);
}
}
tween(powerUpSelectionUI, {
alpha: 1
}, {
duration: 400
});
}
function showPowerUpSelection() {
showingPowerUpSelection = true;
createPowerUpSelectionUI();
}
function hidePowerUpSelection() {
showingPowerUpSelection = false;
if (powerUpSelectionUI) {
tween(powerUpSelectionUI, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
powerUpSelectionUI.destroy();
powerUpSelectionUI = null;
startNextWave();
}
});
}
}
function applyPowerUp(type) {
switch (type) {
case 'health':
player.maxHealth += 50;
player.health = player.maxHealth; // Heal to full new max health
activePowerUps.healthUpgrades++;
// Add health indicator if not present
if (!playerHealthIndicator) {
playerHealthIndicator = player.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
});
playerHealthIndicator.x = -30;
playerHealthIndicator.y = -30;
playerHealthIndicator.tint = 0xFF4444;
// Add pulsing animation
tween(playerHealthIndicator, {
scaleX: 0.4,
scaleY: 0.4,
alpha: 0.9
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
var _healthPulse = function healthPulse() {
tween(playerHealthIndicator, {
scaleX: 0.3,
scaleY: 0.3,
alpha: 0.7
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(playerHealthIndicator, {
scaleX: 0.4,
scaleY: 0.4,
alpha: 0.9
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: _healthPulse
});
}
});
};
_healthPulse();
}
});
}
break;
case 'shooting':
// Improve shooting: increase damage and fire rate
Bullet.prototype.baseDamage = (Bullet.prototype.baseDamage || 25) + 15;
player.shootRate = Math.max(player.shootRate - 5, 8);
activePowerUps.shootingUpgrades++;
// Add shooting indicator if not present
if (!playerShootingIndicator) {
playerShootingIndicator = player.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
alpha: 0.8
});
playerShootingIndicator.x = 30;
playerShootingIndicator.y = -30;
playerShootingIndicator.tint = 0xFFFF44;
// Add rotation animation
tween(playerShootingIndicator, {
rotation: Math.PI * 2
}, {
duration: 2000,
easing: tween.linear,
onFinish: function onFinish() {
var _shootRotate = function shootRotate() {
playerShootingIndicator.rotation = 0;
tween(playerShootingIndicator, {
rotation: Math.PI * 2
}, {
duration: 2000,
easing: tween.linear,
onFinish: _shootRotate
});
};
_shootRotate();
}
});
}
break;
case 'turret':
// Create mini turret at random position
var turret = new MiniTurret();
turret.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
turret.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
miniTurrets.push(turret);
gameCamera.addChild(turret);
activePowerUps.turretCount++;
// Add visual effect to show turret was created
LK.effects.flashObject(turret, 0x44FFFF, 1000);
break;
}
// Update UI immediately after applying power-up
healthText.setText('Health: ' + player.health + '/' + player.maxHealth);
}
function startWave() {
if (waveInProgress) {
return;
}
waveInProgress = {
bossSpawned: false
};
waveTimer = 0;
waveTimeLimit = 60 * 60; // 1 minute for all waves at 60fps
enemySpawnTimer = 0;
enemySpawnRate = Math.max(120 - currentWave * 5, 30); // Spawn every 2-0.5 seconds
console.log('Starting wave ' + currentWave + ' for ' + waveTimeLimit / 60 + ' seconds');
}
function startNextWave() {
waveInProgress = {
bossSpawned: false
};
waveTimer = 0;
waveTimeLimit = 60 * 60; // 1 minute for all waves at 60fps
enemySpawnTimer = 0;
enemySpawnRate = Math.max(120 - currentWave * 5, 30);
console.log('Starting wave ' + currentWave + ' for ' + waveTimeLimit / 60 + ' seconds');
}
function spawnEnemy() {
var enemy = new Enemy();
// Spawn at random edge
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// top
enemy.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
enemy.y = arenaTop - 50;
break;
case 1:
// right
enemy.x = arenaRight + 50;
enemy.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
case 2:
// bottom
enemy.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
enemy.y = arenaBottom + 50;
break;
case 3:
// left
enemy.x = arenaLeft - 50;
enemy.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
}
// Scale enemy with wave - bigger and more resistant
var sizeMultiplier = 1 + (currentWave - 1) * 0.15;
var healthMultiplier = 1 + (currentWave - 1) * 0.5;
enemy.children[0].scaleX = sizeMultiplier;
enemy.children[0].scaleY = sizeMultiplier;
enemy.health = Math.floor(50 * healthMultiplier);
enemy.speed = 1.5 + (currentWave - 1) * 0.1;
enemy.damage = 20 + (currentWave - 1) * 5;
enemy.waveNumber = currentWave;
// Tint stronger enemies
if (currentWave > 5) {
enemy.children[0].tint = 0xFF0000 + currentWave * 0x110000;
}
enemies.push(enemy);
gameCamera.addChild(enemy);
}
function spawnBossEnemy() {
var boss = new BossEnemy();
// Spawn at random edge
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// top
boss.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
boss.y = arenaTop - 80;
break;
case 1:
// right
boss.x = arenaRight + 80;
boss.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
case 2:
// bottom
boss.x = arenaLeft + Math.random() * (arenaRight - arenaLeft);
boss.y = arenaBottom + 80;
break;
case 3:
// left
boss.x = arenaLeft - 80;
boss.y = arenaTop + Math.random() * (arenaBottom - arenaTop);
break;
}
// Scale boss with wave - much bigger and more resistant than regular enemies
var sizeMultiplier = 1.5 + (currentWave - 1) * 0.2;
var healthMultiplier = 2 + (currentWave - 1) * 0.8;
boss.children[0].scaleX = sizeMultiplier;
boss.children[0].scaleY = sizeMultiplier;
boss.health = Math.floor(300 * healthMultiplier);
boss.speed = 1 + (currentWave - 1) * 0.05; // Slower than regular enemies
boss.damage = 50 + (currentWave - 1) * 10;
boss.waveNumber = currentWave;
// Special boss tinting - darker red with wave progression
boss.children[0].tint = 0x8B0000 + currentWave * 0x110000;
// Add menacing glow effect
tween(boss.children[0], {
tint: 0xFF0000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(boss.children[0], {
tint: 0x8B0000 + currentWave * 0x110000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Create looping glow effect
var _glowLoop = function glowLoop() {
tween(boss.children[0], {
tint: 0xFF0000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(boss.children[0], {
tint: 0x8B0000 + currentWave * 0x110000
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: _glowLoop
});
}
});
};
_glowLoop();
}
});
}
});
enemies.push(boss);
gameCamera.addChild(boss);
// Screen flash to announce boss arrival
LK.effects.flashScreen(0xFF0000, 800);
}
function handleMove(x, y, obj) {
if (dragTarget === player) {
// Convert screen coordinates to camera coordinates
var localX = x;
var localY = y;
if (currentZoom > 1) {
// Convert screen touch to world coordinates
localX = (x - gameCamera.x) / currentZoom;
localY = (y - gameCamera.y) / currentZoom;
}
// Set target position instead of direct movement
targetPlayerX = Math.max(arenaLeft + 40, Math.min(arenaRight - 40, localX));
targetPlayerY = Math.max(arenaTop + 40, Math.min(arenaBottom - 40, localY));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragTarget = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragTarget = null;
};
// Create start menu
function createStartMenu() {
menuContainer = game.addChild(new Container());
// Menu background overlay
var menuBg = menuContainer.attachAsset('ground', {
anchorX: 0,
anchorY: 0,
scaleX: 10.24,
scaleY: 13.66
});
menuBg.tint = 0x0A0A0A;
menuBg.alpha = 0.9;
// Game title
var titleText = new Text2('PUERCA DEFENDER', {
size: 120,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
menuContainer.addChild(titleText);
// Game design preview area
var previewContainer = menuContainer.addChild(new Container());
// Preview background
var previewBg = previewContainer.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 4
});
previewBg.x = 1024;
previewBg.y = 850;
previewBg.tint = 0x3A5F3A;
// Preview elements - show mini versions of game assets
var previewPlayer = previewContainer.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
previewPlayer.x = 924;
previewPlayer.y = 850;
var previewEnemy = previewContainer.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
previewEnemy.x = 1024;
previewEnemy.y = 800;
previewEnemy.tint = 0xFF4444;
var previewBoss = previewContainer.attachAsset('bossEnemy', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
previewBoss.x = 1124;
previewBoss.y = 820;
previewBoss.tint = 0x8B0000;
var previewCorn = previewContainer.attachAsset('corn', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
previewCorn.x = 1024;
previewCorn.y = 900;
previewCorn.tint = 0xFFD700;
// Add floating animation to preview elements
tween(previewPlayer, {
y: previewPlayer.y - 10
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
var _floatLoop = function floatLoop() {
tween(previewPlayer, {
y: previewPlayer.y + 20
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(previewPlayer, {
y: previewPlayer.y - 20
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: _floatLoop
});
}
});
};
_floatLoop();
}
});
// Start button
var startButton = menuContainer.addChild(new Container());
var buttonBg = startButton.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 1
});
buttonBg.tint = 0x2E8B57;
buttonBg.x = 0;
buttonBg.y = 0;
var buttonText = new Text2('START GAME', {
size: 70,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
startButton.addChild(buttonText);
startButton.x = 1024;
startButton.y = 1200;
// Button interactions
startButton.down = function (x, y, obj) {
tween(startButton, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 150,
onFinish: function onFinish() {
tween(startButton, {
scaleX: 1,
scaleY: 1
}, {
duration: 150
});
}
});
startGame();
};
// Instructions text
var instructionsText = new Text2('Drag to move player\nCollect corn to buy upgrades\nSurvive 20 waves!', {
size: 50,
fill: 0xCCCCCC
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 1024;
instructionsText.y = 1450;
menuContainer.addChild(instructionsText);
// Animate menu entrance
menuContainer.alpha = 0;
tween(menuContainer, {
alpha: 1
}, {
duration: 1000
});
}
function zoomToDetail() {
if (zoomTransitioning || currentZoom >= targetZoom) {
return;
}
zoomTransitioning = true;
// Calculate center point for zoom (focus on player)
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
// Calculate new camera position to keep player centered
var newCameraX = centerX - player.x * targetZoom;
var newCameraY = centerY - player.y * targetZoom;
// Animate zoom in
tween(gameCamera, {
scaleX: targetZoom,
scaleY: targetZoom,
x: newCameraX,
y: newCameraY
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
currentZoom = targetZoom;
zoomTransitioning = false;
}
});
}
function startGame() {
showingMenu = false;
// Fade out menu
tween(menuContainer, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
menuContainer.destroy();
menuContainer = null;
// Start background music
LK.playMusic('MusicaFondo1');
// Start first wave
LK.setTimeout(function () {
startWave();
gameStarted = true;
// Zoom in for better detail after game starts
LK.setTimeout(function () {
zoomToDetail();
}, 500);
}, 1000);
}
});
}
// Create and show start menu
createStartMenu();
game.update = function () {
if (showingMenu || !gameStarted || showingPowerUpSelection) {
return;
}
// Update player position with smooth interpolation
if (player) {
// Lerp player position toward target position
player.x += (targetPlayerX - player.x) * playerMoveSpeed;
player.y += (targetPlayerY - player.y) * playerMoveSpeed;
// Update camera position to follow player when zoomed
if (currentZoom > 1 && !zoomTransitioning) {
var centerX = 1024;
var centerY = 1366;
gameCamera.x = centerX - player.x * currentZoom;
gameCamera.y = centerY - player.y * currentZoom;
}
}
// Update wave timer and spawn enemies
if (waveInProgress) {
waveTimer++;
enemySpawnTimer++;
// Spawn enemies at intervals
if (enemySpawnTimer >= enemySpawnRate) {
spawnEnemy();
enemySpawnTimer = 0;
}
// Spawn boss enemy when 50% of wave time has passed (once per wave)
var waveProgress = waveTimer / waveTimeLimit;
if (waveProgress >= 0.5 && !waveInProgress.bossSpawned) {
spawnBossEnemy();
waveInProgress.bossSpawned = true;
}
// Update timer display
var timeLeft = Math.max(0, Math.ceil((waveTimeLimit - waveTimer) / 60));
timerText.setText('Time: ' + timeLeft);
// Check wave completion
if (waveTimer >= waveTimeLimit) {
waveInProgress = false;
// Clear remaining enemies
for (var k = enemies.length - 1; k >= 0; k--) {
enemies[k].destroy();
enemies.splice(k, 1);
}
currentWave++;
console.log('Wave ' + (currentWave - 1) + ' completed! Moving to wave ' + currentWave);
if (currentWave > 20) {
LK.showYouWin();
return;
}
waveText.setText('Wave: ' + currentWave);
player.health = player.maxHealth; // Heal to full health between waves
showPowerUpSelection();
return;
}
}
// Update boss wave projectiles
for (var w = bossWaves.length - 1; w >= 0; w--) {
var wave = bossWaves[w];
wave.lifeTime++;
wave.x += wave.velocityX;
wave.y += wave.velocityY;
// Remove waves that are off screen or expired
if (wave.x < 0 || wave.x > 2048 || wave.y < 0 || wave.y > 2732 || wave.lifeTime >= wave.maxLifeTime) {
wave.destroy();
bossWaves.splice(w, 1);
continue;
}
// Check wave-player collision
if (wave.intersects(player)) {
player.health -= wave.damage;
LK.effects.flashObject(player, 0xFF6666, 400);
LK.getSound('enemyHit').play();
wave.destroy();
bossWaves.splice(w, 1);
if (player.health <= 0) {
LK.showGameOver();
return;
}
continue;
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Remove bullets that go off screen
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet-enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
enemy.health -= bullet.damage;
LK.effects.flashObject(enemy, 0xFFFFFF, 200);
LK.getSound('enemyHit').play();
bullet.destroy();
bullets.splice(i, 1);
if (enemy.health <= 0) {
// Drop corn at enemy position
var corn = new Corn();
corn.x = enemy.x;
corn.y = enemy.y;
corn.scoreValue = 10 * enemy.waveNumber;
cornDrops.push(corn);
gameCamera.addChild(corn);
enemy.destroy();
enemies.splice(j, 1);
}
break;
}
}
}
// Check player-enemy collisions
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (player.intersects(enemy)) {
player.health -= enemy.damage;
LK.effects.flashObject(player, 0xFF0000, 300);
enemy.destroy();
enemies.splice(i, 1);
if (player.health <= 0) {
LK.showGameOver();
return;
}
}
}
// Update corn drops and check collection
for (var c = cornDrops.length - 1; c >= 0; c--) {
var corn = cornDrops[c];
// Check if player collects corn
if (player.intersects(corn)) {
LK.setScore(LK.getScore() + corn.scoreValue);
scoreText.setText(LK.getScore().toString());
LK.getSound('cornCollect').play();
// Add collection effect
tween(corn, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
corn.destroy();
}
});
cornDrops.splice(c, 1);
continue;
}
// Remove corn that's been on screen too long (30 seconds)
if (corn.lifeTime === undefined) {
corn.lifeTime = 0;
}
corn.lifeTime++;
if (corn.lifeTime > 1800) {
// 30 seconds at 60fps
corn.destroy();
cornDrops.splice(c, 1);
}
}
// Update UI
healthText.setText('Health: ' + player.health + '/' + player.maxHealth);
};
un puerco de cuerpo completo sin fondo y que se vea tierno pero con expersion de la cara enojado In-Game asset. 2d. High contrast. No shadows
dibuja al animal zorra con expresion malvada estilo igual animado cuerpo completo. In-Game asset. 2d. High contrast. No shadows
una bala estilo cartoon. In-Game asset. 2d. High contrast. No shadows
una valla de corral animada. In-Game asset. 2d. High contrast. No shadows
tierra de corral, textura de corral de granja nocturna. In-Game asset. 2d. High contrast. No shadows
corn with toon style. In-Game asset. 2d. High contrast. No shadows
onda de corte blanca estilo animada. In-Game asset. 2d. High contrast. No shadows