User prompt
Oyunu optimize et hataları kaldır bug olmasın donma olmasın
User prompt
// Temel kule savunma mantığı örneği // Düşman sınıfı class Enemy { constructor(health, speed, position) { this.health = health; this.speed = speed; this.position = position; this.isAlive = true; } move() { this.position += this.speed; } takeDamage(damage) { this.health -= damage; if (this.health <= 0) this.isAlive = false; } } // Kule sınıfı class Tower { constructor(position, range, damage, fireRate) { this.position = position; this.range = range; this.damage = damage; this.fireRate = fireRate; // atış hızı this.cooldown = 0; } canShoot() { return this.cooldown <= 0; } shoot(enemy) { if (this.canShoot() && this.inRange(enemy)) { enemy.takeDamage(this.damage); this.cooldown = this.fireRate; } } inRange(enemy) { return Math.abs(this.position - enemy.position) <= this.range; } updateCooldown() { if (this.cooldown > 0) this.cooldown--; } } // Oyun döngüsü (simplified) let enemies = [new Enemy(100, 1, 0)]; let towers = [new Tower(5, 3, 25, 30)]; function gameLoop() { enemies.forEach(enemy => { if (enemy.isAlive) { enemy.move(); } }); towers.forEach(tower => { tower.updateCooldown(); enemies.forEach(enemy => { if (enemy.isAlive) tower.shoot(enemy); }); }); // Oyun durumu güncellenir, çizim yapılır vs. }
Remix started
Copy Adı Efsane: My Sultan
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BloodParticle = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('confetti', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0xFF0000; // Red color for blood
graphics.scaleX = 0.3; // Smaller particles
graphics.scaleY = 0.3;
self.speedX = (Math.random() - 0.5) * 6;
self.speedY = Math.random() * -4 - 1;
self.gravity = 0.2;
self.life = 30; // Short lived particles
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
self.speedY += self.gravity;
self.life--;
if (self.life <= 0) {
self.alpha = 0;
} else {
// Fade out over time
self.alpha = self.life / 30;
}
};
return self;
});
var Confetti = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('confetti', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = (Math.random() - 0.5) * 10;
self.speedY = Math.random() * -8 - 2;
self.gravity = 0.3;
self.life = 120;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
self.speedY += self.gravity;
self.life--;
if (self.life <= 0) {
self.alpha = 0;
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.enemyType = 'aamir';
self.health = 1;
self.speed = 2;
self.pathIndex = 0;
self.goldReward = 10;
self.init = function (type) {
self.enemyType = type;
if (type === 'vega') {
self.health = 3;
self.speed = 1;
self.goldReward = 25;
} else if (type === 'sultan') {
self.health = 2;
self.speed = 1.5;
self.goldReward = 20;
} else {
self.goldReward = 10;
}
var graphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
};
self.update = function () {
// Follow path if available
if (enemyPath.length > 0 && self.pathIndex < enemyPath.length - 1) {
var currentTarget = enemyPath[self.pathIndex + 1];
var dx = currentTarget.x - self.x;
var dy = currentTarget.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 30) {
self.pathIndex++;
} else {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else {
// Fallback to original movement
self.y += self.speed;
}
};
self.takeDamage = function (damage) {
if (damage === undefined) damage = 1;
self.health -= damage;
if (self.health <= 0) {
// Award gold when enemy dies
playerGold += self.goldReward;
updateGoldDisplay();
return true;
}
return false;
};
return self;
});
var Laser = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 1.0
});
self.duration = 20; // Laser lasts for 20 frames
self.damage = 5; // Higher damage than regular bullets
self.update = function () {
self.duration--;
if (self.duration <= 0) {
self.alpha = 0;
} else {
// Fade out effect
self.alpha = self.duration / 20;
}
};
return self;
});
var ModeButton = Container.expand(function () {
var self = Container.call(this);
var background = self.attachAsset('modeButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.modeText = new Text2('', {
size: 50,
fill: '#000000'
});
self.modeText.anchor.set(0.5, 0.5);
self.addChild(self.modeText);
self.setMode = function (text, mode, enemyCount) {
// Remove existing text and create new one with proper styling
if (self.modeText) {
self.removeChild(self.modeText);
}
self.modeText = new Text2(text, {
size: 50,
fill: '#000000',
stroke: '#FFFFFF',
strokeThickness: 3
});
self.modeText.anchor.set(0.5, 0);
self.modeText.y = 80; // Position text below the button
self.addChild(self.modeText);
self.gameMode = mode;
self.enemyCount = enemyCount;
};
self.down = function (x, y, obj) {
startGame(self.gameMode, self.enemyCount);
};
return self;
});
var Omar = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('omar', {
anchorX: 0.5,
anchorY: 0.5
});
self.shootCooldown = 0;
self.laserCooldown = 0;
self.update = function () {
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.laserCooldown > 0) {
self.laserCooldown--;
}
};
self.shoot = function () {
if (self.shootCooldown <= 0) {
var bullet = new OmarBullet();
bullet.x = self.x;
bullet.y = self.y - 40;
bullets.push(bullet);
game.addChild(bullet);
self.shootCooldown = 15;
LK.getSound('shoot').play();
// Add shooting animation to Omar
tween(self, {
scaleX: 1.1,
scaleY: 1.1,
tint: 0xFFFFAA
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
};
self.shootLaser = function () {
if (self.laserCooldown <= 0) {
var laser = new Laser();
laser.x = self.x;
laser.y = self.y - 40;
lasers.push(laser);
game.addChild(laser);
self.laserCooldown = 60; // 1 second cooldown at 60fps
LK.getSound('shoot').play();
}
};
return self;
});
var OmarAI = Container.expand(function () {
var self = Container.call(this);
self.target = null;
self.isActive = false;
self.moveSpeed = 3;
self.attackRange = 400;
self.lastDecisionTime = 0;
self.decisionCooldown = 30; // frames between AI decisions
self.activate = function () {
self.isActive = true;
};
self.deactivate = function () {
self.isActive = false;
};
self.findNearestEnemy = function () {
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = omar.x - enemy.x;
var dy = omar.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
return nearestEnemy;
};
self.update = function () {
if (!self.isActive || !omar) return;
self.lastDecisionTime++;
// Make decisions every few frames for performance
if (self.lastDecisionTime >= self.decisionCooldown) {
self.target = self.findNearestEnemy();
self.lastDecisionTime = 0;
}
if (self.target) {
// Move towards enemy horizontally
var dx = self.target.x - omar.x;
if (Math.abs(dx) > 50) {
// Dead zone to prevent jittering
if (dx > 0) {
omar.x += self.moveSpeed;
} else {
omar.x -= self.moveSpeed;
}
}
// Keep Omar within screen bounds with proper margins
omar.x = Math.max(95, Math.min(1953, omar.x));
// Shoot if enemy is within range
var distance = Math.sqrt(dx * dx + (self.target.y - omar.y) * (self.target.y - omar.y));
if (distance < self.attackRange) {
omar.shoot();
}
}
};
return self;
});
var OmarBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('omarBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -8;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Terrain = Container.expand(function () {
var self = Container.call(this);
self.init = function (type, x, y) {
var graphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
};
return self;
});
var Tower = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('stone', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0x8B4513; // Brown color for tower
self.range = 300;
self.damage = 25;
self.fireRate = 60; // frames between shots
self.cooldown = 0;
self.level = 1;
self.cost = 50;
// Visual range indicator
self.rangeIndicator = null;
self.showRange = function () {
if (!self.rangeIndicator) {
self.rangeIndicator = new Text2('◯', {
size: self.range * 2,
fill: '#00FF00'
});
self.rangeIndicator.anchor.set(0.5, 0.5);
self.rangeIndicator.alpha = 0.3;
self.rangeIndicator.x = 0;
self.rangeIndicator.y = 0;
self.addChild(self.rangeIndicator);
}
};
self.hideRange = function () {
if (self.rangeIndicator) {
self.removeChild(self.rangeIndicator);
self.rangeIndicator = null;
}
};
self.canShoot = function () {
return self.cooldown <= 0;
};
self.inRange = function (enemy) {
var dx = self.x - enemy.x;
var dy = self.y - enemy.y;
return Math.sqrt(dx * dx + dy * dy) <= self.range;
};
self.shoot = function (enemy) {
if (self.canShoot() && self.inRange(enemy)) {
// Create tower bullet
var bullet = new TowerBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.targetX = enemy.x;
bullet.targetY = enemy.y;
bullet.damage = self.damage;
towerBullets.push(bullet);
game.addChild(bullet);
self.cooldown = self.fireRate;
LK.getSound('shoot').play();
// Tower shoot animation
tween(self, {
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFFFAA
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0x8B4513
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
};
self.upgrade = function () {
if (self.level < 3 && playerGold >= self.getUpgradeCost()) {
playerGold -= self.getUpgradeCost();
self.level++;
self.damage += 15;
self.range += 50;
self.fireRate = Math.max(20, self.fireRate - 10);
// Visual upgrade effect
graphics.scaleX *= 1.1;
graphics.scaleY *= 1.1;
if (self.level === 2) {
graphics.tint = 0xC0C0C0; // Silver
} else if (self.level === 3) {
graphics.tint = 0xFFD700; // Gold
}
updateGoldDisplay();
}
};
self.getUpgradeCost = function () {
return self.level * 75;
};
self.update = function () {
if (self.cooldown > 0) {
self.cooldown--;
}
// Find and shoot at nearest enemy
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (self.inRange(enemy)) {
var dx = self.x - enemy.x;
var dy = self.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
}
if (nearestEnemy) {
self.shoot(nearestEnemy);
}
};
self.down = function (x, y, obj) {
if (gameState === 'playing') {
self.upgrade();
}
};
return self;
});
var TowerBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('omarBullet', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0xFF8C00; // Orange color for tower bullets
self.speed = 8;
self.damage = 25;
self.targetX = 0;
self.targetY = 0;
self.hasHit = false;
self.update = function () {
if (!self.hasHit) {
// Move towards target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
self.hasHit = true;
}
}
// Remove if off screen
if (self.y < -100 || self.y > 2800 || self.x < -100 || self.x > 2148) {
self.alpha = 0;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Sound assets
// UI assets
// Enemy assets
// Hero assets
// Game state
var gameState = 'menu'; // 'menu', 'playing', 'victory'
var currentMode = '';
var enemiesRequired = 0;
var enemiesKilled = 0;
var gameStarted = false;
// Game objects
var omar;
var omarAI;
var bullets = [];
var enemies = [];
var confettiParticles = [];
var bloodParticles = [];
var terrainElements = [];
var lasers = [];
var towers = [];
var towerBullets = [];
var enemyPath = [];
var playerGold = 200;
var goldText;
var selectedTowerType = null;
var placementMode = false;
// UI elements
var titleText;
var scoreText;
var modeButtons = [];
// Enemy spawn timer - optimized for performance
var enemySpawnTimer = 0;
var enemySpawnRate = 60; // frames between spawns - faster to compensate for limited enemies
// Initialize menu
function initMenu() {
gameState = 'menu';
// Title - Enhanced Sultan Style
titleText = new Text2('My Sultan', {
size: 120,
fill: '#FFD700',
// Gold
stroke: '#8B0000',
// Dark red stroke
strokeThickness: 8,
dropShadow: true,
dropShadowColor: '#000000',
dropShadowDistance: 5,
dropShadowAngle: Math.PI / 4
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 400;
game.addChild(titleText);
// Add floating animation with enhanced rotation and scale effects
tween(titleText, {
y: 380,
rotation: 0.1,
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 2500,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Create continuous floating effect with enhanced rotation and scaling
function floatUp() {
tween(titleText, {
y: 370,
rotation: 0.08,
scaleX: 1.08,
scaleY: 1.08
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: floatDown
});
}
function floatDown() {
tween(titleText, {
y: 430,
rotation: -0.08,
scaleX: 0.98,
scaleY: 0.98
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: floatUp
});
}
floatDown();
}
});
// Add enhanced pulsing color effect with magical transitions
function createColorPulse() {
tween(titleText, {
tint: 0xFFB347 // Orange-gold tint
}, {
duration: 1200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(titleText, {
tint: 0xFF6B35 // Deeper orange
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(titleText, {
tint: 0xFFD700 // Back to gold
}, {
duration: 1000,
easing: tween.bounceOut,
onFinish: createColorPulse
});
}
});
}
});
}
createColorPulse();
// Add enhanced scale pulsing with glow effect
function createScalePulse() {
tween(titleText, {
scaleX: 1.15,
scaleY: 1.15,
alpha: 0.9
}, {
duration: 2000,
easing: tween.elasticInOut,
onFinish: function onFinish() {
tween(titleText, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1.0
}, {
duration: 2000,
easing: tween.bounceOut,
onFinish: createScalePulse
});
}
});
}
createScalePulse();
// Create animated background with floating magical particles - optimized
function createBackgroundEffects() {
// Add mystical floating orbs - reduced count
for (var i = 0; i < 6; i++) {
var orb = new Text2('⚫', {
size: 15 + Math.random() * 15,
fill: '#4B0082'
});
orb.anchor.set(0.5, 0.5);
orb.x = Math.random() * 2048;
orb.y = Math.random() * 2732;
orb.alpha = 0.2 + Math.random() * 0.3;
orb.tint = 0x9932CC;
game.addChild(orb);
// Add continuous floating animation
(function (orbObj) {
function floatOrb() {
if (orbObj && orbObj.parent && gameState === 'menu') {
tween(orbObj, {
y: orbObj.y + (Math.random() - 0.5) * 100,
x: orbObj.x + (Math.random() - 0.5) * 75,
scaleX: 0.8 + Math.random() * 0.4,
scaleY: 0.8 + Math.random() * 0.4,
alpha: 0.1 + Math.random() * 0.3,
rotation: Math.random() * Math.PI * 2
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: floatOrb
});
}
}
floatOrb();
})(orb);
}
// Add golden energy streams - optimized
for (var i = 0; i < 4; i++) {
var stream = new Text2('◊', {
size: 10 + Math.random() * 8,
fill: '#FFD700'
});
stream.anchor.set(0.5, 0.5);
stream.x = Math.random() * 2048;
stream.y = 2732 + Math.random() * 100;
stream.alpha = 0.4;
game.addChild(stream);
// Add upward floating animation with safety checks
(function (streamObj) {
function floatUp() {
if (streamObj && streamObj.parent && gameState === 'menu') {
tween(streamObj, {
y: -100,
x: streamObj.x + (Math.random() - 0.5) * 150,
rotation: Math.PI * 2,
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 6000 + Math.random() * 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
if (streamObj && streamObj.parent && gameState === 'menu') {
streamObj.y = 2732 + Math.random() * 100;
streamObj.x = Math.random() * 2048;
streamObj.alpha = 0.4;
streamObj.scaleX = 1.0;
streamObj.scaleY = 1.0;
streamObj.rotation = 0;
LK.setTimeout(floatUp, 1000);
}
}
});
}
}
floatUp();
})(stream);
}
// Add mystical runes that appear and disappear
var runeSymbols = ['◈', '◇', '◉', '◎', '⬟', '⬢', '⬡'];
for (var i = 0; i < 6; i++) {
var rune = new Text2(runeSymbols[Math.floor(Math.random() * runeSymbols.length)], {
size: 40 + Math.random() * 20,
fill: '#8A2BE2'
});
rune.anchor.set(0.5, 0.5);
rune.x = Math.random() * 2048;
rune.y = Math.random() * 2732;
rune.alpha = 0;
game.addChild(rune);
// Add mystical appearance animation
(function (runeObj) {
function runeAppear() {
LK.setTimeout(function () {
tween(runeObj, {
alpha: 0.7,
scaleX: 1.5,
scaleY: 1.5,
rotation: Math.PI
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(runeObj, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5,
rotation: Math.PI * 2
}, {
duration: 1500,
easing: tween.easeIn,
onFinish: function onFinish() {
runeObj.x = Math.random() * 2048;
runeObj.y = Math.random() * 2732;
runeAppear();
}
});
}
});
}, Math.random() * 5000);
}
runeAppear();
})(rune);
}
}
createBackgroundEffects();
// Add sparkle effects around title - optimized
function createSparkles() {
for (var i = 0; i < 3; i++) {
var sparkle = new Text2('✨', {
size: 25 + Math.random() * 15,
fill: '#FFD700'
});
sparkle.anchor.set(0.5, 0.5);
sparkle.x = titleText.x + (Math.random() - 0.5) * 300;
sparkle.y = titleText.y + (Math.random() - 0.5) * 150;
sparkle.alpha = 0;
game.addChild(sparkle);
// Animate sparkle with enhanced effects
tween(sparkle, {
alpha: 1,
scaleX: 1.5,
scaleY: 1.5,
rotation: Math.random() * Math.PI * 2
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(sparkle, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5,
y: sparkle.y - 50
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
if (sparkle && sparkle.parent) {
sparkle.destroy();
}
}
});
}
});
}
}
// Create sparkles periodically - reduced frequency
function sparkleTimer() {
if (gameState === 'menu') {
createSparkles();
LK.setTimeout(sparkleTimer, 3000 + Math.random() * 2000);
}
}
LK.setTimeout(sparkleTimer, 1500);
// Subtitle with enhanced effects
var subtitle = new Text2('Choose Your Quest', {
size: 50,
fill: '#FFFFFF',
stroke: '#FFD700',
strokeThickness: 2
});
subtitle.anchor.set(0.5, 0.5);
subtitle.x = 1024;
subtitle.y = 500;
subtitle.alpha = 0;
subtitle.scaleX = 0.5;
subtitle.scaleY = 0.5;
game.addChild(subtitle);
// Animate subtitle entrance
LK.setTimeout(function () {
tween(subtitle, {
alpha: 1,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1500,
easing: tween.elasticOut
});
}, 1000);
// Add subtle floating animation to subtitle
function subtitleFloat() {
tween(subtitle, {
y: 490,
rotation: 0.01
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(subtitle, {
y: 510,
rotation: -0.01
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: subtitleFloat
});
}
});
}
LK.setTimeout(subtitleFloat, 2000);
// Add color cycling effect to subtitle
function subtitleColorCycle() {
tween(subtitle, {
tint: 0xE6E6FA
}, {
duration: 2500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(subtitle, {
tint: 0xFFFFFF
}, {
duration: 2500,
easing: tween.easeInOut,
onFinish: subtitleColorCycle
});
}
});
}
LK.setTimeout(subtitleColorCycle, 1500);
// Create animated decorative border frame
function createMenuBorder() {
var borderElements = [];
// Top border
for (var i = 0; i < 20; i++) {
var topBorder = new Text2('◆', {
size: 25,
fill: '#DAA520'
});
topBorder.anchor.set(0.5, 0.5);
topBorder.x = 100 + i * 90;
topBorder.y = 150;
topBorder.alpha = 0.8;
game.addChild(topBorder);
borderElements.push(topBorder);
// Add pulsing animation with delay
(function (element, delay) {
LK.setTimeout(function () {
function pulse() {
tween(element, {
scaleX: 1.3,
scaleY: 1.3,
tint: 0xFFD700
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(element, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0xDAA520
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: pulse
});
}
});
}
pulse();
}, delay * 100);
})(topBorder, i);
}
// Bottom border
for (var i = 0; i < 20; i++) {
var bottomBorder = new Text2('◇', {
size: 25,
fill: '#DAA520'
});
bottomBorder.anchor.set(0.5, 0.5);
bottomBorder.x = 100 + i * 90;
bottomBorder.y = 2580;
bottomBorder.alpha = 0.8;
game.addChild(bottomBorder);
borderElements.push(bottomBorder);
// Add wave animation
(function (element, index) {
function wave() {
tween(element, {
y: 2580 + Math.sin(LK.ticks * 0.1 + index * 0.5) * 15,
rotation: Math.sin(LK.ticks * 0.05 + index * 0.3) * 0.2
}, {
duration: 50,
easing: tween.linear,
onFinish: wave
});
}
wave();
})(bottomBorder, i);
}
// Left border
for (var i = 0; i < 25; i++) {
var leftBorder = new Text2('◊', {
size: 20,
fill: '#DAA520'
});
leftBorder.anchor.set(0.5, 0.5);
leftBorder.x = 100;
leftBorder.y = 200 + i * 100;
leftBorder.alpha = 0.8;
game.addChild(leftBorder);
borderElements.push(leftBorder);
// Add flowing animation
(function (element, index) {
LK.setTimeout(function () {
function flow() {
tween(element, {
x: 120,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xB8860B
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(element, {
x: 100,
scaleX: 1.0,
scaleY: 1.0,
tint: 0xDAA520
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: flow
});
}
});
}
flow();
}, index * 150);
})(leftBorder, i);
}
// Right border
for (var i = 0; i < 25; i++) {
var rightBorder = new Text2('◈', {
size: 20,
fill: '#DAA520'
});
rightBorder.anchor.set(0.5, 0.5);
rightBorder.x = 1948;
rightBorder.y = 200 + i * 100;
rightBorder.alpha = 0.8;
game.addChild(rightBorder);
borderElements.push(rightBorder);
// Add flowing animation (opposite direction)
(function (element, index) {
LK.setTimeout(function () {
function flow() {
tween(element, {
x: 1928,
scaleX: 1.2,
scaleY: 1.2,
tint: 0xB8860B
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(element, {
x: 1948,
scaleX: 1.0,
scaleY: 1.0,
tint: 0xDAA520
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: flow
});
}
});
}
flow();
}, index * 150);
})(rightBorder, i);
}
// Corner ornaments
var corners = [{
x: 100,
y: 150,
symbol: '◉'
}, {
x: 1948,
y: 150,
symbol: '◉'
}, {
x: 100,
y: 2580,
symbol: '◉'
}, {
x: 1948,
y: 2580,
symbol: '◉'
}];
corners.forEach(function (corner, index) {
var ornament = new Text2(corner.symbol, {
size: 40,
fill: '#FFD700'
});
ornament.anchor.set(0.5, 0.5);
ornament.x = corner.x;
ornament.y = corner.y;
ornament.alpha = 0.9;
game.addChild(ornament);
// Add rotating glow animation
function rotateGlow() {
tween(ornament, {
rotation: Math.PI * 2,
scaleX: 1.5,
scaleY: 1.5,
tint: 0xFF6347
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
ornament.rotation = 0;
tween(ornament, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0xFFD700
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: rotateGlow
});
}
});
}
LK.setTimeout(rotateGlow, index * 500);
});
}
createMenuBorder();
// Mode buttons with enhanced animations
var nightButton = new ModeButton();
nightButton.setMode('Night Mode (100 enemies)', 'night', 100);
nightButton.x = 1024;
nightButton.y = 800;
nightButton.alpha = 0;
modeButtons.push(nightButton);
game.addChild(nightButton);
// Enhanced entrance animation for night button with dramatic effects
nightButton.scaleX = 0;
nightButton.scaleY = 0;
nightButton.y = 850;
nightButton.rotation = Math.PI;
nightButton.tint = 0x000080;
tween(nightButton, {
alpha: 1,
scaleX: 1.0,
scaleY: 1.0,
y: 800,
rotation: 0,
tint: 0xFFFFFF
}, {
duration: 1800,
easing: tween.elasticOut
});
// Add magical particle trail effect to night button
function createNightButtonTrail() {
for (var i = 0; i < 4; i++) {
var trail = new Text2('⭐', {
size: 15 + Math.random() * 10,
fill: '#87CEEB'
});
trail.anchor.set(0.5, 0.5);
trail.x = nightButton.x + (Math.random() - 0.5) * 200;
trail.y = nightButton.y + (Math.random() - 0.5) * 100;
trail.alpha = 0.8;
game.addChild(trail);
tween(trail, {
y: trail.y - 50,
alpha: 0,
scaleX: 0.3,
scaleY: 0.3,
rotation: Math.PI
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
trail.destroy();
}
});
}
}
function nightButtonTrailTimer() {
createNightButtonTrail();
LK.setTimeout(nightButtonTrailTimer, 1500 + Math.random() * 1000);
}
LK.setTimeout(nightButtonTrailTimer, 2000);
// Add continuous glow effect to night button
function nightButtonGlow() {
tween(nightButton, {
tint: 0x4169E1,
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(nightButton, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: nightButtonGlow
});
}
});
}
LK.setTimeout(nightButtonGlow, 500);
var dayButton = new ModeButton();
dayButton.setMode('Day Mode (100 enemies)', 'day', 100);
dayButton.x = 1024;
dayButton.y = 1000;
dayButton.alpha = 0;
modeButtons.push(dayButton);
game.addChild(dayButton);
// Enhanced entrance animation for day button with sun ray effects
dayButton.scaleX = 0;
dayButton.scaleY = 0;
dayButton.y = 1050;
dayButton.tint = 0xFFA500;
LK.setTimeout(function () {
tween(dayButton, {
alpha: 1,
scaleX: 1.0,
scaleY: 1.0,
y: 1000,
rotation: 0,
tint: 0xFFFFFF
}, {
duration: 1600,
easing: tween.elasticOut
});
// Add sun ray effects around day button
for (var r = 0; r < 12; r++) {
var ray = new Text2('|', {
size: 60,
fill: '#FFD700'
});
ray.anchor.set(0.5, 0);
ray.x = dayButton.x;
ray.y = dayButton.y;
ray.rotation = r * Math.PI / 6;
ray.alpha = 0;
ray.scaleX = 2;
game.addChild(ray);
// Animate rays appearing
(function (rayObj, index) {
LK.setTimeout(function () {
tween(rayObj, {
alpha: 0.4,
scaleY: 1.5,
y: rayObj.y - 30
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Add continuous pulsing to rays
function pulsRay() {
tween(rayObj, {
alpha: 0.6,
scaleY: 1.8
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(rayObj, {
alpha: 0.3,
scaleY: 1.2
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: pulsRay
});
}
});
}
pulsRay();
}
});
}, index * 100);
})(ray, r);
}
}, 600);
// Add continuous glow effect to day button
function dayButtonGlow() {
tween(dayButton, {
tint: 0xFFD700,
scaleX: 1.05,
scaleY: 1.05
}, {
duration: 1800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(dayButton, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1800,
easing: tween.easeInOut,
onFinish: dayButtonGlow
});
}
});
}
LK.setTimeout(dayButtonGlow, 800);
var betrayalButton = new ModeButton();
betrayalButton.setMode('My Sultan Became My Enemy (400)', 'betrayal', 400);
betrayalButton.x = 1024;
betrayalButton.y = 1200;
betrayalButton.alpha = 0;
modeButtons.push(betrayalButton);
game.addChild(betrayalButton);
// Enhanced dramatic entrance for betrayal button with ominous effects
betrayalButton.scaleX = 0;
betrayalButton.scaleY = 0;
betrayalButton.y = 1250;
betrayalButton.tint = 0x800000;
LK.setTimeout(function () {
// Add screen flash before betrayal button appears
LK.effects.flashScreen(0x8B0000, 300);
tween(betrayalButton, {
alpha: 1,
scaleX: 1.0,
scaleY: 1.0,
y: 1200,
rotation: 0,
tint: 0xFFFFFF
}, {
duration: 2000,
easing: tween.elasticOut
});
// Add ominous smoke effects around betrayal button
function createOminousSmoke() {
for (var s = 0; s < 6; s++) {
var smoke = new Text2('☁', {
size: 30 + Math.random() * 20,
fill: '#2F2F2F'
});
smoke.anchor.set(0.5, 0.5);
smoke.x = betrayalButton.x + (Math.random() - 0.5) * 300;
smoke.y = betrayalButton.y + 100 + Math.random() * 50;
smoke.alpha = 0.4;
smoke.tint = 0x8B0000;
game.addChild(smoke);
tween(smoke, {
y: smoke.y - 150,
alpha: 0,
scaleX: 2.0,
scaleY: 2.0,
rotation: Math.PI
}, {
duration: 4000,
easing: tween.easeOut,
onFinish: function onFinish() {
smoke.destroy();
}
});
}
}
function smokeTimer() {
createOminousSmoke();
LK.setTimeout(smokeTimer, 2000 + Math.random() * 1500);
}
smokeTimer();
// Add red lightning effects
function createRedLightning() {
for (var l = 0; l < 3; l++) {
var lightning = new Text2('⚡', {
size: 40 + Math.random() * 20,
fill: '#FF0000'
});
lightning.anchor.set(0.5, 0.5);
lightning.x = betrayalButton.x + (Math.random() - 0.5) * 400;
lightning.y = betrayalButton.y + (Math.random() - 0.5) * 200;
lightning.alpha = 0;
game.addChild(lightning);
tween(lightning, {
alpha: 1,
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(lightning, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
easing: tween.easeIn,
onFinish: function onFinish() {
lightning.destroy();
}
});
}
});
}
}
function lightningTimer() {
if (Math.random() < 0.4) {
createRedLightning();
}
LK.setTimeout(lightningTimer, 1000 + Math.random() * 2000);
}
LK.setTimeout(lightningTimer, 3000);
// Add dramatic shake effect after entrance
LK.setTimeout(function () {
function shakeEffect() {
tween(betrayalButton, {
x: 1024 + (Math.random() - 0.5) * 10,
rotation: (Math.random() - 0.5) * 0.05
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(betrayalButton, {
x: 1024,
rotation: 0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
// Random shake every few seconds
function randomShake() {
if (Math.random() < 0.3) {
shakeEffect();
}
LK.setTimeout(randomShake, 2000 + Math.random() * 3000);
}
randomShake();
}, 2000);
}, 600);
// Add continuous dramatic glow effect to betrayal button
function betrayalButtonGlow() {
tween(betrayalButton, {
tint: 0xFF4500,
scaleX: 1.08,
scaleY: 1.08,
rotation: 0.02
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(betrayalButton, {
tint: 0xFFFFFF,
scaleX: 1.0,
scaleY: 1.0,
rotation: -0.02
}, {
duration: 1200,
easing: tween.easeInOut,
onFinish: betrayalButtonGlow
});
}
});
}
LK.setTimeout(betrayalButtonGlow, 1100);
}
function startGame(mode, enemyCount) {
gameState = 'playing';
currentMode = mode;
enemiesRequired = enemyCount;
enemiesKilled = 0;
gameStarted = true;
// Clear menu
while (game.children.length > 0) {
var child = game.children[0];
child.destroy();
}
// Set background based on mode
if (mode === 'night') {
// Add moon glow animation
var _createMoonGlow = function createMoonGlow() {
tween(moon, {
scaleX: 1.2,
scaleY: 1.2,
alpha: 0.8
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(moon, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1.0
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: _createMoonGlow
});
}
});
};
game.setBackgroundColor(0x000033);
// Add night atmosphere effects
// Create moon glow effect
var moon = new Text2('🌙', {
size: 80,
fill: '#F0F8FF'
});
moon.anchor.set(0.5, 0.5);
moon.x = 1800;
moon.y = 300;
game.addChild(moon);
_createMoonGlow();
// Add twinkling stars
for (var s = 0; s < 15; s++) {
var star = new Text2('⭐', {
size: 20 + Math.random() * 15,
fill: '#FFFFFF'
});
star.anchor.set(0.5, 0.5);
star.x = Math.random() * 2048;
star.y = Math.random() * 400 + 50;
star.alpha = 0.3 + Math.random() * 0.7;
game.addChild(star);
// Add twinkling animation with random delay
(function (starObj) {
var _twinkle = function twinkle() {
tween(starObj, {
alpha: 0.2,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 1000 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(starObj, {
alpha: 1.0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: _twinkle
});
}
});
};
LK.setTimeout(_twinkle, Math.random() * 2000);
})(star);
}
} else if (mode === 'day') {
game.setBackgroundColor(0x87CEEB);
// Add day atmosphere effects
// Create sun with rays
var sun = new Text2('☀️', {
size: 100,
fill: '#FFD700'
});
sun.anchor.set(0.5, 0.5);
sun.x = 250;
sun.y = 250;
game.addChild(sun);
// Add sun rotation animation
tween(sun, {
rotation: Math.PI * 2
}, {
duration: 10000,
easing: tween.linear,
onFinish: function onFinish() {
sun.rotation = 0;
// Create recursive rotation
arguments.callee();
}
});
// Add sun pulsing glow
var _sunGlow = function sunGlow() {
tween(sun, {
scaleX: 1.1,
scaleY: 1.1,
tint: 0xFFA500
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(sun, {
scaleX: 1.0,
scaleY: 1.0,
tint: 0xFFFFFF
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: _sunGlow
});
}
});
};
_sunGlow();
// Create floating clouds
for (var c = 0; c < 6; c++) {
var cloud = new Text2('☁️', {
size: 60 + Math.random() * 30,
fill: '#FFFFFF'
});
cloud.anchor.set(0.5, 0.5);
cloud.x = Math.random() * 2048;
cloud.y = Math.random() * 300 + 100;
cloud.alpha = 0.7 + Math.random() * 0.3;
game.addChild(cloud);
// Add cloud floating animation
(function (cloudObj) {
var startX = cloudObj.x;
var _float2 = function _float() {
tween(cloudObj, {
x: startX + (Math.random() - 0.5) * 200,
scaleX: 0.9 + Math.random() * 0.2,
scaleY: 0.9 + Math.random() * 0.2
}, {
duration: 8000 + Math.random() * 4000,
easing: tween.easeInOut,
onFinish: _float2
});
};
_float2();
})(cloud);
}
// Add light particles floating upward
var createDayParticles = function createDayParticles() {
for (var p = 0; p < 3; p++) {
var particle = new Text2('✨', {
size: 15 + Math.random() * 10,
fill: '#FFD700'
});
particle.anchor.set(0.5, 0.5);
particle.x = Math.random() * 2048;
particle.y = 2732;
particle.alpha = 0.5;
game.addChild(particle);
tween(particle, {
y: -100,
alpha: 0,
rotation: Math.PI * 4,
scaleX: 0.3,
scaleY: 0.3
}, {
duration: 8000 + Math.random() * 4000,
easing: tween.easeOut,
onFinish: function onFinish() {
particle.destroy();
}
});
}
};
// Create day particles periodically
var _dayParticleTimer = function dayParticleTimer() {
createDayParticles();
LK.setTimeout(_dayParticleTimer, 3000 + Math.random() * 2000);
};
_dayParticleTimer();
} else if (mode === 'betrayal') {
game.setBackgroundColor(0x8B0000);
}
// Create Omar
omar = new Omar();
omar.x = 1024;
omar.y = 2200; // Position Omar on the road
game.addChild(omar);
// Create and activate AI
omarAI = new OmarAI();
omarAI.activate();
game.addChild(omarAI);
// Generate terrain for the mode
generateTerrain(mode);
// Create score text
scoreText = new Text2('Enemies: 0 / ' + enemiesRequired, {
size: 60,
fill: '#FFFFFF'
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Create gold display
goldText = new Text2('Gold: ' + playerGold, {
size: 50,
fill: '#FFD700'
});
goldText.anchor.set(0, 0);
goldText.x = 50;
goldText.y = 100;
LK.gui.topLeft.addChild(goldText);
// Create tower placement buttons
var towerButton = new Text2('Build Tower (50g)', {
size: 40,
fill: '#8B4513',
stroke: '#FFFFFF',
strokeThickness: 2
});
towerButton.anchor.set(0, 0);
towerButton.x = 50;
towerButton.y = 200;
LK.gui.topLeft.addChild(towerButton);
// Create enemy path
enemyPath = [{
x: 1024,
y: -50
}, {
x: 1024,
y: 400
}, {
x: 500,
y: 600
}, {
x: 1500,
y: 800
}, {
x: 1024,
y: 1200
}, {
x: 1024,
y: 2300
}];
// Reset arrays
bullets = [];
enemies = [];
confettiParticles = [];
bloodParticles = [];
terrainElements = [];
lasers = [];
towers = [];
towerBullets = [];
playerGold = 200;
placementMode = false;
selectedTowerType = null;
// Reset spawn timer
enemySpawnTimer = 0;
// After score 90, spawn enemies much more frequently
if (enemiesKilled >= 90) {
enemySpawnRate = Math.max(10, 30 - Math.floor((enemiesKilled - 90) / 10) * 5);
} else {
enemySpawnRate = Math.max(30, 90 - Math.floor(enemiesKilled / 20) * 10);
}
}
function generateTerrain(mode) {
// Clear existing terrain
for (var i = terrainElements.length - 1; i >= 0; i--) {
terrainElements[i].destroy();
}
terrainElements = [];
// Add road in the center with mode-specific enhancements
var road = new Terrain();
road.init('road', 1024, 1366);
// Apply mode-specific road effects
if (mode === 'night') {
road.tint = 0x666699; // Darker bluish road for night
road.alpha = 0.9;
} else if (mode === 'day') {
road.tint = 0xFFFFBB; // Brighter, sunlit road for day
road.alpha = 1.0;
// Add subtle road shimmer effect for day
var _roadShimmer = function roadShimmer() {
tween(road, {
tint: 0xFFFFDD
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(road, {
tint: 0xFFFFBB
}, {
duration: 3000,
easing: tween.easeInOut,
onFinish: _roadShimmer
});
}
});
};
_roadShimmer();
} else if (mode === 'betrayal') {
road.tint = 0xAA6666; // Reddish road for betrayal mode
}
terrainElements.push(road);
game.addChild(road);
// Add castle at the top
var castle = new Terrain();
castle.init('castle', 1024, 300);
terrainElements.push(castle);
game.addChild(castle);
// Add some decorative terrain elements based on mode
if (mode === 'day') {
var _loop = function _loop() {
terrain = new Terrain();
type = Math.random() > 0.5 ? 'stone' : 'dirt';
terrain.init(type, Math.random() * 1700 + 174, Math.random() * 2000 + 400);
// Add bright daylight tint to terrain
terrain.tint = 0xFFFF99; // Bright sunny tint
terrain.alpha = 1.0;
// Add floating animation to terrain objects with enhanced brightness effects
terrain.startY = terrain.y;
function createTerrainFloat(terrainObj) {
tween(terrainObj, {
y: terrainObj.startY - 5,
rotation: 0.05,
tint: 0xFFFFAA,
scaleX: 1.02,
scaleY: 1.02
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(terrainObj, {
y: terrainObj.startY + 5,
rotation: -0.05,
tint: 0xFFFF99,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
createTerrainFloat(terrainObj);
}
});
}
});
}
createTerrainFloat(terrain);
terrainElements.push(terrain);
game.addChild(terrain);
},
terrain,
type;
// Add some stones and dirt for day mode
for (var i = 0; i < 8; i++) {
_loop();
}
// Add sun rays effect
for (var r = 0; r < 8; r++) {
var ray = new Text2('|', {
size: 400,
fill: '#FFD700'
});
ray.anchor.set(0.5, 0);
ray.x = 250 + Math.cos(r * Math.PI / 4) * 400;
ray.y = 250;
ray.rotation = r * Math.PI / 4;
ray.alpha = 0.1;
ray.scaleX = 3;
game.addChild(ray);
// Add ray animation
(function (rayObj) {
var _rayPulse = function rayPulse() {
tween(rayObj, {
alpha: 0.2,
scaleX: 4,
scaleY: 1.2
}, {
duration: 4000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(rayObj, {
alpha: 0.05,
scaleX: 3,
scaleY: 1.0
}, {
duration: 4000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: _rayPulse
});
}
});
};
LK.setTimeout(_rayPulse, Math.random() * 2000);
})(ray);
}
} else if (mode === 'night') {
// Add fewer, darker terrain for night mode with mystical effects
for (var i = 0; i < 5; i++) {
var terrain = new Terrain();
terrain.init('stone', Math.random() * 1700 + 174, Math.random() * 2000 + 400);
// Add dark tint to terrain for night mode
terrain.tint = 0x4444AA;
terrain.alpha = 0.8;
// Add mystical glow animation to night terrain
(function (terrainObj) {
var _mysticalGlow = function mysticalGlow() {
tween(terrainObj, {
tint: 0x6666FF,
alpha: 0.9
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(terrainObj, {
tint: 0x4444AA,
alpha: 0.8
}, {
duration: 3000 + Math.random() * 2000,
easing: tween.easeInOut,
onFinish: _mysticalGlow
});
}
});
};
LK.setTimeout(_mysticalGlow, Math.random() * 1000);
})(terrain);
terrainElements.push(terrain);
game.addChild(terrain);
}
// Add night fog effect
var fog = new Text2('🌫️', {
size: 150,
fill: '#E6E6FA'
});
fog.anchor.set(0.5, 0.5);
fog.x = 1024;
fog.y = 1500;
fog.alpha = 0.3;
game.addChild(fog);
// Add fog movement animation
var _fogDrift = function fogDrift() {
tween(fog, {
x: 1024 + (Math.random() - 0.5) * 300,
scaleX: 1.2 + Math.random() * 0.5,
scaleY: 1.2 + Math.random() * 0.5,
alpha: 0.2 + Math.random() * 0.2
}, {
duration: 6000 + Math.random() * 4000,
easing: tween.easeInOut,
onFinish: _fogDrift
});
};
_fogDrift();
} else if (mode === 'betrayal') {
// Add strategic terrain for betrayal mode
for (var i = 0; i < 10; i++) {
var terrain = new Terrain();
var type = Math.random() > 0.3 ? 'stone' : 'dirt';
terrain.init(type, Math.random() * 1700 + 174, Math.random() * 2000 + 400);
terrainElements.push(terrain);
game.addChild(terrain);
}
}
}
function spawnEnemy() {
var enemy = new Enemy();
// Determine enemy type based on mode and progress
var enemyType = 'aamir';
var progress = enemiesKilled / enemiesRequired;
if (currentMode === 'betrayal') {
if (Math.random() < 0.3) {
enemyType = 'sultan';
} else if (progress > 0.7 && Math.random() < 0.2) {
enemyType = 'vega';
}
} else {
if (progress > 0.8 && Math.random() < 0.15) {
enemyType = 'vega';
}
}
enemy.init(enemyType);
enemy.x = Math.random() * 1700 + 174; // Better bounds to keep enemies visible
enemy.y = -50;
// Add spawn entrance animation
enemy.alpha = 0;
enemy.scaleX = 0.3;
enemy.scaleY = 0.3;
enemy.rotation = Math.PI;
// Animate enemy entrance
tween(enemy, {
alpha: 1,
scaleX: 1.0,
scaleY: 1.0,
rotation: 0,
tint: 0xFFFFFF
}, {
duration: 500,
easing: tween.elasticOut
});
// Add spawn glow effect
tween(enemy, {
tint: 0xFF6B35
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemy, {
tint: 0xFFFFFF
}, {
duration: 400,
easing: tween.easeOut
});
}
});
enemies.push(enemy);
game.addChild(enemy);
}
function checkVictory() {
// Check for sultan meeting in night and day modes at score 50
if ((currentMode === 'night' || currentMode === 'day') && enemiesKilled >= 50 && gameState !== 'sultanMeeting') {
gameState = 'sultanMeeting';
LK.getSound('victory').play();
// Create sultan character
var sultanChar = new Terrain();
sultanChar.init('sultan', 1024, 1366);
game.addChild(sultanChar);
tween(sultanChar, {
scaleX: 10,
scaleY: 10
}, {
duration: 2000,
easing: tween.easeOut
});
// Sultan meeting text
var meetingText = new Text2('My Sultan Arrives!', {
size: 80,
fill: '#FFD700',
stroke: '#8B0000',
strokeThickness: 4
});
meetingText.anchor.set(0.5, 0.5);
meetingText.x = 1024;
meetingText.y = 800;
game.addChild(meetingText);
tween(meetingText, {
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFFB347
}, {
duration: 1000,
easing: tween.easeInOut
});
// Create golden confetti for sultan meeting
for (var i = 0; i < 30; i++) {
var confetti = new Confetti();
confetti.x = Math.random() * 2048;
confetti.y = Math.random() * 500 + 500;
confetti.tint = 0xFFD700; // Golden confetti for sultan
confettiParticles.push(confetti);
game.addChild(confetti);
}
// Continue game after sultan meeting
LK.setTimeout(function () {
gameState = 'playing';
meetingText.destroy();
sultanChar.destroy();
}, 3000);
return;
}
// Check for sultan meeting in betrayal mode at exactly 10 enemies killed
if (currentMode === 'betrayal' && enemiesKilled === 10 && gameState !== 'sultanMeeting') {
gameState = 'sultanMeeting';
LK.getSound('victory').play();
// Create sultan character
var sultanChar = new Terrain();
sultanChar.init('sultan', 1024, 1366);
game.addChild(sultanChar);
tween(sultanChar, {
scaleX: 10,
scaleY: 10
}, {
duration: 2000,
easing: tween.easeOut
});
// Sultan betrayal meeting text
var meetingText = new Text2('The Sultan Has Turned Against Us!', {
size: 70,
fill: '#FF0000',
stroke: '#8B0000',
strokeThickness: 4
});
meetingText.anchor.set(0.5, 0.5);
meetingText.x = 1024;
meetingText.y = 800;
game.addChild(meetingText);
tween(meetingText, {
scaleX: 1.2,
scaleY: 1.2,
tint: 0xFF4500
}, {
duration: 1000,
easing: tween.easeInOut
});
// Create red confetti for betrayal meeting
for (var i = 0; i < 30; i++) {
var confetti = new Confetti();
confetti.x = Math.random() * 2048;
confetti.y = Math.random() * 500 + 500;
confetti.tint = 0xFF0000; // Red confetti for betrayal
confettiParticles.push(confetti);
game.addChild(confetti);
}
// Continue game after sultan meeting
LK.setTimeout(function () {
gameState = 'playing';
meetingText.destroy();
sultanChar.destroy();
}, 3000);
return;
}
if (enemiesKilled >= enemiesRequired) {
// Add celebration sparkles around victory text
var createVictorySparkles = function createVictorySparkles() {
for (var s = 0; s < 10; s++) {
var sparkle = new Text2('✨', {
size: 40 + Math.random() * 30,
fill: '#FFD700'
});
sparkle.anchor.set(0.5, 0.5);
sparkle.x = victoryText.x + (Math.random() - 0.5) * 500;
sparkle.y = victoryText.y + (Math.random() - 0.5) * 300;
sparkle.alpha = 0;
game.addChild(sparkle);
tween(sparkle, {
alpha: 1,
scaleX: 2.0,
scaleY: 2.0,
rotation: Math.PI * 2
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(sparkle, {
alpha: 0,
scaleX: 0.2,
scaleY: 0.2
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
sparkle.destroy();
}
});
}
});
}
};
gameState = 'victory';
LK.getSound('victory').play();
// Create optimized confetti (reduced count for performance)
for (var i = 0; i < 20; i++) {
var confetti = new Confetti();
confetti.x = Math.random() * 2048;
confetti.y = Math.random() * 500 + 500;
// Random colors for confetti
var colors = [0xFFD700, 0xFF1493, 0x00FF00, 0x00BFFF, 0xFF4500];
confetti.tint = colors[Math.floor(Math.random() * colors.length)];
confettiParticles.push(confetti);
game.addChild(confetti);
}
// Victory text with enhanced entrance animation
var victoryText = new Text2('Victory! Love Conquers All!', {
size: 70,
fill: '#FFD700',
stroke: '#8B0000',
strokeThickness: 4
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 1024;
victoryText.y = 1366;
victoryText.alpha = 0;
victoryText.scaleX = 0.3;
victoryText.scaleY = 0.3;
game.addChild(victoryText);
// Animate victory text entrance
tween(victoryText, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2,
rotation: 0.1
}, {
duration: 1000,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Add continuous celebration animation
function celebrateAnimation() {
tween(victoryText, {
scaleX: 1.3,
scaleY: 1.3,
tint: 0xFF6B35,
rotation: -0.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(victoryText, {
scaleX: 1.1,
scaleY: 1.1,
tint: 0xFFD700,
rotation: 0.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: celebrateAnimation
});
}
});
}
celebrateAnimation();
}
});
createVictorySparkles();
LK.setTimeout(createVictorySparkles, 1500);
LK.setTimeout(createVictorySparkles, 3000);
// Return to menu after 5 seconds
LK.setTimeout(function () {
// Clear game
while (game.children.length > 0) {
var child = game.children[0];
child.destroy();
}
while (LK.gui.top.children.length > 0) {
var child = LK.gui.top.children[0];
child.destroy();
}
// Reset arrays
bullets = [];
enemies = [];
confettiParticles = [];
bloodParticles = [];
terrainElements = [];
lasers = [];
modeButtons = [];
initMenu();
}, 5000);
}
}
// Touch controls
var isTouching = false;
var lastTapTime = 0;
var doubleTapDelay = 300; // 300ms for double tap detection
game.down = function (x, y, obj) {
if (gameState === 'playing') {
// Check if clicking on tower placement button area
if (x < 300 && y < 300) {
if (x > 50 && x < 250 && y > 200 && y < 250) {
placementMode = !placementMode;
selectedTowerType = placementMode ? 'tower' : null;
return;
}
}
// Tower placement mode
if (placementMode && selectedTowerType === 'tower' && playerGold >= 50) {
// Check if position is valid (not too close to path or other towers)
var validPosition = true;
// Check distance from path
for (var i = 0; i < enemyPath.length; i++) {
var pathPoint = enemyPath[i];
var dx = x - pathPoint.x;
var dy = y - pathPoint.y;
if (Math.sqrt(dx * dx + dy * dy) < 100) {
validPosition = false;
break;
}
}
// Check distance from other towers
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
var dx = x - tower.x;
var dy = y - tower.y;
if (Math.sqrt(dx * dx + dy * dy) < 120) {
validPosition = false;
break;
}
}
if (validPosition && y > 400 && y < 2200 && x > 200 && x < 1848) {
var newTower = new Tower();
newTower.x = x;
newTower.y = y;
towers.push(newTower);
game.addChild(newTower);
playerGold -= 50;
updateGoldDisplay();
placementMode = false;
selectedTowerType = null;
}
return;
}
isTouching = true;
var currentTime = Date.now();
// Check for double tap to shoot laser
if (currentTime - lastTapTime < doubleTapDelay) {
// Add screen shake effect for laser
var screenShake = function screenShake() {
tween(game, {
x: (Math.random() - 0.5) * 15,
y: (Math.random() - 0.5) * 15
}, {
duration: 50,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(game, {
x: 0,
y: 0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
omar.shootLaser();
for (var shakeCount = 0; shakeCount < 3; shakeCount++) {
LK.setTimeout(screenShake, shakeCount * 100);
}
} else {
omar.shoot();
}
lastTapTime = currentTime;
}
};
game.up = function (x, y, obj) {
isTouching = false;
};
game.move = function (x, y, obj) {
if (gameState === 'playing' && omar) {
// Manual control overrides AI
if (omarAI) {
omarAI.deactivate();
}
omar.x = Math.max(40, Math.min(2008, x));
if (isTouching) {
omar.shoot();
}
// Reactivate AI after a short delay
LK.setTimeout(function () {
if (omarAI) {
omarAI.activate();
}
}, 1000);
}
};
game.update = function () {
if (gameState === 'playing') {
// Spawn enemies with better control
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate && enemies.length < 12) {
spawnEnemy();
enemySpawnTimer = 0;
// Gradual spawn rate increase with reasonable limits
if (enemiesKilled >= 90) {
enemySpawnRate = Math.max(20, 45 - Math.floor((enemiesKilled - 90) / 15) * 3);
} else {
enemySpawnRate = Math.max(40, 80 - Math.floor(enemiesKilled / 25) * 5);
}
}
// Update bullets - remove bullets that go too far off screen for performance
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (!bullet || bullet.alpha <= 0) {
if (bullet) bullet.destroy();
bullets.splice(i, 1);
continue;
}
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove bullets that are way off screen for performance
if (bullet.y < -500 || bullet.y > 2800) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Optimized collision detection - only check nearby enemies
var hit = false;
for (var j = enemies.length - 1; j >= 0 && !hit; j--) {
var enemy = enemies[j];
if (!enemy || enemy.alpha <= 0) continue;
// Quick distance check before expensive intersection
var dx = bullet.x - enemy.x;
var dy = bullet.y - enemy.y;
if (dx * dx + dy * dy < 8000 && bullet.intersects(enemy)) {
// Add bullet impact flash effect
tween(enemy, {
tint: 0xFFFFFF,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemy, {
tint: 0xFF0000,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 120,
easing: tween.easeOut
});
}
});
// Create impact explosion particles
for (var p = 0; p < 8; p++) {
var spark = new BloodParticle();
spark.x = bullet.x;
spark.y = bullet.y;
var angle = p * Math.PI * 2 / 8;
spark.speedX = Math.cos(angle) * 4;
spark.speedY = Math.sin(angle) * 4;
spark.life = 15;
bloodParticles.push(spark);
game.addChild(spark);
}
// Add blood spray even when enemy is just damaged (not killed)
for (var k = 0; k < 4; k++) {
var blood = new BloodParticle();
blood.x = enemy.x + (Math.random() - 0.5) * 40;
blood.y = enemy.y + (Math.random() - 0.5) * 40;
blood.speedX = (Math.random() - 0.5) * 8;
blood.speedY = Math.random() * -6 - 2;
blood.life = 25;
blood.scaleX = 0.6;
blood.scaleY = 0.6;
blood.tint = 0xAA0000;
bloodParticles.push(blood);
game.addChild(blood);
}
if (enemy.takeDamage()) {
// Enhanced death animation with screen flash
LK.effects.flashScreen(0xFF4444, 150);
tween(enemy, {
scaleX: 1.8,
scaleY: 1.8,
alpha: 0,
rotation: Math.PI * 0.8,
tint: 0xFF0000
}, {
duration: 400,
easing: tween.bounceOut,
onFinish: function onFinish() {
enemy.destroy();
}
});
// Create optimized blood spray effect - reduced particle count
if (bloodParticles.length < 50) {
// Limit total particles
for (var k = 0; k < 6; k++) {
var blood = new BloodParticle();
blood.x = enemy.x + (Math.random() - 0.5) * 60;
blood.y = enemy.y + (Math.random() - 0.5) * 60;
blood.speedX = (Math.random() - 0.5) * 12;
blood.speedY = Math.random() * -8 - 3;
blood.life = 35; // Shorter life
// Add variety to blood particle colors
var bloodColors = [0xFF0000, 0xCC0000, 0x990000];
blood.tint = bloodColors[Math.floor(Math.random() * bloodColors.length)];
bloodParticles.push(blood);
game.addChild(blood);
}
}
enemies.splice(j, 1);
enemiesKilled++;
// Update score immediately when each enemy dies
scoreText.setText('Enemies: ' + enemiesKilled + ' / ' + enemiesRequired);
checkVictory();
}
// Bullet continues through enemy - no destruction
hit = true;
break;
}
}
if (!hit) {
bullet.lastY = bullet.y;
}
}
// Limit enemies on screen for performance - increase limit after score 90
var enemyLimit = enemiesKilled >= 90 ? 15 : 8;
if (enemies.length > enemyLimit) {
var oldEnemy = enemies.shift();
oldEnemy.destroy();
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
// Game over if enemy passes Omar's defensive line (y > 2300)
if (enemy.lastY <= 2300 && enemy.y > 2300) {
LK.showGameOver();
return;
}
enemy.lastY = enemy.y;
}
// Update lasers
for (var i = lasers.length - 1; i >= 0; i--) {
var laser = lasers[i];
// Add pulsing laser beam effect
if (laser.duration > 0) {
tween(laser, {
scaleX: 1.2 + Math.sin(LK.ticks * 0.3) * 0.2,
tint: 0x00FFFF
}, {
duration: 50,
easing: tween.linear
});
}
// Check laser collision with all enemies in range
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
// Check if enemy intersects with laser beam
if (laser.intersects(enemy)) {
// Laser instantly kills enemies regardless of health
// Create intense explosion effect
LK.effects.flashScreen(0x00FFFF, 200);
// Create electric spark particles
for (var k = 0; k < 12; k++) {
var spark = new BloodParticle();
spark.x = enemy.x + (Math.random() - 0.5) * 60;
spark.y = enemy.y + (Math.random() - 0.5) * 60;
spark.speedX = (Math.random() - 0.5) * 15;
spark.speedY = (Math.random() - 0.5) * 15;
spark.life = 25;
spark.tint = 0x00FFFF; // Electric blue sparks
bloodParticles.push(spark);
game.addChild(spark);
}
// Enhanced enemy destruction animation
tween(enemy, {
scaleX: 2.0,
scaleY: 2.0,
alpha: 0,
rotation: Math.PI * 1.5,
tint: 0x00FFFF
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
enemy.destroy();
}
});
// Create enhanced blood spray effect for laser kills - more dramatic
for (var k = 0; k < 12; k++) {
var blood = new BloodParticle();
blood.x = enemy.x + (Math.random() - 0.5) * 100;
blood.y = enemy.y + (Math.random() - 0.5) * 100;
blood.speedX = (Math.random() - 0.5) * 20; // Faster for laser kills
blood.speedY = Math.random() * -15 - 5; // Higher velocity
blood.life = 60; // Longer lasting
blood.tint = 0xFF0000;
// Add some variety to blood colors for laser kills
var laserBloodColors = [0xFF0000, 0xFF4444, 0xCC0000];
blood.tint = laserBloodColors[Math.floor(Math.random() * laserBloodColors.length)];
bloodParticles.push(blood);
game.addChild(blood);
// Add animation to blood particles
tween(blood, {
scaleX: 1.2,
scaleY: 1.2,
rotation: Math.random() * Math.PI * 2
}, {
duration: blood.life * 16,
easing: tween.easeOut
});
}
// Add additional blood splatter effect for laser kills
for (var k = 0; k < 10; k++) {
var splatter = new BloodParticle();
splatter.x = enemy.x + (Math.random() - 0.5) * 150;
splatter.y = enemy.y + (Math.random() - 0.5) * 150;
splatter.speedX = (Math.random() - 0.5) * 12;
splatter.speedY = (Math.random() - 0.5) * 12;
splatter.life = 80; // Longer for dramatic effect
splatter.scaleX = 0.4;
splatter.scaleY = 0.4;
splatter.tint = 0x660000; // Darker blood for contrast
bloodParticles.push(splatter);
game.addChild(splatter);
}
enemies.splice(j, 1);
enemiesKilled += 5; // Award 5 enemies killed for laser kill
// Update score immediately when each enemy dies
scoreText.setText('Enemies: ' + enemiesKilled + ' / ' + enemiesRequired);
checkVictory();
}
}
// Remove laser when duration expires
if (laser.duration <= 0) {
laser.destroy();
lasers.splice(i, 1);
}
}
// Update towers
for (var i = 0; i < towers.length; i++) {
var tower = towers[i];
tower.update();
}
// Update tower bullets
for (var i = towerBullets.length - 1; i >= 0; i--) {
var bullet = towerBullets[i];
if (bullet.alpha <= 0) {
bullet.destroy();
towerBullets.splice(i, 1);
continue;
}
// Check collision with enemies
var hit = false;
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
var dx = bullet.x - enemy.x;
var dy = bullet.y - enemy.y;
if (dx * dx + dy * dy < 2500 && bullet.intersects(enemy)) {
// Tower bullet impact
tween(enemy, {
tint: 0xFFFFFF,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 60,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemy, {
tint: 0xFF6666,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
// Create impact particles
for (var p = 0; p < 4; p++) {
var spark = new BloodParticle();
spark.x = bullet.x;
spark.y = bullet.y;
var angle = p * Math.PI * 2 / 4;
spark.speedX = Math.cos(angle) * 3;
spark.speedY = Math.sin(angle) * 3;
spark.life = 10;
spark.tint = 0xFF8C00;
bloodParticles.push(spark);
game.addChild(spark);
}
if (enemy.takeDamage(bullet.damage)) {
// Enemy killed by tower
tween(enemy, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0,
rotation: Math.PI * 0.5,
tint: 0xFF4444
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
enemy.destroy();
}
});
// Create blood spray
for (var k = 0; k < 8; k++) {
var blood = new BloodParticle();
blood.x = enemy.x + (Math.random() - 0.5) * 60;
blood.y = enemy.y + (Math.random() - 0.5) * 60;
blood.speedX = (Math.random() - 0.5) * 12;
blood.speedY = Math.random() * -8 - 2;
blood.life = 35;
bloodParticles.push(blood);
game.addChild(blood);
}
enemies.splice(j, 1);
enemiesKilled++;
scoreText.setText('Enemies: ' + enemiesKilled + ' / ' + enemiesRequired);
checkVictory();
}
bullet.destroy();
towerBullets.splice(i, 1);
hit = true;
break;
}
}
}
// Update AI
if (omarAI) {
omarAI.update();
}
// Reduced auto shoot frequency for better performance (only when AI is not active)
if (LK.ticks % 20 === 0 && (!omarAI || !omarAI.isActive)) {
omar.shoot();
}
}
// Update confetti
for (var i = confettiParticles.length - 1; i >= 0; i--) {
var confetti = confettiParticles[i];
if (confetti.life <= 0) {
confetti.destroy();
confettiParticles.splice(i, 1);
}
}
// Update blood particles with better cleanup
for (var i = bloodParticles.length - 1; i >= 0; i--) {
var blood = bloodParticles[i];
if (!blood || blood.life <= 0 || blood.alpha <= 0) {
if (blood && blood.parent) {
blood.destroy();
}
bloodParticles.splice(i, 1);
}
}
// Limit total blood particles for performance
if (bloodParticles.length > 30) {
var excess = bloodParticles.splice(0, bloodParticles.length - 30);
for (var i = 0; i < excess.length; i++) {
if (excess[i] && excess[i].parent) {
excess[i].destroy();
}
}
}
};
function updateGoldDisplay() {
if (goldText) {
goldText.setText('Gold: ' + playerGold);
}
}
// Initialize the menu
initMenu(); ===================================================================
--- original.js
+++ change.js
@@ -615,75 +615,81 @@
}
});
}
createScalePulse();
- // Create animated background with floating magical particles
+ // Create animated background with floating magical particles - optimized
function createBackgroundEffects() {
- // Add mystical floating orbs
- for (var i = 0; i < 12; i++) {
+ // Add mystical floating orbs - reduced count
+ for (var i = 0; i < 6; i++) {
var orb = new Text2('⚫', {
- size: 20 + Math.random() * 25,
+ size: 15 + Math.random() * 15,
fill: '#4B0082'
});
orb.anchor.set(0.5, 0.5);
orb.x = Math.random() * 2048;
orb.y = Math.random() * 2732;
- orb.alpha = 0.3 + Math.random() * 0.4;
+ orb.alpha = 0.2 + Math.random() * 0.3;
orb.tint = 0x9932CC;
game.addChild(orb);
// Add continuous floating animation
(function (orbObj) {
function floatOrb() {
- tween(orbObj, {
- y: orbObj.y + (Math.random() - 0.5) * 200,
- x: orbObj.x + (Math.random() - 0.5) * 150,
- scaleX: 0.8 + Math.random() * 0.6,
- scaleY: 0.8 + Math.random() * 0.6,
- alpha: 0.2 + Math.random() * 0.5,
- rotation: Math.random() * Math.PI * 2
- }, {
- duration: 4000 + Math.random() * 3000,
- easing: tween.easeInOut,
- onFinish: floatOrb
- });
+ if (orbObj && orbObj.parent && gameState === 'menu') {
+ tween(orbObj, {
+ y: orbObj.y + (Math.random() - 0.5) * 100,
+ x: orbObj.x + (Math.random() - 0.5) * 75,
+ scaleX: 0.8 + Math.random() * 0.4,
+ scaleY: 0.8 + Math.random() * 0.4,
+ alpha: 0.1 + Math.random() * 0.3,
+ rotation: Math.random() * Math.PI * 2
+ }, {
+ duration: 3000 + Math.random() * 2000,
+ easing: tween.easeInOut,
+ onFinish: floatOrb
+ });
+ }
}
floatOrb();
})(orb);
}
- // Add golden energy streams
- for (var i = 0; i < 8; i++) {
+ // Add golden energy streams - optimized
+ for (var i = 0; i < 4; i++) {
var stream = new Text2('◊', {
- size: 15 + Math.random() * 10,
+ size: 10 + Math.random() * 8,
fill: '#FFD700'
});
stream.anchor.set(0.5, 0.5);
stream.x = Math.random() * 2048;
- stream.y = 2732 + Math.random() * 200;
- stream.alpha = 0.6;
+ stream.y = 2732 + Math.random() * 100;
+ stream.alpha = 0.4;
game.addChild(stream);
- // Add upward floating animation
+ // Add upward floating animation with safety checks
(function (streamObj) {
function floatUp() {
- tween(streamObj, {
- y: -200,
- x: streamObj.x + (Math.random() - 0.5) * 300,
- rotation: Math.PI * 3,
- alpha: 0,
- scaleX: 0.3,
- scaleY: 0.3
- }, {
- duration: 8000 + Math.random() * 4000,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- streamObj.y = 2732 + Math.random() * 200;
- streamObj.x = Math.random() * 2048;
- streamObj.alpha = 0.6;
- streamObj.scaleX = 1.0;
- streamObj.scaleY = 1.0;
- streamObj.rotation = 0;
- floatUp();
- }
- });
+ if (streamObj && streamObj.parent && gameState === 'menu') {
+ tween(streamObj, {
+ y: -100,
+ x: streamObj.x + (Math.random() - 0.5) * 150,
+ rotation: Math.PI * 2,
+ alpha: 0,
+ scaleX: 0.5,
+ scaleY: 0.5
+ }, {
+ duration: 6000 + Math.random() * 2000,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ if (streamObj && streamObj.parent && gameState === 'menu') {
+ streamObj.y = 2732 + Math.random() * 100;
+ streamObj.x = Math.random() * 2048;
+ streamObj.alpha = 0.4;
+ streamObj.scaleX = 1.0;
+ streamObj.scaleY = 1.0;
+ streamObj.rotation = 0;
+ LK.setTimeout(floatUp, 1000);
+ }
+ }
+ });
+ }
}
floatUp();
})(stream);
}
@@ -734,52 +740,56 @@
})(rune);
}
}
createBackgroundEffects();
- // Add sparkle effects around title
+ // Add sparkle effects around title - optimized
function createSparkles() {
- for (var i = 0; i < 8; i++) {
+ for (var i = 0; i < 3; i++) {
var sparkle = new Text2('✨', {
- size: 35 + Math.random() * 25,
+ size: 25 + Math.random() * 15,
fill: '#FFD700'
});
sparkle.anchor.set(0.5, 0.5);
- sparkle.x = titleText.x + (Math.random() - 0.5) * 500;
- sparkle.y = titleText.y + (Math.random() - 0.5) * 250;
+ sparkle.x = titleText.x + (Math.random() - 0.5) * 300;
+ sparkle.y = titleText.y + (Math.random() - 0.5) * 150;
sparkle.alpha = 0;
game.addChild(sparkle);
// Animate sparkle with enhanced effects
tween(sparkle, {
alpha: 1,
- scaleX: 2.0,
- scaleY: 2.0,
- rotation: Math.random() * Math.PI * 3
+ scaleX: 1.5,
+ scaleY: 1.5,
+ rotation: Math.random() * Math.PI * 2
}, {
- duration: 1200,
- easing: tween.elasticOut,
+ duration: 800,
+ easing: tween.easeOut,
onFinish: function onFinish() {
tween(sparkle, {
alpha: 0,
- scaleX: 0.3,
- scaleY: 0.3,
- y: sparkle.y - 100
+ scaleX: 0.5,
+ scaleY: 0.5,
+ y: sparkle.y - 50
}, {
- duration: 800,
+ duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
- sparkle.destroy();
+ if (sparkle && sparkle.parent) {
+ sparkle.destroy();
+ }
}
});
}
});
}
}
- // Create sparkles periodically
+ // Create sparkles periodically - reduced frequency
function sparkleTimer() {
- createSparkles();
- LK.setTimeout(sparkleTimer, 1500 + Math.random() * 1000);
+ if (gameState === 'menu') {
+ createSparkles();
+ LK.setTimeout(sparkleTimer, 3000 + Math.random() * 2000);
+ }
}
- LK.setTimeout(sparkleTimer, 800);
+ LK.setTimeout(sparkleTimer, 1500);
// Subtitle with enhanced effects
var subtitle = new Text2('Choose Your Quest', {
size: 50,
fill: '#FFFFFF',
@@ -2253,38 +2263,44 @@
}
};
game.update = function () {
if (gameState === 'playing') {
- // Spawn enemies
+ // Spawn enemies with better control
enemySpawnTimer++;
- if (enemySpawnTimer >= enemySpawnRate) {
+ if (enemySpawnTimer >= enemySpawnRate && enemies.length < 12) {
spawnEnemy();
enemySpawnTimer = 0;
- // After score 90, spawn enemies much more frequently
+ // Gradual spawn rate increase with reasonable limits
if (enemiesKilled >= 90) {
- enemySpawnRate = Math.max(10, 30 - Math.floor((enemiesKilled - 90) / 10) * 5);
+ enemySpawnRate = Math.max(20, 45 - Math.floor((enemiesKilled - 90) / 15) * 3);
} else {
- enemySpawnRate = Math.max(30, 90 - Math.floor(enemiesKilled / 20) * 10);
+ enemySpawnRate = Math.max(40, 80 - Math.floor(enemiesKilled / 25) * 5);
}
}
// Update bullets - remove bullets that go too far off screen for performance
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
+ if (!bullet || bullet.alpha <= 0) {
+ if (bullet) bullet.destroy();
+ bullets.splice(i, 1);
+ continue;
+ }
if (bullet.lastY === undefined) bullet.lastY = bullet.y;
// Remove bullets that are way off screen for performance
- if (bullet.y < -1000) {
+ if (bullet.y < -500 || bullet.y > 2800) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Optimized collision detection - only check nearby enemies
var hit = false;
- for (var j = enemies.length - 1; j >= 0; j--) {
+ for (var j = enemies.length - 1; j >= 0 && !hit; j--) {
var enemy = enemies[j];
+ if (!enemy || enemy.alpha <= 0) continue;
// Quick distance check before expensive intersection
var dx = bullet.x - enemy.x;
var dy = bullet.y - enemy.y;
- if (dx * dx + dy * dy < 10000 && bullet.intersects(enemy)) {
+ if (dx * dx + dy * dy < 8000 && bullet.intersects(enemy)) {
// Add bullet impact flash effect
tween(enemy, {
tint: 0xFFFFFF,
scaleX: 1.2,
@@ -2344,45 +2360,25 @@
onFinish: function onFinish() {
enemy.destroy();
}
});
- // Create enhanced blood spray effect with more particles - increased from 8 to 15
- for (var k = 0; k < 15; k++) {
- var blood = new BloodParticle();
- blood.x = enemy.x + (Math.random() - 0.5) * 80; // Wider spread
- blood.y = enemy.y + (Math.random() - 0.5) * 80;
- blood.speedX = (Math.random() - 0.5) * 18; // Faster spray
- blood.speedY = Math.random() * -12 - 4; // More upward velocity
- blood.life = 50; // Longer lasting
- // Add variety to blood particle colors
- var bloodColors = [0xFF0000, 0xCC0000, 0x990000, 0xFF3333];
- blood.tint = bloodColors[Math.floor(Math.random() * bloodColors.length)];
- bloodParticles.push(blood);
- game.addChild(blood);
- // Add tween animation to blood particles for more dynamic effect
- tween(blood, {
- scaleX: 0.8 + Math.random() * 0.4,
- scaleY: 0.8 + Math.random() * 0.4,
- rotation: Math.random() * Math.PI * 2
- }, {
- duration: blood.life * 16,
- easing: tween.easeOut
- });
+ // Create optimized blood spray effect - reduced particle count
+ if (bloodParticles.length < 50) {
+ // Limit total particles
+ for (var k = 0; k < 6; k++) {
+ var blood = new BloodParticle();
+ blood.x = enemy.x + (Math.random() - 0.5) * 60;
+ blood.y = enemy.y + (Math.random() - 0.5) * 60;
+ blood.speedX = (Math.random() - 0.5) * 12;
+ blood.speedY = Math.random() * -8 - 3;
+ blood.life = 35; // Shorter life
+ // Add variety to blood particle colors
+ var bloodColors = [0xFF0000, 0xCC0000, 0x990000];
+ blood.tint = bloodColors[Math.floor(Math.random() * bloodColors.length)];
+ bloodParticles.push(blood);
+ game.addChild(blood);
+ }
}
- // Add additional instant blood splatter around the enemy
- for (var k = 0; k < 8; k++) {
- var splatter = new BloodParticle();
- splatter.x = enemy.x + (Math.random() - 0.5) * 120;
- splatter.y = enemy.y + (Math.random() - 0.5) * 120;
- splatter.speedX = (Math.random() - 0.5) * 8;
- splatter.speedY = (Math.random() - 0.5) * 8;
- splatter.life = 60;
- splatter.scaleX = 0.5;
- splatter.scaleY = 0.5;
- splatter.tint = 0x800000; // Dark red for splatter
- bloodParticles.push(splatter);
- game.addChild(splatter);
- }
enemies.splice(j, 1);
enemiesKilled++;
// Update score immediately when each enemy dies
scoreText.setText('Enemies: ' + enemiesKilled + ' / ' + enemiesRequired);
@@ -2618,16 +2614,27 @@
confetti.destroy();
confettiParticles.splice(i, 1);
}
}
- // Update blood particles
+ // Update blood particles with better cleanup
for (var i = bloodParticles.length - 1; i >= 0; i--) {
var blood = bloodParticles[i];
- if (blood.life <= 0) {
- blood.destroy();
+ if (!blood || blood.life <= 0 || blood.alpha <= 0) {
+ if (blood && blood.parent) {
+ blood.destroy();
+ }
bloodParticles.splice(i, 1);
}
}
+ // Limit total blood particles for performance
+ if (bloodParticles.length > 30) {
+ var excess = bloodParticles.splice(0, bloodParticles.length - 30);
+ for (var i = 0; i < excess.length; i++) {
+ if (excess[i] && excess[i].parent) {
+ excess[i].destroy();
+ }
+ }
+ }
};
function updateGoldDisplay() {
if (goldText) {
goldText.setText('Gold: ' + playerGold);
Siyah saçlı,zayıf,uzun boylu bir erkek genç. In-Game asset. 2d. High contrast. No shadows
Uzun saçlı kahverengi renkte iri bir adam. In-Game asset. 2d. High contrast. No shadows
Yaşlı bir adam kısa boylu aksakallı. In-Game asset. 2d. High contrast. No shadows
Kapalı saçlı orta ağırlıkta bir kız bir sultan çok güzel. In-Game asset. 2d. High contrast. No shadows
Dikey bir yol yap kara yolu. In-Game asset. 2d. High contrast. No shadows
Tabanca mermisi tasarla. In-Game asset. 2d. High contrast. No shadows
Mod butonu tasarla böyle tarz olsun. In-Game asset. 2d. High contrast. No shadows
Konfeti tasarla patlayan. In-Game asset. 2d. High contrast. No shadows
Taş tasarla grey. In-Game asset. 2d. High contrast. No shadows
Bir dirt tasarla. In-Game asset. 2d. High contrast. No shadows