User prompt
make bullet trail transparency %25 opac and %75 transparent
User prompt
can you make bullet trails transparency %75 opac and %25 transparent
User prompt
Please fix the bug: 'ReferenceError: duelState is not defined' in or related to this line: 'if (duelState === STATE_RESULT) {' Line Number: 1265
User prompt
Please fix the bug: 'ReferenceError: duelState is not defined' in or related to this line: 'if (duelState === STATE_RESULT) {' Line Number: 1332
User prompt
Please fix the bug: 'ReferenceError: duelState is not defined' in or related to this line: 'if (duelState === STATE_RESULT) {' Line Number: 1265
User prompt
Please fix the bug: 'ReferenceError: duelState is not defined' in or related to this line: 'if (duelState === STATE_RESULT) {' Line Number: 1332
User prompt
Please fix the bug: 'ReferenceError: duelState is not defined' in or related to this line: 'if (duelState === STATE_RESULT) {' Line Number: 1265
User prompt
Please fix the bug: 'centerX is not defined' in or related to this line: 'world.x = centerX * (1 - startScale);' Line Number: 1384
User prompt
Please fix the bug: 'world is not defined' in or related to this line: 'world.scaleX = world.scaleY = startScale;' Line Number: 1378
User prompt
Mevcut BloodParticle’ın life-cycle’ı yanlış parent’a ekleniyor olabilir. Bunun yerine çok basit bir spawnBlood(x,y) fonksiyonu yazıp, vurma tespit edildiği anda çağır: js Kopyala Düzenle 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
daha hızlı yok olsun
User prompt
make trial even smaller if the size is 10 make it 5
User prompt
Gapsiz Bullet Trail Şu an her frame sabit sayıda partikül çıkıyor, ama aradaki mesafe büyükse boşluk kalıyor. Bunu doldurmak için son konum–şu anki konum arasında, mesafeye göre eşit aralıklarla partikül spawn et: js Kopyala Düzenle // Bullet sınıfı içinde: var Bullet = Container.expand(function(){ var self = Container.call(this); // ... attachment vs. // önce lastX/Y tanımla self.lastX = self.x; self.lastY = self.y; self.update = function(){ // hareket et var oldX = self.x, oldY = self.y; self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; // mesafeyi ölç var dx = self.x - oldX, dy = self.y - oldY; var dist = Math.sqrt(dx*dx + dy*dy); // her 4 piksel için bir partikül var steps = Math.ceil(dist / 4); for(var i = 0; i < steps; i++){ // t [0..1] var t = i/steps; var px = oldX + dx * t; var py = oldY + dy * t; var p = new Particle(); p.x = px; p.y = py; // istenen opacity/scale ayarları Particle içinde zaten var var idx = self.parent.getChildIndex ? self.parent.getChildIndex(self) : -1; if(idx>0) self.parent.addChildAt(p, idx); else self.parent.addChild(p); } // artık eski lastX,lastY'e gerek yok }; return self; });
User prompt
Make bullet trail much denser
User prompt
make bullet trail half as smaller
User prompt
Mermi izi çok daha yoğun, daha uzun ve parlak olsun
User prompt
1) Bullet Trail’ı Güçlendirmek js Kopyala Düzenle // Bullet.update() içindeki trail kısmını bu şekilde değiştir self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; // --- Daha yoğun mermi izi --- // frame başına 10–15 arasında partikül oluştur for (var i = 0; i < 10 + Math.floor(Math.random() * 6); i++) { var p = new Particle(); // bullet arkası için biraz geri ofset var back = 8 + Math.random() * 12; // yanlara da hafif yayılım var spread = (Math.random() - 0.5) * 20; p.x = this.x - this.dirX * back + this.dirY * spread * 0.2; p.y = this.y - this.dirY * back - this.dirX * spread * 0.2; // opaklığı biraz artır p.children[0].alpha = 0.3 + Math.random() * 0.2; // hızla söndür tween(p.children[0], { alpha: 0 }, { duration: 200 + Math.random() * 150, onFinish: () => p.parent && p.parent.removeChild(p) }); this.parent.addChildAt(p, this.parent.getChildIndex(this)); } }; Ve Particle sınıfında, boyutları biraz büyüt, renk tonunu soluk beyaz-bejden daha belirgin yap: js Kopyala Düzenle var Particle = Container.expand(function () { var self = Container.call(this); var size = 12 + Math.random() * 12; // büyükçe var puff = self.attachAsset('centerCircle', { width: size, height: size, color: 0xEEEEEE, // biraz daha parlak beyaz anchorX: 0.5, anchorY: 0.5 }); // fade ve yok etme tween’i Bullet.update içinde zaten yapacağız return self; }); 2) Kan Efekti (Blood Particles) Önce yeni bir BloodParticle sınıfı tanımla: js Kopyala Düzenle var BloodParticle = Container.expand(function () { var self = Container.call(this); // küçük kırmızı damlacık var size = 6 + Math.random() * 8; var drop = self.attachAsset('centerCircle', { width: size, height: size * (0.6 + Math.random() * 0.4), color: 0xCC0000, // koyu kırmızı anchorX: 0.5, anchorY: 0.5 }); drop.alpha = 0.8; // rastgele fırlatma yönü ve hızı var angle = Math.random() * Math.PI * 2; var speed = 2 + Math.random() * 3; self.vx = Math.cos(angle) * speed; self.vy = Math.sin(angle) * speed; // tween ile hızla dağıl ve kaybol tween(self, { alpha: 0 }, { duration: 400 + Math.random() * 200, onUpdate: function () { self.x += self.vx; self.y += self.vy; }, onFinish: function () { if (self.parent) self.parent.removeChild(self); } }); return self; }); Ve düşman vurulduğu yere (örneğin enemy.ragdoll(...) çağrısından hemen önce) şunu ekle: js Kopyala Düzenle // kan efektini spawn et for (var i = 0; i < 12; i++) { var b = new BloodParticle(); b.x = enemy.x; // vurulan pozisyonu istersen playerBullet.x / .y alabilirsin b.y = enemy.y; world.addChild(b); }
User prompt
// Enemy vurulduğunda: function onEnemyHit(x, y) { for (let i = 0; i < 6; i++) { let angle = Math.random() * Math.PI * 2; let speed = 2 + Math.random() * 2; spawnParticle( x, y, 0xff0000, // kırmızı kan Math.cos(angle) * speed, Math.sin(angle) * speed, 500 ); } enemy.ragdoll(); }
User prompt
Mermi izi / “bullet trail” İnce, yarı saydam beyaz veya çok soluk bej bir “smoke puff” ya da çizgi şeklinde kısa ömürlü partiküller. Merminin arkasında birkaç frame boyunca görünüp hızla kaybolacak şekilde: örneğin her Bullet.update() çağrısında, kendi pozisyonunda 3–5 tane küçük parçacık (Particle) yaratıp, alpha değerini 200 → 0 arası tween’leyebilirsin. Böylelikle mermi uçarken arkasında havayı yarıp gelen bir toz bulutu hissi yaratırsın.
User prompt
hide aim & shoot in 4+ rounds
User prompt
statusTxt’in o “ipucu” metinlerini sadece 1–3. raundlarda göstermek ve 4. raundtan itibaren gizlemek için game.update() içindeki hint-blokuna bir koşul ekleyebilirsin. Örneğin: js Kopyala Düzenle game.update = function(dt) { // ...önceki kod... // Zoom bitti ama düello başlamadıysa (hint logic) if ( zoomFinished && !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; } return; // Update’in geri kalanına girme } // DRAW fazındayken “Aim and SHOOT!” if ( duelState === STATE_DRAW ) { statusTxt.setText("Aim and SHOOT!"); statusTxt.visible = true; } // ...kalan update kodu... };
User prompt
Bunu çözmenin en basit yolu, hem player hem enemy aynı anda vurulduğunda “Draw” logic’ini tamamen kaldırıp, önce player’ın vurulup vurulmadığını kontrol etmek ve eğer vurulduysa her hâlükârda kaybetmesini sağlamak. Yani checkBullets() içinde: js Kopyala Düzenle function checkBullets() { // ... önceki kod ... // 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; } } // ... kalan standart tek bullet çarpma kontrolleri ... } Ne değişti? Aynı anda iki mermi de vurduğunda artık önce edist (player’a gelen) kontrol ediliyor ve player ölüyorsa hemen endRound(false) çağrılıyor. Player öldüyse düşman ne kadar da ölse “You Lose” sonuçlanıyor. Eski “draw” şartı tamamen ortadan kalkıyor. Bu şekilde “iki kişi de ölse” mantığına gitmeden, oyuncu vurulduğunda kesin kaybeden o oluyor.
User prompt
The background color of the game is a dark brown shade, specifically set to the hexadecimal color code `#2e1a09` make this color black
User prompt
round 5 boss scale 1.5 ten 1.3 e al
Code edit (1 edits merged)
Please save this source code
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bullet = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0; self.dirX = 0; self.dirY = 0; self.lastX = typeof self.x === "number" ? self.x : 0; self.lastY = typeof self.y === "number" ? self.y : 0; self.update = function () { var oldX = self.x, oldY = self.y; self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; // Gapless bullet trail: spawn particles along the path if (self.parent) { var dx = self.x - oldX, dy = self.y - oldY; var dist = Math.sqrt(dx * dx + dy * dy); var steps = Math.ceil(dist / 4); for (var i = 0; i < steps; i++) { var t = i / steps; var px = oldX + dx * t; var py = oldY + dy * t; var p = new Particle(); p.x = px; p.y = py; var idx = self.parent.getChildIndex ? self.parent.getChildIndex(self) : -1; if (idx > 0) self.parent.addChildAt(p, idx);else self.parent.addChild(p); } } }; return self; }); // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); // Attach enemybottomthing as a child of enemy var enemybottomthing = self.attachAsset('bottomthingenemy', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 80 // moved 10px up from previous (90 -> 80) }); // Legs var lleg = self.attachAsset('enemyLeg', { anchorX: 0.5, anchorY: 0, x: -140 / 4 + 5 - 5, // moved 5px left // use width of enemyBody (140) since body not yet defined y: 180 / 2 - 15 - 3 // use height of enemyBody (180) }); var rleg = self.attachAsset('enemyLeg', { anchorX: 0.5, anchorY: 0, x: 140 / 4 + 5 - 5, // moved 5px left y: 180 / 2 - 15 - 3 }); // Left Arm var larm = self.attachAsset('enemyArm', { anchorX: 0.5, anchorY: 0, x: -140 / 2 + 5 + 10, // use width of enemyBody (140) since body not yet defined // 10px right // 5px closer to body, 10px right y: -80 //{t} // 30px up (10px further down) }); // Body var body = self.attachAsset('enemyBody', { anchorX: 0.5, anchorY: 0.5, x: 10, y: -15 //{h} // 5px daha aşağı, 10px sağa taşındı }); // Head var head = self.attachAsset('enemyHead', { anchorX: 0.5, anchorY: 0.5, x: -4 + 5 - 4, // 4px left from previous // 5px right, 4px left y: -body.height / 2 - 45 - 4 - 5 - 4 // 4px up from previous }); // Right Arm (gun hand) var rarm = self.attachAsset('enemyArm', { anchorX: 0.5, anchorY: 0, x: body.width / 2 - 5, // 5px closer to body y: -80 //{z} // 30px up (10px further down) }); // Legs var lleg = self.attachAsset('enemyLeg', { anchorX: 0.5, anchorY: 0, x: -body.width / 4 + 5 - 5 + 3, // moved 5px left, now 3px right y: body.height / 2 - 15 - 3 //{z} // 3px up }); var rleg = self.attachAsset('enemyLeg', { anchorX: 0.5, anchorY: 0, x: body.width / 4 + 5 - 5 + 3, // moved 5px left, now 3px right y: body.height / 2 - 15 - 3 //{E} // 3px up }); // Gun (in hand) var gun = self.attachAsset('enemyGun', { anchorX: 0.2, // tetiğe yakın pivot anchorY: -0.4, // sapına yakın pivot x: rarm.x + 15, // 4px sağa kaydır y: rarm.y + 15, // 2px alta kaydır rotation: 0 }); // Holster gun (on hip, always visible unless drawn) var hipGun = self.attachAsset('enemyGun', { anchorX: 0.5, anchorY: 0.5, x: body.width / 2 + 8 - 10 - 5 - 10, // 5px further left // 10px further left, 5px more left, 10px more left y: body.height / 2 - 22 + 15 + 10 + 3, // 3px further down // 10px further down, 3px more down rotation: Math.PI / 2 }); // Start with gun in holster, hand empty gun.visible = false; hipGun.visible = true; // Helper methods to switch gun/holster visibility self.toHolster = function () { hipGun.visible = true; gun.visible = false; }; self.toHand = function () { hipGun.visible = false; gun.visible = true; }; self.bodyParts = [body, head, larm, rarm, lleg, rleg]; self.gun = gun; self.rarm = rarm; self.head = head; self.body = body; self.ragdoll = function (hitX, hitY) { for (var i = 0; i < self.bodyParts.length; i++) { var part = self.bodyParts[i]; tween(part, { rotation: (Math.random() - 0.5) * 2.5, x: part.x + (Math.random() - 0.5) * 200, y: part.y + (Math.random() - 0.5) * 200 }, { duration: 600, delay: i * 30, easing: tween.elasticOut }); } }; self.resetPose = function () { // Body body.x = 10; body.y = -15; body.rotation = 0; // Head (use constant offset, not accumulated) head.x = 0; head.y = -body.height / 2 - 45; // SABİT offset, yukarı kayma engellendi head.rotation = 0; // Left Arm larm.x = -body.width / 2 + 5 + 10; larm.y = -80; larm.rotation = 0; // Right Arm rarm.x = body.width / 2 - 5; rarm.y = -80; rarm.rotation = 0; // Left Leg lleg.x = -body.width / 4 + 5 - 5 + 3; lleg.y = body.height / 2 - 15 - 3; lleg.rotation = 0; // Right Leg rleg.x = body.width / 4 + 5 - 5 + 3; rleg.y = body.height / 2 - 15 - 3; rleg.rotation = 0; // Gun (in hand) gun.x = rarm.x + 4; // 4px sağa kaydır gun.y = rarm.y + 2; // 2px alta kaydır gun.rotation = 0; // Hip gun (holster) if (typeof hipGun !== "undefined") { hipGun.x = body.width / 2 + 8 - 10 - 5 - 10; hipGun.y = body.height / 2 - 22 + 15 + 10 + 3; hipGun.rotation = Math.PI / 2; } self.toHolster(); // always start with gun in holster }; return self; }); // Particle class for bullet trail var Particle = Container.expand(function () { var self = Container.call(this); // Use an even smaller, still bright ellipse for smoke puff/trail (size ~5) var size = 5 + Math.random() * 5; // much smaller than before var color = 0xFFFFFF; // pure white for max brightness // Alternate between 75% and 25% opacity for striped effect if (typeof Particle._stripeToggle === "undefined") Particle._stripeToggle = 0; Particle._stripeToggle = 1 - Particle._stripeToggle; var alpha = Particle._stripeToggle ? 0.75 : 0.25; var puff = self.attachAsset('centerCircle', { width: size, height: size * (0.8 + Math.random() * 0.5), color: color, anchorX: 0.5, anchorY: 0.5 }); puff.alpha = alpha; // Fade out and destroy after a much shorter time for even faster trail disappearance tween(puff, { alpha: 0 }, { duration: 70 + Math.random() * 40, onFinish: function onFinish() { if (self.parent) self.parent.removeChild(self); } }); return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); // Head var head = self.attachAsset('playerHead', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -160 / 2 - 45 - 20 // use playerBody height (160) since body not yet defined, moved 25px up }); // Body var body = self.attachAsset('playerBody', { anchorX: 0.5, anchorY: 0.5, x: -12, y: 10 //{1U} // moved 15px down, 5px left from previous }); // bottomthingplayer as child of player, 75px down (moved 15px further down) var bottomthingplayer = self.attachAsset('bottomthingplayer', { anchorX: 0.5, anchorY: 0.5, x: -5, //{21} // moved 5px left y: 101 // moved 6px further down (95+6) }); // Left Arm var larm = self.attachAsset('playerArm', { anchorX: 0.5, anchorY: 0, x: -body.width / 2 - 10 - 5 + 5 + 7 + 3, // move 3px right // move 5px right, 7px more right, 3px more right y: -100 + 10 + 10 + 15, // move 15px down // move 10px down, 15px more down zIndex: -1 // ensure arm is behind body (if zIndex is supported) }); // Move left arm behind body in display list if (typeof self.setChildIndex === "function") { self.setChildIndex(larm, 0); } // Right Arm (gun hand) var rarm = self.attachAsset('playerArm', { anchorX: 0.5, anchorY: 0, x: body.width / 2 + 10 - 5 - 20 - 5 - 10, // 10px more left y: -100 + 10 + 15 + 10 //{1Y} // 10px more down, 15px more down, 10px more down }); // Legs var lleg = self.attachAsset('playerLeg', { anchorX: 0.5, anchorY: 0, x: -body.width / 4 - 10 + 3 + 10, // moved 10px right // move 3px right (total 6px closer) // 10px left, 3px right, 10px right y: body.height / 2 - 10 + 10 // 10px down }); var rleg = self.attachAsset('playerLeg', { anchorX: 0.5, anchorY: 0, x: body.width / 4 - 10 - 3, // move 3px left (total 6px closer) // 10px left, 3px left y: body.height / 2 - 10 + 10 // 10px down }); // Gun (in hand) var gun = self.attachAsset('playerGun', { anchorX: 0.3, // tetiğe yakın pivot anchorY: 1.2, // sapına yakın pivot x: rarm.x + 5, // 5px sağa kaydır y: rarm.y + 3, // 3px alta kaydır rotation: 0 }); // Holster gun (on hip, always visible unless drawn) var hipGun = self.attachAsset('playerGun', { anchorX: 0.5, anchorY: 0.5, x: body.width / 2 + -28, y: body.height / 2 - -12, rotation: Math.PI / 2 }); // Start with gun in holster, hand empty gun.visible = false; hipGun.visible = true; // Helper methods to switch gun/holster visibility self.toHolster = function () { hipGun.visible = true; gun.visible = false; }; self.toHand = function () { hipGun.visible = false; gun.visible = true; }; // Used for ragdoll effect self.bodyParts = [body, head, larm, rarm, lleg, rleg]; // Used for aiming self.gun = gun; self.rarm = rarm; // Used for hit detection self.head = head; self.body = body; // Used for ragdoll self.ragdoll = function (hitX, hitY) { // Animate all parts to random positions/rotations for (var i = 0; i < self.bodyParts.length; i++) { var part = self.bodyParts[i]; tween(part, { rotation: (Math.random() - 0.5) * 2.5, x: part.x + (Math.random() - 0.5) * 200, y: part.y + (Math.random() - 0.5) * 200 }, { duration: 600, delay: i * 30, easing: tween.elasticOut }); } }; // Reset pose self.resetPose = function () { // Body body.x = -12; body.y = 10; body.rotation = 0; // Head (use constant offset, not accumulated) head.x = 0; head.y = -body.height / 2 - 45; // SABİT offset, yukarı kayma engellendi head.rotation = 0; // Left Arm larm.x = -body.width / 2 - 10 - 5 + 5 + 7 + 3; larm.y = -100 + 10 + 10 + 15; larm.rotation = 0; // Move left arm behind body in display list if (typeof self.setChildIndex === "function") { self.setChildIndex(larm, 0); } // Right Arm rarm.x = body.width / 2 + 10 - 5 - 20 - 5 - 10; rarm.y = -100 + 10 + 15 + 10; rarm.rotation = 0; // Left Leg lleg.x = -body.width / 4 - 10 + 3 + 10; lleg.y = body.height / 2 - 10 + 10; lleg.rotation = 0; // Right Leg rleg.x = body.width / 4 - 10 - 3; rleg.y = body.height / 2 - 10 + 10; rleg.rotation = 0; // Gun (in hand) gun.x = rarm.x + 5; // 5px sağa kaydır gun.y = rarm.y + 3; // 3px alta kaydır gun.rotation = 0; // Move bottomthingplayer 6px further down and 5px left if (typeof bottomthingplayer !== "undefined") { bottomthingplayer.x = -5; bottomthingplayer.y = 101; } self.toHolster(); // always start with gun in holster }; return self; }); /**** * Initialize Game ****/ // Helper: getChildIndex and addChildAt for Container (PIXI compatibility) var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Helper: getChildIndex and addChildAt for Container (PIXI compatibility) // Player and enemy bodies (torso, head, arms, legs) as simple shapes // Game state 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; } } // Player bullet hits enemy if (playerBullet) { // Check if bullet reached enemy var dx = playerBullet.x - enemy.x; var dy = playerBullet.y - enemy.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 120) { // Hit! 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); } } // Enemy bullet hits player if (enemyBullet) { var dx = enemyBullet.x - player.x; var dy = enemyBullet.y - player.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 120) { 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); } } // 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
@@ -217,9 +217,12 @@
var self = Container.call(this);
// Use an even smaller, still bright ellipse for smoke puff/trail (size ~5)
var size = 5 + Math.random() * 5; // much smaller than before
var color = 0xFFFFFF; // pure white for max brightness
- var alpha = 0.35 + Math.random() * 0.15; // more opaque
+ // Alternate between 75% and 25% opacity for striped effect
+ if (typeof Particle._stripeToggle === "undefined") Particle._stripeToggle = 0;
+ Particle._stripeToggle = 1 - Particle._stripeToggle;
+ var alpha = Particle._stripeToggle ? 0.75 : 0.25;
var puff = self.attachAsset('centerCircle', {
width: size,
height: size * (0.8 + Math.random() * 0.5),
color: color,
@@ -415,45 +418,32 @@
/****
* Game Code
****/
-/****
-* Game Code
-// (Removed duplicate duelState and state constants)
-// Blood effect: spawn blood drops at (x, y) in parentContainer
-function spawnBlood(x, y, parentContainer) {
- for (var i = 0; i < 20; i++) {
- var drop = new Container();
- // Randomized red ellipse
- 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;
- // Random velocity
- 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;
- // Animate: fly out and fade
- 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);
- }
+// Helper: getChildIndex and addChildAt for Container (PIXI compatibility)
+// Player and enemy bodies (torso, head, arms, legs) as simple shapes
+// Game state
+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;
+ };
}
-// ==== FIX #2 : holster konumu ====
+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;
@@ -487,63 +477,40 @@
// === 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: "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: "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: "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: "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
+ name: "The Undertaker",
+ minReact: 0.6,
+ maxReact: 0.8,
+ coneStart: 18,
+ coneEnd: 0,
+ scale: 1.3
}];
var currentEnemy = null;
-// 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);
- }
- };
-}
// ==== FIX #1 : SAHNENİN BAŞINDA ====
var world = new Container();
game.addChild(world);
// Add arkaplan background image centered in the screen
@@ -949,10 +916,8 @@
var edy = enemyBullet.y - player.y;
var edist = Math.sqrt(edx * edx + edy * edy);
// 1) Önce oyuncuya gelen mermiyi kontrol et:
if (edist < 120) {
- // Blood effect at player position
- spawnBlood(player.x, player.y, world);
// Player vurulmuş, her durumda kaybeder
LK.getSound('hit').play();
player.ragdoll(enemyBullet.x, enemyBullet.y);
game.removeChild(enemyBullet);
@@ -964,10 +929,8 @@
return;
}
// 2) Sonra düşmana geleni:
if (pdist < 120) {
- // Blood effect at enemy position
- spawnBlood(enemy.x, enemy.y, world);
LK.getSound('hit').play();
enemy.ragdoll(playerBullet.x, playerBullet.y);
game.removeChild(playerBullet);
playerBullet = null;
@@ -984,10 +947,8 @@
var dx = playerBullet.x - enemy.x;
var dy = playerBullet.y - enemy.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 120) {
- // Blood effect at enemy position
- spawnBlood(enemy.x, enemy.y, world);
// Hit!
LK.getSound('hit').play();
enemy.ragdoll(playerBullet.x, playerBullet.y);
game.removeChild(playerBullet);
@@ -1003,10 +964,8 @@
var dx = enemyBullet.x - player.x;
var dy = enemyBullet.y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 120) {
- // Blood effect at player position
- spawnBlood(player.x, player.y, world);
LK.getSound('hit').play();
player.ragdoll(enemyBullet.x, enemyBullet.y);
game.removeChild(enemyBullet);
enemyBullet = null;
@@ -1329,15 +1288,8 @@
}
// Camera zoom-in before duel starts
function startZoomIn(music) {
// ==== FIX #1b : zoom fonksiyonunda ====
- // Ensure world is defined before using
- if (typeof world === "undefined") {
- world = new Container();
- game.addChild(world);
- }
- // Define centerX if not already defined
- var centerX = typeof window !== "undefined" && window.centerX !== undefined ? window.centerX : 2048 / 2;
var startScale = 0.4;
world.scaleX = world.scaleY = startScale;
world.x = centerX * (1 - startScale);
world.y = 2732 / 2 * (1 - startScale);