User prompt
Şu anda molotofFlame assetim düşmana hasar vermiyor. Bunu çözmen gerek.
User prompt
Şu anda shuriken asseti çarptığı rakiplere hasar vermiyor. Shuriken assetinin temas ettiği rakipler 6 hasar almalı.
User prompt
Molotofın mekaniğini değiştirelim çünkü bir türlü yapamadın istediğimi. Artık molotof menzilindeki en yakın rakibe doğru fırlatılsın ve düşmana çarptığında patlayıp MolotovFlame yanma alanını oluştursun. Bu alana temas eden rakipler 1 saniye içinde her yarım saniyede 3 olmak üzere toplamda 6 hasar alsın. Ayrıca shurikenin 3 saniye var olup 3 saniye yok olmasını değil artık shurikeni aldığım zaman sürekli var olup etrafımda (ve kendi etrafında) dönmesini istiyorum. Shurikenin saldırı hızı arttığı zaman etrafımda dönme hızı artmalı çünkü onun saldırı hızı aslında benim etrafımda döndüğü hız. Bu arada shurikenin Range+ efsununu basınca dönme menzili artıyor fakat shurikenin boyutu (assetin boyutu falan) artmıyor. Bunları düzeltmen lazım.
User prompt
Please fix the bug: 'TypeError: maintainShurikens is not a function' in or related to this line: 'maintainShurikens(inst);' Line Number: 1863
User prompt
Şu anda molotofun patlayıncaki hasarı (molotovFlame) hala düşmana hasar vermiyor. "Şu anda molotof patlayınca yaptığı yanma alanı (molotovFlame) düşmana hasar vermiyor. molotovFlame'ye temas eden düşmanlar 1 saniye içinde toplam 6 hasar olacak şekilde her yarım saniyede bir 3 hasar almalı. (molotofun damagesi)". Tekra incelemen lazım bu kısmı.
Code edit (2 edits merged)
Please save this source code
User prompt
Şu anda molotof patlayınca yaptığı yanma alanı (molotovFlame) düşmana hasar vermiyor. molotovFlame'ye temas eden düşmanlar 1 saniye içinde toplam 6 hasar olacak şekilde her yarım saniyede bir 3 hasar almalı. (molotofun damagesi)
User prompt
Şu anda roket düşmana tam olarak çarpmadan biraz daha önce patladığı için dairesel alanda patlama yapsa bile düşmana hasar veremiyor çünkü düşmanın önünde patlıyor. Düşmanın tam içine girip patlaması falan gerekiyor galiba çünkü diğer türlü erken patlıyor.
User prompt
Şu anda roketin patlaması hasar vermiyor gibi. Roketin patlamasının hasar vermesi gerekiyor.
Code edit (2 edits merged)
Please save this source code
User prompt
Yine işe yaramadı! Saldırı hızımı bu şekilde arttıramıyorum! Çok iyi düşünmen gerekiyor tüm kodu iyice incele ve analiz et sorun nerede?
Code edit (3 edits merged)
Please save this source code
User prompt
"/* ==== WEAPON META TABLE ==== */" kısmından değiştirince cd'yi saldırı hızımı arttırabiliyorum ama "// Efsun metni "
Code edit (4 edits merged)
Please save this source code
User prompt
Ya sen şu anda 0.8 yaptın bunları fakat saldırı hızımı arttırmıyor diyorum sana, saldırı hızım artmıyor! Bir sorun var!
User prompt
Şu kısmı böyle yaptım "// Efsun metni "
Code edit (1 edits merged)
Please save this source code
User prompt
Şu anda saldırı hızını arttırdığım zaman saldırı hızı gerçekten de artmıyor, bir sorun var galiba.
User prompt
Shuriken yine gözükmüyor hiçbir zaman! Ayrıca şu kısım "// Efsun metni "
Code edit (1 edits merged)
Please save this source code
User prompt
Shuriken alındığı zaman menzilinde düşman olmasa bile sürekli 3 saniye var olup hem karakterin hem de kendi etrafında dönüp sonra 3 saniye yok olmalı ve bunu döngü halinde sürekli tekrarlamalı. Fakat şu anda shurikeni hiçbir şekilde göremiyorum. Bunu düzeltmen lazım.
User prompt
Bumerang, ball, brick, aura, molotov ve shuriken assetleri sürekli kendi etraflarında dairesel olarak dönüyor olmalılar. Molotofun ve roketin alan hasarı veren dairesel assetleri (molotovFlame ve rocketBoom) dairesel olarak dönmeyecek. Sadece molotofun kendisi dairesel olarak dönecek kendi etrafında.
User prompt
Bumerang düşmana çarpınca yok olmamalı, düşmana hasar verip içinden geçmeli. Bumerang fırlayıp dairemsi bir yörünge izleyip (bumerang yörüngesi) geri gelmeli ve bu esnada çarptığı düşmanlara hasar vermeli. Bumerang karakterime geri geldiğinde yok olabilir. Sonra tekrar fırlatılabilir. Benzer şekilde top da düşmana çarpınca yok olmamalı, düşmana hasar verip içinden geçmeli. Top duvardan bir kere sekebilir ve bir kere sektikten sonra ekranın dışına çıkınca yok olur fakat bu esnada çarptığı (içinden geçtiği) düşmanlara hasar verir. Shuriken silahını alınca sürekli olarak dönmeye başlıyor. Shuriken silahı sürekli dönmemeli. 3 saniyede bir 3 saniyeliğine var olup dönmeli ve dönerken biçip geçtiği rakiplere hasar vermeli. 3 saniye sonra yok olmalı ve 3 saniye sonra tekrar var olup dönüp hasar vermeye devam etmeli. Roket ve molotof fırlatıldıklarında tam düşmana çarptıkları ya da kırılıp yok oldukları noktada çembersel bir alanda hasar vermeli. Bazen mesela molotofu sağ tarafa fırlatıyor ama molotofun yanma patlaması solda ya da başka bir yerlerde falan oluyor böyle olmamalı yani. Roket ve molotof nerede duruyor/çarpıyorsa orada patlamalı. Ayrıca roketin patlaması ve molotofun yanması aynı şeyler değil farklı şeyler. Molotofun yanması molotovFlame asseti fakat roketin patlaması rocketBoom asseti olmalı. Ayrıca bullet assetini (sarı bir daire gibi bir şey) kullanmadığım için onu silmende sakınca yoktur galiba, silmeni istiyorum.
User prompt
Ball silahımın ball assetini fırlatması gerekirken şu anda küçücük bir bullet fırlatıyor. Benim kodumda bullet diye bir asset olmamalı zaten. Ben bullet diye bir asseti hiç kullanmıyorum. Bulleti sadece bazı tanımlamalarda kullanıyorum ama silah olarak bullet kullanmıyorum hiçbir şekilde. Bunu düzeltmemiz lazım.
User prompt
Ama şu anda kartların açıklamaları tek satırda yazıldığı için kartın dışına taşıyor. Bunu düzeltmemiz lazım. Yazılar kartın dışına taşmamalı.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bomb = Container.expand(function () { var self = Container.call(this); self.active = true; var bombGraphics = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 60, tint: 0xff0000 }); self.update = function () { if (!player || !self.active) { return; } var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.active = false; // Deal 20 damage to all non-boss enemies on screen for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var screenDx = Math.abs(enemy.x - player.x); var screenDy = Math.abs(enemy.y - player.y); if (screenDx < 1024 && screenDy < 1366) { // Deal 20 damage, drop exp and remove if dead if (enemy.takeDamage(20)) { dropExpOrb(enemy.x, enemy.y); enemy.destroy(); enemies.splice(i, 1); } } } LK.effects.flashScreen(0xff0000, 300); if (self.parent) { self.destroy(); } return true; } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); self.damage = 10; self.speed = 15; self.dirX = 0; self.dirY = 0; self.piercing = 1; self.hitEnemies = []; var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Seviye seçim ekranı açıkken hiçbir şey yapma if (skillSelectionActive) { return; } // Hareket this.x += this.dirX * this.speed; this.y += this.dirY * this.speed; // Ekranın çok uzağına çıktıysa sil var dx = this.x - player.x; var dy = this.y - player.y; if (Math.abs(dx) > 2000 || Math.abs(dy) > 2000) { this.destroy(); var bi = bullets.indexOf(this); if (bi >= 0) { bullets.splice(bi, 1); } return; } // “Menzil” filtresi: bu top silahının menzili WEAPONS.ball.range var maxRange = WEAPONS.ball.range * (player.weapons && player.weapons.ball ? player.weapons.ball.rngMul : 1); // (Eğer o envanterde yoksa rngMul=1 varsaydık) // Düşmana çarpma kontrolü & menzil filtresi for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; if (this.intersects(e) && isWithinRange(e, maxRange)) { damageEnemy(e, this.damage); this.destroy(); var bi2 = bullets.indexOf(this); if (bi2 >= 0) { bullets.splice(bi2, 1); } return; } } }; return self; }); // ChickenLeg pickup class var ChickenLeg = Container.expand(function () { var self = Container.call(this); self.active = true; var chickenLegGraphics = self.attachAsset('chickenLeg', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 60 }); self.update = function () { if (!player || !self.active) { return; } var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.active = false; // Heal player for 30% of max HP, but not above max HP var healAmount = Math.floor(player.maxHp * 0.3); var oldHp = player.hp; player.hp = Math.min(player.hp + healAmount, player.maxHp); var actualHealed = player.hp - oldHp; if (actualHealed > 0) { LK.effects.flashObject(player, 0x00ff00, 300); // Show green HP gain text with black border var healText = new Text2('+' + actualHealed.toFixed(1), { size: 48, fill: 0x00ff00, stroke: 0x000000, strokeThickness: 4 }); healText.anchor.set(0.5); healText.x = player.x; healText.y = player.y - (player.height ? player.height / 2 : 60); healText.alpha = 1; gameContainer.addChild(healText); tween(healText, { y: healText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (healText.parent) { healText.destroy(); } } }); } LK.getSound('pickup').play(); if (self.parent) { self.destroy(); } return true; } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); self.hp = 20; self.maxHp = 20; self.damage = 10; self.speed = 2; self.expValue = 5; self.type = 'normal'; self.critChance = 0.25; // Düşmanlar da %25 kritik vuruş şansı ile başlar var enemyGraphics = self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function (amount) { self.hp -= amount; LK.effects.flashObject(self, 0xff0000, 200); if (self.hp <= 0) { return true; // Enemy died } return false; // Enemy still alive }; self.update = function () { if (!player || skillSelectionActive) { return; } // Flip enemy graphic to face player if (self.x < player.x) { enemyGraphics.scaleX = 1; } else if (self.x > player.x) { enemyGraphics.scaleX = -1; } // Debuff: Stun if (self.stunBuff && self.stunBuffTime !== undefined) { var stunDuration = Math.floor(self.stunBuff * 60); // seconds to frames if (gameTime - self.stunBuffTime < stunDuration) { // Stunned: do not move or attack return; } else { self.stunBuff = 0; self.stunBuffTime = undefined; } } // 1) Oyuncuya olan vektörü bul var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Debuff: Slow var speedMul = 1; if (self.slowBuff && self.slowBuffTime !== undefined) { var slowDuration = 120; // 2 seconds if (gameTime - self.slowBuffTime < slowDuration) { speedMul = Math.max(0, 1 - self.slowBuff / 100); } else { self.slowBuff = 0; self.slowBuffTime = undefined; } } // 2) Eğer düşman, oyuncuya 150 pikselden yakınsa hareket etme if (dist > 150) { // 3) Aksi halde 50px uzaktan hareket et self.x += dx / dist * self.speed * speedMul; self.y += dy / dist * self.speed * speedMul; } // Bleeding+ if (self.bleedBuff && self.bleedBuffTime !== undefined) { var bleedDuration = 240; // 4 seconds (60fps) if (gameTime - self.bleedBuffTime < bleedDuration) { // Every 30 frames (0.5s), apply bleed damage if (!self.bleedTicks) { self.bleedTicks = 0; } var ticks = Math.floor((gameTime - self.bleedBuffTime) / 30); while (self.bleedTicks < ticks) { var bleedDmg = self.maxHp * (self.bleedBuff / 100); // allow fractional self.hp -= bleedDmg; LK.effects.flashObject(self, 0xaa0000, 100); // Show damage text for bleeding (always, even if <1) var dmgText = new Text2(bleedDmg.toFixed(1), { size: 48, fill: 0x00ff00, // green for regen, but for bleed use red stroke: 0x000000, strokeThickness: 4 }); dmgText.setText('-' + bleedDmg.toFixed(1)); dmgText.fill = 0xff3333; dmgText.anchor.set(0.5); dmgText.x = self.x; dmgText.y = self.y - (self.height ? self.height / 2 : 60); dmgText.alpha = 1; gameContainer.addChild(dmgText); tween(dmgText, { y: dmgText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (dmgText.parent) { dmgText.destroy(); } } }); if (self.hp <= 0) { if (self.parent) { self.destroy(); } break; } self.bleedTicks++; } } else { self.bleedBuff = 0; self.bleedBuffTime = undefined; self.bleedTicks = 0; } } // Grit Wound+ if (self.gritWound && self.lastGritWoundTime !== undefined) { var gritDuration = 240; // 4 seconds if (gameTime - self.lastGritWoundTime < gritDuration) { // No regen logic here, but you can use self.gritWound for regen reduction elsewhere // Example: If you add enemy regen, show green text here if (self.enemyRegen && self.hp < self.maxHp) { var regenAmount = self.maxHp * (self.enemyRegen / 100); if (self.gritWound > 0) { regenAmount = regenAmount * (1 - self.gritWound / 100); } var oldHp = self.hp; self.hp = Math.min(self.hp + regenAmount, self.maxHp); var actualHealed = self.hp - oldHp; if (actualHealed > 0) { // Show green HP gain text with black border var healText = new Text2('+' + actualHealed.toFixed(1), { size: 48, fill: 0x00ff00, stroke: 0x000000, strokeThickness: 4 }); healText.anchor.set(0.5); healText.x = self.x; healText.y = self.y - (self.height ? self.height / 2 : 60); healText.alpha = 1; gameContainer.addChild(healText); tween(healText, { y: healText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (healText.parent) { healText.destroy(); } } }); } } } else { self.gritWound = 0; self.lastGritWoundTime = undefined; } } // --- Enemy HP regen after wave 5, scaling with wave --- if (self.enemyRegen && self.enemyRegen > 0 && (!self.gritWound || self.gritWound === 0)) { if (!self.lastEnemyRegenTime) { self.lastEnemyRegenTime = 0; } if (gameTime - self.lastEnemyRegenTime >= 300) { // every 5s var regenAmount = self.maxHp * (self.enemyRegen / 100); var oldHp = self.hp; self.hp = Math.min(self.hp + regenAmount, self.maxHp); var actualHealed = self.hp - oldHp; if (actualHealed > 0) { // Show green HP gain text with black border var healText = new Text2('+' + actualHealed.toFixed(1), { size: 48, fill: 0x00ff00, stroke: 0x000000, strokeThickness: 4 }); healText.anchor.set(0.5); healText.x = self.x; healText.y = self.y - (self.height ? self.height / 2 : 60); healText.alpha = 1; gameContainer.addChild(healText); tween(healText, { y: healText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (healText.parent) { healText.destroy(); } } }); } self.lastEnemyRegenTime = gameTime; } } // Burada asla destroy() yok; sadece hareketi sınırlıyoruz }; return self; }); var ExpOrb = Container.expand(function () { var self = Container.call(this); // 1) spawnTime kaydet self.spawnTime = gameTime; self.value = 1; // Each orb always gives 1 EXP self.magnetSpeed = 0; var orbGraphics = self.attachAsset('expOrb', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // ORB YAŞI (frame cinsinden) var age = gameTime - self.spawnTime; // 2) Eğer 10 saniye geçmişse (600 frame), orb’u yok et ve listeden çıkar if (age >= 600) { // yok et if (self.parent) { self.destroy(); } var idx = expOrbs.indexOf(self); if (idx >= 0) { expOrbs.splice(idx, 1); } return; } // 3) Son 5 saniyede (age >= 300), yanıp sönme uygulaması if (age >= 300) { // kalan süre var remaining = 600 - age; // 300’den 0’a kadar azalır // blink periyodu: remaining / 50’ye bağlı (en hızlı 1 frame’lik periyot) var blinkInterval = Math.ceil(remaining / 50); if (blinkInterval < 1) { blinkInterval = 1; } // yaşa göre çift/tek periyoda bölerek görünürlüğü değiştir var phase = Math.floor(age / blinkInterval); self.visible = phase % 2 === 0; } else { // son 5 saniye değilse görünür olsun self.visible = true; } // 4) Normal manyetik çekim hareketi if (!player || self.magnetSpeed === 0) { return; } var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.x += dx / dist * self.magnetSpeed; self.y += dy / dist * self.magnetSpeed; } }; return self; }); var Joystick = Container.expand(function () { var self = Container.call(this); self.active = false; self.dirX = 0; self.dirY = 0; var base = self.attachAsset('joystickBase', { anchorX: 0.5, anchorY: 0.5 }); base.alpha = 0.5; var knob = self.attachAsset('joystickKnob', { anchorX: 0.5, anchorY: 0.5 }); knob.alpha = 0.7; self.setKnobPosition = function (x, y) { var dx = x - base.x; var dy = y - base.y; var dist = Math.sqrt(dx * dx + dy * dy); var maxDist = 60; if (dist > maxDist) { dx = dx / dist * maxDist; dy = dy / dist * maxDist; } knob.x = dx; knob.y = dy; // Defensive: avoid division by zero if (maxDist === 0) { self.dirX = 0; self.dirY = 0; } else { self.dirX = dx / maxDist; self.dirY = dy / maxDist; } }; self.reset = function () { knob.x = 0; knob.y = 0; self.dirX = 0; self.dirY = 0; self.active = false; }; return self; }); var Magnet = Container.expand(function () { var self = Container.call(this); self.active = true; var magnetGraphics = self.attachAsset('magnet', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 60, tint: 0x0099ff }); self.update = function () { if (!player || !self.active) { return; } var dx = player.x - self.x; var dy = player.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.active = false; // Magnetize all exp orbs on screen for (var i = 0; i < expOrbs.length; i++) { var orb = expOrbs[i]; var orbDx = Math.abs(orb.x - player.x); var orbDy = Math.abs(orb.y - player.y); if (orbDx < 1024 && orbDy < 1366) { orb.magnetSpeed = 20; } } if (self.parent) { self.destroy(); } return true; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); self.level = 1; self.exp = 0; self.expToNext = 10; self.hp = 100; self.maxHp = 100; self.damage = 10.0; self.fireRate = 30; self.bulletSpeed = 15; self.moveSpeed = 5; self.pickupRange = 100; self.lastFire = 0; self.critChance = 0.25; // Oyuncu başlangıçta %25 kritik vuruş şansı /* ===== BUFFS ===== */ self.buffs = { damageReduction: 0, // percent, e.g. 10 means 10% moveSpeed: 0, // percent, e.g. 20 means 20% hpRegen: 0, // percent per 5s damageReflection: 0, // percent gritWound: 0, // percent enemySlow: 0, // percent enemyStun: 0, // seconds bleeding: 0, // percent per tick critChance: 0 // Critical Hit Chance+ buff, percent (15 means +15%) }; self.lastRegenTime = 0; /* ===== WEAPON INVENTORY ===== */ self.weapons = {}; // key → instance var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function (amount) { // Damage Reduction+ var finalAmount = amount; if (self.buffs.damageReduction > 0) { finalAmount = Math.ceil(amount * (1 - self.buffs.damageReduction / 100)); } self.hp -= finalAmount; LK.effects.flashObject(self, 0xff0000, 300); LK.getSound('damageTaken').play(); // Damage Reflection+ if (self.buffs.damageReflection > 0 && enemies.length > 0) { // Find nearest enemy in contact (or just first in range) for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; var dx = e.x - self.x; var dy = e.y - self.y; var distSq = dx * dx + dy * dy; if (distSq <= 22500) { // same as contact check var reflectDmg = Math.ceil(finalAmount * self.buffs.damageReflection / 100); if (reflectDmg > 0) { damageEnemy(e, reflectDmg); // Show damage text for reflection var dmgText = new Text2(reflectDmg.toFixed(1), { size: 48, fill: 0xffffff, stroke: 0x000000, strokeThickness: 4 }); dmgText.anchor.set(0.5); dmgText.x = e.x; dmgText.y = e.y - (e.height ? e.height / 2 : 60); dmgText.alpha = 1; gameContainer.addChild(dmgText); tween(dmgText, { y: dmgText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (dmgText.parent) { dmgText.destroy(); } } }); } break; } } } if (self.hp <= 0) { LK.showGameOver(); } }; self.gainExp = function (amount) { // Add exp orbs self.exp += amount; // Level up if exp orbs >= current level while (self.exp >= self.level) { self.exp -= self.level; self.levelUp(); } }; self.update = function () { // Flip player graphic based on movement direction if (self.lastX === undefined) { self.lastX = self.x; } if (self.x > self.lastX) { playerGraphics.scaleX = 1; } else if (self.x < self.lastX) { playerGraphics.scaleX = -1; } self.lastX = self.x; // Movement Speed+ if (self.buffs.moveSpeed > 0) { self.moveSpeed = 5 * (1 + self.buffs.moveSpeed / 100); } else { self.moveSpeed = 5; } // HP Regeneration+ if (self.buffs.hpRegen > 0 && gameTime - (self.lastRegenTime || 0) >= 300) { var regenAmount = self.maxHp * (self.buffs.hpRegen / 100); // allow fractional regen if (regenAmount > 0 && self.hp < self.maxHp) { var oldHp = self.hp; self.hp = Math.min(self.hp + regenAmount, self.maxHp); var actualHealed = self.hp - oldHp; if (actualHealed > 0) { LK.effects.flashObject(self, 0x00ff00, 200); // Show green HP gain text with black border var healText = new Text2('+' + actualHealed.toFixed(1), { size: 48, fill: 0x00ff00, stroke: 0x000000, strokeThickness: 4 }); healText.anchor.set(0.5); healText.x = self.x; healText.y = self.y - (self.height ? self.height / 2 : 60); healText.alpha = 1; gameContainer.addChild(healText); tween(healText, { y: healText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (healText.parent) { healText.destroy(); } } }); } } self.lastRegenTime = gameTime; } for (var k in self.weapons) { var inst = self.weapons[k], meta = WEAPONS[k]; if (--inst.cdCnt <= 0) { fireWeapon(k, inst, meta); inst.cdCnt = meta.cd; } } }; self.levelUp = function () { self.level++; // self.exp is now handled in gainExp, do not reset here self.expToNext = self.level * 15; // self.maxHp += 10; // Artık seviye atlayınca max HP artmıyor // Do NOT restore full health on level up // self.hp = self.maxHp; // Increase movement speed by 4% per level up self.moveSpeed *= 1.04; LK.getSound('levelup').play(); showSkillSelection(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x111111 }); /**** * Game Code ****/ /* ==== UNIVERSAL HELPERS ==== */ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function isWithinRange(e, maxRange) { var dx = e.x - player.x; var dy = e.y - player.y; return dx * dx + dy * dy <= maxRange * maxRange; } function addWeapon(key) { // <-- artık global if (player && Object.keys(player.weapons).length >= 6) { return; // Zaten 6 silah varsa yeni eklemeye izin verme } var m = WEAPONS[key]; var target = player ? player : { weapons: {} }; // sınıf kurulumunda da çalışsın target.weapons[key] = { cd: m.cd, cdCnt: m.cd, dmgMul: 1, rngMul: 1, amount: 1, upgrade: 0, enchTaken: [] }; } function rand(min, max) { return min + Math.random() * (max - min); } function distSq(a, b) { var dx = a.x - b.x, dy = a.y - b.y; return dx * dx + dy * dy; } function unitDir(from, to) { var dx = to.x - from.x, dy = to.y - from.y, d = Math.sqrt(dx * dx + dy * dy); return { dx: dx / d, dy: dy / d, len: d }; } /* ==== WEAPON META TABLE ==== */ var WEAPONS = { sword: { cd: 120, dmg: 6, range: 200, type: 'melee', ench: ["Sword Damage+", "Sword Attack Speed+", "Sword Range+"], up: ["Sword +1", "Sword +2", "Sword +3"] }, boomerang: { cd: 180, dmg: 6, range: 1000, type: 'boomerang', ench: ["Boomerang Damage+", "Boomerang Attack Speed+", "Boomerang Range+"], up: ["Boomerang +1", "Boomerang +2", "Boomerang +3"] }, ball: { cd: 180, dmg: 6, range: 1000, type: 'ball', ench: ["Ball Damage+", "Ball Attack Speed+", "Ball Range+"], up: ["Ball +1", "Ball +2", "Ball +3"] }, rocket: { cd: 480, dmg: 16, range: 1200, type: 'rocket', ench: ["Rocket Damage+", "Rocket Attack Speed+", "Rocket Range+"], up: ["Rocket +1", "Rocket +2", "Rocket +3"] }, brick: { cd: 240, dmg: 8, range: 800, type: 'brick', ench: ["Brick Damage+", "Brick Attack Speed+", "Brick Range+"], up: ["Back 75°", "Front 45°", "Back 45°"] }, lightning: { cd: 240, dmg: 16, range: 1500, type: 'lightning', ench: ["Lightning Damage+", "Lightning Attack Speed+", "Lightning Range+"], up: ["Lightning +1", "Lightning +2", "Lightning +3"] }, aura: { cd: 60, dmg: 2, range: 250, type: 'aura', ench: ["Aura Damage+", "Aura Attack Speed+", "Aura Range+"], up: ["Slow 25%", "Slow 50%", "Slow 75%"] }, molotov: { cd: 180, dmg: 6, range: 800, type: 'molotov', ench: ["Molotov Damage+", "Molotov Attack Speed+", "Molotov Range+"], up: ["Molotov +1", "Molotov +2", "Molotov +3"] }, shuriken: { cd: 180, dmg: 6, range: 250, type: 'shuriken', ench: ["Shuriken Damage+", "Shuriken Attack Speed+", "Shuriken Range+"], up: ["Shuriken +1", "Shuriken +2", "Shuriken +3"] } }; var player; var enemies = []; var bullets = []; var expOrbs = []; var joystick; var gameTime = 0; var waveNumber = 1; // bossSpawned variable removed; boss is now spawned every 10th wave var selectedSkills = []; var camera = { x: 0, y: 0 }; var gameContainer; var skillSelectionActive = false; var pickups = []; var lastPickupSpawn = 0; // Initialize game world gameContainer = game.addChild(new Container()); // Tile seamless background image to cover the visible area and follow the camera var bgTileAsset = LK.getAsset('seamlessBackGround', { anchorX: 0, anchorY: 0 }); var bgTileWidth = bgTileAsset.width; var bgTileHeight = bgTileAsset.height; var bgTilesX = Math.ceil(2048 / bgTileWidth) + 2; // +2 for safe margin var bgTilesY = Math.ceil(2732 / bgTileHeight) + 2; var backgroundTiles = []; for (var i = 0; i < bgTilesX; i++) { for (var j = 0; j < bgTilesY; j++) { var tile = LK.getAsset('seamlessBackGround', { anchorX: 0, anchorY: 0 }); tile.x = i * bgTileWidth; tile.y = j * bgTileHeight; gameContainer.addChild(tile); backgroundTiles.push(tile); } } // Create player player = gameContainer.addChild(new Player()); player.x = 1024; player.y = 1366; addWeapon('sword'); // --- Health bar for player --- // Rectangle health bar (depletes right to left) player.hpBar = new Container(); // Remove shadow/overlay: set bg alpha lower so it doesn't affect fg color player.hpBarBg = LK.getAsset('hpBarRect', { anchorX: 0, anchorY: 0.5 }); player.hpBarBg.alpha = 0.3; // Lower alpha so fg color is not affected player.hpBarFg = LK.getAsset('hpBarRectFg', { anchorX: -0.02, anchorY: 0.5 }); player.hpBar.addChild(player.hpBarBg); player.hpBar.addChild(player.hpBarFg); player.hpBar.y = -140; player.hpBar.x = -110; // align left edge to player center player.addChild(player.hpBar); // --- Health bar for enemies will be created on spawnEnemy --- // Create joystick joystick = new Joystick(); joystick.x = 0; joystick.y = -200; LK.gui.bottom.addChild(joystick); // UI Elements var timerText = new Text2('00:00', { size: 80, fill: 0xFFFFFF }); timerText.anchor.set(0.5, 0); LK.gui.top.addChild(timerText); // Add wave number display to top center var waveText = new Text2('Wave 1', { size: 80, fill: 0x00FFFF }); waveText.anchor.set(0.5, 0); waveText.y = 100; LK.gui.top.addChild(waveText); var levelText = new Text2('Level 1', { size: 60, fill: 0xFFFF00 }); levelText.anchor.set(0, 0); levelText.y = 10; levelText.x = 200; LK.gui.top.addChild(levelText); var hpText = new Text2('HP: 100/100', { size: 60, fill: 0xFF0000 }); hpText.anchor.set(1, 0); hpText.y = 10; hpText.x = -200; LK.gui.top.addChild(hpText); // Spawn functions function spawnEnemy(type, x, y) { var enemy = new Enemy(); enemy.x = x; enemy.y = y; // --- Zombi temel istatistikleri ve dalga ölçekleme --- var baseHp = 20; var baseDmg = 10; var baseSpeed = 2; var hp = baseHp * Math.pow(1.05, waveNumber - 1); var dmg = baseDmg * Math.pow(1.05, waveNumber - 1); var speed = baseSpeed * Math.pow(1.05, waveNumber - 1); enemy.maxHp = hp; enemy.hp = hp; enemy.damage = dmg; enemy.speed = speed; // --- Düşman can yenileme: 5. dalgadan sonra, her 5 dalgada +1% artar --- if (waveNumber > 5) { // 6-10: 5%, 11-15: 6%, 16-20: 7%, ... var regenPercent = 5 + Math.floor((waveNumber - 6) / 5) + 0; enemy.enemyRegen = regenPercent; } else { enemy.enemyRegen = 0; } enemies.push(enemy); gameContainer.addChild(enemy); // --- Health bar for enemy --- // Rectangle health bar (depletes right to left) enemy.hpBar = new Container(); // Remove shadow/overlay: set bg alpha lower so it doesn't affect fg color enemy.hpBarBg = LK.getAsset('enemyHpBarRect', { anchorX: 0.0, anchorY: 0.5 }); enemy.hpBarBg.alpha = 0.3; // Lower alpha so fg color is not affected enemy.hpBarFg = LK.getAsset('enemyHpBarRectFg', { anchorX: -0.04, anchorY: 0.5 }); enemy.hpBar.addChild(enemy.hpBarBg); enemy.hpBar.addChild(enemy.hpBarFg); enemy.hpBar.y = -110; enemy.hpBar.x = -80; // align left edge to enemy center enemy.addChild(enemy.hpBar); } function spawnWave() { var spawnCount = 5 + waveNumber * 2; var spawnRadius = 1500; for (var i = 0; i < spawnCount; i++) { var angle = Math.random() * Math.PI * 2; var x = player.x + Math.cos(angle) * spawnRadius; var y = player.y + Math.sin(angle) * spawnRadius; spawnEnemy('normal', x, y); } } function dropExpOrb(x, y) { var orb = new ExpOrb(); orb.x = x; orb.y = y; // orb.value is always 1 in ExpOrb class expOrbs.push(orb); gameContainer.addChild(orb); } /* =============================================================== */ /* NINE-WEAPON FIRE / PROJECTILES */ /* =============================================================== */ function nearestEnemy() { var best = null, bestD = 1e9; for (var i = 0; i < enemies.length; i++) { var d = distSq(player, enemies[i]); if (d < bestD) { best = enemies[i]; bestD = d; } } return best; } function damageEnemy(e, dmg, attacker) { // attacker: optional, can be player or enemy // Play hit sound on every hit LK.getSound('hit').play(); // Determine crit chance and crit type var critChance = 0.25; // default var critType = null; // null, "low", "high" var isPlayerAttack = false; if (attacker === undefined) { attacker = player; } if (attacker === player) { isPlayerAttack = true; critChance = player.critChance !== undefined ? player.critChance : 0.25; } else if (attacker && attacker.type === 'normal') { critChance = attacker.critChance !== undefined ? attacker.critChance : 0.25; } var critRoll = Math.random(); var critValue = 1; if (critRoll < critChance) { // Crit! Now decide low or high if (Math.random() < 0.5) { critType = "low"; critValue = 1.2; } else { critType = "high"; critValue = 1.4; } } var finalDmg = dmg * critValue; // Apply debuffs if player has buffs if (player && player.buffs) { // Grit Wound+ if (player.buffs.gritWound > 0) { e.gritWound = player.buffs.gritWound; e.lastGritWoundTime = gameTime; } // Enemy Slow+ if (player.buffs.enemySlow > 0) { e.slowBuff = player.buffs.enemySlow; e.slowBuffTime = gameTime; } // Enemy Stun+ if (player.buffs.enemyStun > 0) { e.stunBuff = player.buffs.enemyStun; e.stunBuffTime = gameTime; } // Bleeding+ if (player.buffs.bleeding > 0) { e.bleedBuff = player.buffs.bleeding; e.bleedBuffTime = gameTime; e.bleedTicks = 0; } } // Hasar yazısı göster if (typeof finalDmg === "number") { var fillColor = 0xffffff; var strokeColor = 0x000000; if (isPlayerAttack) { if (critType === "low") { fillColor = 0xffe066; // sarı } else if (critType === "high") { fillColor = 0xff3333; // kırmızı } else { fillColor = 0xffffff; // beyaz } } else { // Enemy attack, use default fillColor = 0xff3333; } var dmgText = new Text2(finalDmg.toFixed(1), { size: 48, fill: fillColor, stroke: strokeColor, strokeThickness: 4 }); dmgText.anchor.set(0.5); dmgText.x = e.x; dmgText.y = e.y - (e.height ? e.height / 2 : 60); dmgText.alpha = 1; gameContainer.addChild(dmgText); // Yavaşça yukarı çıkıp kaybolsun tween(dmgText, { y: dmgText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (dmgText.parent) { dmgText.destroy(); } } }); } if (e.takeDamage(finalDmg)) { // Play death sound (if you have a death sound asset, e.g. 'death') if (LK.getSound('death')) { LK.getSound('death').play(); } // Ölünce exp orb düşür: dropExpOrb(e.x, e.y); // Sonra düşmanı kaldır ve yok et: var idx = enemies.indexOf(e); enemies.splice(idx, 1); e.destroy(); } } /* ---- sword (melee slash) ---- */ function swingSword(inst) { var sorted = enemies.slice().sort(function (a, b) { return distSq(player, a) - distSq(player, b); }); if (sorted.length === 0) { return; } for (var n = 0; n < inst.amount; n++) { var idx = n < sorted.length ? n : 0; var target = sorted[idx]; var dir = unitDir(player, target); var arc = gameContainer.addChild(new Container()); arc.x = player.x; arc.y = player.y; arc.attachAsset('swordHit', { anchorX: 0, anchorY: 0.5, rotation: Math.atan2(dir.dy, dir.dx), scaleX: inst.rngMul, scaleY: inst.rngMul }); arc.life = 10; arc.dmg = WEAPONS.sword.dmg * inst.dmgMul; arc.hitList = []; arc.update = function () { if (--this.life <= 0) { if (this.parent) { this.destroy(); } return; } var maxRange = WEAPONS.sword.range * inst.rngMul; for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; // hem arc.intersects hem oyuncudan menzil kontrolü if (this.hitList.indexOf(e) === -1 && this.intersects(e) && isWithinRange(e, maxRange)) { this.hitList.push(e); damageEnemy(e, this.dmg); } } }; } } /* ---- boomerang ---- */ function fireBoomerang(inst) { var target = nearestEnemy(); if (!target) { return; } var dir = unitDir(player, target); // Bu silahın menzilini WEAPONS tablosundan alıp, inst.rngMul ile ölçekleyebiliriz: var maxRange = WEAPONS.boomerang.range * inst.rngMul; for (var n = 0; n < inst.amount; n++) { var p = gameContainer.addChild(new Container()); var boomerangAsset = p.attachAsset('boomerang', { anchorX: 0.5, anchorY: 0.5, scaleX: inst.rngMul, scaleY: inst.rngMul }); p._rotationAngle = 0; p._boomerangAsset = boomerangAsset; p.x = player.x; p.y = player.y; p.dirX = dir.dx; p.dirY = dir.dy; p.speed = 12; p.dmg = WEAPONS.boomerang.dmg * inst.dmgMul; p.life = 300; p.hitEnemies = []; p.update = function () { if (skillSelectionActive) { return; } // 1) Hareket this.x += this.dirX * this.speed; this.y += this.dirY * this.speed; // Rotate boomerang asset if (this._boomerangAsset) { this._rotationAngle = (this._rotationAngle || 0) + 0.3; this._boomerangAsset.rotation = this._rotationAngle; } // 2) “life” 150’de geri dönüş if (--this.life === 150) { var u = unitDir(this, player); this.dirX = u.dx; this.dirY = u.dy; } // 3) Boomerang ekranın çok dışına çıktıysa sil var dx = this.x - player.x; var dy = this.y - player.y; if (Math.abs(dx) > 2000 || Math.abs(dy) > 2000) { if (this.parent) { this.destroy(); } var idx = bullets.indexOf(this); if (idx >= 0) { bullets.splice(idx, 1); } return; } // 4) Düşmanlara çarpma kontrolü & menzil filtresi // maxRange her frame güncel olmalı (örn. buff alınırsa) var curMaxRange = WEAPONS.boomerang.range * inst.rngMul; for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; // e, oyuncudan maxRange uzaklık içindeyse vur: if (this.hitEnemies.indexOf(e) === -1 && this.intersects(e) && isWithinRange(e, curMaxRange)) { damageEnemy(e, this.dmg); this.hitEnemies.push(e); } } // 5) Oyuncuya döndüyse yok et var distToPlayer = Math.sqrt((this.x - player.x) * (this.x - player.x) + (this.y - player.y) * (this.y - player.y)); if (distToPlayer < 60) { if (this.parent) { this.destroy(); } var idx4 = bullets.indexOf(this); if (idx4 >= 0) { bullets.splice(idx4, 1); } return; } // 6) “life” sıfırlandıysa sil if (this.life <= 0) { if (this.parent) { this.destroy(); } var idx3 = bullets.indexOf(this); if (idx3 >= 0) { bullets.splice(idx3, 1); } } }; bullets.push(p); } } /* ---- top (rebound ball) ---- */ function fireBall(inst) { var target = nearestEnemy(); if (!target) { return; } var dir = unitDir(player, target); for (var n = 0; n < inst.amount; n++) { var p = new Container(); // Attach the 'ball' asset, scale by range multiplier var ballGraphics = p.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: inst.rngMul, scaleY: inst.rngMul }); p._rotationAngle = 0; p._ballAsset = ballGraphics; p.x = player.x; p.y = player.y; p.dirX = dir.dx; p.dirY = dir.dy; p.damage = 12 * inst.dmgMul; p.speed = 14; p.bounced = false; p.hitEnemies = []; p.update = function () { // Seviye seçim ekranı açıkken hiçbir şey yapma if (skillSelectionActive) { return; } // Hareket this.x += this.dirX * this.speed; this.y += this.dirY * this.speed; // Rotate ball asset if (this._ballAsset) { this._rotationAngle = (this._rotationAngle || 0) + 0.3; this._ballAsset.rotation = this._rotationAngle; } // Sınırları belirle (ekran sınırı: 0-2048 x, 0-2732 y) var minX = 0, maxX = 2048, minY = 0, maxY = 2732; if (!this.bounced) { if (this.x < minX || this.x > maxX) { this.dirX = -this.dirX; this.bounced = true; this.x = Math.max(minX, Math.min(this.x, maxX)); } if (this.y < minY || this.y > maxY) { this.dirY = -this.dirY; this.bounced = true; this.y = Math.max(minY, Math.min(this.y, maxY)); } } else { if (this.x < minX || this.x > maxX || this.y < minY || this.y > maxY) { if (this.parent) { this.destroy(); } var bi = bullets.indexOf(this); if (bi >= 0) { bullets.splice(bi, 1); } return; } } // “Menzil” filtresi: bu top silahının menzili WEAPONS.ball.range var maxRange = WEAPONS.ball.range * (player.weapons && player.weapons.ball ? player.weapons.ball.rngMul : 1); // Düşmana çarpma kontrolü & menzil filtresi for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; if (this.hitEnemies.indexOf(e) === -1 && this.intersects(e) && isWithinRange(e, maxRange)) { damageEnemy(e, this.damage); this.hitEnemies.push(e); } } }; bullets.push(p); gameContainer.addChild(p); } } /* ---- rocket ---- */ function fireRocket(inst) { var target = nearestEnemy(); if (!target) { return; } var dir = unitDir(player, target); // Bu silahın menzili: var maxRange = WEAPONS.rocket.range * inst.rngMul; for (var n = 0; n < inst.amount; n++) { var p = gameContainer.addChild(new Container()); p.attachAsset('rocket', { anchorX: 0.5, anchorY: 0.5, scaleX: inst.rngMul, scaleY: inst.rngMul }); p.x = player.x; p.y = player.y; p.dirX = dir.dx; p.dirY = dir.dy; p.speed = 10; p.dmg = WEAPONS.rocket.dmg * inst.dmgMul; p.update = function () { if (skillSelectionActive) { return; } // 1) Hareket this.x += this.dirX * this.speed; this.y += this.dirY * this.speed; // 2) Düşmana çarpma kontrolü & menzil filtresi for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; // Eğer bu e, oyuncudan maxRange uzaklık içindeyse AoE hasar uygula if (this.intersects(e) && isWithinRange(e, maxRange)) { LK.getSound('rocketBoom').play(); // a) Dairesel patlama efekti: rocketBoom asseti kullanılmalı var explosion = gameContainer.addChild(new Container()); var gfx = LK.getAsset('rocketBoom', { anchorX: 0.5, anchorY: 0.5, scaleX: inst.rngMul * (80 / 70), scaleY: inst.rngMul * (80 / 70), alpha: 0.6 }); explosion.addChild(gfx); explosion.x = this.x; explosion.y = this.y; explosion.life = 30; explosion.update = function () { if (--this.life <= 0) { this.destroy(); } else { this.children[0].alpha = this.life / 30 * 0.6; } }; // b) AoE hasar: sadece menzil içindekileri vur for (var k = enemies.length - 1; k >= 0; k--) { var e2 = enemies[k]; if (distSq(this, e2) < 16000 && isWithinRange(e2, maxRange)) { damageEnemy(e2, this.dmg); } } // c) Bu roketi sil if (this.parent) { this.destroy(); } var bi = bullets.indexOf(this); if (bi >= 0) { bullets.splice(bi, 1); } return; } } // 3) Ekranın dışına çıkarsa sil var dx = this.x - player.x; var dy = this.y - player.y; if (Math.abs(dx) > 2000 || Math.abs(dy) > 2000) { if (this.parent) { this.destroy(); } var bi2 = bullets.indexOf(this); if (bi2 >= 0) { bullets.splice(bi2, 1); } return; } }; bullets.push(p); } } /* ---- brick ---- */ function throwBrick(inst, angDeg) { var rad = angDeg * Math.PI / 180; var p = gameContainer.addChild(new Container()); var brickAsset = p.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5, scaleX: inst.rngMul, scaleY: inst.rngMul }); p._rotationAngle = 0; p._brickAsset = brickAsset; p.x = player.x; p.y = player.y; p.vx = Math.cos(rad) * 14; p.vy = Math.sin(rad) * 14; p.g = 0.3; p.dmg = WEAPONS.brick.dmg * inst.dmgMul; // Bu silahın menzili: var maxRange = WEAPONS.brick.range * inst.rngMul; p.update = function () { if (skillSelectionActive) { return; } // 1) Yerçekimi ve hareket this.vy += this.g; this.x += this.vx; this.y += this.vy; // Rotate brick asset if (this._brickAsset) { this._rotationAngle = (this._rotationAngle || 0) + 0.3; this._brickAsset.rotation = this._rotationAngle; } // 2) Düşmana çarpma kontrolü & menzil filtresi for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; if (this.intersects(e) && isWithinRange(e, maxRange)) { damageEnemy(e, this.dmg); if (this.parent) { this.destroy(); } return; } } // 3) Belirli mesafeden uzaklaşırsa yok et var dx = this.x - player.x; var dy = this.y - player.y; if (Math.abs(dx) > 2000 || Math.abs(dy) > 2000) { if (this.parent) { this.destroy(); } return; } }; } /* ---- lightning ---- */ function castLightning(inst) { // 1) Menzildeki düşmanları filtrele var maxRange = WEAPONS.lightning.range * inst.rngMul; var candidates = enemies.filter(function (e) { var dx = e.x - player.x; var dy = e.y - player.y; return dx * dx + dy * dy <= maxRange * maxRange; }); if (candidates.length === 0) { return; } // 2) Rastgele birini seç var victim = candidates[Math.floor(Math.random() * candidates.length)]; // 3) Efekti ekle var l = gameContainer.addChild(new Container()); l.attachAsset('lightning', { anchorX: 0.5, anchorY: 1, scaleX: inst.rngMul, scaleY: inst.rngMul }); l.x = victim.x; l.y = victim.y; l.life = 15; l.update = function () { if (skillSelectionActive) { return; } if (--this.life === 14) { damageEnemy(victim, WEAPONS.lightning.dmg * inst.dmgMul); } if (this.life <= 0) { if (this.parent) { this.destroy(); } } }; } /* ---- aura ---- */ var auraField = null; function ensureAura(inst) { // 1) Sadece ilk defa oluşturulacak: if (!auraField) { auraField = player.addChild(new Container()); auraField.attachAsset('auraField', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: inst.rngMul, scaleY: inst.rngMul }); // Oyuncunun tam ortası (yerel koordinat): auraField.x = 0; auraField.y = 0; } // Her frame aura görselini güncelle (range buff alınırsa anında büyüsün/küçülsün) if (auraField && auraField.children && auraField.children.length > 0) { auraField.children[0].scaleX = inst.rngMul; auraField.children[0].scaleY = inst.rngMul; // Rotate aura asset if (typeof auraField._rotationAngle === "undefined") { auraField._rotationAngle = 0; } auraField._rotationAngle += 0.03; auraField.children[0].rotation = auraField._rotationAngle; } // 2) Hasar uygulama kısmı (oyuncudan r uzaklıktaysa vur): var r = WEAPONS.aura.range * inst.rngMul; for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; var dx = e.x - player.x; var dy = e.y - player.y; if (dx * dx + dy * dy < r * r) { damageEnemy(e, inst.dmgMul * 5); } } } /* ---- molotov ---- */ function throwMolotov(inst) { var a = Math.random() * Math.PI * 2, d = rand(300, 600), tx = player.x + Math.cos(a) * d, ty = player.y + Math.sin(a) * d; var p = gameContainer.addChild(new Container()); var molotovAsset = p.attachAsset('molotov', { anchorX: 0.5, anchorY: 0.5, scaleX: inst.rngMul, scaleY: inst.rngMul }); p._rotationAngle = 0; p._molotovAsset = molotovAsset; p.x = player.x; p.y = player.y; var u = unitDir(p, { x: tx, y: ty }); p.dirX = u.dx; p.dirY = u.dy; p.speed = 16; p.life = 60; p.update = function () { if (skillSelectionActive) { return; } this.x += this.dirX * this.speed; this.y += this.dirY * this.speed; // Rotate molotov asset if (this._molotovAsset) { this._rotationAngle = (this._rotationAngle || 0) + 0.3; this._molotovAsset.rotation = this._rotationAngle; } if (--this.life <= 0) { spawnFlame(this.x, this.y, inst); if (this.parent) { this.destroy(); } } }; bullets.push(p); } /* ---- molotov flame ---- */ function spawnFlame(x, y, inst) { var f = gameContainer.addChild(new Container()); f.attachAsset('molotovFlame', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4, scaleX: inst.rngMul, scaleY: inst.rngMul }); f.x = x; f.y = y; f.life = 60; f.dmg = WEAPONS.molotov.dmg * inst.dmgMul; // Molotov alanının menzili (örnek olarak 70→çevrede yarıçap 70px) var maxFlameRange = 70 * inst.rngMul; f.update = function () { if (skillSelectionActive) { return; } // 1) Düşmana hasar kontrolü & menzil filtresi for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; // “distSq(f,e) < 4900” yerine “4900 = 70^2” diyorduk. // Şimdi ek olarak oyuncudan menzil kontrolü de ekleyelim: if (distSq(f, e) < maxFlameRange * maxFlameRange && isWithinRange(e, maxFlameRange)) { damageEnemy(e, this.dmg); } } // 2) Ömür kontrolü if (--this.life <= 0) { if (this.parent) { this.destroy(); } return; } // 3) Ekranın uzağına çıktıysa sil var dx = this.x - player.x; var dy = this.y - player.y; if (Math.abs(dx) > 2000 || Math.abs(dy) > 2000) { if (this.parent) { this.destroy(); } return; } }; } /* ---- shuriken ring ---- */ var shurikenObjs = []; function maintainShurikens(inst) { // Shuriken state: visible for 3s, invisible for 3s, repeat if (typeof maintainShurikens._timer === "undefined") { maintainShurikens._timer = 0; maintainShurikens._visible = false; } maintainShurikens._timer++; // 180 frame = 3s at 60fps if (maintainShurikens._timer >= 180) { maintainShurikens._timer = 0; maintainShurikens._visible = !maintainShurikens._visible; // When becoming invisible, destroy all shurikens if (!maintainShurikens._visible) { shurikenObjs.forEach(function (s) { if (s.parent) { s.destroy(); } }); shurikenObjs = []; } } // If visible, ensure shurikens exist and update if (maintainShurikens._visible) { // Always create shurikens if not present or if amount changed if (shurikenObjs.length !== inst.amount) { shurikenObjs.forEach(function (s) { if (s.parent) { s.destroy(); } }); shurikenObjs = []; var n = inst.amount; var r = WEAPONS.shuriken.range * inst.rngMul; for (var i = 0; i < n; i++) { var s = gameContainer.addChild(new Container()); s.attachAsset('shuriken', { anchorX: 0.5, anchorY: 0.5, scaleX: inst.rngMul, scaleY: inst.rngMul }); s.angle = i / n * Math.PI * 2; s.hitEnemies = []; s.update = function () { if (skillSelectionActive) { return; } var curR = WEAPONS.shuriken.range * inst.rngMul; // Orbit around player this.angle += 0.15; this.x = player.x + Math.cos(this.angle) * curR; this.y = player.y + Math.sin(this.angle) * curR; // Rotate shuriken asset if (this.children && this.children.length > 0) { if (typeof this._rotationAngle === "undefined") { this._rotationAngle = 0; } this._rotationAngle += 0.4; this.children[0].rotation = this._rotationAngle; } // Damage enemies if intersecting and within range for (var k = enemies.length - 1; k >= 0; k--) { var e = enemies[k]; if (this.hitEnemies.indexOf(e) === -1 && this.intersects(e) && isWithinRange(e, curR)) { damageEnemy(e, WEAPONS.shuriken.dmg * inst.dmgMul); this.hitEnemies.push(e); } } }; shurikenObjs.push(s); } } // Always update shuriken positions even if already created for (var i = 0; i < shurikenObjs.length; i++) { if (typeof shurikenObjs[i].update === "function") { shurikenObjs[i].update(); } } } else { // Not visible, ensure all shurikens are destroyed if (shurikenObjs.length > 0) { shurikenObjs.forEach(function (s) { if (s.parent) { s.destroy(); } }); shurikenObjs = []; } } } /* ---- ana fireWeapon anahtarı ---- */ function fireWeapon(key, inst, meta) { switch (meta.type) { case 'melee': swingSword(inst); break; case 'boomerang': fireBoomerang(inst); break; case 'ball': fireBall(inst); break; case 'rocket': fireRocket(inst); break; case 'brick': throwBrick(inst, 75); if (inst.upgrade > 0) { throwBrick(inst, -75); } if (inst.upgrade > 1) { throwBrick(inst, 45); } if (inst.upgrade > 2) { throwBrick(inst, -45); } break; case 'lightning': for (var n = 0; n < inst.amount; n++) { castLightning(inst); } break; case 'aura': ensureAura(inst); break; case 'molotov': for (var n = 0; n < inst.amount; n++) { throwMolotov(inst); } break; case 'shuriken': maintainShurikens(inst); break; } } function showSkillSelection() { skillSelectionActive = true; // 1) Yeni bir Overlay (seçim ekranı) oluşturuyoruz var ov = game.addChild(new Container()); ov.x = 1024; ov.y = 1366; var choices = []; // 2) Eğer oyuncu seviyesi 5'in katı ise (5,10,15,...) if (player.level % 5 === 0) { var ownedCount = Object.keys(player.weapons).length; // 2.a) Hâlâ < 6 silah sahibi ise: yeni silah açma seçenekleri if (ownedCount < 6) { // Kilidi açılmamış silahlar havuzunu al var pool = Object.keys(WEAPONS).filter(function (key) { return !player.weapons[key]; }); // Havuzdan rastgele 3 silah göster, her biri benzersiz while (choices.length < 3 && pool.length > 0) { var rnd = Math.floor(Math.random() * pool.length); choices.push(pool.splice(rnd, 1)[0]); } } else { // 2.b) Zaten 6 silah sahibi ise: önce silahların upgrade durumlarını kontrol et var upgradePool = []; Object.keys(player.weapons).forEach(function (key) { var inst = player.weapons[key]; if (inst.upgrade < 3) { // Eğer bu silah hâlâ < 3 aşama güçlendirilmişse, // “bu silahın bir sonraki upgrade aşaması” havuza eklenir. upgradePool.push({ w: key }); } }); if (upgradePool.length > 0) { // 2.b.i) En az bir silah yükseltmesi kalmış demektir: // Rastgele en fazla 3 tane “silah güçlendirme” seçeneği göster, her biri benzersiz while (choices.length < 3 && upgradePool.length > 0) { var rnd2 = Math.floor(Math.random() * upgradePool.length); choices.push({ w: upgradePool[rnd2].w, type: "upgrade" }); upgradePool.splice(rnd2, 1); } } else { // 2.b.ii) Tüm 6 silah zaten upgrade === 3 ise: // Bu aşamadan sonra artık sadece efsun kartı göster. // Her kart benzersiz olmalı (hem silah hem efsun kombinasyonu) var ownedKeys2 = Object.keys(player.weapons); var usedPairs = []; var attempts = 0; while (choices.length < 3 && attempts < 20) { var randomKey2 = ownedKeys2[Math.floor(Math.random() * ownedKeys2.length)]; var enchList = WEAPONS[randomKey2].ench; var rnd3 = enchList[Math.floor(Math.random() * enchList.length)]; var pairKey = randomKey2 + "|" + rnd3; if (usedPairs.indexOf(pairKey) === -1) { choices.push({ w: randomKey2, e: rnd3 }); usedPairs.push(pairKey); } attempts++; } } } } else { // 3) Seviye 5'in katı değilse: doğrudan efsun kartları göster // Her kart benzersiz olmalı (hem silah hem efsun kombinasyonu) var ownedKeys = Object.keys(player.weapons); var usedPairs2 = []; var attempts2 = 0; while (choices.length < 3 && attempts2 < 20) { var randomKey = ownedKeys[Math.floor(Math.random() * ownedKeys.length)]; var enchList = WEAPONS[randomKey].ench; var rnd4 = enchList[Math.floor(Math.random() * enchList.length)]; var pairKey2 = randomKey + "|" + rnd4; if (usedPairs2.indexOf(pairKey2) === -1) { choices.push({ w: randomKey, e: rnd4 }); usedPairs2.push(pairKey2); } attempts2++; } } // 4) choices dizisini “3 adet kart” olarak UI’da çizelim // --- BUFF havuzu --- // --- Buff/efsun/buff limit tracking --- if (!player.buffCounts) { player.buffCounts = {}; } if (!player.efsunCounts) { player.efsunCounts = {}; } // --- BUFF havuzu --- var buffPool = [{ key: "damageReduction", label: "Damage Reduction+", desc: "Take 10% less damage per level" }, { key: "moveSpeed", label: "Movement Speed Increase+", desc: "Move 20% faster per level" }, { key: "hpRegen", label: "HP Regeneration+", desc: "Regenerate 1% max HP every 5s per level" }, { key: "damageReflection", label: "Damage Reflection+", desc: "Reflect 5% damage per level" }, { key: "gritWound", label: "Grit Wound+", desc: "Reduce enemy regen by 10% per level" }, { key: "enemySlow", label: "Enemy Slow+", desc: "Slow enemies by 10% per level" }, { key: "enemyStun", label: "Enemy Stun+", desc: "Stun enemies for 0.1s per level" }, { key: "bleeding", label: "Bleeding+", desc: "Bleed: 4s, 0.5s tick, 5% max HP per tick per level" }, { key: "critChance", label: "Critical Hit Chance+", desc: "Increase critical hit chance by 15% per level" }, { key: "maxHpPlus", label: "Maximum HP+", desc: "Increase max HP by 25 per level" }]; // Remove buffs that have been taken 5 times buffPool = buffPool.filter(function (buff) { var k = buff.key; return (player.buffCounts[k] || 0) < 5; }); // Rastgele bir buff seç (her zaman 4. seçenek) var buffIdx = Math.floor(Math.random() * buffPool.length); var buffChoice = buffPool[buffIdx]; choices = choices.slice(0, 3); // Sadece ilk 3'ü tut choices.push({ type: "buff", buff: buffChoice }); // 4. seçenek buff // Remove efsun options that have been taken 5 times choices = choices.filter(function (c) { if (_typeof(c) === "object" && c.e) { var key = c.w + "|" + c.e; return (player.efsunCounts[key] || 0) < 5; } return true; }); choices.forEach(function (c, idx) { var card = ov.addChild(new Container()); // 4. kartı mavi yap if (idx === 3) { card.attachAsset('skillCard', { anchorX: 0.5, anchorY: 0.5, tint: 0x3399ff // mavi renk }); } else { card.attachAsset('skillCard', { anchorX: 0.5, anchorY: 0.5 }); } // Kartlar arası mesafeyi artır (ör: 420px) card.x = (idx - 1.5) * 420; card.y = 0; var label, fn, desc = ""; if (typeof c === "string") { // c, yeni kilidi açılacak silahın anahtarı (ör. "boomerang") var key = c; var own = !!player.weapons[key]; if (!own) { // Hâlâ envanterde yoksa “Unlock <silah adı>” label = "Unlock " + key; fn = function fn() { addWeapon(key); }; } else if (player.weapons[key].upgrade < 3) { // Silah zaten varsa ve upgrade < 3 ise: label = WEAPONS[key].up[player.weapons[key].upgrade]; fn = function fn() { player.weapons[key].upgrade++; player.weapons[key].amount++; }; } else { // Eğer upgrade === 3’e ulaşmışsa: label = "No Option"; fn = function fn() {}; } } else if (c.type === "upgrade") { // c = { w: "sword", type:"upgrade" } var wkey = c.w; label = WEAPONS[wkey].up[player.weapons[wkey].upgrade]; fn = function fn() { player.weapons[wkey].upgrade++; player.weapons[wkey].amount++; }; } else if (c.type === "buff") { label = c.buff.label; desc = c.buff.desc; fn = function fn() { // Buff mantığı var k = c.buff.key; if (!player.buffCounts[k]) { player.buffCounts[k] = 0; } if (player.buffCounts[k] >= 5) { return; } // Defensive: do not allow more than 5 switch (k) { case "damageReduction": player.buffs.damageReduction += 10; break; case "moveSpeed": player.buffs.moveSpeed += 20; break; case "hpRegen": player.buffs.hpRegen += 1; break; case "damageReflection": player.buffs.damageReflection += 5; break; case "gritWound": player.buffs.gritWound += 10; break; case "enemySlow": player.buffs.enemySlow += 10; break; case "enemyStun": player.buffs.enemyStun += 0.1; break; case "bleeding": player.buffs.bleeding += 1; break; case "critChance": player.buffs.critChance += 15; player.critChance = 0.25 + player.buffs.critChance / 100; if (player.critChance > 1) { player.critChance = 1; } break; case "maxHpPlus": player.maxHp += 25; break; } player.buffCounts[k]++; }; } else { // c = { w: "<silahAnahtarı>", e: "<SilahName> Damage+" veya "<SilahName> Attack Speed+" vb. } var w2 = c.w; var efsun = c.e; label = efsun; // Efsun açıklaması if (efsun.endsWith(" Damage+")) { desc = "Increases weapon damage by 20%"; } else if (efsun.endsWith(" Attack Speed+")) { desc = "Increases weapon attack speed by 20%"; } else if (efsun.endsWith(" Range+")) { desc = "Increases weapon range and size by 20%"; } else { desc = ""; } fn = function fn() { var key = w2 + "|" + efsun; if (!player.efsunCounts[key]) { player.efsunCounts[key] = 0; } if (player.efsunCounts[key] >= 5) { return; } // Defensive: do not allow more than 5 var inst = player.weapons[w2]; // Efsun metni "<SilahName> Damage+" ile bitiyorsa hasar çarpanını %20 artır: if (efsun.endsWith(" Damage+")) { inst.dmgMul *= 1.2; } // Efsun metni "<SilahName> Attack Speed+" ile bitiyorsa cd süresini %20 azalt: if (efsun.endsWith(" Attack Speed+")) { inst.cd *= 0.2; } // Efsun metni "<SilahName> Range+" ile bitiyorsa hem menzil hem boyut çarpanını %20 artır: if (efsun.endsWith(" Range+")) { inst.rngMul *= 3.2; inst.sizeMul *= 3.2; } // "Size+" efsunu artık yok, hiçbir şey yapma player.efsunCounts[key]++; }; } var txt = new Text2(label, { size: 40, fill: 0xffffff }); txt.anchor.set(0.5); card.addChild(txt); if (desc) { // Card width is 400, so max text width should be less (e.g. 340) var descTxt = new Text2(desc, { size: 28, fill: 0xcccccc, wordWrap: true, wordWrapWidth: 340, align: "center" }); descTxt.anchor.set(0.5, 0); descTxt.y = 60; card.addChild(descTxt); } card.down = function () { fn(); ov.destroy(); skillSelectionActive = false; levelText.setText('Level ' + player.level); }; }); } // Input handling game.down = function (x, y, obj) { if (skillSelectionActive) { return; } var localPos = game.toLocal({ x: x, y: y }); if (localPos.y > 2000) { joystick.active = true; joystick.setKnobPosition(0, 0); } }; game.move = function (x, y, obj) { if (!joystick.active || skillSelectionActive) { return; } var localPos = LK.gui.bottom.toLocal({ x: x, y: y }); var dx = localPos.x - joystick.x; var dy = localPos.y - joystick.y; joystick.setKnobPosition(dx, dy); }; game.up = function (x, y, obj) { joystick.reset(); }; // Game update game.update = function () { if (skillSelectionActive) { return; } gameTime++; // Update timer → geçen süreyi göster var elapsedSeconds = Math.floor(gameTime / 60); var minutes = Math.floor(elapsedSeconds / 60); var seconds = elapsedSeconds % 60; timerText.setText((minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds)); // Update UI hpText.setText('HP: ' + player.hp.toFixed(1) + '/' + player.maxHp.toFixed(1)); // Show exp orbs and required exp for next level levelText.setText('Level ' + player.level + ' EXP: ' + player.exp + '/' + player.level); // Show current wave waveText.setText('Wave ' + waveNumber); // Player movement if (joystick.active) { player.x += joystick.dirX * player.moveSpeed; player.y += joystick.dirY * player.moveSpeed; } /* Fire weapons / aura etc. */ player.update(); // --- Update player health bar --- if (player.hpBar && player.hpBarFg) { var hpRatio = Math.max(0, Math.min(1, player.hp / player.maxHp)); player.hpBarFg.width = 212 * hpRatio; // Move foreground bar's x so it depletes from right to left player.hpBarFg.x = 0; // Player HP bar color: green >80%, yellow 50-80%, orange 20-50%, red+blink <20% if (hpRatio > 0.8) { player.hpBarFg.tint = 0x00ff44; // green player.hpBarFg.alpha = 1; } else if (hpRatio > 0.5) { player.hpBarFg.tint = 0xffe066; // yellow player.hpBarFg.alpha = 1; } else if (hpRatio > 0.2) { player.hpBarFg.tint = 0xff9900; // orange player.hpBarFg.alpha = 1; } else { // <20%: red and blinking // Blink: alternate between red and transparent every 6 frames (~10Hz) player.hpBarFg.tint = 0xff0000; // pure red for critical if (gameTime % 12 < 6) { player.hpBarFg.alpha = 1; } else { player.hpBarFg.alpha = 0.3; } } } // --- Update enemy health bars --- for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (enemy.hpBar && enemy.hpBarFg) { var ehpRatio = Math.max(0, Math.min(1, enemy.hp / enemy.maxHp)); enemy.hpBarFg.width = 152 * ehpRatio; enemy.hpBarFg.x = 0; // Enemy HP bar color: always red, regardless of HP enemy.hpBarFg.tint = 0xff4444; enemy.hpBarFg.alpha = 1; } } // Camera follow player camera.x = player.x - 1024; camera.y = player.y - 1366; gameContainer.x = -camera.x; gameContainer.y = -camera.y; // Update background tiles to always cover the visible area if (backgroundTiles && backgroundTiles.length) { var startX = Math.floor(camera.x / bgTileWidth) * bgTileWidth; var startY = Math.floor(camera.y / bgTileHeight) * bgTileHeight; var idx = 0; for (var i = 0; i < bgTilesX; i++) { for (var j = 0; j < bgTilesY; j++) { var tile = backgroundTiles[idx++]; tile.x = startX + i * bgTileWidth; tile.y = startY + j * bgTileHeight; } } } // Progress to next wave only when all enemies are cleared if (typeof nextWaveTimeout === "undefined") { nextWaveTimeout = null; } if (enemies.length === 0 && !nextWaveTimeout) { nextWaveTimeout = LK.setTimeout(function () { waveNumber++; spawnWave(); nextWaveTimeout = null; }, 3000); } if (enemies.length > 0 && nextWaveTimeout) { LK.clearTimeout(nextWaveTimeout); nextWaveTimeout = null; } // Update enemies for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - player.x; var dy = enemy.y - player.y; var distSq = dx * dx + dy * dy; // 150 piksel mesafe için distSq <= 22500 kullanıyoruz. if (distSq <= 22500) { if (enemy.lastHitTime === undefined || gameTime - enemy.lastHitTime >= 60) { // Enemy crit logic var critChance = enemy.critChance !== undefined ? enemy.critChance : 0.25; var critType = null; var critValue = 1; if (Math.random() < critChance) { if (Math.random() < 0.5) { critType = "low"; critValue = 1.2; } else { critType = "high"; critValue = 1.4; } } // Calculate enemy's final damage (base * crit multiplier) var finalDmg = enemy.damage * critValue; // Apply player damage reduction buff before taking damage var reducedDmg = finalDmg; if (player.buffs && player.buffs.damageReduction > 0) { reducedDmg = Math.ceil(finalDmg * (1 - player.buffs.damageReduction / 100)); } player.takeDamage(reducedDmg); // Show damage text for enemy crits on player var fillColor = 0xff3333; if (critType === "low") { fillColor = 0xffe066; } if (critType === "high") { fillColor = 0xff3333; } var dmgText = new Text2(reducedDmg.toFixed(1), { size: 48, fill: fillColor, stroke: 0x000000, strokeThickness: 4 }); dmgText.anchor.set(0.5); dmgText.x = player.x; dmgText.y = player.y - (player.height ? player.height / 2 : 60); dmgText.alpha = 1; gameContainer.addChild(dmgText); tween(dmgText, { y: dmgText.y - 60, alpha: 0 }, { duration: 500, easing: tween.linear, onFinish: function onFinish() { if (dmgText.parent) { dmgText.destroy(); } } }); enemy.lastHitTime = gameTime; } } } // Update exp orbs for (var i = expOrbs.length - 1; i >= 0; i--) { var orb = expOrbs[i]; var dx = orb.x - player.x; var dy = orb.y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < player.pickupRange) { orb.magnetSpeed = 10; } if (orb.intersects(player)) { player.gainExp(orb.value); orb.destroy(); expOrbs.splice(i, 1); LK.getSound('pickup').play(); } } // Spawn pickups randomly if (gameTime - lastPickupSpawn > 1800 && Math.random() < 0.1) { lastPickupSpawn = gameTime; var pickup; var angle = Math.random() * Math.PI * 2; var distance = 300 + Math.random() * 500; var pickupX = player.x + Math.cos(angle) * distance; var pickupY = player.y + Math.sin(angle) * distance; var randVal = Math.random(); if (randVal < 0.4) { pickup = new Bomb(); } else if (randVal < 0.8) { pickup = new Magnet(); } else { pickup = new ChickenLeg(); } pickup.x = pickupX; pickup.y = pickupY; pickups.push(pickup); gameContainer.addChild(pickup); } // Update pickups for (var i = pickups.length - 1; i >= 0; i--) { var pickup = pickups[i]; if (!pickup.active) { pickups.splice(i, 1); } } }; // Initial spawn spawnWave(); // Start background music at game start LK.playMusic('backGroundMusic');
===================================================================
--- original.js
+++ change.js
@@ -1534,9 +1534,11 @@
if (auraField && auraField.children && auraField.children.length > 0) {
auraField.children[0].scaleX = inst.rngMul;
auraField.children[0].scaleY = inst.rngMul;
// Rotate aura asset
- if (typeof auraField._rotationAngle === "undefined") auraField._rotationAngle = 0;
+ if (typeof auraField._rotationAngle === "undefined") {
+ auraField._rotationAngle = 0;
+ }
auraField._rotationAngle += 0.03;
auraField.children[0].rotation = auraField._rotationAngle;
}
// 2) Hasar uygulama kısmı (oyuncudan r uzaklıktaysa vur):
@@ -1657,9 +1659,11 @@
maintainShurikens._visible = !maintainShurikens._visible;
// When becoming invisible, destroy all shurikens
if (!maintainShurikens._visible) {
shurikenObjs.forEach(function (s) {
- if (s.parent) s.destroy();
+ if (s.parent) {
+ s.destroy();
+ }
});
shurikenObjs = [];
}
}
@@ -1667,9 +1671,11 @@
if (maintainShurikens._visible) {
// Always create shurikens if not present or if amount changed
if (shurikenObjs.length !== inst.amount) {
shurikenObjs.forEach(function (s) {
- if (s.parent) s.destroy();
+ if (s.parent) {
+ s.destroy();
+ }
});
shurikenObjs = [];
var n = inst.amount;
var r = WEAPONS.shuriken.range * inst.rngMul;
@@ -1683,17 +1689,21 @@
});
s.angle = i / n * Math.PI * 2;
s.hitEnemies = [];
s.update = function () {
- if (skillSelectionActive) return;
+ if (skillSelectionActive) {
+ return;
+ }
var curR = WEAPONS.shuriken.range * inst.rngMul;
// Orbit around player
this.angle += 0.15;
this.x = player.x + Math.cos(this.angle) * curR;
this.y = player.y + Math.sin(this.angle) * curR;
// Rotate shuriken asset
if (this.children && this.children.length > 0) {
- if (typeof this._rotationAngle === "undefined") this._rotationAngle = 0;
+ if (typeof this._rotationAngle === "undefined") {
+ this._rotationAngle = 0;
+ }
this._rotationAngle += 0.4;
this.children[0].rotation = this._rotationAngle;
}
// Damage enemies if intersecting and within range
@@ -1717,9 +1727,11 @@
} else {
// Not visible, ensure all shurikens are destroyed
if (shurikenObjs.length > 0) {
shurikenObjs.forEach(function (s) {
- if (s.parent) s.destroy();
+ if (s.parent) {
+ s.destroy();
+ }
});
shurikenObjs = [];
}
}
@@ -2060,9 +2072,9 @@
inst.dmgMul *= 1.2;
}
// Efsun metni "<SilahName> Attack Speed+" ile bitiyorsa cd süresini %20 azalt:
if (efsun.endsWith(" Attack Speed+")) {
- inst.cd *= 0.8;
+ inst.cd *= 0.2;
}
// Efsun metni "<SilahName> Range+" ile bitiyorsa hem menzil hem boyut çarpanını %20 artır:
if (efsun.endsWith(" Range+")) {
inst.rngMul *= 3.2;
Survivor.io style 2D sword swing effect made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows. It should only have a slash effect, no swords. The slash effect should also be in the shape of a half moon.
Survivor.io style 2D round soccer ball made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A 2D Survivor.io style lightning strike from a cloud in the sky to the ground, made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A red and blue Survivor.io style 2D U-shaped (with N and S) magnet made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D shuriken made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D brick made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D missile rocket made by HABBY PTE. LTD.
A 2D green radiating circular aura in the Survivor.io style made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A 2D bomb in the style of Survivor.io, made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A 2D circular burning effect in Survivor.io style made by HABBY PTE. LTD. (not only the surroundings but also the inside burns) In-Game asset. 2d. High contrast. No shadows
A 2D molotov in the Survivor.io style made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D greenish exp sphere made by HABBY PTE. LTD. No exp written on it. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D half-moon orange boomerang made by HABBY PTE. LTD. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D 1 chicken leg.. In-Game asset. 2d. High contrast. No shadows
2D survivor.io game style atomic boom effect front view. No text written on it.
2D. Ranged zombie. attacks with poisonous saliva. In-Game asset. 2d. High contrast. No shadows
2D. Child (small) zombie. He has a small saw in his hand.. In-Game asset. 2d. High contrast. No shadows
2D. Fat zombie. His hands are too big.. In-Game asset. 2d. High contrast. No shadows
Poisonous green circular saliva. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Small green claw slash effect. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Giant boss angry reddish zombie. 2D.. In-Game asset. 2d. High contrast. No shadows
Small saw slash effect. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Big red fist slash effect. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Kanlı kemik 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
2D character that looks like a prophet and holds a holy book in his hand.. In-Game asset. 2d. High contrast. No shadows
A background image (wallpaper) representing an old prophet-like man with white hair and beard, wearing a priest's robe (hooded) and holding a holy book (christianity, cross) in his hand, fighting against zombies.. In-Game asset. 2d. High contrast. No shadows
Zombie flesh and bone themed 2D cardboard hollow (without text) horizontal rectangular button.. In-Game asset. 2d. High contrast. No shadows
2D. Healer zombie. Like a female zombie in a healer costume.. In-Game asset. 2d. High contrast. No shadows
2D. Brain illustrated healing potion.. In-Game asset. 2d. High contrast. No shadows
A healing blood pool with circular zombie brain and bone particles. Green + (healing) symbols on top. 2D.. In-Game asset. 2d. High contrast. No shadows
2D. Survivor.io game style skill card. No text written on it. No symbols on it. Just the blank card. Green.. In-Game asset. 2d. High contrast. No shadows
2D. Cartoon. The rise of the zombie ghost spirit from the ground.. In-Game asset. 2d. High contrast. No shadows
levelup
Sound effect
hit
Sound effect
rocketBoom
Sound effect
pickup
Sound effect
backGroundMusic
Music
death
Sound effect
damageTaken
Sound effect
mainMenuMusic
Music
deathScreenMusic
Music
swordSoundEffect
Sound effect
bumerangSoundEffect
Sound effect
brickSoundEffect
Sound effect
lightningSoundEffect
Sound effect
ballSoundEffect
Sound effect
rocketSoundEffect
Sound effect
auraSoundEffect
Sound effect
molotovSoundEffect
Sound effect
molotovBoom
Sound effect
introSpeech
Sound effect
bombBoomSound
Sound effect