User prompt
Görev veren NPC'ye tıkladığımız zaman Karakterin yukarısında Görev hakkında ''Kabul Et - Reddet'' butonları olsun. Ona göre etkileşimde olalım ve ona göre görevi yapalım veya yapmayalım. Verdiğimiz yanıta göre yapay zeka cevap versin ve verdiği görev hakkında işlem yapsın.
User prompt
NPC'ye tıkladığım zaman NPC görevi veya bulunduğum etkileşim Level altında küçük şekilde ve bir süre spawn olsun ve ne konuda etkileşimde bulundum ise bileyim.
User prompt
NPC soru sorduğunda, tıkladığım zaman NPC bir süre dursun.
User prompt
NPC Trade sorusu soruyor. tıkla diyor. Tıklıyorum, ticaret paneli açılmıyor.
User prompt
NPC'ye yaklaşıyorum ama hiçbirşey olmuyor. Ne çıkıyor ise, NPC üzerinde çıksın yaklaşınca.
User prompt
Haritada unsurların spawn olma oranını genel olarak ortalama %10 oranında artır. (Korsanlar hariç)
User prompt
Wave altına, Level ve EXP sistemi ekle, oyundaki RPG görevlerinden EXP kazanalım. RPG Macera oyunu olarak sistemi kur.
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'indexOf')' in or related to this line: 'if (!npcActive && tradeText.text.indexOf("Trade:") !== 0 && tradeText.text.indexOf("Special:") !== 0) {' Line Number: 1428
User prompt
NPC'ler ile ilgili etkileşim kuralım ve birçok RPG ve macera konusu ekle. Bazen de ticaret yapalım. NPC'ler yapay zeka oyuncuları tarafından yönetilsin.
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği veya mekaniği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, Ticaret ve RPG katacak mekanik ve özellik ekle.
User prompt
Haritada unsurların spawn olma oranını genel olarak ortalama %10 oranında artır.
User prompt
''Reduce spawn rate of all entities and asteroids by 80%'' bunu %70 olarak değiştir. Ama korsanlar için %85 olsun. Çünkü korsan çok.
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği veya mekaniği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak mekanik ve özellik ekle.
User prompt
Asteroid'lere de otomatik ateş olsun. Ancak şuan haritada spawn olan unsur oranını %80 oranında azalt. Çok fazla unsur var.
User prompt
Kod içinde olan veya olmayan, oyuna uygun birçok özelliği veya mekaniği aktif et. Uyumsuz ise ekleme. Birbirinden farklı, eğlence katacak mekanik ve özellik ekle.
User prompt
Coins ve hammadde sayıları ekranda görünmüyor. Görünecek şekilde ekranda ki dış alanları sola kaydır.
User prompt
Düşmana, çok yaklaşırsak bize saldırsın ve biz ona çok yaklaşırsak saldıralım. Yoksa normal seyrinde devam etsinler.
User prompt
Haritada ki unsurlar otomatik spawn olma sistemini kaldır. İlerledikçe harita dışından spawn olarak gelsinler veya rastgele dolaşsınlar. sabit durmasın hiç birşey. Bir akış olsun.
User prompt
Harita sürekli aşağı doğru kaymasın, Karakterin gittiği yöne doğru haritada gidelim.
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'healthText.style.fill = "#00ff00";' Line Number: 255
Code edit (1 edits merged)
Please save this source code
User prompt
Galactic Trader: Sonsuz Görevler
Initial prompt
Oyuncu, haritanın merkezinde bir uzay mekiğini joystick ile kontrol eder. Sonsuz bir galakside rastgele NPC’ler belirir ve oyuncuya görevler ile ticaret fırsatları sunar. Korsan savaş gemileriyle karşılaşılır; savaşarak coin ve hammadde toplanır. Toplanan kaynaklar ticaretle satılır, yeni yükseltmeler ve ekipmanlar alınır. Görevler ve ticaret ilerledikçe yeni bölgeler ve zorluklar açılır. Oyun, sonsuz ilerleme ve sürekli gelişen görevlerle devam eder.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Asteroid = Container.expand(function () { var self = Container.call(this); var asteroidGraphics = self.attachAsset('resource', { anchorX: 0.5, anchorY: 0.5, tint: 0x8B4513, scaleX: 2, scaleY: 2 }); self.health = 50; self.resources = Math.floor(Math.random() * 10) + 5; self.vx = (Math.random() - 0.5) * 0.5; self.vy = (Math.random() - 0.5) * 0.5; self.rotationSpeed = (Math.random() - 0.5) * 0.02; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffffff, 100); }; self.update = function () { self.x += self.vx; self.y += self.vy; self.rotation += self.rotationSpeed; }; return self; }); // Black Hole Hazard Class var BlackHole = Container.expand(function () { var self = Container.call(this); var bhGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5, scaleX: 8, scaleY: 8, tint: 0x222222 }); self.radius = 200; self.pullStrength = 0.7 + Math.random() * 0.5; self.damageRadius = 120; self.update = function () { // Animate black hole bhGraphics.rotation += 0.03; // Pull ship if in range var dx = ship.x - self.x; var dy = ship.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.radius) { var pull = (self.radius - dist) / self.radius * self.pullStrength; ship.x -= dx / dist * pull; ship.y -= dy / dist * pull; // Camera follows ship, so move all objects accordingly for (var i = 0; i < stars.length; i++) { stars[i].x -= dx / dist * pull; stars[i].y -= dy / dist * pull; } for (var i = 0; i < npcs.length; i++) { npcs[i].x -= dx / dist * pull; npcs[i].y -= dy / dist * pull; } for (var i = 0; i < pirates.length; i++) { pirates[i].x -= dx / dist * pull; pirates[i].y -= dy / dist * pull; } for (var i = 0; i < coins.length; i++) { coins[i].x -= dx / dist * pull; coins[i].y -= dy / dist * pull; } for (var i = 0; i < resources.length; i++) { resources[i].x -= dx / dist * pull; resources[i].y -= dy / dist * pull; } for (var i = 0; i < bullets.length; i++) { bullets[i].x -= dx / dist * pull; bullets[i].y -= dy / dist * pull; } for (var i = 0; i < enemyBullets.length; i++) { enemyBullets[i].x -= dx / dist * pull; enemyBullets[i].y -= dy / dist * pull; } for (var i = 0; i < asteroids.length; i++) { asteroids[i].x -= dx / dist * pull; asteroids[i].y -= dy / dist * pull; } for (var i = 0; i < upgradeStations.length; i++) { upgradeStations[i].x -= dx / dist * pull; upgradeStations[i].y -= dy / dist * pull; } for (var i = 0; i < boostParticles.length; i++) { boostParticles[i].x -= dx / dist * pull; boostParticles[i].y -= dy / dist * pull; } for (var i = 0; i < explosions.length; i++) { explosions[i].x -= dx / dist * pull; explosions[i].y -= dy / dist * pull; } } // Damage ship if too close if (dist < self.damageRadius) { if (!self.lastDamaged || LK.ticks - self.lastDamaged > 30) { ship.takeDamage(10); self.lastDamaged = LK.ticks; LK.effects.flashObject(ship, 0x000000, 200); } } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.damage = 10; self.directionX = 0; self.directionY = -1; self.update = function () { self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); var coinGraphics = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.value = Math.floor(Math.random() * 10) + 5; self.update = function () { self.rotation += 0.05; }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.damage = 5; self.directionX = 0; self.directionY = 0; self.update = function () { self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; }; return self; }); var NPC = Container.expand(function () { var self = Container.call(this); var npcGraphics = self.attachAsset('npc', { anchorX: 0.5, anchorY: 0.5 }); // --- RPG/Adventure/Trade/AI properties --- var questTypes = ['trade', 'delivery', 'explore', 'escort', 'hunt', 'puzzle']; self.questType = questTypes[Math.floor(Math.random() * questTypes.length)]; self.questActive = true; self.questProgress = 0; self.questTarget = null; self.reward = Math.floor(Math.random() * 80) + 30; self.dialogueStep = 0; self.hasTraded = false; self.isAI = true; // AI-driven self.baseY = 0; self.moveSpeed = 1 + Math.random() * 2; self.moveAngle = Math.random() * Math.PI * 2; self.wanderTimer = 0; self.lastAIAction = 0; self.targetX = null; self.targetY = null; self.rpgName = "NPC-" + Math.floor(Math.random() * 10000); self.rpgMood = Math.random() < 0.5 ? "friendly" : "neutral"; self.rpgInventory = { metal: Math.floor(Math.random() * 10), energy: Math.floor(Math.random() * 10), coins: Math.floor(Math.random() * 30) }; self.rpgTradeOffer = { give: Math.random() < 0.5 ? "metal" : "energy", giveAmount: Math.floor(Math.random() * 5) + 1, want: Math.random() < 0.5 ? "energy" : "metal", wantAmount: Math.floor(Math.random() * 5) + 1 }; // --- AI/Quest logic --- self.update = function () { // Pause logic: If pauseUntil is set and not expired, skip movement if (self.pauseUntil && LK.ticks < self.pauseUntil) { // Still paused, only float animation self.y += Math.sin(LK.ticks * 0.05) * 0.5; return; } // AI: Sometimes move toward a random point, sometimes wander self.wanderTimer++; if (self.wanderTimer > 120 + Math.random() * 120) { if (Math.random() < 0.5) { // Pick a random point to move toward (simulate AI goal seeking) self.targetX = self.x + (Math.random() - 0.5) * 800; self.targetY = self.y + (Math.random() - 0.5) * 800; } else { self.targetX = null; self.targetY = null; } self.moveAngle = Math.random() * Math.PI * 2; self.wanderTimer = 0; } // Move toward target if set, else wander if (self.targetX !== null && self.targetY !== null) { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 10) { self.x += dx / dist * self.moveSpeed; self.y += dy / dist * self.moveSpeed; self.moveAngle = Math.atan2(dy, dx); } else { self.targetX = null; self.targetY = null; } } else { self.x += Math.cos(self.moveAngle) * self.moveSpeed; self.y += Math.sin(self.moveAngle) * self.moveSpeed; } // Float animation on top of movement self.y += Math.sin(LK.ticks * 0.05) * 0.5; // --- RPG/Quest/Adventure logic: update quest progress if active --- if (self.questActive && self.questType === 'explore' && self.questTarget) { // If player is close to quest target, complete quest var dx = ship.x - self.questTarget.x; var dy = ship.y - self.questTarget.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.questProgress = 1; } } if (self.questActive && self.questType === 'escort' && self.questTarget) { // If NPC is close to quest target, complete quest var dx = self.x - self.questTarget.x; var dy = self.y - self.questTarget.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.questProgress = 1; } } if (self.questActive && self.questType === 'hunt' && self.questTarget) { // If quest target pirate is dead, complete quest if (self.questTarget._destroyed) { self.questProgress = 1; } } if (self.questActive && self.questType === 'puzzle') { // Simulate puzzle solved after some time if (LK.ticks % 600 === 0) { self.questProgress = 1; } } }; // --- RPG/Adventure/Trade: interaction method for player tap/close --- self.interact = function () { // Dialogue/quest/trade logic if (!self.questActive) return "I'm just exploring the stars!"; // Helper for EXP gain and level up function gainEXP(amount) { playerEXP += amount; var leveledUp = false; while (playerEXP >= expToNext(playerLevel)) { playerEXP -= expToNext(playerLevel); playerLevel++; leveledUp = true; } updateUI(); if (leveledUp) { LK.effects.flashObject(ship, 0x00ffcc, 800); return "Level Up! Now Level " + playerLevel + "!"; } return null; } if (self.questType === 'trade') { if (!self.hasTraded) { // Offer trade if (self.rpgTradeOffer.give === 'metal' && playerMetal >= self.rpgTradeOffer.wantAmount) { playerMetal -= self.rpgTradeOffer.wantAmount; playerEnergy += self.rpgTradeOffer.giveAmount; self.hasTraded = true; var expMsg = gainEXP(10 + Math.floor(Math.random() * 10)); return self.rpgName + ": Thanks for the trade! +" + self.rpgTradeOffer.giveAmount + " energy!" + (expMsg ? "\n" + expMsg : ""); } else if (self.rpgTradeOffer.give === 'energy' && playerEnergy >= self.rpgTradeOffer.wantAmount) { playerEnergy -= self.rpgTradeOffer.wantAmount; playerMetal += self.rpgTradeOffer.giveAmount; self.hasTraded = true; var expMsg = gainEXP(10 + Math.floor(Math.random() * 10)); return self.rpgName + ": Thanks for the trade! +" + self.rpgTradeOffer.giveAmount + " metal!" + (expMsg ? "\n" + expMsg : ""); } else { return self.rpgName + ": I can trade " + self.rpgTradeOffer.giveAmount + " " + self.rpgTradeOffer.give + " for " + self.rpgTradeOffer.wantAmount + " " + self.rpgTradeOffer.want + "."; } } else { return self.rpgName + ": Good luck out there!"; } } if (self.questType === 'delivery') { if (self.questProgress === 0) { // Assign delivery quest: go to a random point if (!self.questTarget) { self.questTarget = { x: self.x + (Math.random() - 0.5) * 2000, y: self.y + (Math.random() - 0.5) * 2000 }; return self.rpgName + ": Can you deliver this package to (" + Math.floor(self.questTarget.x) + "," + Math.floor(self.questTarget.y) + ")?"; } else { var dx = ship.x - self.questTarget.x; var dy = ship.y - self.questTarget.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.questProgress = 1; playerCoins += self.reward; questsCompleted++; var expMsg = gainEXP(40 + Math.floor(Math.random() * 20)); return self.rpgName + ": Delivery complete! Reward: " + self.reward + " coins!" + (expMsg ? "\n" + expMsg : ""); } else { return self.rpgName + ": Please deliver to (" + Math.floor(self.questTarget.x) + "," + Math.floor(self.questTarget.y) + ")"; } } } else { return self.rpgName + ": Thank you for your help!"; } } if (self.questType === 'explore') { if (self.questProgress === 0) { if (!self.questTarget) { self.questTarget = { x: self.x + (Math.random() - 0.5) * 2000, y: self.y + (Math.random() - 0.5) * 2000 }; return self.rpgName + ": Can you explore the area at (" + Math.floor(self.questTarget.x) + "," + Math.floor(self.questTarget.y) + ")?"; } else { var dx = ship.x - self.questTarget.x; var dy = ship.y - self.questTarget.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.questProgress = 1; playerCoins += self.reward; questsCompleted++; var expMsg = gainEXP(30 + Math.floor(Math.random() * 15)); return self.rpgName + ": Thanks for exploring! Reward: " + self.reward + " coins!" + (expMsg ? "\n" + expMsg : ""); } else { return self.rpgName + ": Please explore (" + Math.floor(self.questTarget.x) + "," + Math.floor(self.questTarget.y) + ")"; } } } else { return self.rpgName + ": You are a true explorer!"; } } if (self.questType === 'escort') { if (self.questProgress === 0) { if (!self.questTarget) { self.questTarget = { x: self.x + (Math.random() - 0.5) * 2000, y: self.y + (Math.random() - 0.5) * 2000 }; return self.rpgName + ": Can you escort me to (" + Math.floor(self.questTarget.x) + "," + Math.floor(self.questTarget.y) + ")?"; } else { var dx = self.x - self.questTarget.x; var dy = self.y - self.questTarget.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80) { self.questProgress = 1; playerCoins += self.reward; questsCompleted++; var expMsg = gainEXP(35 + Math.floor(Math.random() * 15)); return self.rpgName + ": Safe arrival! Reward: " + self.reward + " coins!" + (expMsg ? "\n" + expMsg : ""); } else { // Move toward target if player is close var pdx = ship.x - self.x; var pdy = ship.y - self.y; var pdist = Math.sqrt(pdx * pdx + pdy * pdy); if (pdist < 200) { var tdx = self.questTarget.x - self.x; var tdy = self.questTarget.y - self.y; var tdist = Math.sqrt(tdx * tdx + tdy * tdy); if (tdist > 10) { self.x += tdx / tdist * self.moveSpeed; self.y += tdy / tdist * self.moveSpeed; } } return self.rpgName + ": Please escort me to (" + Math.floor(self.questTarget.x) + "," + Math.floor(self.questTarget.y) + ")"; } } } else { return self.rpgName + ": Thank you for the escort!"; } } if (self.questType === 'hunt') { if (self.questProgress === 0) { if (!self.questTarget) { // Assign a random pirate as target if (pirates.length > 0) { self.questTarget = pirates[Math.floor(Math.random() * pirates.length)]; return self.rpgName + ": Can you defeat pirate #" + self.questTarget.rpgName + "?"; } else { return self.rpgName + ": No pirates nearby, come back later!"; } } else { if (self.questTarget._destroyed) { self.questProgress = 1; playerCoins += self.reward; questsCompleted++; var expMsg = gainEXP(50 + Math.floor(Math.random() * 20)); return self.rpgName + ": Pirate defeated! Reward: " + self.reward + " coins!" + (expMsg ? "\n" + expMsg : ""); } else { return self.rpgName + ": Please defeat pirate #" + (self.questTarget.rpgName || "unknown"); } } } else { return self.rpgName + ": You are a true hero!"; } } if (self.questType === 'puzzle') { if (self.questProgress === 0) { return self.rpgName + ": Solve my puzzle! (Wait a bit...)"; } else { playerCoins += self.reward; questsCompleted++; self.questProgress = 2; var expMsg = gainEXP(25 + Math.floor(Math.random() * 10)); return self.rpgName + ": Puzzle solved! Reward: " + self.reward + " coins!" + (expMsg ? "\n" + expMsg : ""); } } return self.rpgName + ": Safe travels!"; }; return self; }); var Pirate = Container.expand(function () { var self = Container.call(this); var pirateGraphics = self.attachAsset('pirate', { anchorX: 0.5, anchorY: 0.5 }); self.health = 30; self.speed = 2; self.fireRate = 60; self.lastFire = 0; self.loot = Math.floor(Math.random() * 30) + 10; self.moveAngle = Math.random() * Math.PI * 2; self.patrolTimer = 0; self.aggroRange = 600; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(self, 0xffffff, 100); }; self.update = function () { // Movement AI self.patrolTimer++; if (self.patrolTimer > 180) { self.moveAngle = Math.random() * Math.PI * 2; self.patrolTimer = 0; } // Patrol movement self.x += Math.cos(self.moveAngle) * self.speed * 0.5; self.y += Math.sin(self.moveAngle) * self.speed * 0.5; }; return self; }); var Resource = Container.expand(function () { var self = Container.call(this); var resourceGraphics = self.attachAsset('resource', { anchorX: 0.5, anchorY: 0.5 }); self.type = Math.random() < 0.5 ? 'metal' : 'energy'; self.amount = Math.floor(Math.random() * 5) + 1; self.update = function () { self.rotation += 0.03; }; return self; }); var Ship = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('ship', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.maxHealth = 100; self.shield = 50; self.maxShield = 50; self.shieldRegenDelay = 0; self.speed = 5; self.fireRate = 10; self.damage = 10; self.lastFire = 0; self.boostSpeed = 0; self.boostCooldown = 0; self.takeDamage = function (amount) { // Shield absorbs damage first if (self.shield > 0) { var shieldDamage = Math.min(amount, self.shield); self.shield -= shieldDamage; amount -= shieldDamage; LK.effects.flashObject(self, 0x0088ff, 100); self.shieldRegenDelay = 180; // 3 seconds delay before shield regen } if (amount > 0) { self.health -= amount; LK.effects.flashObject(self, 0xff0000, 200); } if (self.health <= 0) { self.health = 0; LK.showGameOver(); } }; self.update = function () { // Shield regeneration if (self.shieldRegenDelay > 0) { self.shieldRegenDelay--; } else if (self.shield < self.maxShield) { self.shield = Math.min(self.shield + 0.1, self.maxShield); } // Boost cooldown if (self.boostCooldown > 0) { self.boostCooldown--; } if (self.boostSpeed > 0) { self.boostSpeed -= 0.2; } }; return self; }); var Star = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5 }); self.speed = Math.random() * 2 + 0.5; starGraphics.alpha = Math.random() * 0.8 + 0.2; self.vx = (Math.random() - 0.5) * 0.5; self.vy = (Math.random() - 0.5) * 0.5; self.update = function () { // Slow floating movement self.x += self.vx; self.y += self.vy; }; return self; }); // Trade Station Class var TradeStation = Container.expand(function () { var self = Container.call(this); var tradeGraphics = self.attachAsset('npc', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ff99, scaleX: 2, scaleY: 2 }); self.type = 'trade'; self.rotationSpeed = 0.01; self.offerType = Math.random() < 0.5 ? 'buy' : 'sell'; // buy: station buys from player, sell: station sells to player self.resourceType = Math.random() < 0.5 ? 'metal' : 'energy'; self.amount = Math.floor(Math.random() * 10) + 5; self.price = Math.floor(Math.random() * 30) + 10; self.specialOffer = Math.random() < 0.2; // 20% chance for special upgrade offer self.specialUpgrade = null; if (self.specialOffer) { var upgrades = [{ name: 'maxHealth', label: 'Max Health +30', cost: 200 }, { name: 'maxShield', label: 'Max Shield +20', cost: 180 }, { name: 'damage', label: 'Damage +5', cost: 150 }, { name: 'speed', label: 'Speed +1', cost: 120 }]; self.specialUpgrade = upgrades[Math.floor(Math.random() * upgrades.length)]; } self.update = function () { self.rotation += self.rotationSpeed; // Pulse effect var scale = 2 + Math.sin(LK.ticks * 0.05) * 0.1; tradeGraphics.scaleX = scale; tradeGraphics.scaleY = scale; }; return self; }); var UpgradeStation = Container.expand(function () { var self = Container.call(this); var stationGraphics = self.attachAsset('pirate', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ffff, scaleX: 1.5, scaleY: 1.5 }); self.type = 'upgrade'; self.upgrades = [{ name: 'health', cost: 100, metalCost: 10 }, { name: 'shield', cost: 150, metalCost: 15 }, { name: 'damage', cost: 200, energyCost: 20 }, { name: 'speed', cost: 120, energyCost: 10 }]; self.currentUpgrade = 0; self.rotationSpeed = 0.01; self.update = function () { self.rotation += self.rotationSpeed; // Pulse effect var scale = 1.5 + Math.sin(LK.ticks * 0.05) * 0.1; stationGraphics.scaleX = scale; stationGraphics.scaleY = scale; }; return self; }); // Wormhole Teleporter Class var Wormhole = Container.expand(function () { var self = Container.call(this); var whGraphics = self.attachAsset('star', { anchorX: 0.5, anchorY: 0.5, scaleX: 5, scaleY: 5, tint: 0x00ffff }); self.radius = 120; self.cooldown = 0; self.update = function () { whGraphics.rotation += 0.07; // Teleport ship if close and not on cooldown var dx = ship.x - self.x; var dy = ship.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.radius && self.cooldown <= 0) { // Teleport ship to a random far location var tx = ship.x + (Math.random() - 0.5) * 4000; var ty = ship.y + (Math.random() - 0.5) * 4000; var dx2 = tx - ship.x; var dy2 = ty - ship.y; ship.x = tx; ship.y = ty; // Move all objects to keep camera effect for (var i = 0; i < stars.length; i++) { stars[i].x -= dx2; stars[i].y -= dy2; } for (var i = 0; i < npcs.length; i++) { npcs[i].x -= dx2; npcs[i].y -= dy2; } for (var i = 0; i < pirates.length; i++) { pirates[i].x -= dx2; pirates[i].y -= dy2; } for (var i = 0; i < coins.length; i++) { coins[i].x -= dx2; coins[i].y -= dy2; } for (var i = 0; i < resources.length; i++) { resources[i].x -= dx2; resources[i].y -= dy2; } for (var i = 0; i < bullets.length; i++) { bullets[i].x -= dx2; bullets[i].y -= dy2; } for (var i = 0; i < enemyBullets.length; i++) { enemyBullets[i].x -= dx2; enemyBullets[i].y -= dy2; } for (var i = 0; i < asteroids.length; i++) { asteroids[i].x -= dx2; asteroids[i].y -= dy2; } for (var i = 0; i < upgradeStations.length; i++) { upgradeStations[i].x -= dx2; upgradeStations[i].y -= dy2; } for (var i = 0; i < boostParticles.length; i++) { boostParticles[i].x -= dx2; boostParticles[i].y -= dy2; } for (var i = 0; i < explosions.length; i++) { explosions[i].x -= dx2; explosions[i].y -= dy2; } for (var i = 0; i < blackHoles.length; i++) { blackHoles[i].x -= dx2; blackHoles[i].y -= dy2; } for (var i = 0; i < wormholes.length; i++) { if (wormholes[i] !== self) { wormholes[i].x -= dx2; wormholes[i].y -= dy2; } } self.cooldown = 180; LK.effects.flashScreen(0x00ffff, 500); } if (self.cooldown > 0) self.cooldown--; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000033 }); /**** * Game Code ****/ // Game variables var ship; var joystickBase; var joystickHandle; var isDragging = false; var bullets = []; var enemyBullets = []; var npcs = []; var pirates = []; var coins = []; var resources = []; var stars = []; var asteroids = []; var upgradeStations = []; var boostParticles = []; var explosions = []; var blackHoles = []; var wormholes = []; var tradeStations = []; var tradeText = new Text2('', { size: 40, fill: 0x00ff99 }); tradeText.anchor.set(0.5, 0); tradeText.y = 180; LK.gui.top.addChild(tradeText); var camera = { x: 0, y: 0 }; // Trade station tap detection (RPG/ticaret) for (var i = 0; i < tradeStations.length; i++) { var ts = tradeStations[i]; var dist = Math.sqrt(Math.pow(ts.x - ship.x, 2) + Math.pow(ts.y - ship.y, 2)); if (dist < 180) { game._lastTradeStationTap = LK.ticks; break; } } var waveNumber = 0; var enemiesKilled = 0; var totalDistance = 0; // Player stats var playerCoins = storage.coins || 0; var playerMetal = storage.metal || 0; var playerEnergy = storage.energy || 0; var questsCompleted = storage.questsCompleted || 0; // UI Elements var coinText = new Text2('Coins: ' + playerCoins, { size: 50, fill: 0xFFFF00 }); coinText.anchor.set(0, 0); coinText.x = 120; coinText.y = 20; LK.gui.topLeft.addChild(coinText); var resourceText = new Text2('Metal: ' + playerMetal + ' Energy: ' + playerEnergy, { size: 40, fill: 0xFFFFFF }); resourceText.anchor.set(0, 0); resourceText.x = 120; resourceText.y = 80; LK.gui.topLeft.addChild(resourceText); var healthText = new Text2('Health: 100/100', { size: 50, fill: 0x00FF00 }); healthText.anchor.set(0.5, 0); LK.gui.top.addChild(healthText); var shieldText = new Text2('Shield: 50/50', { size: 40, fill: 0x0088FF }); shieldText.anchor.set(0.5, 0); shieldText.y = 60; LK.gui.top.addChild(shieldText); var boostText = new Text2('BOOST READY', { size: 35, fill: 0x00FFFF }); boostText.anchor.set(0.5, 0); boostText.y = 110; LK.gui.top.addChild(boostText); var waveText = new Text2('Wave: 1', { size: 45, fill: 0xFFFFFF }); waveText.anchor.set(1, 0); waveText.x = -20; waveText.y = 20; LK.gui.topRight.addChild(waveText); // Level/EXP system var playerLevel = storage.playerLevel || 1; var playerEXP = storage.playerEXP || 0; var expToNext = function expToNext(lv) { return 100 + (lv - 1) * 50; }; var expText = new Text2('Level: ' + playerLevel + ' EXP: ' + playerEXP + '/' + expToNext(playerLevel), { size: 38, fill: 0x00ffcc }); expText.anchor.set(1, 0); expText.x = -20; expText.y = 80; LK.gui.topRight.addChild(expText); // Create joystick joystickBase = game.addChild(LK.getAsset('joystickBase', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 2432 })); joystickBase.alpha = 0.5; joystickHandle = game.addChild(LK.getAsset('joystickHandle', { anchorX: 0.5, anchorY: 0.5, x: 300, y: 2432 })); joystickHandle.alpha = 0.7; // Create ship ship = game.addChild(new Ship()); ship.x = 1024; ship.y = 1366; // Start background music LK.playMusic('bgmusic'); // Initialize star field for (var i = 0; i < 50; i++) { spawnStar(); } // Helper functions function spawnStar() { var star = new Star(); // Spawn from edges of visible area var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: // Top star.x = ship.x + (Math.random() - 0.5) * 2500; star.y = ship.y - 1500; break; case 1: // Right star.x = ship.x + 1500; star.y = ship.y + (Math.random() - 0.5) * 2500; break; case 2: // Bottom star.x = ship.x + (Math.random() - 0.5) * 2500; star.y = ship.y + 1500; break; case 3: // Left star.x = ship.x - 1500; star.y = ship.y + (Math.random() - 0.5) * 2500; break; } stars.push(star); game.addChild(star); } function spawnNPC() { var npc = new NPC(); // Spawn from edges of visible area var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: // Top npc.x = ship.x + (Math.random() - 0.5) * 2000; npc.y = ship.y - 1500; break; case 1: // Right npc.x = ship.x + 1500; npc.y = ship.y + (Math.random() - 0.5) * 2000; break; case 2: // Bottom npc.x = ship.x + (Math.random() - 0.5) * 2000; npc.y = ship.y + 1500; break; case 3: // Left npc.x = ship.x - 1500; npc.y = ship.y + (Math.random() - 0.5) * 2000; break; } npc.baseY = npc.y; npcs.push(npc); game.addChild(npc); } function spawnPirate() { var pirate = new Pirate(); // Spawn from edges of visible area var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: // Top pirate.x = ship.x + (Math.random() - 0.5) * 1800; pirate.y = ship.y - 1400; break; case 1: // Right pirate.x = ship.x + 1400; pirate.y = ship.y + (Math.random() - 0.5) * 1800; break; case 2: // Bottom pirate.x = ship.x + (Math.random() - 0.5) * 1800; pirate.y = ship.y + 1400; break; case 3: // Left pirate.x = ship.x - 1400; pirate.y = ship.y + (Math.random() - 0.5) * 1800; break; } // Scale pirate stats based on wave pirate.health = 30 + waveNumber * 10; pirate.damage = 5 + Math.floor(waveNumber / 2); pirates.push(pirate); game.addChild(pirate); } function spawnAsteroid() { var asteroid = new Asteroid(); var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: asteroid.x = ship.x + (Math.random() - 0.5) * 2200; asteroid.y = ship.y - 1600; break; case 1: asteroid.x = ship.x + 1600; asteroid.y = ship.y + (Math.random() - 0.5) * 2200; break; case 2: asteroid.x = ship.x + (Math.random() - 0.5) * 2200; asteroid.y = ship.y + 1600; break; case 3: asteroid.x = ship.x - 1600; asteroid.y = ship.y + (Math.random() - 0.5) * 2200; break; } asteroids.push(asteroid); game.addChild(asteroid); } function spawnUpgradeStation() { var station = new UpgradeStation(); station.x = ship.x + (Math.random() - 0.5) * 3000; station.y = ship.y + (Math.random() - 0.5) * 3000; upgradeStations.push(station); game.addChild(station); } function spawnTradeStation() { var ts = new TradeStation(); // Spawn from edges of visible area var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: ts.x = ship.x + (Math.random() - 0.5) * 2000; ts.y = ship.y - 1500; break; case 1: ts.x = ship.x + 1500; ts.y = ship.y + (Math.random() - 0.5) * 2000; break; case 2: ts.x = ship.x + (Math.random() - 0.5) * 2000; ts.y = ship.y + 1500; break; case 3: ts.x = ship.x - 1500; ts.y = ship.y + (Math.random() - 0.5) * 2000; break; } tradeStations.push(ts); game.addChild(ts); } function createExplosion(x, y) { for (var i = 0; i < 8; i++) { var particle = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: x, y: y }); particle.vx = (Math.random() - 0.5) * 10; particle.vy = (Math.random() - 0.5) * 10; particle.life = 30; explosions.push(particle); game.addChild(particle); } } function spawnBlackHole() { var bh = new BlackHole(); // Spawn far from ship, random edge var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: bh.x = ship.x + (Math.random() - 0.5) * 2000; bh.y = ship.y - 1700; break; case 1: bh.x = ship.x + 1700; bh.y = ship.y + (Math.random() - 0.5) * 2000; break; case 2: bh.x = ship.x + (Math.random() - 0.5) * 2000; bh.y = ship.y + 1700; break; case 3: bh.x = ship.x - 1700; bh.y = ship.y + (Math.random() - 0.5) * 2000; break; } blackHoles.push(bh); game.addChild(bh); } function spawnWormhole() { var wh = new Wormhole(); // Spawn far from ship, random edge var edge = Math.floor(Math.random() * 4); switch (edge) { case 0: wh.x = ship.x + (Math.random() - 0.5) * 2000; wh.y = ship.y - 1700; break; case 1: wh.x = ship.x + 1700; wh.y = ship.y + (Math.random() - 0.5) * 2000; break; case 2: wh.x = ship.x + (Math.random() - 0.5) * 2000; wh.y = ship.y + 1700; break; case 3: wh.x = ship.x - 1700; wh.y = ship.y + (Math.random() - 0.5) * 2000; break; } wormholes.push(wh); game.addChild(wh); } function createBoostParticle() { var particle = LK.getAsset('boostParticle', { anchorX: 0.5, anchorY: 0.5, x: ship.x - Math.cos(ship.rotation - Math.PI / 2) * 50, y: ship.y - Math.sin(ship.rotation - Math.PI / 2) * 50 }); particle.vx = -Math.cos(ship.rotation - Math.PI / 2) * 5 + (Math.random() - 0.5) * 2; particle.vy = -Math.sin(ship.rotation - Math.PI / 2) * 5 + (Math.random() - 0.5) * 2; particle.life = 20; boostParticles.push(particle); game.addChild(particle); } function updateUI() { coinText.setText('Coins: ' + playerCoins); resourceText.setText('Metal: ' + playerMetal + ' Energy: ' + playerEnergy); healthText.setText('Health: ' + ship.health + '/' + ship.maxHealth); shieldText.setText('Shield: ' + Math.floor(ship.shield) + '/' + ship.maxShield); waveText.setText('Wave: ' + (waveNumber + 1)); expText.setText('Level: ' + playerLevel + ' EXP: ' + playerEXP + '/' + expToNext(playerLevel)); // Update health text color if (ship.health > 60) { healthText.fill = 0x00ff00; } else if (ship.health > 30) { healthText.fill = 0xffff00; } else { healthText.fill = 0xff0000; } // Update shield text color if (ship.shield > 30) { shieldText.fill = 0x0088ff; } else if (ship.shield > 10) { shieldText.fill = 0xffff00; } else { shieldText.fill = 0xff0000; } // Update boost text if (ship.boostCooldown <= 0) { boostText.setText('BOOST READY'); boostText.fill = 0x00ffff; } else { boostText.setText('BOOST: ' + Math.ceil(ship.boostCooldown / 60) + 's'); boostText.fill = 0x888888; } storage.playerLevel = playerLevel; storage.playerEXP = playerEXP; } function saveProgress() { storage.coins = playerCoins; storage.metal = playerMetal; storage.energy = playerEnergy; storage.questsCompleted = questsCompleted; } // Event handlers game.down = function (x, y, obj) { if (Math.sqrt(Math.pow(x - joystickBase.x, 2) + Math.pow(y - joystickBase.y, 2)) < 100) { isDragging = true; joystickHandle.x = x; joystickHandle.y = y; } else if (y < 300 && ship.boostCooldown <= 0) { // Boost when tapping upper area of screen ship.boostSpeed = 10; ship.boostCooldown = 300; // 5 seconds cooldown if (LK.getSound('boost')) { LK.getSound('boost').play(); } } else { // Check for NPC tap (RPG/adventure/trade) for (var i = 0; i < npcs.length; i++) { var npc = npcs[i]; var dist = Math.sqrt(Math.pow(npc.x - ship.x, 2) + Math.pow(npc.y - ship.y, 2)); if (dist < 180) { game._lastNPCTap = LK.ticks; break; } } } }; game.move = function (x, y, obj) { if (isDragging) { var dx = x - joystickBase.x; var dy = y - joystickBase.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 100) { dx = dx / distance * 100; dy = dy / distance * 100; } joystickHandle.x = joystickBase.x + dx; joystickHandle.y = joystickBase.y + dy; } }; game.up = function (x, y, obj) { isDragging = false; joystickHandle.x = joystickBase.x; joystickHandle.y = joystickBase.y; }; // Main game loop game.update = function () { // Ship movement var shipDX = 0; var shipDY = 0; if (isDragging) { var dx = joystickHandle.x - joystickBase.x; var dy = joystickHandle.y - joystickBase.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 10) { var effectiveSpeed = ship.speed + ship.boostSpeed; shipDX = dx / 100 * effectiveSpeed; shipDY = dy / 100 * effectiveSpeed; ship.rotation = Math.atan2(dy, dx) + Math.PI / 2; // Create boost particles when boosting if (ship.boostSpeed > 0 && LK.ticks % 2 === 0) { createBoostParticle(); } } } // Track total distance traveled totalDistance += Math.sqrt(shipDX * shipDX + shipDY * shipDY); // Update camera to follow ship movement camera.x += shipDX; camera.y += shipDY; // Move all world objects opposite to ship movement to create camera effect for (var i = 0; i < stars.length; i++) { stars[i].x -= shipDX; stars[i].y -= shipDY; } for (var i = 0; i < npcs.length; i++) { npcs[i].x -= shipDX; npcs[i].y -= shipDY; } for (var i = 0; i < pirates.length; i++) { pirates[i].x -= shipDX; pirates[i].y -= shipDY; } for (var i = 0; i < coins.length; i++) { coins[i].x -= shipDX; coins[i].y -= shipDY; } for (var i = 0; i < resources.length; i++) { resources[i].x -= shipDX; resources[i].y -= shipDY; } for (var i = 0; i < bullets.length; i++) { bullets[i].x -= shipDX; bullets[i].y -= shipDY; } for (var i = 0; i < enemyBullets.length; i++) { enemyBullets[i].x -= shipDX; enemyBullets[i].y -= shipDY; } for (var i = 0; i < asteroids.length; i++) { asteroids[i].x -= shipDX; asteroids[i].y -= shipDY; } for (var i = 0; i < upgradeStations.length; i++) { upgradeStations[i].x -= shipDX; upgradeStations[i].y -= shipDY; } for (var i = 0; i < boostParticles.length; i++) { boostParticles[i].x -= shipDX; boostParticles[i].y -= shipDY; } for (var i = 0; i < explosions.length; i++) { explosions[i].x -= shipDX; explosions[i].y -= shipDY; } // Auto fire at very close pirates or asteroids if (LK.ticks - ship.lastFire > ship.fireRate && (pirates.length > 0 || asteroids.length > 0)) { // Find nearest pirate or asteroid within 200 pixels var nearestTarget = null; var nearestDistance = Infinity; var isPirate = false; // Check pirates for (var i = 0; i < pirates.length; i++) { var dist = Math.sqrt(Math.pow(pirates[i].x - ship.x, 2) + Math.pow(pirates[i].y - ship.y, 2)); if (dist < 200 && dist < nearestDistance) { nearestDistance = dist; nearestTarget = pirates[i]; isPirate = true; } } // Check asteroids for (var i = 0; i < asteroids.length; i++) { var dist = Math.sqrt(Math.pow(asteroids[i].x - ship.x, 2) + Math.pow(asteroids[i].y - ship.y, 2)); if (dist < 200 && dist < nearestDistance) { nearestDistance = dist; nearestTarget = asteroids[i]; isPirate = false; } } if (nearestTarget) { var bullet = new Bullet(); bullet.x = ship.x; bullet.y = ship.y; var angle = Math.atan2(nearestTarget.y - ship.y, nearestTarget.x - ship.x); bullet.directionX = Math.cos(angle); bullet.directionY = Math.sin(angle); bullet.rotation = angle + Math.PI / 2; bullets.push(bullet); game.addChild(bullet); ship.lastFire = LK.ticks; LK.getSound('shoot').play(); } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) { bullet.destroy(); bullets.splice(i, 1); continue; } // Check collision with pirates for (var j = pirates.length - 1; j >= 0; j--) { if (bullet.intersects(pirates[j])) { pirates[j].takeDamage(bullet.damage); if (pirates[j].health <= 0) { enemiesKilled++; createExplosion(pirates[j].x, pirates[j].y); // Drop loot var coin = new Coin(); coin.x = pirates[j].x; coin.y = pirates[j].y; coin.value = coin.value * (1 + Math.floor(waveNumber / 3)); coins.push(coin); game.addChild(coin); if (Math.random() < 0.3) { var resource = new Resource(); resource.x = pirates[j].x + (Math.random() - 0.5) * 50; resource.y = pirates[j].y + (Math.random() - 0.5) * 50; resources.push(resource); game.addChild(resource); } pirates[j].destroy(); pirates.splice(j, 1); // Check for wave completion if (enemiesKilled >= 10 + waveNumber * 5) { waveNumber++; enemiesKilled = 0; // Spawn upgrade station every 3 waves if (waveNumber % 3 === 0) { spawnUpgradeStation(); } } } bullet.destroy(); bullets.splice(i, 1); LK.getSound('hit').play(); break; } } // Check collision with asteroids for (var j = asteroids.length - 1; j >= 0; j--) { if (bullet.intersects(asteroids[j])) { asteroids[j].takeDamage(bullet.damage); if (asteroids[j].health <= 0) { // Drop multiple resources for (var k = 0; k < asteroids[j].resources; k++) { var resource = new Resource(); resource.x = asteroids[j].x + (Math.random() - 0.5) * 100; resource.y = asteroids[j].y + (Math.random() - 0.5) * 100; resource.amount = Math.floor(Math.random() * 3) + 1; resources.push(resource); game.addChild(resource); } createExplosion(asteroids[j].x, asteroids[j].y); asteroids[j].destroy(); asteroids.splice(j, 1); } bullet.destroy(); bullets.splice(i, 1); LK.getSound('hit').play(); break; } } } // Update enemy bullets for (var i = enemyBullets.length - 1; i >= 0; i--) { var bullet = enemyBullets[i]; if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) { bullet.destroy(); enemyBullets.splice(i, 1); continue; } if (bullet.intersects(ship)) { ship.takeDamage(bullet.damage); updateUI(); bullet.destroy(); enemyBullets.splice(i, 1); LK.getSound('hit').play(); } } // Update pirates for (var i = 0; i < pirates.length; i++) { var pirate = pirates[i]; // Update pirate AI var dist = Math.sqrt(Math.pow(ship.x - pirate.x, 2) + Math.pow(ship.y - pirate.y, 2)); // Only chase and attack when very close (within 200 pixels) if (dist < 200) { // Chase ship when very close var angle = Math.atan2(ship.y - pirate.y, ship.x - pirate.x); pirate.x += Math.cos(angle) * pirate.speed; pirate.y += Math.sin(angle) * pirate.speed; pirate.rotation = angle + Math.PI / 2; // Pirate shooting when very close if (LK.ticks - pirate.lastFire > pirate.fireRate) { var bullet = new EnemyBullet(); bullet.x = pirate.x; bullet.y = pirate.y; bullet.directionX = Math.cos(angle); bullet.directionY = Math.sin(angle); enemyBullets.push(bullet); game.addChild(bullet); pirate.lastFire = LK.ticks; } } if (dist > 2000) { pirate.destroy(); pirates.splice(i, 1); i--; } } // Update NPCs var npcActive = false; for (var i = npcs.length - 1; i >= 0; i--) { var npc = npcs[i]; // Remove NPCs that are too far away var dist = Math.sqrt(Math.pow(npc.x - ship.x, 2) + Math.pow(npc.y - ship.y, 2)); if (dist > 2500) { npc.destroy(); npcs.splice(i, 1); continue; } // RPG/Adventure: If player is close, show interaction UI if (dist < 180) { npcActive = true; // Remove any previous floating text if (npc._npcText && npc._npcText.parent) { npc._npcText.parent.removeChild(npc._npcText); npc._npcText = null; } var npcMsg = ""; if (game._lastNPCTap !== undefined && game._lastNPCTap + 30 > LK.ticks && game._lastNPC !== npc) { // Player tapped recently, interact var msg = npc.interact(); npcMsg = msg; updateUI(); saveProgress(); game._lastNPC = npc; // Pause NPC for 2 seconds (120 ticks) after interaction npc.pauseUntil = LK.ticks + 120; // Also clear tradeText in GUI tradeText.setText(''); // --- Show floating interaction label under NPC for a short duration --- if (msg && typeof msg === "string" && msg.length > 0) { // Remove previous interaction label if any if (npc._npcInteractionLabel && npc._npcInteractionLabel.parent) { npc._npcInteractionLabel.parent.removeChild(npc._npcInteractionLabel); npc._npcInteractionLabel = null; } var interactionLabel = new Text2(msg.split('\n')[0], { size: 30, fill: 0xffffff, align: "center" }); interactionLabel.anchor.set(0.5, 0); interactionLabel.x = npc.x; interactionLabel.y = npc.y + 70; npc._npcInteractionLabel = interactionLabel; game.addChild(interactionLabel); // Set a timer to remove after 2.5 seconds (150 ticks) npc._npcInteractionLabelExpire = LK.ticks + 150; } // --- NPC Trade Panel Logic --- if (npc.questType === 'trade' && npc.questActive && !npc.hasTraded) { // Show a trade panel above the NPC with offer and tap-to-trade var offer = npc.rpgTradeOffer; var canTrade = false; var tradeMsg = ""; if (offer.give === 'metal' && playerMetal >= offer.wantAmount) { canTrade = true; tradeMsg = "Trade: Give " + offer.wantAmount + " " + offer.want + " for " + offer.giveAmount + " " + offer.give + " (Tap to confirm)"; } else if (offer.give === 'energy' && playerEnergy >= offer.wantAmount) { canTrade = true; tradeMsg = "Trade: Give " + offer.wantAmount + " " + offer.want + " for " + offer.giveAmount + " " + offer.give + " (Tap to confirm)"; } else { tradeMsg = "Trade: Need " + offer.wantAmount + " " + offer.want + " to trade for " + offer.giveAmount + " " + offer.give; } // Remove previous trade panel if any if (npc._npcTradePanel && npc._npcTradePanel.parent) { npc._npcTradePanel.parent.removeChild(npc._npcTradePanel); npc._npcTradePanel = null; } var tradePanel = new Text2(tradeMsg, { size: 36, fill: canTrade ? 0x00ff99 : 0xff8888, align: "center" }); tradePanel.anchor.set(0.5, 0); tradePanel.x = npc.x; tradePanel.y = npc.y + 80; npc._npcTradePanel = tradePanel; game.addChild(tradePanel); // If tapped again within window, perform trade if (canTrade && game._lastNPCTap !== undefined && game._lastNPCTap + 15 > LK.ticks && game._lastNPCTrade !== npc) { // Actually perform trade if (offer.give === 'metal') { playerMetal -= offer.wantAmount; playerEnergy += offer.giveAmount; } else { playerEnergy -= offer.wantAmount; playerMetal += offer.giveAmount; } npc.hasTraded = true; var expMsg = "EXP +" + (10 + Math.floor(Math.random() * 10)); playerEXP += 10 + Math.floor(Math.random() * 10); updateUI(); saveProgress(); // Show confirmation tradePanel.setText("Trade complete!\n" + expMsg); tradePanel.fill = 0x00ffcc; game._lastNPCTrade = npc; } } else { // Remove trade panel if not trading if (npc._npcTradePanel && npc._npcTradePanel.parent) { npc._npcTradePanel.parent.removeChild(npc._npcTradePanel); npc._npcTradePanel = null; } } } else if (!npc.questActive || npc.questProgress > 0) { npcMsg = npc.rpgName + ": " + (npc.questActive ? "Thank you!" : "Safe travels!"); // Remove trade panel if not trading if (npc._npcTradePanel && npc._npcTradePanel.parent) { npc._npcTradePanel.parent.removeChild(npc._npcTradePanel); npc._npcTradePanel = null; } } else { // Show quest/trade offer if (npc.questType === 'trade') { npcMsg = npc.rpgName + ": Trade? Tap to interact."; } else if (npc.questType === 'delivery') { npcMsg = npc.rpgName + ": Delivery quest! Tap to interact."; } else if (npc.questType === 'explore') { npcMsg = npc.rpgName + ": Exploration quest! Tap to interact."; } else if (npc.questType === 'escort') { npcMsg = npc.rpgName + ": Escort quest! Tap to interact."; } else if (npc.questType === 'hunt') { npcMsg = npc.rpgName + ": Hunt quest! Tap to interact."; } else if (npc.questType === 'puzzle') { npcMsg = npc.rpgName + ": Puzzle quest! Tap to interact."; } // Remove trade panel if not trading if (npc._npcTradePanel && npc._npcTradePanel.parent) { npc._npcTradePanel.parent.removeChild(npc._npcTradePanel); npc._npcTradePanel = null; } } // Show floating text above NPC if (npcMsg) { var npcText = new Text2(npcMsg, { size: 38, fill: 0x00ffcc, align: "center" }); npcText.anchor.set(0.5, 1); npcText.x = npc.x; npcText.y = npc.y - 70; // Remove previous if any if (npc._npcText && npc._npcText.parent) { npc._npcText.parent.removeChild(npc._npcText); } npc._npcText = npcText; game.addChild(npcText); } // Remove tradeText from GUI tradeText.setText(''); } else { // Remove floating text if player is not close if (npc._npcText && npc._npcText.parent) { npc._npcText.parent.removeChild(npc._npcText); npc._npcText = null; } } // Remove floating interaction label if expired if (npc._npcInteractionLabel && npc._npcInteractionLabelExpire !== undefined && LK.ticks > npc._npcInteractionLabelExpire) { if (npc._npcInteractionLabel.parent) { npc._npcInteractionLabel.parent.removeChild(npc._npcInteractionLabel); } npc._npcInteractionLabel = null; npc._npcInteractionLabelExpire = undefined; } } if (!npcActive) { game._lastNPC = null; } // Update asteroids for (var i = asteroids.length - 1; i >= 0; i--) { var asteroid = asteroids[i]; var dist = Math.sqrt(Math.pow(asteroid.x - ship.x, 2) + Math.pow(asteroid.y - ship.y, 2)); if (dist > 2500) { asteroid.destroy(); asteroids.splice(i, 1); } } // Update upgrade stations for (var i = upgradeStations.length - 1; i >= 0; i--) { var station = upgradeStations[i]; var dist = Math.sqrt(Math.pow(station.x - ship.x, 2) + Math.pow(station.y - ship.y, 2)); if (dist < 100 && playerCoins >= 100) { // Apply random upgrade var upgrade = station.upgrades[Math.floor(Math.random() * station.upgrades.length)]; if (upgrade.name === 'health' && playerMetal >= (upgrade.metalCost || 0)) { ship.maxHealth += 20; ship.health = ship.maxHealth; playerCoins -= upgrade.cost; playerMetal -= upgrade.metalCost || 0; } else if (upgrade.name === 'shield' && playerMetal >= (upgrade.metalCost || 0)) { ship.maxShield += 10; ship.shield = ship.maxShield; playerCoins -= upgrade.cost; playerMetal -= upgrade.metalCost || 0; } else if (upgrade.name === 'damage' && playerEnergy >= (upgrade.energyCost || 0)) { ship.damage += 5; playerCoins -= upgrade.cost; playerEnergy -= upgrade.energyCost || 0; } else if (upgrade.name === 'speed' && playerEnergy >= (upgrade.energyCost || 0)) { ship.speed += 1; playerCoins -= upgrade.cost; playerEnergy -= upgrade.energyCost || 0; } if (LK.getSound('upgrade')) { LK.getSound('upgrade').play(); } updateUI(); saveProgress(); station.destroy(); upgradeStations.splice(i, 1); } if (dist > 3000) { station.destroy(); upgradeStations.splice(i, 1); } } // Update boost particles for (var i = boostParticles.length - 1; i >= 0; i--) { var particle = boostParticles[i]; particle.x += particle.vx; particle.y += particle.vy; particle.life--; particle.alpha = particle.life / 20; if (particle.life <= 0) { particle.destroy(); boostParticles.splice(i, 1); } } // Update explosion particles for (var i = explosions.length - 1; i >= 0; i--) { var particle = explosions[i]; particle.x += particle.vx; particle.y += particle.vy; particle.vx *= 0.9; particle.vy *= 0.9; particle.life--; particle.alpha = particle.life / 30; particle.scaleX = particle.scaleY = 1 + (30 - particle.life) / 10; if (particle.life <= 0) { particle.destroy(); explosions.splice(i, 1); } } // Collect items for (var i = coins.length - 1; i >= 0; i--) { if (coins[i].intersects(ship)) { playerCoins += coins[i].value; coins[i].destroy(); coins.splice(i, 1); LK.getSound('collect').play(); updateUI(); saveProgress(); } } for (var i = resources.length - 1; i >= 0; i--) { if (resources[i].intersects(ship)) { if (resources[i].type === 'metal') { playerMetal += resources[i].amount; } else { playerEnergy += resources[i].amount; } resources[i].destroy(); resources.splice(i, 1); LK.getSound('collect').play(); updateUI(); saveProgress(); } } // Update stars for (var i = stars.length - 1; i >= 0; i--) { var dist = Math.sqrt(Math.pow(stars[i].x - ship.x, 2) + Math.pow(stars[i].y - ship.y, 2)); if (dist > 2000) { stars[i].destroy(); stars.splice(i, 1); } } // Update black holes for (var i = blackHoles.length - 1; i >= 0; i--) { var bh = blackHoles[i]; if (bh.update) bh.update(); var dist = Math.sqrt(Math.pow(bh.x - ship.x, 2) + Math.pow(bh.y - ship.y, 2)); if (dist > 3000) { bh.destroy(); blackHoles.splice(i, 1); } } // Update wormholes for (var i = wormholes.length - 1; i >= 0; i--) { var wh = wormholes[i]; if (wh.update) wh.update(); var dist = Math.sqrt(Math.pow(wh.x - ship.x, 2) + Math.pow(wh.y - ship.y, 2)); if (dist > 3000) { wh.destroy(); wormholes.splice(i, 1); } } // Update trade stations (RPG/ticaret) var tradeActive = false; for (var i = tradeStations.length - 1; i >= 0; i--) { var ts = tradeStations[i]; if (ts.update) ts.update(); var dist = Math.sqrt(Math.pow(ts.x - ship.x, 2) + Math.pow(ts.y - ship.y, 2)); if (dist < 180) { tradeActive = true; // Show trade offer if (ts.specialOffer && ts.specialUpgrade) { tradeText.setText('Special: ' + ts.specialUpgrade.label + ' for ' + ts.specialUpgrade.cost + ' coins\n(Tap to buy)'); // Buy special upgrade on tap if (game._lastTradeStation !== ts && game._lastTradeStationTap !== undefined && game._lastTradeStationTap + 30 > LK.ticks) { if (playerCoins >= ts.specialUpgrade.cost) { playerCoins -= ts.specialUpgrade.cost; if (ts.specialUpgrade.name === 'maxHealth') { ship.maxHealth += 30; ship.health = ship.maxHealth; } else if (ts.specialUpgrade.name === 'maxShield') { ship.maxShield += 20; ship.shield = ship.maxShield; } else if (ts.specialUpgrade.name === 'damage') { ship.damage += 5; } else if (ts.specialUpgrade.name === 'speed') { ship.speed += 1; } LK.effects.flashObject(ship, 0x00ff99, 400); updateUI(); saveProgress(); ts.destroy(); tradeStations.splice(i, 1); tradeText.setText('Upgrade purchased!'); game._lastTradeStation = null; break; } else { tradeText.setText('Not enough coins!'); } } } else if (ts.offerType === 'buy') { tradeText.setText('Trade: Sell ' + ts.amount + ' ' + ts.resourceType + ' for ' + ts.price + ' coins\n(Tap to sell)'); // Sell resource on tap if (game._lastTradeStation !== ts && game._lastTradeStationTap !== undefined && game._lastTradeStationTap + 30 > LK.ticks) { if (ts.resourceType === 'metal' && playerMetal >= ts.amount) { playerMetal -= ts.amount; playerCoins += ts.price; LK.effects.flashObject(ship, 0x00ff99, 200); updateUI(); saveProgress(); ts.destroy(); tradeStations.splice(i, 1); tradeText.setText('Sold!'); game._lastTradeStation = null; break; } else if (ts.resourceType === 'energy' && playerEnergy >= ts.amount) { playerEnergy -= ts.amount; playerCoins += ts.price; LK.effects.flashObject(ship, 0x00ff99, 200); updateUI(); saveProgress(); ts.destroy(); tradeStations.splice(i, 1); tradeText.setText('Sold!'); game._lastTradeStation = null; break; } else { tradeText.setText('Not enough ' + ts.resourceType + '!'); } } } else if (ts.offerType === 'sell') { tradeText.setText('Trade: Buy ' + ts.amount + ' ' + ts.resourceType + ' for ' + ts.price + ' coins\n(Tap to buy)'); // Buy resource on tap if (game._lastTradeStation !== ts && game._lastTradeStationTap !== undefined && game._lastTradeStationTap + 30 > LK.ticks) { if (playerCoins >= ts.price) { playerCoins -= ts.price; if (ts.resourceType === 'metal') { playerMetal += ts.amount; } else { playerEnergy += ts.amount; } LK.effects.flashObject(ship, 0x00ff99, 200); updateUI(); saveProgress(); ts.destroy(); tradeStations.splice(i, 1); tradeText.setText('Purchased!'); game._lastTradeStation = null; break; } else { tradeText.setText('Not enough coins!'); } } } game._lastTradeStation = ts; } if (dist > 2500) { ts.destroy(); tradeStations.splice(i, 1); } } if (!tradeActive) { tradeText.setText(''); game._lastTradeStation = null; } // Spawn entities (reduced by 70%) if (LK.ticks % 100 === 0) { if (Math.random() < 0.5) { // 50% chance spawnStar(); } } // Spawn black holes occasionally if (LK.ticks % 3600 === 0 && Math.random() < 0.6) { spawnBlackHole(); } // Spawn wormholes occasionally if (LK.ticks % 4200 === 0 && Math.random() < 0.6) { spawnWormhole(); } // Spawn trade stations occasionally (RPG/ticaret) if (LK.ticks % 4800 === 0 && Math.random() < 0.6) { spawnTradeStation(); } if (LK.ticks % 900 === 0) { var spawnRoll = Math.random(); if (spawnRoll < 0.15) { // 15% chance (pirates reduced by 85%) spawnPirate(); } else if (spawnRoll < 0.31) { // 16% chance (NPCs increased by 10%) spawnNPC(); } else if (spawnRoll < 0.33) { // 2% chance // Spawn multiple entities occasionally spawnPirate(); spawnNPC(); } } // Spawn asteroids (reduced by 70%) if (LK.ticks % 1500 === 0) { if (Math.random() < 0.5) { // 50% chance spawnAsteroid(); } } // Wave-based pirate spawning if (LK.ticks % (180 - Math.min(waveNumber * 10, 100)) === 0) { var piratesInWave = 1 + Math.floor(waveNumber / 2); for (var j = 0; j < piratesInWave; j++) { spawnPirate(); } } // Boss wave every 5 waves if (waveNumber > 0 && waveNumber % 5 === 0 && pirates.length === 0) { var bossPirate = new Pirate(); bossPirate.x = ship.x + 1000; bossPirate.y = ship.y; bossPirate.health = 200 + waveNumber * 20; bossPirate.damage = 10 + waveNumber; bossPirate.loot = 200 + waveNumber * 50; bossPirate.speed = 3; var bossGraphics = bossPirate.children[0]; bossGraphics.tint = 0xff00ff; bossGraphics.scaleX = 2; bossGraphics.scaleY = 2; pirates.push(bossPirate); game.addChild(bossPirate); } // Update score LK.setScore(playerCoins + questsCompleted * 100 + enemiesKilled * 10 + Math.floor(totalDistance / 100)); updateUI(); };
===================================================================
--- original.js
+++ change.js
@@ -1433,8 +1433,28 @@
// Pause NPC for 2 seconds (120 ticks) after interaction
npc.pauseUntil = LK.ticks + 120;
// Also clear tradeText in GUI
tradeText.setText('');
+ // --- Show floating interaction label under NPC for a short duration ---
+ if (msg && typeof msg === "string" && msg.length > 0) {
+ // Remove previous interaction label if any
+ if (npc._npcInteractionLabel && npc._npcInteractionLabel.parent) {
+ npc._npcInteractionLabel.parent.removeChild(npc._npcInteractionLabel);
+ npc._npcInteractionLabel = null;
+ }
+ var interactionLabel = new Text2(msg.split('\n')[0], {
+ size: 30,
+ fill: 0xffffff,
+ align: "center"
+ });
+ interactionLabel.anchor.set(0.5, 0);
+ interactionLabel.x = npc.x;
+ interactionLabel.y = npc.y + 70;
+ npc._npcInteractionLabel = interactionLabel;
+ game.addChild(interactionLabel);
+ // Set a timer to remove after 2.5 seconds (150 ticks)
+ npc._npcInteractionLabelExpire = LK.ticks + 150;
+ }
// --- NPC Trade Panel Logic ---
if (npc.questType === 'trade' && npc.questActive && !npc.hasTraded) {
// Show a trade panel above the NPC with offer and tap-to-trade
var offer = npc.rpgTradeOffer;
@@ -1544,8 +1564,16 @@
npc._npcText.parent.removeChild(npc._npcText);
npc._npcText = null;
}
}
+ // Remove floating interaction label if expired
+ if (npc._npcInteractionLabel && npc._npcInteractionLabelExpire !== undefined && LK.ticks > npc._npcInteractionLabelExpire) {
+ if (npc._npcInteractionLabel.parent) {
+ npc._npcInteractionLabel.parent.removeChild(npc._npcInteractionLabel);
+ }
+ npc._npcInteractionLabel = null;
+ npc._npcInteractionLabelExpire = undefined;
+ }
}
if (!npcActive) {
game._lastNPC = null;
}
Uzay temalı global Cevher ticareti, gerçekçi, Altında "Trade" yazsın. In-Game asset. High contrast. No shadows
Uzay temalı global Cevher ticareti, uzay istasyonu, gerçekçi, Altında "Space Stations" yazsın. In-Game asset. High contrast. No shadows
Uzay temalı global Cevher deposu, uzay kargosu, gerçekçi, Altında "Storage" yazsın. In-Game asset. High contrast. No shadows
Uzay temalı Gemi Geliştirme, Tamirci İstasyonu, gerçekçi, Altında "Upgrade" yazsın. In-Game asset. High contrast. No shadows
Uzay temalı global Achievements, gerçekçi, Altında "Achievements" yazsın. In-Game asset. High contrast. No shadows
Uzay temalı, içi altın dolu kapağı açık kasa, gerçekçi, In-Game asset. High contrast. No shadows
Uzay temalı Spaceship Crew, gerçekçi, Altında "crew" yazsın. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı altın coin, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı Savaş Gemisi, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows
Uzay temalı asteroid, üzerinde cevherler bulunsun, gerçekçi, yazısız üstten görünüm. In-Game asset. High contrast. No shadows