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.update = function () {
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
};
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;
});
// 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
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Game state
// Player and enemy bodies (torso, head, arms, legs) as simple shapes
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
@@ -1178,11 +1178,17 @@
// resetDuel();
// }
} else {
if (duelState === STATE_DRAW) {
- statusTxt.setText("Aim and SHOOT!");
+ if (roundNum <= 3) {
+ statusTxt.setText("Aim and SHOOT!");
+ statusTxt.visible = true;
+ } else {
+ statusTxt.visible = false;
+ }
+ } else {
+ statusTxt.visible = true;
}
- statusTxt.visible = true;
}
};
// Early lose function
function earlyLose() {