User prompt
4 ve 10 u 2 ile 8 yapalım
User prompt
mermi düşmana ya da oyuncuya çarptığında red particles isimli asset merminin gittiği yönde merminin gittiği yönün üst alt çapraz yönlerinden çoğalsın ve biraz density ekle ve ilerledikçe büyüsünler ve ilerledikçe görünürlüklerini yavaşça kaybetsinler
User prompt
replace muzzle flash with muzzleeffect
User prompt
make muzzleeffect asset for muzzle flash
User prompt
her silahın namlu kısmında küçük bir flaş patlaması yaşansın 0.1 saniyeliğine silahın uç kısmında çıksın ve yok olsun
User prompt
Please fix the bug: 'KanDamlaParticle is not defined' in or related to this line: 'var damla = new KanDamlaParticle();' Line Number: 61
User prompt
Sprite Hazırlığı 5×5–10×10 piksel boyutunda, kırmızıya yakın bir daire veya kare oluşturun. Oyun motorunuzun asset yöneticisine (“kanDamlası” vb. adıyla) ekleyin. Havuz (Pool) Kurulumu Başlangıçta örneğin 50–100 adet kan damlası objesi yaratıp bir listeye koyun. Hepsi başta görünmez (alpha=0) ve “hazır” durumda beklesin. Efekt Tetikleme Karakterin veya düşmanın vurulduğu noktada, tek satırlık bir emitKanEfekti(x, y, mermiYonu) çağrısı yapın. Bu fonksiyon, havuzdan 10–20 adet parçacığı alır, pozisyon, hız, renk, ömür gibi değerleri atar ve ekranda görünür kılar. Döngüsel Güncelleme Her frame’de havuzdaki “aktif” parçacıkları: x += vx; y += vy; alpha -= fadeSpeed; lifespan-- lifespan ≤ 0 veya alpha ≤ 0 ise havuza geri döndürün. Parametre İnce Ayarı Parçacık sayısı: Efektin yoğunluğu. Hız ve açı: Kan damlalarının dağılım şekli. Ömür ve saydamlık: Ne kadar süre kalacağı. Renk tonları: Örneğin farklı düşman tiplerine uygun varyasyonlar.
User prompt
if one of the characters get hit start a blood effect like a spray and make this blood effect the way bullet was coming from start it from the point it touched the body
User prompt
Please fix the bug: 'Uncaught ReferenceError: Bullet is not defined' in or related to this line: 'playerBullet = new Bullet();' Line Number: 460
User prompt
Please fix the bug: 'Enemy is not defined' in or related to this line: 'var enemy = new Enemy();' Line Number: 214
User prompt
Please fix the bug: 'Player is not defined' in or related to this line: 'var player = new Player();' Line Number: 163
User prompt
Bu hatayı almanızın nedeni, new Particle() dediğiniz yerde hâlâ bir Particle tanımı olmaması. JS’de bir sınıfı, fonksiyonu veya değişkeni kullanmadan önce mutlaka tanımlı olması gerekir. Aşağıdaki adımları izleyerek hatayı çözebilirsiniz: 1. Particle sınıfını tanımlayın Bullet’ın sürüklediği partikülleri yaratacak olan Particle sınıfını, mutlaka Bullet sınıfınızın öğesinden önce dosyanızda tanımlayın. Örneğin: js Kopyala Düzenle // Dosyanızın en başlarına ekleyin: var Particle = Container.expand(function() { var self = Container.call(this); // Burada kendi trail-görselinizi yaratın: var size = 5 + Math.random()*5; var puff = self.attachAsset('centerCircle', { width: size, height: size*0.8, color: 0xFFFFFF, anchorX:0.5, anchorY:0.5 }); puff.alpha = 0.5 + Math.random()*0.5; // Fade-out örneği: tween(puff, { alpha: 0 }, { duration: 100, onFinish: function(){ self.parent && self.parent.removeChild(self); } }); return self; }); 2. Bullet sınıfını bu tanımdan sonra yazın Artık Bullet sınıfınızda güvenle new Particle() kullanabilirsiniz: js Kopyala Düzenle var Bullet = Container.expand(function() { var self = Container.call(this); // ... self.update = function() { // hareket ettirme // ... // trail için: if (self.parent) { for (var i=0; i<20; i++) { var p = new Particle(); p.x = self.x; p.y = self.y; self.parent.addChildAt(p, self.parent.getChildIndex(self)); } } }; return self; });
User prompt
Hazır Damla Havuzu Kur – Oyun başlamadan önce ekran dışında “kan damlası” resimlerinden (ya da ufak kırmızı dairelerden) bir kutu oluşturursun. – Bu kutuda, örneğin 100–200 tane hazır damla bekler; sahnede aktif kullanılmayınca hep orada durur. Vuruş Anında Damla Fırlat – Kurşun düşmana değdiğinde, o vurulan noktayı alırsın. – Havuzdan 15–20 tane hazır damlayı alıp, vurulan noktanın tam üstüne koyarsın. – Her birine biraz rastgele yön ve hız verirsin (bazısı yukarı, bazısı yana, farklı hızlarda). Damla Hareketi ve Solma – Oyun her kareyi güncellerken, aktif damlaların konumunu hızlarına göre taşır, hafifçe yere doğru çekersin (yerçekimi). – Aynı anda saydamlıklarını (alpha) yavaş yavaş azaltırsın; bu sayede damlalar “süzülerek” kaybolur. Ömür Tükenince Geri Katla – Bir damlanın saydamlığı sıfıra ulaştığında (ya da belli bir süre dolduğunda), onu sahneden kaldırıp havuza geri koyarsın. – Böylece aynı damla, ilerleyen dakikalarda tekrar kullanılabilir; yeni nesil damla yaratmaya gerek kalmaz. Ayarlarla Oynayarak Farklı Hissiyat – Havuz büyüklüğü (kaç damla saklansın), bir vuruşta kaçını fırlatacağın, düşüş hızı, solma süresi gibi parametreler çok kısa bir ayarla “hafif sıçrama”dan “fırtına gibi patlama”ya götürebilir.
User prompt
Declare world immediately after you create your game (and before any calls to startZoomIn). Remove any stray “Aborted”, “⏪Revert to here” or commented-out partial code around that section—those will stop your parser from seeing the real world declaration. Only call startZoomIn() after you’ve done: js Kopyala Düzenle var game = new LK.Game({ backgroundColor: 0x000000 }); var world = new Container(); game.addChild(world); // ... all your other initialization ... Minimal snippet js Kopyala Düzenle // 1) Create your game... var game = new LK.Game({ backgroundColor: 0x2e1a09 }); // 2) Define 'world' on the global scope var world = new Container(); game.addChild(world); // 3) ...then everything else (assets, Player/Enemy classes, UI setup, etc.) // 4) Finally, *after* world exists, call startZoomIn: function startZoomIn(music) { var startScale = 0.4; world.scaleX = world.scaleY = startScale; world.x = centerX * (1 - startScale); world.y = 2732/2 * (1 - startScale); LK.playMusic(music || 'duelmusic'); tween(world, {scaleX:1, scaleY:1, x:0, y:0}, { duration: 4000, easing: tween.quadInOut, onFinish: function(){ zoomFinished = true; } }); } // 5) Now it won’t throw “world is not defined” startZoomIn(); Checklist: Top of your file (right after var game = ...) you must have: js Kopyala Düzenle var world = new Container(); game.addChild(world); Remove any stray comments like “⏪Revert to here” that interrupt code flow. Don’t call startZoomIn() until that world line has run. Once you do that, world will be in scope and your startZoomIn call will work without errors.
User prompt
Please fix the bug: 'ReferenceError: duelState is not defined' in or related to this line: 'if (duelState === STATE_RESULT) {' Line Number: 1213
User prompt
Please fix the bug: 'ReferenceError: duelState is not defined' in or related to this line: 'if (duelState === STATE_RESULT) {' Line Number: 1212
User prompt
Please fix the bug: 'world is not defined' in or related to this line: 'world.scaleX = world.scaleY = startScale;' Line Number: 1325
User prompt
Please fix the bug: 'world is not defined' in or related to this line: 'world.scaleX = world.scaleY = startScale;' Line Number: 1325
User prompt
Please fix the bug: 'world is not defined' in or related to this line: 'world.scaleX = world.scaleY = startScale;' Line Number: 1325
User prompt
Please fix the bug: 'world is not defined' in or related to this line: 'world.scaleX = world.scaleY = startScale;' Line Number: 1325
User prompt
Please fix the bug: 'world is not defined' in or related to this line: 'world.scaleX = world.scaleY = startScale;' Line Number: 1325
User prompt
It turns out nothing mystical is wrong with PIXI or your tweens — you’re simply calling startZoomIn() before your world variable actually exists. Here’s how to fix it: Declare world immediately after you create your game (and before any calls to startZoomIn). Remove any stray “Aborted”, “⏪Revert to here” or commented-out partial code around that section—those will stop your parser from seeing the real world declaration. Only call startZoomIn() after you’ve done: js Kopyala Düzenle var game = new LK.Game({ backgroundColor: 0x000000 }); var world = new Container(); game.addChild(world); // ... all your other initialization ... Minimal snippet js Kopyala Düzenle // 1) Create your game... var game = new LK.Game({ backgroundColor: 0x2e1a09 }); // 2) Define 'world' on the global scope var world = new Container(); game.addChild(world); // 3) ...then everything else (assets, Player/Enemy classes, UI setup, etc.) // 4) Finally, *after* world exists, call startZoomIn: function startZoomIn(music) { var startScale = 0.4; world.scaleX = world.scaleY = startScale; world.x = centerX * (1 - startScale); world.y = 2732/2 * (1 - startScale); LK.playMusic(music || 'duelmusic'); tween(world, {scaleX:1, scaleY:1, x:0, y:0}, { duration: 4000, easing: tween.quadInOut, onFinish: function(){ zoomFinished = true; } }); } // 5) Now it won’t throw “world is not defined” startZoomIn(); Checklist: Top of your file (right after var game = ...) you must have: js Kopyala Düzenle var world = new Container(); game.addChild(world); Remove any stray comments like “⏪Revert to here” that interrupt code flow. Don’t call startZoomIn() until that world line has run. Once you do that, world will be in scope and your startZoomIn call will work without errors.
User prompt
Please fix the bug: 'world is not defined' in or related to this line: 'world.scaleX = world.scaleY = startScale;' Line Number: 1324
User prompt
delete everything about bullet particules and do this function spawnBlood(x, y, parentContainer){ // 15–20 damla for(var i=0; i<20; i++){ var drop = new Container(); // kırmızı bir daire var blob = drop.attachAsset('centerCircle', { width: 6 + Math.random()*10, height: (6 + Math.random()*10) * (0.6 + Math.random()*0.4), color: 0xCC0000, anchorX: 0.5, anchorY: 0.5 }); drop.x = x; drop.y = y; // rastgele hız var ang = Math.random()*Math.PI*2; var speed = 2 + Math.random()*3; var vx = Math.cos(ang)*speed; var vy = Math.sin(ang)*speed; // fade-out ve uçuş tween(drop, { x: x + vx*20, y: y + vy*20, alpha: 0 }, { duration: 400 + Math.random()*200, onFinish: function(){ if(drop.parent) drop.parent.removeChild(drop); } }); parentContainer.addChild(drop); } } Ve bunu bullet–enemy collision anında çağır: js Kopyala Düzenle // checkBullets içinde, enemy vurulduğunda: if(dist < 120){ // önce kan spawnBlood(enemy.x, enemy.y, world); // sonra ragdoll vs. enemy.ragdoll(playerBullet.x, playerBullet.y); // ... } Aynı şekilde, oyuncu vurulduğunda da spawnBlood(player.x, player.y, world).
User prompt
make bullet trail transparency %25 opac and %75 transparent
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Minimal Player class definition to fix 'Player is not defined' var Player = Container.expand(function () { var self = Container.call(this); // Add a simple body part for demonstration self.body = LK.getAsset('playerBody', { anchorX: 0.5, anchorY: 0.5 }); self.addChild(self.body); // Add a right arm for aiming self.rarm = LK.getAsset('playerArm', { anchorX: 0.5, anchorY: 0.1 }); self.rarm.x = 0; self.rarm.y = self.body.height * 0.1; self.addChild(self.rarm); // Add a gun self.gun = LK.getAsset('playerGun', { anchorX: 0.5, anchorY: 0.5 }); self.gun.x = 0; self.gun.y = self.body.height * 0.3; self.addChild(self.gun); // Reset pose self.resetPose = function () { self.rarm.rotation = 0; self.gun.rotation = Math.PI / 2; }; // Move gun to holster self.toHolster = function () { self.gun.visible = true; self.gun.rotation = Math.PI / 2; }; // Move gun to hand self.toHand = function () { self.gun.visible = true; self.gun.rotation = 0; }; // Ragdoll animation (placeholder) self.ragdoll = function () { self.gun.visible = false; }; return self; }); /**** * Initialize Game ****/ // Helper: getChildIndex and addChildAt for Container (PIXI compatibility) var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game state // Player and enemy bodies (torso, head, arms, legs) as simple shapes // Helper: getChildIndex and addChildAt for Container (PIXI compatibility) if (typeof Container.prototype.getChildIndex !== "function") { Container.prototype.getChildIndex = function (child) { if (!this.children) return -1; for (var i = 0; i < this.children.length; i++) { if (this.children[i] === child) return i; } return -1; }; } if (typeof Container.prototype.addChildAt !== "function") { Container.prototype.addChildAt = function (child, idx) { if (!this.children) this.children = []; if (child.parent) child.parent.removeChild(child); this.children.splice(idx, 0, child); child.parent = this; // If LK engine needs, also call addChild for proper registration if (typeof this.addChild === "function" && this.children.length === 1) { this.addChild(child); } }; } var STATE_WAIT = 0; var STATE_DRAW = 1; var STATE_SHOT = 2; var STATE_RESULT = 3; var duelState = STATE_WAIT; var canShoot = false; var playerShot = false; var enemyShot = false; var playerBullet = null; var enemyBullet = null; var duelTimer = null; var drawTimeout = null; var resultTimeout = null; var duelStartTime = 0; var playerShotTime = 0; var enemyShotTime = 0; var aimX = 0; var aimY = 0; var aimRadius = 180; var aimAngle = 0; var aimSpeed = 0.018; // %30 daha yavaş var aimDir = 1; var aimActive = false; var playerScore = 0; var roundNum = 1; var maxRounds = 5; // === GLOBAL SHOT COUNTERS === var playerShotsFiredCnt = 0; var enemyShotsFiredCnt = 0; // === PLAYER SHOT COOLDOWN === var playerShotCooldown = 0; // ms left until next shot allowed // === GUN RECOIL CONSTANTS === var RECOIL_ANGLE = 0.4; // tip the barrel a little farther (≈23° instead of 17°) var RECOIL_TIME = 200; // total recoil lasts 0.2s instead of 0.5s var enemyData = [{ name: "Greenhorn", minReact: 3.0, maxReact: 3.4, coneStart: 42, coneEnd: 0 }, { name: "Billy the Kid", minReact: 2.4, maxReact: 2.7, coneStart: 36, coneEnd: 0 }, { name: "Doc Holliday", minReact: 1.6, maxReact: 1.9, coneStart: 30, coneEnd: 0 }, { name: "Calamity Jane", minReact: 1.0, maxReact: 1.3, coneStart: 24, coneEnd: 0 }, { name: "The Undertaker", minReact: 0.6, maxReact: 0.8, coneStart: 18, coneEnd: 0, scale: 1.3 }]; var currentEnemy = null; // ==== FIX #1 : SAHNENİN BAŞINDA ==== var world = new Container(); game.addChild(world); // Add arkaplan background image centered in the screen var arkaplan = LK.getAsset('arkaplan', { anchorX: 0.5, anchorY: 0.5 }); arkaplan.x = 2048 / 2; arkaplan.y = 2732 / 2; world.addChild(arkaplan); // Player and enemy var player = new Player(); var enemy = new Enemy(); world.addChild(player); world.addChild(enemy); // Center positions var centerX = 2048 / 2; var playerY = 2732 * 0.7; var enemyY = 2732 * 0.3; // 6-bullet UI for player and enemy var playerAmmoUI = []; var enemyAmmoUI = []; function setupAmmoUI() { // Remove old UI if any for (var i = 0; i < playerAmmoUI.length; i++) { if (playerAmmoUI[i].parent) { playerAmmoUI[i].parent.removeChild(playerAmmoUI[i]); } } for (var i = 0; i < enemyAmmoUI.length; i++) { if (enemyAmmoUI[i].parent) { enemyAmmoUI[i].parent.removeChild(enemyAmmoUI[i]); } } playerAmmoUI = []; enemyAmmoUI = []; for (var i = 0; i < 6; i++) { var px = player.x - 120 + i * 40; var ex = enemy.x - 120 + i * 40; var bulletP = LK.getAsset('bullet', { scaleX: 0.6, scaleY: 0.6, anchorX: 0.5, anchorY: 0.5 }); var bulletE = LK.getAsset('bullet', { scaleX: 0.6, scaleY: 0.6, anchorX: 0.5, anchorY: 0.5 }); bulletP.y = player.y + 250 + 60; // Düşman: yalnızca 5. raundda 75 px yukarı var enemyExtraY = roundNum === 5 ? -75 : 0; bulletE.y = enemy.y - 250 + enemyExtraY; bulletP.x = px; bulletE.x = ex; // HUD’u world içine koy ki zoom animasyonuyla birlikte büyüsün world.addChild(bulletP); world.addChild(bulletE); playerAmmoUI.push(bulletP); enemyAmmoUI.push(bulletE); } } // Position player and enemy player.x = centerX - 500; player.y = playerY; enemy.x = centerX + 500; enemy.y = enemyY; // Score text var scoreTxt = new Text2('Score: 0', { size: 90, fill: 0xFFF7D6 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Round text var roundTxt = new Text2('', { size: 70, fill: 0xFFE4B5 }); roundTxt.anchor.set(0.5, 0); LK.gui.top.addChild(roundTxt); roundTxt.y = 110; // Duel status text var statusTxt = new Text2('', { size: 110, fill: 0xFFECB3 }); statusTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(statusTxt); // (Aim reticle removed) // Helper: reset all state for a new round function resetDuel() { duelState = STATE_WAIT; canShoot = false; playerShot = false; enemyShot = false; playerBullet = null; enemyBullet = null; duelStartTime = 0; playerShotTime = 0; enemyShotTime = 0; aimAngle = Math.random() * Math.PI * 2; aimDir = Math.random() > 0.5 ? 1 : -1; aimActive = false; // (aimReticle removed) player.resetPose(); enemy.resetPose(); player.toHolster(); enemy.toHolster(); holsterFull.visible = true; holsterEmpty.visible = false; setupAmmoUI(); // === RESET SHOT COUNTERS === playerShotsFiredCnt = 0; enemyShotsFiredCnt = 0; // === RESET HOLSTER FLAGS === playerReady = false; // yeni ← round’a nötr gir holdingHolster = false; // yeni holsterHoldTime = 0; // güvenlik duelStarted = false; // <-- YENİ: her raunda nötr gir cancelHold(); // 1. raunddan kalma musicTimeout varsa temizle zoomFinished = false; // yeni animasyona hazırlan var roundMusic = roundNum === 1 ? 'duelmusic' : roundNum === 2 ? 'round2music' : roundNum === 3 ? 'round3music' : roundNum === 4 ? 'round4music' : 'round5music'; startZoomIn(roundMusic); statusTxt.setText("Wait for the music..."); statusTxt.visible = true; // Set up enemy for this round currentEnemy = enemyData[roundNum - 1]; roundTxt.setText("Round " + roundNum + ": " + currentEnemy.name); // Boss scale (if any) enemy.scaleX = enemy.scaleY = currentEnemy.scale || 1; // Play duel music // (music now only plays during zoom-in, do not play here) // drawTimeout is now set after zoom-in, not here if (drawTimeout) { LK.clearTimeout(drawTimeout); } } // Start the "DRAW!" phase function startDraw() { if (!playerReady) { earlyLose(); return; } duelState = STATE_DRAW; canShoot = true; aimActive = true; // (aimReticle removed) statusTxt.setText("DRAW!"); statusTxt.visible = true; LK.stopMusic(); LK.getSound('draw').play(); player.toHand(); // draw from holster enemy.toHand(); // enemy draws too aimEnemyGunAt(player.x, player.y - 40); // hemen hizala duelStartTime = Date.now(); // Enemy will shoot after their reaction time var reactTime = 1200; // fallback default if (currentEnemy && typeof currentEnemy.minReact === "number" && typeof currentEnemy.maxReact === "number") { reactTime = 1000 * (currentEnemy.minReact + Math.random() * (currentEnemy.maxReact - currentEnemy.minReact)); reactTime *= 0.425; // %57.5 daha hızlı tepki (eski 0.5 ve yeni 0.35 arası) } if (duelTimer) { LK.clearTimeout(duelTimer); } duelTimer = LK.setTimeout(enemyFire, reactTime); } // Player fires function playerFire(x, y) { // 6 mermi limiti if (playerShotsFiredCnt >= 6) { statusTxt.setText("Out of ammo!"); statusTxt.visible = true; return; } if (!canShoot) { return; } // === COOLDOWN: Block if cooldown active === if (playerShotCooldown > 0) { return; } playerShot = true; playerShotsFiredCnt++; // sayaç ↑ playerShotTime = Date.now(); // === COOLDOWN: Set cooldown after shot === playerShotCooldown = 300; // 0.3 seconds in ms // Animate gun recoil only (no arm kick) { // capture the gun’s base rotation: var baseRot = player.gun.rotation; // tween up half-time: tween(player.gun, { rotation: baseRot - RECOIL_ANGLE }, { duration: RECOIL_TIME / 2, easing: tween.cubicOut, onFinish: function onFinish() { // tween back down the other half: tween(player.gun, { rotation: baseRot }, { duration: RECOIL_TIME / 2, easing: tween.cubicIn }); } }); } LK.getSound('gunshot').play(); // Create bullet playerBullet = new Bullet(); // Muzzle position helper function muzzlePos() { // Use full gun width/height for muzzle (center anchor) var gunW = player.gun.width || 60; var gunH = player.gun.height || 15; return { x: player.x + player.gun.x + Math.cos(player.gun.rotation) * gunW, y: player.y + player.gun.y + Math.sin(player.gun.rotation) * gunH }; } var muzzle = muzzlePos(); playerBullet.x = muzzle.x; playerBullet.y = muzzle.y; // Ateş anındaki imleç (x, y) fonksiyona zaten parametre olarak geliyor var dx = x - muzzle.x; var dy = y - muzzle.y; var dist = Math.sqrt(dx * dx + dy * dy); playerBullet.dirX = dx / dist; playerBullet.dirY = dy / dist; playerBullet.speed = 60; game.addChild(playerBullet); // Decrement player bullet UI for (var i = 0; i < playerAmmoUI.length; i++) { if (playerAmmoUI[i].visible !== false) { playerAmmoUI[i].visible = false; break; } } // If shot before draw, instant loss if (duelState === STATE_WAIT) { duelState = STATE_RESULT; statusTxt.setText("You shot too early!\nYou Lose!"); statusTxt.visible = true; LK.getSound('fail').play(); player.ragdoll(); enemy.ragdoll(); endRound(false); return; } // bir sonraki mermiye izin ver if (duelState === STATE_DRAW && playerShotsFiredCnt < 6) { canShoot = true; aimActive = true; // (aimReticle removed) } // DRAW fazı açık kalsın ki 6 mermi bitene kadar tekrar tekrar ateş edebilelim } // Enemy fires function enemyFire() { var _currentEnemy; if (enemyShotsFiredCnt >= 6 || duelState === STATE_RESULT) { return; } if (!enemyShot) { enemyShot = true; } // ilk mermi için eski bayrak enemyShotsFiredCnt++; enemyShotTime = Date.now(); // Ateşten önce hedefe çevir aimEnemyGunAt(player.x, player.y - 40); // Animate gun recoil only (no arm kick) { var baseRotE = enemy.gun.rotation; tween(enemy.gun, { rotation: baseRotE + RECOIL_ANGLE }, { duration: RECOIL_TIME / 2, easing: tween.cubicOut, onFinish: function onFinish() { tween(enemy.gun, { rotation: baseRotE }, { duration: RECOIL_TIME / 2, easing: tween.cubicIn }); } }); } LK.getSound('gunshot').play(); // Create bullet enemyBullet = new Bullet(); var gunW = enemy.gun.width || 60; var gunH = enemy.gun.height || 18; enemyBullet.x = enemy.x + enemy.gun.x + Math.cos(enemy.gun.rotation) * gunW; enemyBullet.y = enemy.y + enemy.gun.y + Math.sin(enemy.gun.rotation) * gunH; // Decrement enemy bullet UI for (var i = 0; i < enemyAmmoUI.length; i++) { if (enemyAmmoUI[i].visible !== false) { enemyAmmoUI[i].visible = false; break; } } // Konik isabet modeliyle hedef seçimi // 1️⃣ hedef vektörü var baseDX = player.x - enemyBullet.x; var baseDY = player.y - 40 - enemyBullet.y; // gövdenin biraz üstü var baseAng = Math.atan2(baseDY, baseDX); // 2️⃣ saçılma açısı (daralan koni) var sIdx = enemyShotsFiredCnt; // 1-6 var sMax = 6; var cStart = currentEnemy && typeof currentEnemy.coneStart === "number" ? currentEnemy.coneStart : 24; // fallback var cEnd = currentEnemy && typeof currentEnemy.coneEnd === "number" ? currentEnemy.coneEnd : 0; var coneDeg = cStart + (cEnd - cStart) * ((sIdx - 1) / (sMax - 1)); var coneRad = coneDeg * Math.PI / 180; var isLast = sIdx === sMax; // son kurşun var spread = isLast ? 0 : Math.random() * coneRad - coneRad / 2; // 3️⃣ hedef noktasını diagramdaki yayı keserek bul var range = 1500; // ekran dışına yeter var targetX = enemyBullet.x + Math.cos(baseAng + spread) * range; var targetY = enemyBullet.y + Math.sin(baseAng + spread) * range; var dx = targetX - enemyBullet.x; var dy = targetY - enemyBullet.y; var dist = Math.sqrt(dx * dx + dy * dy); enemyBullet.dirX = dx / dist; enemyBullet.dirY = dy / dist; enemyBullet.speed = 60; game.addChild(enemyBullet); // sonraki mermi (tak-tak) 0.6 sn sonra if (enemyShotsFiredCnt < 6) { LK.setTimeout(enemyFire, 600); } // Round oyuncu ateş etmediyse ANCAK bütün 6 mermi atıldıktan sonra if (enemyShotsFiredCnt === 6 && !playerShot) { // Son kurşunun ekrandan çıkması için çok kısa bir gecikme bırak LK.setTimeout(function () { if (duelState !== STATE_RESULT) { duelState = STATE_RESULT; statusTxt.setText("You Survived!"); statusTxt.visible = true; endRound(true); } }, 350); } } // End round, win: true/false function endRound(win) { canShoot = false; aimActive = false; // (aimReticle removed) // Clear all timers immediately cancelHold(); // musicTimeout'u iptal eder if (duelTimer) { LK.clearTimeout(duelTimer); duelTimer = null; } if (drawTimeout) { LK.clearTimeout(drawTimeout); drawTimeout = null; } if (resultTimeout) { LK.clearTimeout(resultTimeout); resultTimeout = null; } drawTimeout = null; duelTimer = null; resultTimeout = null; duelState = STATE_RESULT; // Next round or end game resultTimeout = LK.setTimeout(function () { if (win) { playerScore += 1; scoreTxt.setText("Score: " + playerScore); roundNum += 1; if (roundNum > maxRounds) { statusTxt.setText("You Win!\nScore: " + playerScore); statusTxt.visible = true; LK.showYouWin(); } else { resetDuel(); } } else { statusTxt.setText("You Lose!\nScore: " + playerScore); statusTxt.visible = true; LK.showGameOver(); } }, 1600); } // Handle aiming reticle movement (circular motion) function updateAimReticle() { // (aim reticle removed) } // Handle bullet collisions and duel result function checkBullets() { // Hem bullet’lar var mı diye bak: if (playerBullet && enemyBullet) { var pdx = playerBullet.x - enemy.x; var pdy = playerBullet.y - enemy.y; var pdist = Math.sqrt(pdx * pdx + pdy * pdy); var edx = enemyBullet.x - player.x; var edy = enemyBullet.y - player.y; var edist = Math.sqrt(edx * edx + edy * edy); // 1) Önce oyuncuya gelen mermiyi kontrol et: if (edist < 120) { // Player vurulmuş, her durumda kaybeder LK.getSound('hit').play(); player.ragdoll(enemyBullet.x, enemyBullet.y); game.removeChild(enemyBullet); enemyBullet = null; duelState = STATE_RESULT; statusTxt.setText("You were shot!"); statusTxt.visible = true; endRound(false); return; } // 2) Sonra düşmana geleni: if (pdist < 120) { LK.getSound('hit').play(); enemy.ragdoll(playerBullet.x, playerBullet.y); game.removeChild(playerBullet); playerBullet = null; duelState = STATE_RESULT; statusTxt.setText("You Win the Duel!"); statusTxt.visible = true; endRound(true); return; } } // Remove bullets if off screen if (playerBullet && (playerBullet.x < 0 || playerBullet.x > 2048 || playerBullet.y < 0 || playerBullet.y > 2732)) { game.removeChild(playerBullet); playerBullet = null; // === COOLDOWN: Only allow new shot if cooldown expired === if (playerShotCooldown <= 0) { canShoot = true; } } if (enemyBullet && (enemyBullet.x < 0 || enemyBullet.x > 2048 || enemyBullet.y < 0 || enemyBullet.y > 2732)) { game.removeChild(enemyBullet); enemyBullet = null; enemyShot = false; // yeni atışa izin ver } } // ==== FIX #2 : holster konumu ==== // Use two holster sprites: full and empty, toggle visibility var holsterFull = LK.getAsset('kilif', { width: 300, height: 300, anchorX: -0.2, anchorY: 0 }); var holsterEmpty = LK.getAsset('kilifbos', { width: 300, height: 300, anchorX: -0.2, anchorY: 0 }); holsterFull.visible = true; holsterEmpty.visible = false; var holsterOffset = 250; holsterFull.x = player.x - 200; holsterFull.y = player.y + player.body.height / 2 + holsterOffset; holsterEmpty.x = holsterFull.x; holsterEmpty.y = holsterFull.y; world.addChild(holsterFull); world.addChild(holsterEmpty); // === Place enemygunpocket in the middle of the screen === var enemygunpocket = LK.getAsset('enemygunpocket', { anchorX: 0.5, anchorY: 0.5 }); enemygunpocket.x = 2048 / 2 + 550 + 50 - 30 - 5 - 5; enemygunpocket.y = 2732 / 2 - 600 + 150 + 10; world.addChild(enemygunpocket); // Helper: check if global point is inside holsterFull's bounds (always use holsterFull for hit area) function holsterContains(globalX, globalY) { // Global (stage) → world-içi (local) koordinata çevir var localX = (globalX - world.x) / world.scaleX; var localY = (globalY - world.y) / world.scaleY; // kilif sprite’ının local kutusu var b = { x: holsterFull.x, y: holsterFull.y, w: holsterFull.width, h: holsterFull.height }; return localX >= b.x && localX <= b.x + b.w && localY >= b.y && localY <= b.y + b.h; } // Holster hold/zoom/duel state var zoomFinished = false, duelStarted = false, holsterHoldTime = 0; var playerReady = false; var holdingHolster = false; // Track if holster is being held var musicTimeout = null; // Timer for music/draw phase function beginHold() { if (musicTimeout) { LK.clearTimeout(musicTimeout); } var extra = 4000 + Math.random() * 6000; // 4-10 s musicTimeout = LK.setTimeout(stopMusicAndDraw, extra); } function cancelHold() { if (musicTimeout) { LK.clearTimeout(musicTimeout); } musicTimeout = null; } function stopMusicAndDraw() { if (duelState !== STATE_WAIT) return; LK.stopMusic(); // müzik sustu if (enemygunpocket && enemygunpocket.visible !== false) { enemygunpocket.visible = false; } duelStarted = true; // <-- ERKEN KAYIP KONTROLÜ ARTIK PASİF holsterHoldTime = 0; // güvenlik: sayaç sıfırla startDraw(); // DRAW fazına geç } // Touch/click to fire or start holster hold game.down = function (x, y, obj) { if (duelState === STATE_RESULT) return; // No fire until duel actually started if (zoomFinished && !duelStarted && holsterContains(x, y)) { playerReady = true; holdingHolster = true; // holster pressed player.toHand(); // ← kılıftan çek (hemen ele ver) // Play holdsound when gun is drawn to hand LK.getSound('holdsound').play(); // --- holster assetini kilifbos ile değiştir (Çözüm 2: iki sprite, görünürlük) --- holsterFull.visible = false; holsterEmpty.visible = true; pointGunAt(x, y); // artık global ve erişilebilir beginHold(); // HOLD başlatılırken zamanlayıcı kuruluyor return; } if (!duelStarted) { return; } if (duelState === STATE_DRAW && canShoot && aimActive) { playerFire(x, y); } else if (duelState === STATE_WAIT && !playerShot) { playerFire(x, y); } }; // On pointer up, check for early leave from holster // ==== FIX #4c : tetikleyici ===== game.up = function (x, y, obj) { if (duelState === STATE_RESULT) return; // HOLSTER EARLY RELEASE CHECK holdingHolster = false; // holster released cancelHold(); // el çekildi, zamanlayıcı iptal if (!duelStarted && playerReady && duelState === STATE_WAIT) { earlyLose(); return; } if (duelState === STATE_DRAW && canShoot) { playerFire(x, y); return; } }; // Move reticle with finger (optional: drag to aim) game.move = function (x, y, obj) { if (duelState === STATE_RESULT) return; // Holster hold/early leave logic if (zoomFinished && !duelStarted) { if (holsterContains(x, y)) { // handled in update for dt-accurate timing } else if (holdingHolster) { cancelHold(); earlyLose(); } } // (aim reticle removed) // Namlu her zaman fareyi izlesin (DRAW’tan önce holster tutulurken de) pointGunAt(x, y); }; /**** GLOBAL YARDIMCI : Silahı imlece çevir ****/ function pointGunAt(globalX, globalY) { if (duelState === STATE_RESULT) return; // 1) Omuz pivotu – dünya koordinatı var shX = player.x + player.rarm.x; var shY = player.y + player.rarm.y; // 2) Omuz → imleç vektörü ve açı (0 rad = sağ) var dx = globalX - shX; var dy = globalY - shY; var ang = Math.atan2(dy, dx); // 3) Kol sprite’ı AŞAĞI bakıyor → –90° (-π/2) düzelt var armRot = ang - Math.PI / 2; player.rarm.rotation = armRot; // 4) El / silah konumu (player LOCAL) var L = player.rarm.height; // ≈110 px // ❗️ Doğru ofset: (-sin, +cos) player.gun.x = player.rarm.x - Math.sin(armRot) * L + 5; // +5px x-offset player.gun.y = player.rarm.y + Math.cos(armRot) * L + 3; // +3px y-offset // 5) Silah namlu yönü if (!duelStarted && holsterContains(globalX, globalY)) { player.gun.rotation = Math.PI / 2; // kılıfta ⇒ namlu yere } else { player.gun.rotation = ang; // hedefe bak } } /**** GLOBAL : Enemy silahını hedefe çevir ****/ function aimEnemyGunAt(globalX, globalY) { if (duelState === STATE_RESULT) return; // 1) Omuz pivotu (world) var shX = enemy.x + enemy.rarm.x; var shY = enemy.y + enemy.rarm.y; // 2) Omuz→hedef vektörü var dx = globalX - shX; var dy = globalY - shY; var ang = Math.atan2(dy, dx); // 3) Kol sprite’ı AŞAĞI bakıyor → –90° (–π/2) düzeltme var armRot = ang - Math.PI / 2; enemy.rarm.rotation = armRot; // 4) El / silah konumu (enemy LOCAL) **ayna!** var L = enemy.rarm.height; // ≈145 px enemy.gun.x = enemy.rarm.x - Math.sin(armRot) * L + 4; // +4px x-offset enemy.gun.y = enemy.rarm.y + Math.cos(armRot) * L + 2; // +2px y-offset // 5) Namluyu hedefe döndür enemy.gun.rotation = ang; } // Helper to update holster box position under player's feet function updateHolsterBox() { holsterFull.x = player.x - 200; holsterFull.y = player.y + player.body.height / 2 + holsterOffset; holsterEmpty.x = holsterFull.x; holsterEmpty.y = holsterFull.y; } // Main update loop game.update = function (dt) { if (duelState === STATE_RESULT) { // Optionally, statusTxt can still be shown statusTxt.visible = true; return; } // Move enemygun assets in pocket 5px down and 10px left when music is not stopped if (LK.musicPlaying && enemygunpocket) { enemygunpocket.x = 2048 / 2 + 550 + 50 - 30 - 5 - 5 - 10; // 10px more left enemygunpocket.y = 2732 / 2 - 600 + 150 + 10 + 5; // 5px more down } // Hide status text during zoom-in if (!zoomFinished) { statusTxt.visible = false; return; } // Always update holster position to follow player updateHolsterBox(); // (aim reticle removed) // Rakip silahı eldeyse oyuncuyu takip etsin if (enemy.gun.visible) { aimEnemyGunAt(player.x, player.y - 40); } // Animate bullets if (playerBullet) { playerBullet.update(); } if (enemyBullet) { enemyBullet.update(); } // === PLAYER SHOT COOLDOWN TIMER === if (playerShotCooldown > 0) { var dtMs = typeof dt === "number" ? dt : 16.7; playerShotCooldown -= dtMs; if (playerShotCooldown < 0) { playerShotCooldown = 0; } } // Check for bullet collisions checkBullets(); // ==== FIX #3 : statusTxt ayarı ==== // Holster hold logic after zoom if (zoomFinished && !duelStarted) { // Use pointerX/Y for current pointer var px = typeof game.pointerX === "number" ? game.pointerX : 0; var py = typeof game.pointerY === "number" ? game.pointerY : 0; var dtMs = typeof dt === "number" ? dt : 16.7; if (holsterContains(px, py) && holdingHolster) { holsterHoldTime += dtMs; } else { if (holsterHoldTime > 0 && holdingHolster) { earlyLose(); } holsterHoldTime = 0; } if (!duelStarted) { // Sadece roundNum 1–3 arası ipuçlarını göster if (roundNum <= 3) { if (!playerReady) { statusTxt.setText("Hold holster to start duel"); } else { statusTxt.setText("Wait for music to end…\nthen aim & release"); } statusTxt.visible = true; } else { // 4. raund ve sonrası için hiç göstermeme statusTxt.visible = false; } } // if (holsterHoldTime >= 4000 && !duelStarted) { // duelStarted = true; // holsterHoldTime = 0; // resetDuel(); // } } else { if (duelState === STATE_DRAW) { if (roundNum <= 3) { statusTxt.setText("Aim and SHOOT!"); statusTxt.visible = true; } else { statusTxt.visible = false; } } else { statusTxt.visible = true; } } }; // Early lose function function earlyLose() { if (duelState === STATE_RESULT) { return; } // only trigger once holdingHolster = false; holsterHoldTime = 0; duelStarted = false; LK.stopMusic(); if (drawTimeout) { LK.clearTimeout(drawTimeout); } statusTxt.setText("Too early!\nYou lose!"); statusTxt.visible = true; LK.getSound('gunshot').play(); // yere ateş LK.getSound('fail').play(); // Optionally, also play gunshot sound: // LK.getSound('gunshot').play(); // Show game over after 1 second LK.setTimeout(function () { LK.showGameOver(); }, 1000); } // Camera zoom-in before duel starts function startZoomIn(music) { // ==== FIX #1b : zoom fonksiyonunda ==== var startScale = 0.4; world.scaleX = world.scaleY = startScale; world.x = centerX * (1 - startScale); world.y = 2732 / 2 * (1 - startScale); LK.playMusic(music || 'duelmusic'); tween(world, { scaleX: 1, scaleY: 1, x: 0, y: 0 }, { duration: 4000, easing: tween.quadInOut, onFinish: function onFinish() { zoomFinished = true; } }); } // Start zoom-in and music immediately on boot startZoomIn();
===================================================================
--- original.js
+++ change.js
@@ -3,8 +3,58 @@
****/
var tween = LK.import("@upit/tween.v1");
/****
+* Classes
+****/
+// Minimal Player class definition to fix 'Player is not defined'
+var Player = Container.expand(function () {
+ var self = Container.call(this);
+ // Add a simple body part for demonstration
+ self.body = LK.getAsset('playerBody', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.addChild(self.body);
+ // Add a right arm for aiming
+ self.rarm = LK.getAsset('playerArm', {
+ anchorX: 0.5,
+ anchorY: 0.1
+ });
+ self.rarm.x = 0;
+ self.rarm.y = self.body.height * 0.1;
+ self.addChild(self.rarm);
+ // Add a gun
+ self.gun = LK.getAsset('playerGun', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.gun.x = 0;
+ self.gun.y = self.body.height * 0.3;
+ self.addChild(self.gun);
+ // Reset pose
+ self.resetPose = function () {
+ self.rarm.rotation = 0;
+ self.gun.rotation = Math.PI / 2;
+ };
+ // Move gun to holster
+ self.toHolster = function () {
+ self.gun.visible = true;
+ self.gun.rotation = Math.PI / 2;
+ };
+ // Move gun to hand
+ self.toHand = function () {
+ self.gun.visible = true;
+ self.gun.rotation = 0;
+ };
+ // Ragdoll animation (placeholder)
+ self.ragdoll = function () {
+ self.gun.visible = false;
+ };
+ return self;
+});
+
+/****
* Initialize Game
****/
// Helper: getChildIndex and addChildAt for Container (PIXI compatibility)
var game = new LK.Game({