User prompt
Titanfall: The Idle Legion
Initial prompt
## **Oyun Konsepti: DPS Idle** Harika bir oyun yarat. Bu oyun, mobil platformlar için tasarlanmış, **boşta (idle) bir RPG oyunu** olsun. Oyunun adı **"Titanfall: The Idle Legion"**. **Oyunun Amacı:** Oyuncu, güçlü bir kahraman lejyonunu yöneterek devasa "Titan"lara karşı savaşır. Oyuncunun ana hedefi, lejyonunun DPS'ini (Saniye Başına Hasar) sürekli olarak artırarak daha büyük ve daha zorlu Titanları yenmektir. ### **Oynanış Mekanikleri** 1. **Savaş Mekaniği:** * Savaşlar otomatik olarak gerçekleşir. Kahramanlar, ekrana dokunmaya gerek kalmadan Titanlara sürekli olarak saldırır. * Oyuncunun ana rolü, lejyonu geliştirmek ve optimize etmektir. * **"Boss Savaşları":** Her 10 dalgada bir, daha zorlu bir Titan "Boss" ile karşılaşılır. Boss'u yenmek, yeni bir bölgeye geçişi sağlar ve daha iyi ödüller kazandırır. 2. **İlerleme ve Geliştirme Sistemleri:** * **Kahramanlar:** Oyuncular, farklı yeteneklere ve rollere (DPS, destek, tank) sahip kahramanları toplar ve yükseltir. Her kahramanın kendine özgü bir "özel yeteneği" vardır. * **Ekipman:** Kahramanlara silahlar, zırhlar ve aksesuarlar takılabilir. Bu ekipmanlar, kahramanların saldırı gücünü, canını ve diğer istatistiklerini artırır. * **Geliştirme Ağacı:** Oyuncular, "yetenek puanları" kazanarak lejyonun genel DPS'ini, altın kazancını veya kritik vuruş şansını artıran pasif yetenekleri açabilirler. * **"Prestij Sistemi":** Belirli bir aşamaya ulaşıldığında, oyuncu oyunu sıfırlayarak "prestij puanları" kazanabilir. Bu puanlar, kalıcı güçlendirmeler sağlayarak bir sonraki oyuna daha güçlü başlamayı mümkün kılar. 3. **Para Birimleri ve Kaynaklar:** * **Altın:** Düşmanları yenerek kazanılır. Kahramanları yükseltmek ve yetenekleri geliştirmek için kullanılır. * **Kristaller:** Nadir bulunan bir para birimi. Yeni kahramanlar çağırmak, nadir ekipman almak veya özel yetenekleri anında kullanmak için kullanılır. ### **Grafik ve Ses Tasarımı** * **Grafik Stili:** Canlı, karikatürize 2D grafikler. Kahramanlar ve Titanlar detaylı ve akılda kalıcı tasarımlara sahip olsun. Saldırı efektleri renkli ve göz alıcı olmalı. * **Arayüz (UI):** Kullanıcı dostu ve mobil cihazlar için optimize edilmiş, basit ve anlaşılır bir arayüz. Tüm önemli bilgiler (DPS, altın, boss dalgası) tek bir ekranda görülebilir olmalı. * **Ses ve Müzik:** Enerjik ve döngüsel bir müzik. Saldırı ve yetenek ses efektleri tatmin edici ve güçlü olmalı. **UPIT, bu bilgileri kullanarak oyunun bir prototipini hayal et. İlk 5 kahramanın (isimleri ve yetenekleriyle birlikte) ve ilk Boss'un (ismi ve özellikleri) bir listesini yap. Ayrıca, oyunun açılışını ve prestij sisteminin nasıl işleyeceğini adım adım anlat.** --
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('titan', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 50;
self.health = self.maxHealth;
self.goldReward = 20;
self.isBoss = false;
self.waveNumber = 1;
// Health bar elements - will be created when enemy is spawned
self.healthBarBg = null;
self.healthBarFill = null;
self.healthText = null;
self.createHealthBar = function () {
// Health bar background - positioned at top of screen
self.healthBarBg = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 0.7
});
self.healthBarBg.tint = 0x333333;
self.healthBarBg.x = 1024;
self.healthBarBg.y = 200;
game.addChild(self.healthBarBg);
// Health bar fill - positioned at top of screen
self.healthBarFill = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 0.7
});
self.healthBarFill.tint = 0x27ae60;
self.healthBarFill.x = 1024;
self.healthBarFill.y = 200;
game.addChild(self.healthBarFill);
// Health text inside health bar - positioned at top of screen
self.healthText = new Text2(formatNumber(self.health) + '/' + formatNumber(self.maxHealth), {
size: 32,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0.5);
self.healthText.x = 1024;
self.healthText.y = 200;
game.addChild(self.healthText);
};
self.setWaveColor = function (waveNum) {
self.waveNumber = waveNum;
var colors = [0xffffff, 0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xffeaa7, 0xdda0dd, 0xff7675, 0x74b9ff, 0x00b894];
var colorIndex = (waveNum - 1) % colors.length;
enemyGraphics.tint = colors[colorIndex];
};
self.updateHealthBar = function () {
var healthPercent = self.health / self.maxHealth;
self.healthBarFill.scaleX = 1.8 * healthPercent;
if (healthPercent > 0.6) {
self.healthBarFill.tint = 0x27ae60; // Green
} else if (healthPercent > 0.3) {
self.healthBarFill.tint = 0xf39c12; // Orange
} else {
self.healthBarFill.tint = 0xe74c3c; // Red
}
// Update health text
if (self.healthText) {
self.healthText.setText(formatNumber(Math.max(0, self.health)) + '/' + formatNumber(self.maxHealth));
}
};
self.takeDamage = function (damage) {
var wasAtFullHealth = self.health === self.maxHealth;
self.health -= damage;
self.updateHealthBar();
// Get current wave color for restore
var colors = [0xffffff, 0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xffeaa7, 0xdda0dd, 0xff7675, 0x74b9ff, 0x00b894];
var colorIndex = (self.waveNumber - 1) % colors.length;
var originalColor = colors[colorIndex];
// Store original position and scale for animation reset
var originalX = enemyGraphics.x;
var originalY = enemyGraphics.y;
var originalScaleX = enemyGraphics.scaleX;
var originalScaleY = enemyGraphics.scaleY;
// Enhanced damage animation with scaling and shaking effect
tween(enemyGraphics, {
tint: 0xff0000,
scaleX: originalScaleX * 1.2,
scaleY: originalScaleY * 1.2,
x: originalX + (Math.random() - 0.5) * 20
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: originalColor,
scaleX: originalScaleX,
scaleY: originalScaleY,
x: originalX,
y: originalY
}, {
duration: 120,
easing: tween.easeInOut
});
}
});
// Create damage number popup
var damageText = new Text2('-' + formatNumber(damage), {
size: 60,
fill: 0xFF0000
});
damageText.anchor.set(0.5, 0.5);
damageText.x = self.x + (Math.random() - 0.5) * 80;
damageText.y = self.y - 50;
damageText.alpha = 1;
game.addChild(damageText);
// Animate damage text floating up and fading
tween(damageText, {
y: damageText.y - 120,
alpha: 0,
scaleX: 0.7,
scaleY: 0.7
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
damageText.destroy();
}
});
if (self.health <= 0) {
// Check if this was a one-shot kill (enemy was at full health before this damage)
if (wasAtFullHealth) {
self.showHeadshotEffect();
}
self.die();
}
};
self.showHeadshotEffect = function () {
// Play headshot sound effect
if (storage.soundEnabled !== false) {
LK.getSound('headshot').play();
}
// Create headshot text
var headshotText = new Text2('HEADSHOT!', {
size: 80,
fill: 0xFFD700
});
headshotText.anchor.set(0.5, 0.5);
headshotText.x = self.x;
headshotText.y = self.y - 100;
headshotText.alpha = 1;
game.addChild(headshotText);
// Create pulsing scale effect
tween(headshotText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(headshotText, {
scaleX: 1,
scaleY: 1,
y: headshotText.y - 80,
alpha: 0
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
headshotText.destroy();
}
});
}
});
// Create explosion effect with scaling circle
var explosionEffect = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1
});
explosionEffect.x = self.x;
explosionEffect.y = self.y;
explosionEffect.tint = 0xFFD700;
explosionEffect.alpha = 0.8;
game.addChild(explosionEffect);
// Animate explosion expanding and fading
tween(explosionEffect, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
explosionEffect.destroy();
}
});
};
self.die = function () {
gold += self.goldReward * 2; // Increase gold reward by 2x
var crystalReward = self.isBoss ? 10 : 3;
// Increase crystal reward when wave 100 is passed
if (wave >= 100) {
crystalReward = Math.floor(crystalReward * 2.5); // 2.5x crystal multiplier for wave 100+
}
crystals += crystalReward;
updateGoldDisplay();
updateCrystalsDisplay();
if (storage.soundEnabled !== false) {
LK.getSound('enemyDeath').play();
}
// Destroy health bar elements
if (self.healthBarBg && self.healthBarBg.parent) {
self.healthBarBg.destroy();
}
if (self.healthBarFill && self.healthBarFill.parent) {
self.healthBarFill.destroy();
}
if (self.healthText && self.healthText.parent) {
self.healthText.destroy();
}
// Death animation
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
self.destroy();
spawnNextEnemy();
}
});
};
return self;
});
var Boss = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace graphics with boss asset
self.removeChildren();
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 5000;
self.health = self.maxHealth;
self.goldReward = 500;
self.isBoss = true;
// Override createHealthBar for boss with larger scale
self.createHealthBar = function () {
// Health bar background - positioned at top of screen
self.healthBarBg = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 0.8
});
self.healthBarBg.tint = 0x333333;
self.healthBarBg.x = 1024;
self.healthBarBg.y = 200;
game.addChild(self.healthBarBg);
self.healthBarFill = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 0.8
});
self.healthBarFill.tint = 0x8e44ad;
self.healthBarFill.x = 1024;
self.healthBarFill.y = 200;
game.addChild(self.healthBarFill);
// Health text inside boss health bar - positioned at top of screen
self.healthText = new Text2(formatNumber(self.health) + '/' + formatNumber(self.maxHealth), {
size: 36,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0.5);
self.healthText.x = 1024;
self.healthText.y = 200;
game.addChild(self.healthText);
};
// Override updateHealthBar for boss with larger scale
self.updateHealthBar = function () {
var healthPercent = self.health / self.maxHealth;
self.healthBarFill.scaleX = 2.2 * healthPercent;
if (healthPercent > 0.6) {
self.healthBarFill.tint = 0x8e44ad; // Purple for boss
} else if (healthPercent > 0.3) {
self.healthBarFill.tint = 0x9b59b6; // Lighter purple
} else {
self.healthBarFill.tint = 0xe74c3c; // Red
}
// Update health text
if (self.healthText) {
self.healthText.setText(formatNumber(Math.max(0, self.health)) + '/' + formatNumber(self.maxHealth));
}
};
var originalSetWaveColor = self.setWaveColor;
self.setWaveColor = function (waveNum) {
self.waveNumber = waveNum;
// Bosses always stay purple but get darker with higher waves
var darkness = Math.min(waveNum * 0.1, 0.7);
var baseColor = 0x8e44ad;
var r = baseColor >> 16 & 0xFF;
var g = baseColor >> 8 & 0xFF;
var b = baseColor & 0xFF;
r = Math.floor(r * (1 - darkness));
g = Math.floor(g * (1 - darkness));
b = Math.floor(b * (1 - darkness));
bossGraphics.tint = r << 16 | g << 8 | b;
};
// Override takeDamage for boss with enhanced effects
self.takeDamage = function (damage) {
var wasAtFullHealth = self.health === self.maxHealth;
self.health -= damage;
self.updateHealthBar();
// Store original position and scale for animation reset
var originalX = bossGraphics.x;
var originalY = bossGraphics.y;
var originalScaleX = bossGraphics.scaleX;
var originalScaleY = bossGraphics.scaleY;
// More dramatic boss damage animation
tween(bossGraphics, {
tint: 0xff0000,
scaleX: originalScaleX * 1.15,
scaleY: originalScaleY * 1.15,
x: originalX + (Math.random() - 0.5) * 30,
y: originalY + (Math.random() - 0.5) * 15
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bossGraphics, {
tint: 0x8e44ad,
scaleX: originalScaleX,
scaleY: originalScaleY,
x: originalX,
y: originalY
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
// Create larger damage number for boss
var damageText = new Text2('-' + formatNumber(damage), {
size: 80,
fill: 0xFF4444
});
damageText.anchor.set(0.5, 0.5);
damageText.x = self.x + (Math.random() - 0.5) * 100;
damageText.y = self.y - 80;
damageText.alpha = 1;
game.addChild(damageText);
// Animate boss damage text with more dramatic effect
tween(damageText, {
y: damageText.y - 150,
alpha: 0,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
damageText.destroy();
}
});
if (self.health <= 0) {
// Check if this was a one-shot kill (enemy was at full health before this damage)
if (wasAtFullHealth) {
self.showHeadshotEffect();
}
self.die();
}
};
// Override showHeadshotEffect for boss with more dramatic effect
self.showHeadshotEffect = function () {
// Play headshot sound effect for boss
if (storage.soundEnabled !== false) {
LK.getSound('headshot').play();
}
// Create headshot text for boss (bigger and more dramatic)
var headshotText = new Text2('BOSS HEADSHOT!', {
size: 100,
fill: 0xFF0000
});
headshotText.anchor.set(0.5, 0.5);
headshotText.x = self.x;
headshotText.y = self.y - 150;
headshotText.alpha = 1;
game.addChild(headshotText);
// Create pulsing scale effect
tween(headshotText, {
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(headshotText, {
scaleX: 1,
scaleY: 1,
y: headshotText.y - 100,
alpha: 0
}, {
duration: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
headshotText.destroy();
}
});
}
});
// Create larger explosion effect for boss
var explosionEffect = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1
});
explosionEffect.x = self.x;
explosionEffect.y = self.y;
explosionEffect.tint = 0xFF0000;
explosionEffect.alpha = 1;
game.addChild(explosionEffect);
// Animate boss explosion expanding and fading
tween(explosionEffect, {
scaleX: 5,
scaleY: 5,
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
explosionEffect.destroy();
}
});
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.level = 1;
self.damage = 5;
self.attackSpeed = 1000; // milliseconds between attacks
self.lastAttackTime = 0;
self.cost = 100;
self.type = 'DPS'; // DPS, Support, Tank
self.attack = function () {
if (currentEnemy && LK.ticks * 16.67 - self.lastAttackTime >= self.attackSpeed / gameSpeed) {
// Add hero arm animation when attacking
tween(heroGraphics, {
rotation: 0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(heroGraphics, {
rotation: 0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
var projectile = new HeroProjectile();
projectile.x = self.x;
projectile.y = self.y;
projectile.targetX = currentEnemy.x;
projectile.targetY = currentEnemy.y;
projectile.damage = self.damage;
projectiles.push(projectile);
game.addChild(projectile);
if (storage.soundEnabled !== false) {
LK.getSound('attack').play();
}
self.lastAttackTime = LK.ticks * 16.67;
}
};
self.upgrade = function () {
var upgradeCost = Math.floor(self.cost * Math.pow(1.15, self.level - 1));
if (gold >= upgradeCost) {
gold -= upgradeCost;
self.level++;
self.damage = Math.floor(self.damage * 1.1);
self.cost = upgradeCost;
storage.heroLevel = self.level;
updateGoldDisplay();
}
};
self.update = function () {
self.attack();
};
return self;
});
var HeroProjectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('heroProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 5;
self.targetX = 0;
self.targetY = 0;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10) {
// Hit target
if (currentEnemy) {
currentEnemy.takeDamage(self.damage);
}
var index = projectiles.indexOf(self);
if (index > -1) {
projectiles.splice(index, 1);
}
self.destroy();
} else {
// Move towards target
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
};
return self;
});
var SettingsPanel = Container.expand(function () {
var self = Container.call(this);
// Semi-transparent overlay
var overlay = LK.getAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
overlay.tint = 0x000000;
overlay.alpha = 0.8;
overlay.x = 1024;
overlay.y = 1366;
self.addChild(overlay);
// Settings panel background
var panelBg = self.attachAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5
});
panelBg.x = 1024;
panelBg.y = 1366;
// Title
var titleText = new Text2('AYARLAR', {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 1066;
self.addChild(titleText);
// Music toggle
var musicToggle = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
musicToggle.x = 1174;
musicToggle.y = 1200;
musicToggle.tint = storage.musicEnabled !== false ? 0x27ae60 : 0xe74c3c;
self.addChild(musicToggle);
var musicLabel = new Text2('Müzik:', {
size: 40,
fill: 0xFFFFFF
});
musicLabel.anchor.set(0, 0.5);
musicLabel.x = 774;
musicLabel.y = 1200;
self.addChild(musicLabel);
var musicText = new Text2(storage.musicEnabled !== false ? 'AÇIK' : 'KAPALI', {
size: 30,
fill: 0xFFFFFF
});
musicText.anchor.set(0.5, 0.5);
musicText.x = 1174;
musicText.y = 1200;
self.addChild(musicText);
musicToggle.down = function () {
storage.musicEnabled = !storage.musicEnabled;
musicToggle.tint = storage.musicEnabled ? 0x27ae60 : 0xe74c3c;
musicText.setText(storage.musicEnabled ? 'AÇIK' : 'KAPALI');
if (storage.musicEnabled) {
LK.playMusic('battleMusic');
} else {
LK.stopMusic();
}
};
// Sound effects toggle
var soundToggle = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
soundToggle.x = 1174;
soundToggle.y = 1300;
soundToggle.tint = storage.soundEnabled !== false ? 0x27ae60 : 0xe74c3c;
self.addChild(soundToggle);
var soundLabel = new Text2('Efektler:', {
size: 40,
fill: 0xFFFFFF
});
soundLabel.anchor.set(0, 0.5);
soundLabel.x = 774;
soundLabel.y = 1300;
self.addChild(soundLabel);
var soundText = new Text2(storage.soundEnabled !== false ? 'AÇIK' : 'KAPALI', {
size: 30,
fill: 0xFFFFFF
});
soundText.anchor.set(0.5, 0.5);
soundText.x = 1174;
soundText.y = 1300;
self.addChild(soundText);
soundToggle.down = function () {
storage.soundEnabled = !storage.soundEnabled;
soundToggle.tint = storage.soundEnabled ? 0x27ae60 : 0xe74c3c;
soundText.setText(storage.soundEnabled ? 'AÇIK' : 'KAPALI');
};
// Language toggle
var langToggle = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
langToggle.x = 1174;
langToggle.y = 1400;
langToggle.tint = 0x3498db;
self.addChild(langToggle);
var langLabel = new Text2('Dil:', {
size: 40,
fill: 0xFFFFFF
});
langLabel.anchor.set(0, 0.5);
langLabel.x = 774;
langLabel.y = 1400;
self.addChild(langLabel);
var langText = new Text2(storage.language || 'TR', {
size: 30,
fill: 0xFFFFFF
});
langText.anchor.set(0.5, 0.5);
langText.x = 1174;
langText.y = 1400;
self.addChild(langText);
langToggle.down = function () {
storage.language = storage.language === 'EN' ? 'TR' : 'EN';
gameLanguage = storage.language;
langText.setText(storage.language);
self.updateLanguage();
updateAllLanguageTexts();
};
// Reset game button
var resetBtn = LK.getAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5
});
resetBtn.x = 1024;
resetBtn.y = 1500;
resetBtn.tint = 0xe74c3c;
self.addChild(resetBtn);
var resetText = new Text2('OYUNU SIFIRLA', {
size: 36,
fill: 0xFFFFFF
});
resetText.anchor.set(0.5, 0.5);
resetText.x = 1024;
resetText.y = 1500;
self.addChild(resetText);
resetBtn.down = function () {
// Reset all game state and upgrades
storage.gold = 500;
storage.crystals = 10;
storage.wave = 1;
storage.currentDPS = 0;
delete storage.heroLevel;
delete storage.prestigeMultiplier;
LK.showGameOver();
};
// Close button
var closeBtn = LK.getAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5
});
closeBtn.x = 1024;
closeBtn.y = 1600;
closeBtn.tint = 0x95a5a6;
self.addChild(closeBtn);
var closeText = new Text2('KAPAT', {
size: 36,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 1024;
closeText.y = 1600;
self.addChild(closeText);
closeBtn.down = function () {
self.hide();
};
self.updateLanguage = function () {
var isEn = storage.language === 'EN';
titleText.setText(isEn ? 'SETTINGS' : 'AYARLAR');
musicLabel.setText(isEn ? 'Music:' : 'Müzik:');
soundLabel.setText(isEn ? 'Effects:' : 'Efektler:');
langLabel.setText(isEn ? 'Language:' : 'Dil:');
musicText.setText(storage.musicEnabled !== false ? isEn ? 'ON' : 'AÇIK' : isEn ? 'OFF' : 'KAPALI');
soundText.setText(storage.soundEnabled !== false ? isEn ? 'ON' : 'AÇIK' : isEn ? 'OFF' : 'KAPALI');
resetText.setText(isEn ? 'RESET GAME' : 'OYUNU SIFIRLA');
closeText.setText(isEn ? 'CLOSE' : 'KAPAT');
};
self.show = function () {
self.alpha = 1;
self.visible = true;
game.isPaused = true;
// Bring settings panel to front to ensure it's on top
if (self.parent) {
self.parent.setChildIndex(self, self.parent.children.length - 1);
}
// Also ensure overlay is on top
if (overlay.parent) {
overlay.parent.setChildIndex(overlay, overlay.parent.children.length - 1);
}
// And ensure panel background is on top
if (panelBg.parent) {
panelBg.parent.setChildIndex(panelBg, panelBg.parent.children.length - 1);
}
// Bring all text and buttons to front to ensure they're above the panel
if (titleText.parent) {
titleText.parent.setChildIndex(titleText, titleText.parent.children.length - 1);
}
if (musicToggle.parent) {
musicToggle.parent.setChildIndex(musicToggle, musicToggle.parent.children.length - 1);
}
if (musicLabel.parent) {
musicLabel.parent.setChildIndex(musicLabel, musicLabel.parent.children.length - 1);
}
if (musicText.parent) {
musicText.parent.setChildIndex(musicText, musicText.parent.children.length - 1);
}
if (soundToggle.parent) {
soundToggle.parent.setChildIndex(soundToggle, soundToggle.parent.children.length - 1);
}
if (soundLabel.parent) {
soundLabel.parent.setChildIndex(soundLabel, soundLabel.parent.children.length - 1);
}
if (soundText.parent) {
soundText.parent.setChildIndex(soundText, soundText.parent.children.length - 1);
}
if (langToggle.parent) {
langToggle.parent.setChildIndex(langToggle, langToggle.parent.children.length - 1);
}
if (langLabel.parent) {
langLabel.parent.setChildIndex(langLabel, langLabel.parent.children.length - 1);
}
if (langText.parent) {
langText.parent.setChildIndex(langText, langText.parent.children.length - 1);
}
if (resetBtn.parent) {
resetBtn.parent.setChildIndex(resetBtn, resetBtn.parent.children.length - 1);
}
if (resetText.parent) {
resetText.parent.setChildIndex(resetText, resetText.parent.children.length - 1);
}
if (closeBtn.parent) {
closeBtn.parent.setChildIndex(closeBtn, closeBtn.parent.children.length - 1);
}
if (closeText.parent) {
closeText.parent.setChildIndex(closeText, closeText.parent.children.length - 1);
}
};
self.hide = function () {
self.alpha = 0;
self.visible = false;
game.isPaused = false;
};
// Start hidden
self.hide();
return self;
});
var TutorialPanel = Container.expand(function () {
var self = Container.call(this);
// Semi-transparent overlay
var overlay = LK.getAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
overlay.tint = 0x000000;
overlay.alpha = 0.9;
overlay.x = 1024;
overlay.y = 1366;
self.addChild(overlay);
// Tutorial panel background
var panelBg = self.attachAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.3
});
panelBg.x = 1024;
panelBg.y = 1366;
// Title
var titleText = new Text2('OYUNU ÖĞRENİN', {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 1000;
self.addChild(titleText);
// Tutorial content
var tutorialText = new Text2('• Ekrana dokunarak altın kazanın\n• Altınla kahramanınızı güçlendirin\n• Dalgaları geçip kristal toplayın\n• 1000 kristalle prestij yapın\n• Bossları yenip ilerleyin!', {
size: 36,
fill: 0xFFFFFF
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 1024;
tutorialText.y = 1300;
self.addChild(tutorialText);
// Gold tap hint
var tapHintText = new Text2('💰 EKRANA DOKUNUN = ALTIN 💰', {
size: 40,
fill: 0xFFD700
});
tapHintText.anchor.set(0.5, 0.5);
tapHintText.x = 1024;
tapHintText.y = 1500;
self.addChild(tapHintText);
// Close button (X)
var closeBtn = LK.getAsset('settingsIcon', {
anchorX: 0.5,
anchorY: 0.5
});
closeBtn.x = 1300;
closeBtn.y = 900;
closeBtn.tint = 0xe74c3c;
self.addChild(closeBtn);
var closeText = new Text2('✕', {
size: 50,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeText);
closeBtn.down = function () {
self.hide();
};
self.show = function () {
self.alpha = 1;
self.visible = true;
game.isPaused = true;
};
self.updateLanguage = function () {
titleText.setText(getText('learnGame'));
tutorialText.setText(getText('tutorialText'));
tapHintText.setText(getText('tapHint'));
};
self.hide = function () {
self.alpha = 0;
self.visible = false;
game.isPaused = false;
// Mark tutorial as seen
storage.tutorialSeen = true;
};
// Start visible
self.alpha = 1;
self.visible = true;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Add background image
var backgroundImage = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
backgroundImage.x = 0;
backgroundImage.y = 0;
game.addChild(backgroundImage);
// Reset game state - clear all storage
storage.gold = 500;
storage.crystals = 10;
storage.wave = 1;
storage.currentDPS = 0;
storage.prestigeMultiplier = 1;
delete storage.heroLevel;
delete storage.autoUpgradeEnabled;
delete storage.autoClickEnabled;
delete storage.gameSpeed;
delete storage.tutorialSeen;
// Game state variables
var gold = 500;
var crystals = 10;
var wave = 1;
var currentDPS = 0;
var prestigeMultiplier = 1;
var heroes = [];
var enemies = [];
var projectiles = [];
var currentEnemy = null;
// UI elements
var goldText = new Text2('Gold: ' + gold, {
size: 40,
fill: 0xFFD700
});
goldText.anchor.set(0, 0);
goldText.x = 120;
goldText.y = 50;
// Add to game but will be moved to top layer in update function
game.addChild(goldText);
var crystalsText = new Text2('Crystals: ' + crystals, {
size: 40,
fill: 0x9B59B6
});
crystalsText.anchor.set(0, 0);
crystalsText.x = 120;
crystalsText.y = 100;
// Add to game but will be moved to top layer in update function
game.addChild(crystalsText);
var waveText = new Text2('Wave: ' + wave, {
size: 50,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
waveText.x = 1024;
waveText.y = 50;
// Add to game but will be moved to top layer in update function
game.addChild(waveText);
var dpsText = new Text2('DPS: ' + currentDPS, {
size: 40,
fill: 0xE74C3C
});
dpsText.anchor.set(1, 0);
dpsText.x = 1928;
dpsText.y = 50;
// Add to game but will be moved to top layer in update function
game.addChild(dpsText);
var prestigePointsText = new Text2('Prestige: ' + Math.floor(prestigeMultiplier * 100 - 100) + ' (' + prestigeMultiplier.toFixed(1) + 'x)', {
size: 35,
fill: 0x9B59B6
});
prestigePointsText.anchor.set(1, 0);
prestigePointsText.x = 1928;
prestigePointsText.y = 100;
// Add to game but will be moved to top layer in update function
game.addChild(prestigePointsText);
// Damage upgrade button
var upgradeBtn = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
upgradeBtn.x = -260;
upgradeBtn.y = -40;
LK.gui.bottom.addChild(upgradeBtn);
var upgradeBtnText = new Text2('Upgrade Damage\n100 Gold', {
size: 22,
fill: 0xFFFFFF
});
upgradeBtnText.anchor.set(0.5, 0.5);
upgradeBtnText.x = 0;
upgradeBtnText.y = 0;
upgradeBtn.addChild(upgradeBtnText);
upgradeBtn.down = function () {
if (heroes.length > 0) {
var baseCost = 100; // Use fixed base cost
var upgradeCost = Math.floor(baseCost * Math.pow(1.15, heroes[0].level - 1));
if (gold >= upgradeCost) {
gold -= upgradeCost;
heroes[0].level++;
heroes[0].damage = Math.floor(heroes[0].damage * 1.2); // Increase damage by 20% per upgrade
storage.heroLevel = heroes[0].level;
updateGoldDisplay();
updateUpgradeButton();
}
}
};
// Auto upgrade button
var autoUpgradeBtn = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
autoUpgradeBtn.x = -60;
autoUpgradeBtn.y = -40;
LK.gui.bottom.addChild(autoUpgradeBtn);
var autoUpgradeBtnText = new Text2('Auto\nOFF', {
size: 22,
fill: 0xFFFFFF
});
autoUpgradeBtnText.anchor.set(0.5, 0.5);
autoUpgradeBtnText.x = 0;
autoUpgradeBtnText.y = 0;
autoUpgradeBtn.addChild(autoUpgradeBtnText);
// Auto upgrade state
var autoUpgradeEnabled = false;
var autoUpgradeLastCheck = 0;
// Auto click button
var autoClickBtn = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
autoClickBtn.x = 50;
autoClickBtn.y = 0;
LK.gui.left.addChild(autoClickBtn);
var autoClickBtnText = new Text2('Auto\nClick\nOFF', {
size: 18,
fill: 0xFFFFFF
});
autoClickBtnText.anchor.set(0.5, 0.5);
autoClickBtnText.x = 0;
autoClickBtnText.y = 0;
autoClickBtn.addChild(autoClickBtnText);
// Auto click state
var autoClickEnabled = false;
var autoClickLastTime = 0;
var autoClickInterval = 1000; // Click every 1000ms (1 time per second)
// Update auto upgrade button display
function updateAutoUpgradeButton() {
if (autoUpgradeEnabled) {
autoUpgradeBtn.tint = 0x27ae60; // Green when enabled
autoUpgradeBtnText.setText('Auto\nON');
} else {
autoUpgradeBtn.tint = 0xe74c3c; // Red when disabled
autoUpgradeBtnText.setText('Auto\nOFF');
}
}
// Update auto click button display
function updateAutoClickButton() {
if (autoClickEnabled) {
autoClickBtn.tint = 0x27ae60; // Green when enabled
autoClickBtnText.setText('Auto\nClick\nON');
} else {
autoClickBtn.tint = 0xe74c3c; // Red when disabled
autoClickBtnText.setText('Auto\nClick\nOFF');
}
}
// Initialize auto upgrade button state
updateAutoUpgradeButton();
autoUpgradeBtn.down = function () {
autoUpgradeEnabled = !autoUpgradeEnabled;
storage.autoUpgradeEnabled = autoUpgradeEnabled;
updateAutoUpgradeButton();
};
// Initialize auto click button state
updateAutoClickButton();
autoClickBtn.down = function () {
autoClickEnabled = !autoClickEnabled;
storage.autoClickEnabled = autoClickEnabled;
updateAutoClickButton();
};
// Auto upgrade function
function performAutoUpgrade() {
if (!autoUpgradeEnabled || heroes.length === 0) {
return;
}
var baseCost = 100;
var upgradeCost = Math.floor(baseCost * Math.pow(1.15, heroes[0].level - 1));
if (gold >= upgradeCost) {
gold -= upgradeCost;
heroes[0].level++;
heroes[0].damage = Math.floor(heroes[0].damage * 1.2);
storage.heroLevel = heroes[0].level;
updateGoldDisplay();
updateUpgradeButton();
}
}
// Summon button removed - hero çağır butonunu kaldır
// Prestige button
var prestigeBtn = LK.getAsset('summonButton', {
anchorX: 0.5,
anchorY: 0.5
});
prestigeBtn.x = 120;
prestigeBtn.y = -40;
LK.gui.bottom.addChild(prestigeBtn);
var prestigeBtnText = new Text2(getText('Prestige') + '\n' + formatNumber(500) + ' ' + getText('Crystals'), {
size: 24,
fill: 0xFFFFFF
});
prestigeBtnText.anchor.set(0.5, 0.5);
prestigeBtnText.x = 0;
prestigeBtnText.y = 0;
prestigeBtn.addChild(prestigeBtnText);
prestigeBtn.down = function () {
if (crystals >= 500) {
crystals -= 500;
doPrestige();
updateCrystalsDisplay();
}
};
// Game speed control
var gameSpeed = 1;
var gameSpeedMultipliers = [1, 2];
var gameSpeedButton = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
gameSpeedButton.x = -50;
gameSpeedButton.y = -120;
LK.gui.bottomRight.addChild(gameSpeedButton);
var gameSpeedText = new Text2(gameSpeed + 'x', {
size: 30,
fill: 0xFFFFFF
});
gameSpeedText.anchor.set(0.5, 0.5);
gameSpeedText.x = 0;
gameSpeedText.y = 0;
gameSpeedButton.addChild(gameSpeedText);
gameSpeedButton.down = function () {
var currentIndex = gameSpeedMultipliers.indexOf(gameSpeed);
var nextIndex = (currentIndex + 1) % gameSpeedMultipliers.length;
gameSpeed = gameSpeedMultipliers[nextIndex];
storage.gameSpeed = gameSpeed;
gameSpeedText.setText(gameSpeed + 'x');
};
// Settings icon in bottom right
var settingsIcon = LK.getAsset('settingsIcon', {
anchorX: 0.5,
anchorY: 0.5
});
settingsIcon.x = -50;
settingsIcon.y = -50;
LK.gui.bottomRight.addChild(settingsIcon);
var settingsText = new Text2('⚙', {
size: 50,
fill: 0xFFFFFF
});
settingsText.anchor.set(0.5, 0.5);
settingsText.x = 0;
settingsText.y = 0;
settingsIcon.addChild(settingsText);
// Settings panel
var settingsPanel = new SettingsPanel();
game.addChild(settingsPanel);
settingsIcon.down = function () {
settingsPanel.show();
};
// Tutorial panel - show only once for new players
var tutorialPanel = new TutorialPanel();
game.addChild(tutorialPanel);
// Show tutorial for fresh start
tutorialPanel.show();
game.isPaused = true;
// Language system
var gameLanguage = storage.language || 'TR';
var languageTexts = {
TR: {
gold: 'Altın',
crystals: 'Kristal',
wave: 'Dalga',
dps: 'DPS',
upgradeDamage: 'Hasarı Yükselt',
prestige: 'Prestij',
settings: 'AYARLAR',
music: 'Müzik:',
effects: 'Efektler:',
language: 'Dil:',
on: 'AÇIK',
off: 'KAPALI',
resetGame: 'OYUNU SIFIRLA',
close: 'KAPAT',
learnGame: 'OYUNU ÖĞRENİN',
tutorialText: '• Ekrana dokunarak altın kazanın\n• Altınla kahramanınızı güçlendirin\n• Dalgaları geçip kristal toplayın\n• 1000 kristalle prestij yapın\n• Bossları yenip ilerleyin!',
tapHint: '🏆 EKRANA DOKUNUN = ALTIN',
gold_unit: 'Altın',
crystals_unit: 'Kristal'
},
EN: {
gold: 'Gold',
crystals: 'Crystals',
wave: 'Wave',
dps: 'DPS',
upgradeDamage: 'Upgrade Damage',
prestige: 'Prestige',
settings: 'SETTINGS',
music: 'Music:',
effects: 'Effects:',
language: 'Language:',
on: 'ON',
off: 'OFF',
resetGame: 'RESET GAME',
close: 'CLOSE',
learnGame: 'LEARN THE GAME',
tutorialText: '• Tap screen to earn gold\n• Use gold to upgrade your hero\n• Beat waves to collect crystals\n• Prestige with 1000 crystals\n• Defeat bosses to progress!',
tapHint: '🏆 TAP SCREEN = GOLD',
gold_unit: 'Gold',
crystals_unit: 'Crystals'
}
};
function getText(key) {
// Ensure languageTexts object exists
if (!languageTexts) {
return key;
}
// Ensure gameLanguage is valid, default to 'TR' if not
var lang = gameLanguage && languageTexts[gameLanguage] ? gameLanguage : 'TR';
// Safely access language texts with fallbacks
if (languageTexts[lang] && languageTexts[lang][key]) {
return languageTexts[lang][key];
}
if (languageTexts.TR && languageTexts.TR[key]) {
return languageTexts.TR[key];
}
return key; // Return the key itself as fallback
}
// Number formatting function for global abbreviations
function formatNumber(num) {
if (num < 1000) {
return num.toString();
}
if (num < 1000000) {
return (num / 1000).toFixed(1) + 'K';
}
if (num < 1000000000) {
return (num / 1000000).toFixed(1) + 'M';
}
if (num < 1000000000000) {
return (num / 1000000000).toFixed(1) + 'B';
}
if (num < 1000000000000000) {
return (num / 1000000000000).toFixed(1) + 'T';
}
if (num < 1000000000000000000) {
return (num / 1000000000000000).toFixed(1) + 'Q';
}
return (num / 1000000000000000000).toFixed(1) + 'Qi';
}
// Game functions
function updateGoldDisplay() {
goldText.setText(getText('gold') + ': ' + formatNumber(gold));
storage.gold = gold;
}
function updateCrystalsDisplay() {
crystalsText.setText(getText('crystals') + ': ' + formatNumber(crystals));
storage.crystals = crystals;
}
function updateWaveDisplay() {
waveText.setText(getText('wave') + ': ' + formatNumber(wave));
storage.wave = wave;
}
function updateDPSDisplay() {
var totalDPS = 0;
for (var i = 0; i < heroes.length; i++) {
totalDPS += Math.floor(heroes[i].damage * 1000 / heroes[i].attackSpeed);
}
currentDPS = totalDPS;
storage.currentDPS = currentDPS;
dpsText.setText(getText('dps') + ': ' + formatNumber(totalDPS));
}
function updatePrestigePointsDisplay() {
var points = Math.floor(prestigeMultiplier * 100 - 100);
prestigePointsText.setText('Prestij: ' + points + ' (' + prestigeMultiplier.toFixed(1) + 'x)');
}
function updateUpgradeButton() {
if (heroes.length > 0) {
var baseCost = 100; // Use fixed base cost instead of hero.cost
var cost = Math.floor(baseCost * Math.pow(1.15, heroes[0].level));
upgradeBtnText.setText(getText('upgradeDamage') + '\n' + formatNumber(cost) + ' ' + getText('gold_unit'));
}
}
function updateAllLanguageTexts() {
// Update main UI displays
updateGoldDisplay();
updateCrystalsDisplay();
updateWaveDisplay();
updateDPSDisplay();
updatePrestigePointsDisplay();
updateUpgradeButton();
// Update prestige button
prestigeBtnText.setText(getText('prestige') + '\n' + formatNumber(500) + ' ' + getText('crystals_unit'));
// Update settings panel if it exists
if (settingsPanel && settingsPanel.updateLanguage) {
settingsPanel.updateLanguage();
}
// Update tutorial panel if it exists
if (tutorialPanel && tutorialPanel.updateLanguage) {
tutorialPanel.updateLanguage();
}
}
function summonHero() {
var hero = new Hero();
hero.x = 300 + heroes.length * 100;
hero.y = 1800;
// Apply stored upgrade levels
if (storage.heroLevel) {
hero.level = storage.heroLevel;
hero.damage = Math.floor(10 * Math.pow(1.1, hero.level - 1) * prestigeMultiplier);
}
// Apply prestige multiplier to new heroes
hero.damage = Math.floor(hero.damage * prestigeMultiplier);
heroes.push(hero);
game.addChild(hero);
}
function doPrestige() {
// Increase prestige multiplier by 1.2x
prestigeMultiplier *= 1.2;
storage.prestigeMultiplier = prestigeMultiplier;
// Reset all game state
gold = 500;
crystals = 10;
wave = 1;
currentDPS = 0;
// Clear all game objects
for (var i = heroes.length - 1; i >= 0; i--) {
heroes[i].destroy();
}
heroes = [];
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
currentEnemy = null;
for (var i = projectiles.length - 1; i >= 0; i--) {
projectiles[i].destroy();
}
projectiles = [];
// Clear storage upgrades (reset upgrades on prestige)
delete storage.heroLevel;
// Update storage with reset values
storage.gold = gold;
storage.crystals = crystals;
storage.wave = wave;
storage.currentDPS = currentDPS;
// Update displays
updateGoldDisplay();
updateCrystalsDisplay();
updateWaveDisplay();
updateDPSDisplay();
updatePrestigePointsDisplay();
// Restart the game with prestige bonus
summonHero();
spawnEnemy();
}
function spawnEnemy() {
// Don't spawn if there are already enemies alive
if (enemies.length > 0 || currentEnemy) {
return;
}
var enemy;
if (wave % 10 === 0) {
// Boss wave - only spawn boss
enemy = new Boss();
enemy.maxHealth = Math.floor(250 * Math.pow(5.0, Math.floor(wave / 10)));
} else {
// Regular wave - spawn single titan
enemy = new Enemy();
enemy.maxHealth = Math.floor(50 * Math.pow(1.15, wave));
}
enemy.health = enemy.maxHealth;
enemy.goldReward = Math.floor(enemy.goldReward * Math.pow(1.1, wave));
enemy.setWaveColor(wave);
enemy.createHealthBar();
enemy.updateHealthBar();
enemy.x = 1500;
enemy.y = 1800;
enemies.push(enemy);
game.addChild(enemy);
currentEnemy = enemy;
}
function spawnNextEnemy() {
// Clear current enemy reference
currentEnemy = null;
// Always spawn next enemy after a small delay
LK.setTimeout(function () {
// Check if we should proceed to next wave
if (enemies.length === 0) {
wave++;
updateWaveDisplay();
}
spawnEnemy();
}, 1000 / gameSpeed);
}
// Initialize first hero and enemy
summonHero();
spawnEnemy();
// Start background music
if (storage.musicEnabled !== false) {
LK.playMusic('battleMusic');
}
// Click rate limiting variables
var clickTimes = [];
var maxClicksPerSecond = 10;
var maxTotalClicksPerSecond = 20;
// Hold state variables
var isHolding = false;
var holdStartTime = 0;
var lastGoldGenTime = 0;
var goldPerSecondWhileHolding = 5; // Generate 5 gold per second while holding
// Screen tap handler for gold generation
game.down = function (x, y, obj) {
// Only give gold if game is not paused
if (!game.isPaused) {
var currentTime = Date.now();
// Clean up old click times (older than 1 second)
clickTimes = clickTimes.filter(function (time) {
return currentTime - time < 1000;
});
// Check if we've exceeded the click limits
if (clickTimes.length >= maxTotalClicksPerSecond) {
return; // Block the click if we've hit the 20 clicks per second limit
}
// Check if we've exceeded 10 clicks in the last 100ms (to ensure max 10 clicks per second rate)
var recentClicks = clickTimes.filter(function (time) {
return currentTime - time < 100;
});
if (recentClicks.length >= 1) {
return; // Block the click if we've already clicked in the last 100ms
}
// Record this click time
clickTimes.push(currentTime);
// Start holding state
isHolding = true;
holdStartTime = currentTime;
lastGoldGenTime = currentTime;
var tapGold = Math.floor((2 + wave * 1) * prestigeMultiplier);
// Increase tap gold by 1.5x when wave 100 is passed
if (wave >= 100) {
tapGold = Math.floor(tapGold * 1.5);
}
gold += tapGold;
updateGoldDisplay();
// Create gold icon animation
var goldIcon = LK.getAsset('goldIcon', {
anchorX: 0.5,
anchorY: 0.5
});
goldIcon.x = x;
goldIcon.y = y;
goldIcon.alpha = 1;
game.addChild(goldIcon);
// Animate gold icon moving up and fading out
tween(goldIcon, {
y: y - 100,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
goldIcon.destroy();
}
});
}
};
// Screen release handler
game.up = function (x, y, obj) {
isHolding = false;
};
// Main game loop
game.update = function () {
// Skip update if game is paused
if (game.isPaused) {
return;
}
// Check for wave 100 attack speed boost
if (wave >= 100) {
// Apply 1.25x attack speed boost to all heroes
for (var i = 0; i < heroes.length; i++) {
if (!heroes[i].speedBoosted) {
heroes[i].attackSpeed = Math.floor(heroes[i].attackSpeed / 1.25);
heroes[i].speedBoosted = true;
}
}
}
// Handle continuous gold generation while holding
if (isHolding) {
var currentTime = Date.now();
var timeSinceLastGold = currentTime - lastGoldGenTime;
// Generate gold every 200ms (5 times per second)
if (timeSinceLastGold >= 200) {
var holdGold = Math.floor((1 + wave * 0.5) * prestigeMultiplier);
gold += holdGold;
updateGoldDisplay();
lastGoldGenTime = currentTime;
// Create small gold icon animation at random position
var goldIcon = LK.getAsset('goldIcon', {
anchorX: 0.5,
anchorY: 0.5
});
goldIcon.x = 800 + Math.random() * 400; // Random x between 800-1200
goldIcon.y = 1000 + Math.random() * 400; // Random y between 1000-1400
goldIcon.alpha = 0.8;
goldIcon.scaleX = 0.7;
goldIcon.scaleY = 0.7;
game.addChild(goldIcon);
// Animate small gold icon
tween(goldIcon, {
y: goldIcon.y - 50,
alpha: 0
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
goldIcon.destroy();
}
});
}
}
// Update displays
updateDPSDisplay();
updatePrestigePointsDisplay();
updateUpgradeButton();
// Move UI texts to top layer every frame to ensure they stay on top
if (goldText && goldText.parent) {
goldText.parent.setChildIndex(goldText, goldText.parent.children.length - 1);
}
if (crystalsText && crystalsText.parent) {
crystalsText.parent.setChildIndex(crystalsText, crystalsText.parent.children.length - 1);
}
if (waveText && waveText.parent) {
waveText.parent.setChildIndex(waveText, waveText.parent.children.length - 1);
}
if (dpsText && dpsText.parent) {
dpsText.parent.setChildIndex(dpsText, dpsText.parent.children.length - 1);
}
if (prestigePointsText && prestigePointsText.parent) {
prestigePointsText.parent.setChildIndex(prestigePointsText, prestigePointsText.parent.children.length - 1);
}
// Auto upgrade check (every 100ms to avoid lag)
if (LK.ticks % 6 === 0) {
performAutoUpgrade();
}
// Auto click check (every 60 ticks = 1 second)
if (autoClickEnabled && LK.ticks % 60 === 0) {
var currentTime = Date.now();
if (currentTime - autoClickLastTime >= 1000) {
// Give 1 gold per second
var tapGold = 1;
gold += tapGold;
updateGoldDisplay();
autoClickLastTime = currentTime;
// Create gold icon animation at random position
var goldIcon = LK.getAsset('goldIcon', {
anchorX: 0.5,
anchorY: 0.5
});
goldIcon.x = 800 + Math.random() * 400; // Random x between 800-1200
goldIcon.y = 1000 + Math.random() * 400; // Random y between 1000-1400
goldIcon.alpha = 0.8;
goldIcon.scaleX = 0.7;
goldIcon.scaleY = 0.7;
game.addChild(goldIcon);
// Animate gold icon
tween(goldIcon, {
y: goldIcon.y - 50,
alpha: 0
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
goldIcon.destroy();
}
});
}
}
// Clean up destroyed projectiles
for (var i = projectiles.length - 1; i >= 0; i--) {
if (!projectiles[i].parent) {
projectiles.splice(i, 1);
}
}
// Clean up destroyed enemies
for (var i = enemies.length - 1; i >= 0; i--) {
if (!enemies[i].parent) {
if (enemies[i] === currentEnemy) {
currentEnemy = null;
}
enemies.splice(i, 1);
}
}
// Set current enemy to first alive enemy if none is set
if (!currentEnemy && enemies.length > 0) {
currentEnemy = enemies[0];
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('titan', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 50;
self.health = self.maxHealth;
self.goldReward = 20;
self.isBoss = false;
self.waveNumber = 1;
// Health bar elements - will be created when enemy is spawned
self.healthBarBg = null;
self.healthBarFill = null;
self.healthText = null;
self.createHealthBar = function () {
// Health bar background - positioned at top of screen
self.healthBarBg = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 0.7
});
self.healthBarBg.tint = 0x333333;
self.healthBarBg.x = 1024;
self.healthBarBg.y = 200;
game.addChild(self.healthBarBg);
// Health bar fill - positioned at top of screen
self.healthBarFill = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.8,
scaleY: 0.7
});
self.healthBarFill.tint = 0x27ae60;
self.healthBarFill.x = 1024;
self.healthBarFill.y = 200;
game.addChild(self.healthBarFill);
// Health text inside health bar - positioned at top of screen
self.healthText = new Text2(formatNumber(self.health) + '/' + formatNumber(self.maxHealth), {
size: 32,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0.5);
self.healthText.x = 1024;
self.healthText.y = 200;
game.addChild(self.healthText);
};
self.setWaveColor = function (waveNum) {
self.waveNumber = waveNum;
var colors = [0xffffff, 0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xffeaa7, 0xdda0dd, 0xff7675, 0x74b9ff, 0x00b894];
var colorIndex = (waveNum - 1) % colors.length;
enemyGraphics.tint = colors[colorIndex];
};
self.updateHealthBar = function () {
var healthPercent = self.health / self.maxHealth;
self.healthBarFill.scaleX = 1.8 * healthPercent;
if (healthPercent > 0.6) {
self.healthBarFill.tint = 0x27ae60; // Green
} else if (healthPercent > 0.3) {
self.healthBarFill.tint = 0xf39c12; // Orange
} else {
self.healthBarFill.tint = 0xe74c3c; // Red
}
// Update health text
if (self.healthText) {
self.healthText.setText(formatNumber(Math.max(0, self.health)) + '/' + formatNumber(self.maxHealth));
}
};
self.takeDamage = function (damage) {
var wasAtFullHealth = self.health === self.maxHealth;
self.health -= damage;
self.updateHealthBar();
// Get current wave color for restore
var colors = [0xffffff, 0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xffeaa7, 0xdda0dd, 0xff7675, 0x74b9ff, 0x00b894];
var colorIndex = (self.waveNumber - 1) % colors.length;
var originalColor = colors[colorIndex];
// Store original position and scale for animation reset
var originalX = enemyGraphics.x;
var originalY = enemyGraphics.y;
var originalScaleX = enemyGraphics.scaleX;
var originalScaleY = enemyGraphics.scaleY;
// Enhanced damage animation with scaling and shaking effect
tween(enemyGraphics, {
tint: 0xff0000,
scaleX: originalScaleX * 1.2,
scaleY: originalScaleY * 1.2,
x: originalX + (Math.random() - 0.5) * 20
}, {
duration: 80,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: originalColor,
scaleX: originalScaleX,
scaleY: originalScaleY,
x: originalX,
y: originalY
}, {
duration: 120,
easing: tween.easeInOut
});
}
});
// Create damage number popup
var damageText = new Text2('-' + formatNumber(damage), {
size: 60,
fill: 0xFF0000
});
damageText.anchor.set(0.5, 0.5);
damageText.x = self.x + (Math.random() - 0.5) * 80;
damageText.y = self.y - 50;
damageText.alpha = 1;
game.addChild(damageText);
// Animate damage text floating up and fading
tween(damageText, {
y: damageText.y - 120,
alpha: 0,
scaleX: 0.7,
scaleY: 0.7
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
damageText.destroy();
}
});
if (self.health <= 0) {
// Check if this was a one-shot kill (enemy was at full health before this damage)
if (wasAtFullHealth) {
self.showHeadshotEffect();
}
self.die();
}
};
self.showHeadshotEffect = function () {
// Play headshot sound effect
if (storage.soundEnabled !== false) {
LK.getSound('headshot').play();
}
// Create headshot text
var headshotText = new Text2('HEADSHOT!', {
size: 80,
fill: 0xFFD700
});
headshotText.anchor.set(0.5, 0.5);
headshotText.x = self.x;
headshotText.y = self.y - 100;
headshotText.alpha = 1;
game.addChild(headshotText);
// Create pulsing scale effect
tween(headshotText, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(headshotText, {
scaleX: 1,
scaleY: 1,
y: headshotText.y - 80,
alpha: 0
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
headshotText.destroy();
}
});
}
});
// Create explosion effect with scaling circle
var explosionEffect = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1
});
explosionEffect.x = self.x;
explosionEffect.y = self.y;
explosionEffect.tint = 0xFFD700;
explosionEffect.alpha = 0.8;
game.addChild(explosionEffect);
// Animate explosion expanding and fading
tween(explosionEffect, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
explosionEffect.destroy();
}
});
};
self.die = function () {
gold += self.goldReward * 2; // Increase gold reward by 2x
var crystalReward = self.isBoss ? 10 : 3;
// Increase crystal reward when wave 100 is passed
if (wave >= 100) {
crystalReward = Math.floor(crystalReward * 2.5); // 2.5x crystal multiplier for wave 100+
}
crystals += crystalReward;
updateGoldDisplay();
updateCrystalsDisplay();
if (storage.soundEnabled !== false) {
LK.getSound('enemyDeath').play();
}
// Destroy health bar elements
if (self.healthBarBg && self.healthBarBg.parent) {
self.healthBarBg.destroy();
}
if (self.healthBarFill && self.healthBarFill.parent) {
self.healthBarFill.destroy();
}
if (self.healthText && self.healthText.parent) {
self.healthText.destroy();
}
// Death animation
tween(self, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
self.destroy();
spawnNextEnemy();
}
});
};
return self;
});
var Boss = Enemy.expand(function () {
var self = Enemy.call(this);
// Replace graphics with boss asset
self.removeChildren();
var bossGraphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.maxHealth = 5000;
self.health = self.maxHealth;
self.goldReward = 500;
self.isBoss = true;
// Override createHealthBar for boss with larger scale
self.createHealthBar = function () {
// Health bar background - positioned at top of screen
self.healthBarBg = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 0.8
});
self.healthBarBg.tint = 0x333333;
self.healthBarBg.x = 1024;
self.healthBarBg.y = 200;
game.addChild(self.healthBarBg);
self.healthBarFill = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 0.8
});
self.healthBarFill.tint = 0x8e44ad;
self.healthBarFill.x = 1024;
self.healthBarFill.y = 200;
game.addChild(self.healthBarFill);
// Health text inside boss health bar - positioned at top of screen
self.healthText = new Text2(formatNumber(self.health) + '/' + formatNumber(self.maxHealth), {
size: 36,
fill: 0xFFFFFF
});
self.healthText.anchor.set(0.5, 0.5);
self.healthText.x = 1024;
self.healthText.y = 200;
game.addChild(self.healthText);
};
// Override updateHealthBar for boss with larger scale
self.updateHealthBar = function () {
var healthPercent = self.health / self.maxHealth;
self.healthBarFill.scaleX = 2.2 * healthPercent;
if (healthPercent > 0.6) {
self.healthBarFill.tint = 0x8e44ad; // Purple for boss
} else if (healthPercent > 0.3) {
self.healthBarFill.tint = 0x9b59b6; // Lighter purple
} else {
self.healthBarFill.tint = 0xe74c3c; // Red
}
// Update health text
if (self.healthText) {
self.healthText.setText(formatNumber(Math.max(0, self.health)) + '/' + formatNumber(self.maxHealth));
}
};
var originalSetWaveColor = self.setWaveColor;
self.setWaveColor = function (waveNum) {
self.waveNumber = waveNum;
// Bosses always stay purple but get darker with higher waves
var darkness = Math.min(waveNum * 0.1, 0.7);
var baseColor = 0x8e44ad;
var r = baseColor >> 16 & 0xFF;
var g = baseColor >> 8 & 0xFF;
var b = baseColor & 0xFF;
r = Math.floor(r * (1 - darkness));
g = Math.floor(g * (1 - darkness));
b = Math.floor(b * (1 - darkness));
bossGraphics.tint = r << 16 | g << 8 | b;
};
// Override takeDamage for boss with enhanced effects
self.takeDamage = function (damage) {
var wasAtFullHealth = self.health === self.maxHealth;
self.health -= damage;
self.updateHealthBar();
// Store original position and scale for animation reset
var originalX = bossGraphics.x;
var originalY = bossGraphics.y;
var originalScaleX = bossGraphics.scaleX;
var originalScaleY = bossGraphics.scaleY;
// More dramatic boss damage animation
tween(bossGraphics, {
tint: 0xff0000,
scaleX: originalScaleX * 1.15,
scaleY: originalScaleY * 1.15,
x: originalX + (Math.random() - 0.5) * 30,
y: originalY + (Math.random() - 0.5) * 15
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bossGraphics, {
tint: 0x8e44ad,
scaleX: originalScaleX,
scaleY: originalScaleY,
x: originalX,
y: originalY
}, {
duration: 150,
easing: tween.easeInOut
});
}
});
// Create larger damage number for boss
var damageText = new Text2('-' + formatNumber(damage), {
size: 80,
fill: 0xFF4444
});
damageText.anchor.set(0.5, 0.5);
damageText.x = self.x + (Math.random() - 0.5) * 100;
damageText.y = self.y - 80;
damageText.alpha = 1;
game.addChild(damageText);
// Animate boss damage text with more dramatic effect
tween(damageText, {
y: damageText.y - 150,
alpha: 0,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
damageText.destroy();
}
});
if (self.health <= 0) {
// Check if this was a one-shot kill (enemy was at full health before this damage)
if (wasAtFullHealth) {
self.showHeadshotEffect();
}
self.die();
}
};
// Override showHeadshotEffect for boss with more dramatic effect
self.showHeadshotEffect = function () {
// Play headshot sound effect for boss
if (storage.soundEnabled !== false) {
LK.getSound('headshot').play();
}
// Create headshot text for boss (bigger and more dramatic)
var headshotText = new Text2('BOSS HEADSHOT!', {
size: 100,
fill: 0xFF0000
});
headshotText.anchor.set(0.5, 0.5);
headshotText.x = self.x;
headshotText.y = self.y - 150;
headshotText.alpha = 1;
game.addChild(headshotText);
// Create pulsing scale effect
tween(headshotText, {
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(headshotText, {
scaleX: 1,
scaleY: 1,
y: headshotText.y - 100,
alpha: 0
}, {
duration: 1000,
easing: tween.easeIn,
onFinish: function onFinish() {
headshotText.destroy();
}
});
}
});
// Create larger explosion effect for boss
var explosionEffect = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.1
});
explosionEffect.x = self.x;
explosionEffect.y = self.y;
explosionEffect.tint = 0xFF0000;
explosionEffect.alpha = 1;
game.addChild(explosionEffect);
// Animate boss explosion expanding and fading
tween(explosionEffect, {
scaleX: 5,
scaleY: 5,
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
explosionEffect.destroy();
}
});
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.level = 1;
self.damage = 5;
self.attackSpeed = 1000; // milliseconds between attacks
self.lastAttackTime = 0;
self.cost = 100;
self.type = 'DPS'; // DPS, Support, Tank
self.attack = function () {
if (currentEnemy && LK.ticks * 16.67 - self.lastAttackTime >= self.attackSpeed / gameSpeed) {
// Add hero arm animation when attacking
tween(heroGraphics, {
rotation: 0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(heroGraphics, {
rotation: 0
}, {
duration: 100,
easing: tween.easeIn
});
}
});
var projectile = new HeroProjectile();
projectile.x = self.x;
projectile.y = self.y;
projectile.targetX = currentEnemy.x;
projectile.targetY = currentEnemy.y;
projectile.damage = self.damage;
projectiles.push(projectile);
game.addChild(projectile);
if (storage.soundEnabled !== false) {
LK.getSound('attack').play();
}
self.lastAttackTime = LK.ticks * 16.67;
}
};
self.upgrade = function () {
var upgradeCost = Math.floor(self.cost * Math.pow(1.15, self.level - 1));
if (gold >= upgradeCost) {
gold -= upgradeCost;
self.level++;
self.damage = Math.floor(self.damage * 1.1);
self.cost = upgradeCost;
storage.heroLevel = self.level;
updateGoldDisplay();
}
};
self.update = function () {
self.attack();
};
return self;
});
var HeroProjectile = Container.expand(function () {
var self = Container.call(this);
var projectileGraphics = self.attachAsset('heroProjectile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 5;
self.targetX = 0;
self.targetY = 0;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10) {
// Hit target
if (currentEnemy) {
currentEnemy.takeDamage(self.damage);
}
var index = projectiles.indexOf(self);
if (index > -1) {
projectiles.splice(index, 1);
}
self.destroy();
} else {
// Move towards target
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
};
return self;
});
var SettingsPanel = Container.expand(function () {
var self = Container.call(this);
// Semi-transparent overlay
var overlay = LK.getAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
overlay.tint = 0x000000;
overlay.alpha = 0.8;
overlay.x = 1024;
overlay.y = 1366;
self.addChild(overlay);
// Settings panel background
var panelBg = self.attachAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5
});
panelBg.x = 1024;
panelBg.y = 1366;
// Title
var titleText = new Text2('AYARLAR', {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 1066;
self.addChild(titleText);
// Music toggle
var musicToggle = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
musicToggle.x = 1174;
musicToggle.y = 1200;
musicToggle.tint = storage.musicEnabled !== false ? 0x27ae60 : 0xe74c3c;
self.addChild(musicToggle);
var musicLabel = new Text2('Müzik:', {
size: 40,
fill: 0xFFFFFF
});
musicLabel.anchor.set(0, 0.5);
musicLabel.x = 774;
musicLabel.y = 1200;
self.addChild(musicLabel);
var musicText = new Text2(storage.musicEnabled !== false ? 'AÇIK' : 'KAPALI', {
size: 30,
fill: 0xFFFFFF
});
musicText.anchor.set(0.5, 0.5);
musicText.x = 1174;
musicText.y = 1200;
self.addChild(musicText);
musicToggle.down = function () {
storage.musicEnabled = !storage.musicEnabled;
musicToggle.tint = storage.musicEnabled ? 0x27ae60 : 0xe74c3c;
musicText.setText(storage.musicEnabled ? 'AÇIK' : 'KAPALI');
if (storage.musicEnabled) {
LK.playMusic('battleMusic');
} else {
LK.stopMusic();
}
};
// Sound effects toggle
var soundToggle = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
soundToggle.x = 1174;
soundToggle.y = 1300;
soundToggle.tint = storage.soundEnabled !== false ? 0x27ae60 : 0xe74c3c;
self.addChild(soundToggle);
var soundLabel = new Text2('Efektler:', {
size: 40,
fill: 0xFFFFFF
});
soundLabel.anchor.set(0, 0.5);
soundLabel.x = 774;
soundLabel.y = 1300;
self.addChild(soundLabel);
var soundText = new Text2(storage.soundEnabled !== false ? 'AÇIK' : 'KAPALI', {
size: 30,
fill: 0xFFFFFF
});
soundText.anchor.set(0.5, 0.5);
soundText.x = 1174;
soundText.y = 1300;
self.addChild(soundText);
soundToggle.down = function () {
storage.soundEnabled = !storage.soundEnabled;
soundToggle.tint = storage.soundEnabled ? 0x27ae60 : 0xe74c3c;
soundText.setText(storage.soundEnabled ? 'AÇIK' : 'KAPALI');
};
// Language toggle
var langToggle = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
langToggle.x = 1174;
langToggle.y = 1400;
langToggle.tint = 0x3498db;
self.addChild(langToggle);
var langLabel = new Text2('Dil:', {
size: 40,
fill: 0xFFFFFF
});
langLabel.anchor.set(0, 0.5);
langLabel.x = 774;
langLabel.y = 1400;
self.addChild(langLabel);
var langText = new Text2(storage.language || 'TR', {
size: 30,
fill: 0xFFFFFF
});
langText.anchor.set(0.5, 0.5);
langText.x = 1174;
langText.y = 1400;
self.addChild(langText);
langToggle.down = function () {
storage.language = storage.language === 'EN' ? 'TR' : 'EN';
gameLanguage = storage.language;
langText.setText(storage.language);
self.updateLanguage();
updateAllLanguageTexts();
};
// Reset game button
var resetBtn = LK.getAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5
});
resetBtn.x = 1024;
resetBtn.y = 1500;
resetBtn.tint = 0xe74c3c;
self.addChild(resetBtn);
var resetText = new Text2('OYUNU SIFIRLA', {
size: 36,
fill: 0xFFFFFF
});
resetText.anchor.set(0.5, 0.5);
resetText.x = 1024;
resetText.y = 1500;
self.addChild(resetText);
resetBtn.down = function () {
// Reset all game state and upgrades
storage.gold = 500;
storage.crystals = 10;
storage.wave = 1;
storage.currentDPS = 0;
delete storage.heroLevel;
delete storage.prestigeMultiplier;
LK.showGameOver();
};
// Close button
var closeBtn = LK.getAsset('settingsButton', {
anchorX: 0.5,
anchorY: 0.5
});
closeBtn.x = 1024;
closeBtn.y = 1600;
closeBtn.tint = 0x95a5a6;
self.addChild(closeBtn);
var closeText = new Text2('KAPAT', {
size: 36,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeText.x = 1024;
closeText.y = 1600;
self.addChild(closeText);
closeBtn.down = function () {
self.hide();
};
self.updateLanguage = function () {
var isEn = storage.language === 'EN';
titleText.setText(isEn ? 'SETTINGS' : 'AYARLAR');
musicLabel.setText(isEn ? 'Music:' : 'Müzik:');
soundLabel.setText(isEn ? 'Effects:' : 'Efektler:');
langLabel.setText(isEn ? 'Language:' : 'Dil:');
musicText.setText(storage.musicEnabled !== false ? isEn ? 'ON' : 'AÇIK' : isEn ? 'OFF' : 'KAPALI');
soundText.setText(storage.soundEnabled !== false ? isEn ? 'ON' : 'AÇIK' : isEn ? 'OFF' : 'KAPALI');
resetText.setText(isEn ? 'RESET GAME' : 'OYUNU SIFIRLA');
closeText.setText(isEn ? 'CLOSE' : 'KAPAT');
};
self.show = function () {
self.alpha = 1;
self.visible = true;
game.isPaused = true;
// Bring settings panel to front to ensure it's on top
if (self.parent) {
self.parent.setChildIndex(self, self.parent.children.length - 1);
}
// Also ensure overlay is on top
if (overlay.parent) {
overlay.parent.setChildIndex(overlay, overlay.parent.children.length - 1);
}
// And ensure panel background is on top
if (panelBg.parent) {
panelBg.parent.setChildIndex(panelBg, panelBg.parent.children.length - 1);
}
// Bring all text and buttons to front to ensure they're above the panel
if (titleText.parent) {
titleText.parent.setChildIndex(titleText, titleText.parent.children.length - 1);
}
if (musicToggle.parent) {
musicToggle.parent.setChildIndex(musicToggle, musicToggle.parent.children.length - 1);
}
if (musicLabel.parent) {
musicLabel.parent.setChildIndex(musicLabel, musicLabel.parent.children.length - 1);
}
if (musicText.parent) {
musicText.parent.setChildIndex(musicText, musicText.parent.children.length - 1);
}
if (soundToggle.parent) {
soundToggle.parent.setChildIndex(soundToggle, soundToggle.parent.children.length - 1);
}
if (soundLabel.parent) {
soundLabel.parent.setChildIndex(soundLabel, soundLabel.parent.children.length - 1);
}
if (soundText.parent) {
soundText.parent.setChildIndex(soundText, soundText.parent.children.length - 1);
}
if (langToggle.parent) {
langToggle.parent.setChildIndex(langToggle, langToggle.parent.children.length - 1);
}
if (langLabel.parent) {
langLabel.parent.setChildIndex(langLabel, langLabel.parent.children.length - 1);
}
if (langText.parent) {
langText.parent.setChildIndex(langText, langText.parent.children.length - 1);
}
if (resetBtn.parent) {
resetBtn.parent.setChildIndex(resetBtn, resetBtn.parent.children.length - 1);
}
if (resetText.parent) {
resetText.parent.setChildIndex(resetText, resetText.parent.children.length - 1);
}
if (closeBtn.parent) {
closeBtn.parent.setChildIndex(closeBtn, closeBtn.parent.children.length - 1);
}
if (closeText.parent) {
closeText.parent.setChildIndex(closeText, closeText.parent.children.length - 1);
}
};
self.hide = function () {
self.alpha = 0;
self.visible = false;
game.isPaused = false;
};
// Start hidden
self.hide();
return self;
});
var TutorialPanel = Container.expand(function () {
var self = Container.call(this);
// Semi-transparent overlay
var overlay = LK.getAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
overlay.tint = 0x000000;
overlay.alpha = 0.9;
overlay.x = 1024;
overlay.y = 1366;
self.addChild(overlay);
// Tutorial panel background
var panelBg = self.attachAsset('settingsPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.3
});
panelBg.x = 1024;
panelBg.y = 1366;
// Title
var titleText = new Text2('OYUNU ÖĞRENİN', {
size: 60,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 1000;
self.addChild(titleText);
// Tutorial content
var tutorialText = new Text2('• Ekrana dokunarak altın kazanın\n• Altınla kahramanınızı güçlendirin\n• Dalgaları geçip kristal toplayın\n• 1000 kristalle prestij yapın\n• Bossları yenip ilerleyin!', {
size: 36,
fill: 0xFFFFFF
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 1024;
tutorialText.y = 1300;
self.addChild(tutorialText);
// Gold tap hint
var tapHintText = new Text2('💰 EKRANA DOKUNUN = ALTIN 💰', {
size: 40,
fill: 0xFFD700
});
tapHintText.anchor.set(0.5, 0.5);
tapHintText.x = 1024;
tapHintText.y = 1500;
self.addChild(tapHintText);
// Close button (X)
var closeBtn = LK.getAsset('settingsIcon', {
anchorX: 0.5,
anchorY: 0.5
});
closeBtn.x = 1300;
closeBtn.y = 900;
closeBtn.tint = 0xe74c3c;
self.addChild(closeBtn);
var closeText = new Text2('✕', {
size: 50,
fill: 0xFFFFFF
});
closeText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeText);
closeBtn.down = function () {
self.hide();
};
self.show = function () {
self.alpha = 1;
self.visible = true;
game.isPaused = true;
};
self.updateLanguage = function () {
titleText.setText(getText('learnGame'));
tutorialText.setText(getText('tutorialText'));
tapHintText.setText(getText('tapHint'));
};
self.hide = function () {
self.alpha = 0;
self.visible = false;
game.isPaused = false;
// Mark tutorial as seen
storage.tutorialSeen = true;
};
// Start visible
self.alpha = 1;
self.visible = true;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Add background image
var backgroundImage = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
backgroundImage.x = 0;
backgroundImage.y = 0;
game.addChild(backgroundImage);
// Reset game state - clear all storage
storage.gold = 500;
storage.crystals = 10;
storage.wave = 1;
storage.currentDPS = 0;
storage.prestigeMultiplier = 1;
delete storage.heroLevel;
delete storage.autoUpgradeEnabled;
delete storage.autoClickEnabled;
delete storage.gameSpeed;
delete storage.tutorialSeen;
// Game state variables
var gold = 500;
var crystals = 10;
var wave = 1;
var currentDPS = 0;
var prestigeMultiplier = 1;
var heroes = [];
var enemies = [];
var projectiles = [];
var currentEnemy = null;
// UI elements
var goldText = new Text2('Gold: ' + gold, {
size: 40,
fill: 0xFFD700
});
goldText.anchor.set(0, 0);
goldText.x = 120;
goldText.y = 50;
// Add to game but will be moved to top layer in update function
game.addChild(goldText);
var crystalsText = new Text2('Crystals: ' + crystals, {
size: 40,
fill: 0x9B59B6
});
crystalsText.anchor.set(0, 0);
crystalsText.x = 120;
crystalsText.y = 100;
// Add to game but will be moved to top layer in update function
game.addChild(crystalsText);
var waveText = new Text2('Wave: ' + wave, {
size: 50,
fill: 0xFFFFFF
});
waveText.anchor.set(0.5, 0);
waveText.x = 1024;
waveText.y = 50;
// Add to game but will be moved to top layer in update function
game.addChild(waveText);
var dpsText = new Text2('DPS: ' + currentDPS, {
size: 40,
fill: 0xE74C3C
});
dpsText.anchor.set(1, 0);
dpsText.x = 1928;
dpsText.y = 50;
// Add to game but will be moved to top layer in update function
game.addChild(dpsText);
var prestigePointsText = new Text2('Prestige: ' + Math.floor(prestigeMultiplier * 100 - 100) + ' (' + prestigeMultiplier.toFixed(1) + 'x)', {
size: 35,
fill: 0x9B59B6
});
prestigePointsText.anchor.set(1, 0);
prestigePointsText.x = 1928;
prestigePointsText.y = 100;
// Add to game but will be moved to top layer in update function
game.addChild(prestigePointsText);
// Damage upgrade button
var upgradeBtn = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
upgradeBtn.x = -260;
upgradeBtn.y = -40;
LK.gui.bottom.addChild(upgradeBtn);
var upgradeBtnText = new Text2('Upgrade Damage\n100 Gold', {
size: 22,
fill: 0xFFFFFF
});
upgradeBtnText.anchor.set(0.5, 0.5);
upgradeBtnText.x = 0;
upgradeBtnText.y = 0;
upgradeBtn.addChild(upgradeBtnText);
upgradeBtn.down = function () {
if (heroes.length > 0) {
var baseCost = 100; // Use fixed base cost
var upgradeCost = Math.floor(baseCost * Math.pow(1.15, heroes[0].level - 1));
if (gold >= upgradeCost) {
gold -= upgradeCost;
heroes[0].level++;
heroes[0].damage = Math.floor(heroes[0].damage * 1.2); // Increase damage by 20% per upgrade
storage.heroLevel = heroes[0].level;
updateGoldDisplay();
updateUpgradeButton();
}
}
};
// Auto upgrade button
var autoUpgradeBtn = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
autoUpgradeBtn.x = -60;
autoUpgradeBtn.y = -40;
LK.gui.bottom.addChild(autoUpgradeBtn);
var autoUpgradeBtnText = new Text2('Auto\nOFF', {
size: 22,
fill: 0xFFFFFF
});
autoUpgradeBtnText.anchor.set(0.5, 0.5);
autoUpgradeBtnText.x = 0;
autoUpgradeBtnText.y = 0;
autoUpgradeBtn.addChild(autoUpgradeBtnText);
// Auto upgrade state
var autoUpgradeEnabled = false;
var autoUpgradeLastCheck = 0;
// Auto click button
var autoClickBtn = LK.getAsset('upgradeButton', {
anchorX: 0.5,
anchorY: 0.5
});
autoClickBtn.x = 50;
autoClickBtn.y = 0;
LK.gui.left.addChild(autoClickBtn);
var autoClickBtnText = new Text2('Auto\nClick\nOFF', {
size: 18,
fill: 0xFFFFFF
});
autoClickBtnText.anchor.set(0.5, 0.5);
autoClickBtnText.x = 0;
autoClickBtnText.y = 0;
autoClickBtn.addChild(autoClickBtnText);
// Auto click state
var autoClickEnabled = false;
var autoClickLastTime = 0;
var autoClickInterval = 1000; // Click every 1000ms (1 time per second)
// Update auto upgrade button display
function updateAutoUpgradeButton() {
if (autoUpgradeEnabled) {
autoUpgradeBtn.tint = 0x27ae60; // Green when enabled
autoUpgradeBtnText.setText('Auto\nON');
} else {
autoUpgradeBtn.tint = 0xe74c3c; // Red when disabled
autoUpgradeBtnText.setText('Auto\nOFF');
}
}
// Update auto click button display
function updateAutoClickButton() {
if (autoClickEnabled) {
autoClickBtn.tint = 0x27ae60; // Green when enabled
autoClickBtnText.setText('Auto\nClick\nON');
} else {
autoClickBtn.tint = 0xe74c3c; // Red when disabled
autoClickBtnText.setText('Auto\nClick\nOFF');
}
}
// Initialize auto upgrade button state
updateAutoUpgradeButton();
autoUpgradeBtn.down = function () {
autoUpgradeEnabled = !autoUpgradeEnabled;
storage.autoUpgradeEnabled = autoUpgradeEnabled;
updateAutoUpgradeButton();
};
// Initialize auto click button state
updateAutoClickButton();
autoClickBtn.down = function () {
autoClickEnabled = !autoClickEnabled;
storage.autoClickEnabled = autoClickEnabled;
updateAutoClickButton();
};
// Auto upgrade function
function performAutoUpgrade() {
if (!autoUpgradeEnabled || heroes.length === 0) {
return;
}
var baseCost = 100;
var upgradeCost = Math.floor(baseCost * Math.pow(1.15, heroes[0].level - 1));
if (gold >= upgradeCost) {
gold -= upgradeCost;
heroes[0].level++;
heroes[0].damage = Math.floor(heroes[0].damage * 1.2);
storage.heroLevel = heroes[0].level;
updateGoldDisplay();
updateUpgradeButton();
}
}
// Summon button removed - hero çağır butonunu kaldır
// Prestige button
var prestigeBtn = LK.getAsset('summonButton', {
anchorX: 0.5,
anchorY: 0.5
});
prestigeBtn.x = 120;
prestigeBtn.y = -40;
LK.gui.bottom.addChild(prestigeBtn);
var prestigeBtnText = new Text2(getText('Prestige') + '\n' + formatNumber(500) + ' ' + getText('Crystals'), {
size: 24,
fill: 0xFFFFFF
});
prestigeBtnText.anchor.set(0.5, 0.5);
prestigeBtnText.x = 0;
prestigeBtnText.y = 0;
prestigeBtn.addChild(prestigeBtnText);
prestigeBtn.down = function () {
if (crystals >= 500) {
crystals -= 500;
doPrestige();
updateCrystalsDisplay();
}
};
// Game speed control
var gameSpeed = 1;
var gameSpeedMultipliers = [1, 2];
var gameSpeedButton = LK.getAsset('toggleButton', {
anchorX: 0.5,
anchorY: 0.5
});
gameSpeedButton.x = -50;
gameSpeedButton.y = -120;
LK.gui.bottomRight.addChild(gameSpeedButton);
var gameSpeedText = new Text2(gameSpeed + 'x', {
size: 30,
fill: 0xFFFFFF
});
gameSpeedText.anchor.set(0.5, 0.5);
gameSpeedText.x = 0;
gameSpeedText.y = 0;
gameSpeedButton.addChild(gameSpeedText);
gameSpeedButton.down = function () {
var currentIndex = gameSpeedMultipliers.indexOf(gameSpeed);
var nextIndex = (currentIndex + 1) % gameSpeedMultipliers.length;
gameSpeed = gameSpeedMultipliers[nextIndex];
storage.gameSpeed = gameSpeed;
gameSpeedText.setText(gameSpeed + 'x');
};
// Settings icon in bottom right
var settingsIcon = LK.getAsset('settingsIcon', {
anchorX: 0.5,
anchorY: 0.5
});
settingsIcon.x = -50;
settingsIcon.y = -50;
LK.gui.bottomRight.addChild(settingsIcon);
var settingsText = new Text2('⚙', {
size: 50,
fill: 0xFFFFFF
});
settingsText.anchor.set(0.5, 0.5);
settingsText.x = 0;
settingsText.y = 0;
settingsIcon.addChild(settingsText);
// Settings panel
var settingsPanel = new SettingsPanel();
game.addChild(settingsPanel);
settingsIcon.down = function () {
settingsPanel.show();
};
// Tutorial panel - show only once for new players
var tutorialPanel = new TutorialPanel();
game.addChild(tutorialPanel);
// Show tutorial for fresh start
tutorialPanel.show();
game.isPaused = true;
// Language system
var gameLanguage = storage.language || 'TR';
var languageTexts = {
TR: {
gold: 'Altın',
crystals: 'Kristal',
wave: 'Dalga',
dps: 'DPS',
upgradeDamage: 'Hasarı Yükselt',
prestige: 'Prestij',
settings: 'AYARLAR',
music: 'Müzik:',
effects: 'Efektler:',
language: 'Dil:',
on: 'AÇIK',
off: 'KAPALI',
resetGame: 'OYUNU SIFIRLA',
close: 'KAPAT',
learnGame: 'OYUNU ÖĞRENİN',
tutorialText: '• Ekrana dokunarak altın kazanın\n• Altınla kahramanınızı güçlendirin\n• Dalgaları geçip kristal toplayın\n• 1000 kristalle prestij yapın\n• Bossları yenip ilerleyin!',
tapHint: '🏆 EKRANA DOKUNUN = ALTIN',
gold_unit: 'Altın',
crystals_unit: 'Kristal'
},
EN: {
gold: 'Gold',
crystals: 'Crystals',
wave: 'Wave',
dps: 'DPS',
upgradeDamage: 'Upgrade Damage',
prestige: 'Prestige',
settings: 'SETTINGS',
music: 'Music:',
effects: 'Effects:',
language: 'Language:',
on: 'ON',
off: 'OFF',
resetGame: 'RESET GAME',
close: 'CLOSE',
learnGame: 'LEARN THE GAME',
tutorialText: '• Tap screen to earn gold\n• Use gold to upgrade your hero\n• Beat waves to collect crystals\n• Prestige with 1000 crystals\n• Defeat bosses to progress!',
tapHint: '🏆 TAP SCREEN = GOLD',
gold_unit: 'Gold',
crystals_unit: 'Crystals'
}
};
function getText(key) {
// Ensure languageTexts object exists
if (!languageTexts) {
return key;
}
// Ensure gameLanguage is valid, default to 'TR' if not
var lang = gameLanguage && languageTexts[gameLanguage] ? gameLanguage : 'TR';
// Safely access language texts with fallbacks
if (languageTexts[lang] && languageTexts[lang][key]) {
return languageTexts[lang][key];
}
if (languageTexts.TR && languageTexts.TR[key]) {
return languageTexts.TR[key];
}
return key; // Return the key itself as fallback
}
// Number formatting function for global abbreviations
function formatNumber(num) {
if (num < 1000) {
return num.toString();
}
if (num < 1000000) {
return (num / 1000).toFixed(1) + 'K';
}
if (num < 1000000000) {
return (num / 1000000).toFixed(1) + 'M';
}
if (num < 1000000000000) {
return (num / 1000000000).toFixed(1) + 'B';
}
if (num < 1000000000000000) {
return (num / 1000000000000).toFixed(1) + 'T';
}
if (num < 1000000000000000000) {
return (num / 1000000000000000).toFixed(1) + 'Q';
}
return (num / 1000000000000000000).toFixed(1) + 'Qi';
}
// Game functions
function updateGoldDisplay() {
goldText.setText(getText('gold') + ': ' + formatNumber(gold));
storage.gold = gold;
}
function updateCrystalsDisplay() {
crystalsText.setText(getText('crystals') + ': ' + formatNumber(crystals));
storage.crystals = crystals;
}
function updateWaveDisplay() {
waveText.setText(getText('wave') + ': ' + formatNumber(wave));
storage.wave = wave;
}
function updateDPSDisplay() {
var totalDPS = 0;
for (var i = 0; i < heroes.length; i++) {
totalDPS += Math.floor(heroes[i].damage * 1000 / heroes[i].attackSpeed);
}
currentDPS = totalDPS;
storage.currentDPS = currentDPS;
dpsText.setText(getText('dps') + ': ' + formatNumber(totalDPS));
}
function updatePrestigePointsDisplay() {
var points = Math.floor(prestigeMultiplier * 100 - 100);
prestigePointsText.setText('Prestij: ' + points + ' (' + prestigeMultiplier.toFixed(1) + 'x)');
}
function updateUpgradeButton() {
if (heroes.length > 0) {
var baseCost = 100; // Use fixed base cost instead of hero.cost
var cost = Math.floor(baseCost * Math.pow(1.15, heroes[0].level));
upgradeBtnText.setText(getText('upgradeDamage') + '\n' + formatNumber(cost) + ' ' + getText('gold_unit'));
}
}
function updateAllLanguageTexts() {
// Update main UI displays
updateGoldDisplay();
updateCrystalsDisplay();
updateWaveDisplay();
updateDPSDisplay();
updatePrestigePointsDisplay();
updateUpgradeButton();
// Update prestige button
prestigeBtnText.setText(getText('prestige') + '\n' + formatNumber(500) + ' ' + getText('crystals_unit'));
// Update settings panel if it exists
if (settingsPanel && settingsPanel.updateLanguage) {
settingsPanel.updateLanguage();
}
// Update tutorial panel if it exists
if (tutorialPanel && tutorialPanel.updateLanguage) {
tutorialPanel.updateLanguage();
}
}
function summonHero() {
var hero = new Hero();
hero.x = 300 + heroes.length * 100;
hero.y = 1800;
// Apply stored upgrade levels
if (storage.heroLevel) {
hero.level = storage.heroLevel;
hero.damage = Math.floor(10 * Math.pow(1.1, hero.level - 1) * prestigeMultiplier);
}
// Apply prestige multiplier to new heroes
hero.damage = Math.floor(hero.damage * prestigeMultiplier);
heroes.push(hero);
game.addChild(hero);
}
function doPrestige() {
// Increase prestige multiplier by 1.2x
prestigeMultiplier *= 1.2;
storage.prestigeMultiplier = prestigeMultiplier;
// Reset all game state
gold = 500;
crystals = 10;
wave = 1;
currentDPS = 0;
// Clear all game objects
for (var i = heroes.length - 1; i >= 0; i--) {
heroes[i].destroy();
}
heroes = [];
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
currentEnemy = null;
for (var i = projectiles.length - 1; i >= 0; i--) {
projectiles[i].destroy();
}
projectiles = [];
// Clear storage upgrades (reset upgrades on prestige)
delete storage.heroLevel;
// Update storage with reset values
storage.gold = gold;
storage.crystals = crystals;
storage.wave = wave;
storage.currentDPS = currentDPS;
// Update displays
updateGoldDisplay();
updateCrystalsDisplay();
updateWaveDisplay();
updateDPSDisplay();
updatePrestigePointsDisplay();
// Restart the game with prestige bonus
summonHero();
spawnEnemy();
}
function spawnEnemy() {
// Don't spawn if there are already enemies alive
if (enemies.length > 0 || currentEnemy) {
return;
}
var enemy;
if (wave % 10 === 0) {
// Boss wave - only spawn boss
enemy = new Boss();
enemy.maxHealth = Math.floor(250 * Math.pow(5.0, Math.floor(wave / 10)));
} else {
// Regular wave - spawn single titan
enemy = new Enemy();
enemy.maxHealth = Math.floor(50 * Math.pow(1.15, wave));
}
enemy.health = enemy.maxHealth;
enemy.goldReward = Math.floor(enemy.goldReward * Math.pow(1.1, wave));
enemy.setWaveColor(wave);
enemy.createHealthBar();
enemy.updateHealthBar();
enemy.x = 1500;
enemy.y = 1800;
enemies.push(enemy);
game.addChild(enemy);
currentEnemy = enemy;
}
function spawnNextEnemy() {
// Clear current enemy reference
currentEnemy = null;
// Always spawn next enemy after a small delay
LK.setTimeout(function () {
// Check if we should proceed to next wave
if (enemies.length === 0) {
wave++;
updateWaveDisplay();
}
spawnEnemy();
}, 1000 / gameSpeed);
}
// Initialize first hero and enemy
summonHero();
spawnEnemy();
// Start background music
if (storage.musicEnabled !== false) {
LK.playMusic('battleMusic');
}
// Click rate limiting variables
var clickTimes = [];
var maxClicksPerSecond = 10;
var maxTotalClicksPerSecond = 20;
// Hold state variables
var isHolding = false;
var holdStartTime = 0;
var lastGoldGenTime = 0;
var goldPerSecondWhileHolding = 5; // Generate 5 gold per second while holding
// Screen tap handler for gold generation
game.down = function (x, y, obj) {
// Only give gold if game is not paused
if (!game.isPaused) {
var currentTime = Date.now();
// Clean up old click times (older than 1 second)
clickTimes = clickTimes.filter(function (time) {
return currentTime - time < 1000;
});
// Check if we've exceeded the click limits
if (clickTimes.length >= maxTotalClicksPerSecond) {
return; // Block the click if we've hit the 20 clicks per second limit
}
// Check if we've exceeded 10 clicks in the last 100ms (to ensure max 10 clicks per second rate)
var recentClicks = clickTimes.filter(function (time) {
return currentTime - time < 100;
});
if (recentClicks.length >= 1) {
return; // Block the click if we've already clicked in the last 100ms
}
// Record this click time
clickTimes.push(currentTime);
// Start holding state
isHolding = true;
holdStartTime = currentTime;
lastGoldGenTime = currentTime;
var tapGold = Math.floor((2 + wave * 1) * prestigeMultiplier);
// Increase tap gold by 1.5x when wave 100 is passed
if (wave >= 100) {
tapGold = Math.floor(tapGold * 1.5);
}
gold += tapGold;
updateGoldDisplay();
// Create gold icon animation
var goldIcon = LK.getAsset('goldIcon', {
anchorX: 0.5,
anchorY: 0.5
});
goldIcon.x = x;
goldIcon.y = y;
goldIcon.alpha = 1;
game.addChild(goldIcon);
// Animate gold icon moving up and fading out
tween(goldIcon, {
y: y - 100,
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
goldIcon.destroy();
}
});
}
};
// Screen release handler
game.up = function (x, y, obj) {
isHolding = false;
};
// Main game loop
game.update = function () {
// Skip update if game is paused
if (game.isPaused) {
return;
}
// Check for wave 100 attack speed boost
if (wave >= 100) {
// Apply 1.25x attack speed boost to all heroes
for (var i = 0; i < heroes.length; i++) {
if (!heroes[i].speedBoosted) {
heroes[i].attackSpeed = Math.floor(heroes[i].attackSpeed / 1.25);
heroes[i].speedBoosted = true;
}
}
}
// Handle continuous gold generation while holding
if (isHolding) {
var currentTime = Date.now();
var timeSinceLastGold = currentTime - lastGoldGenTime;
// Generate gold every 200ms (5 times per second)
if (timeSinceLastGold >= 200) {
var holdGold = Math.floor((1 + wave * 0.5) * prestigeMultiplier);
gold += holdGold;
updateGoldDisplay();
lastGoldGenTime = currentTime;
// Create small gold icon animation at random position
var goldIcon = LK.getAsset('goldIcon', {
anchorX: 0.5,
anchorY: 0.5
});
goldIcon.x = 800 + Math.random() * 400; // Random x between 800-1200
goldIcon.y = 1000 + Math.random() * 400; // Random y between 1000-1400
goldIcon.alpha = 0.8;
goldIcon.scaleX = 0.7;
goldIcon.scaleY = 0.7;
game.addChild(goldIcon);
// Animate small gold icon
tween(goldIcon, {
y: goldIcon.y - 50,
alpha: 0
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
goldIcon.destroy();
}
});
}
}
// Update displays
updateDPSDisplay();
updatePrestigePointsDisplay();
updateUpgradeButton();
// Move UI texts to top layer every frame to ensure they stay on top
if (goldText && goldText.parent) {
goldText.parent.setChildIndex(goldText, goldText.parent.children.length - 1);
}
if (crystalsText && crystalsText.parent) {
crystalsText.parent.setChildIndex(crystalsText, crystalsText.parent.children.length - 1);
}
if (waveText && waveText.parent) {
waveText.parent.setChildIndex(waveText, waveText.parent.children.length - 1);
}
if (dpsText && dpsText.parent) {
dpsText.parent.setChildIndex(dpsText, dpsText.parent.children.length - 1);
}
if (prestigePointsText && prestigePointsText.parent) {
prestigePointsText.parent.setChildIndex(prestigePointsText, prestigePointsText.parent.children.length - 1);
}
// Auto upgrade check (every 100ms to avoid lag)
if (LK.ticks % 6 === 0) {
performAutoUpgrade();
}
// Auto click check (every 60 ticks = 1 second)
if (autoClickEnabled && LK.ticks % 60 === 0) {
var currentTime = Date.now();
if (currentTime - autoClickLastTime >= 1000) {
// Give 1 gold per second
var tapGold = 1;
gold += tapGold;
updateGoldDisplay();
autoClickLastTime = currentTime;
// Create gold icon animation at random position
var goldIcon = LK.getAsset('goldIcon', {
anchorX: 0.5,
anchorY: 0.5
});
goldIcon.x = 800 + Math.random() * 400; // Random x between 800-1200
goldIcon.y = 1000 + Math.random() * 400; // Random y between 1000-1400
goldIcon.alpha = 0.8;
goldIcon.scaleX = 0.7;
goldIcon.scaleY = 0.7;
game.addChild(goldIcon);
// Animate gold icon
tween(goldIcon, {
y: goldIcon.y - 50,
alpha: 0
}, {
duration: 600,
easing: tween.easeOut,
onFinish: function onFinish() {
goldIcon.destroy();
}
});
}
}
// Clean up destroyed projectiles
for (var i = projectiles.length - 1; i >= 0; i--) {
if (!projectiles[i].parent) {
projectiles.splice(i, 1);
}
}
// Clean up destroyed enemies
for (var i = enemies.length - 1; i >= 0; i--) {
if (!enemies[i].parent) {
if (enemies[i] === currentEnemy) {
currentEnemy = null;
}
enemies.splice(i, 1);
}
}
// Set current enemy to first alive enemy if none is set
if (!currentEnemy && enemies.length > 0) {
currentEnemy = enemies[0];
}
};
Büyücü. In-Game asset. 2d. High contrast. No shadows
Titan enemy. In-Game asset. 2d. High contrast. No shadows
Boss Titan. In-Game asset. 2d. High contrast. No shadows
GOLD. In-Game asset. 2d. High contrast. No shadows
doğa. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
fireball. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat