User prompt
1. Gun pivot’unu doğru yere kaydırmak Şu anda silahın anchorX/Y’si 0.5,0.5 (ortada). Bunu, “tetiğin” tam gövdeye yakın ucuna sabitlemeliyiz. Örneğin: js Kopyala Düzenle // Player sınıfında: var gun = self.attachAsset('playerGun', { anchorX: 0.2, // tavsiye edilen değer (tetiğe yakın tarafa kaydır) anchorY: 0.8, // tüfeğin namlu ucundan değil, sapına yakın olsun x: rarm.x, y: rarm.y, rotation: 0 }); Benzer şekilde Enemy sınıfında da: js Kopyala Düzenle var gun = self.attachAsset('enemyGun', { anchorX: 0.2, anchorY: 0.8, x: rarm.x, y: rarm.y, rotation: 0 }); Bu değişiklikten sonra gun.x ve gun.y zaten kol pivot’nuz (rarm.x, rarm.y) ile eşleşiyor; dolayısıyla silah sapı doğrudan elin ortasına yerleşmiş oluyor. 2. Offset’leri ufak tweaks ile ince ayarlamak Pivot’u taşıdığımızda görsel olarak hâlâ biraz kayma olabilir. Bu durumda x ve y başlangıç değerlerinize birkaç piksel ekleyip çıkararak elin tam ucuna denk getirebilirsiniz: js Kopyala Düzenle // Player: var gun = self.attachAsset('playerGun', { anchorX: 0.2, anchorY: 0.8, x: rarm.x + 5, // 5px sağa kaydır y: rarm.y + 3, // 3px alta kaydır rotation: 0 }); // Enemy: var gun = self.attachAsset('enemyGun', { anchorX: 0.2, anchorY: 0.8, x: rarm.x + 4, y: rarm.y + 2, rotation: 0 }); 3. Dinamik yönlendirme fonksiyonunda da offset’i uygulamak Eğer silahı pointGunAt() içinde yeniden konumlandırıyorsanız, orada da aynı 5px/3px gibi offset’i ekleyin: js Kopyala Düzenle function pointGunAt(globalX, globalY) { // ...hesaplar... player.gun.x = player.rarm.x - Math.sin(armRot)*L + 5; // +5 piksel x-offset player.gun.y = player.rarm.y + Math.cos(armRot)*L + 3; // +3 piksel y-offset player.gun.rotation = ang; } Aynı işi aimEnemyGunAt() içinde de yapın.
User prompt
Görünüşe göre resetPose metodu, Round 1’den sonra karakterin pozlarını tam başta olduğu gibi sıfırlamıyor; özellikle kafanın Y konumu eski değerini koruyor ve her round’da giderek yukarı kayıyor. Bunu düzeltmek için resetPose’un içinde kafanın (ve diğer parçaların) başlangıç “offset” değerlerini doğrudan sabit olarak tanımlamalısın. Şöyle yapabiliriz: js Kopyala Düzenle // Player.resetPose içinde... self.resetPose = function() { // ...body reset... body.x = -12; body.y = 10; body.rotation = 0; // HEAD’i mutlaka en son değil ama doğru değerlerle resetle head.x = 0; head.y = -body.height/2 - 45; // ← burayı sabit tut head.rotation = 0; // kol, bacak, silah vb. de aynı şekilde sabit değerler almalı // ... }; js Kopyala Düzenle // Enemy.resetPose içinde... self.resetPose = function() { // ...body reset... body.x = 10; body.y = -15; body.rotation = 0; // HEAD reset head.x = 0; head.y = -body.height/2 - 45; // ← burayı sabit tut head.rotation = 0; // kollar, bacaklar, hipGun vs... // ... };
Code edit (1 edits merged)
Please save this source code
User prompt
move enemy hipgun 10 pixels left further
User prompt
move enemy hipgun location 3 pixels down further aand move it 5 pixels left further
User prompt
move enemy hipgun location 10 pixels down further and move 10 pixels left further
User prompt
move enemy hipgun location 15 pixels down further
User prompt
move enemy pocketed gun 15 pixels down further
User prompt
move enemy's pocketed gun 15 pixels down 10 pixels left
User prompt
player’s holster 20px to the left and 30px down, and moved the enemy’s pocketed gun 5px left and 10px down
User prompt
move player left arm 15 pixels down 3 pixels right
User prompt
move player arm 15 pixels down
User prompt
move player left leg 10 pixels right
User prompt
move it 6 pixels down further and move it 5 pixels left
User prompt
move it 15 pixels down further
User prompt
move it more 30 pixels
User prompt
move it 30 pixels down
User prompt
make bottomthing player a child of player then move it 20 pixels down
User prompt
move bottomthingenemy 10 pixels up
User prompt
move bottomthing enemy 20 pixels down
User prompt
move bottomthingenemy 50 pixels up
User prompt
make enemybottomthing a child of enemy
User prompt
move player left arm 7 pixels right
User prompt
move player arm behind player body
User prompt
move player legs closer each side by 6 pixels
/**** * 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.5, // 0.5 yerine 0.5 anchorY: 0.5, x: rarm.x, y: rarm.y + rarm.height, 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, y: body.height / 2 - 22, 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, gun]; 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.x = 10; body.y = -15; //{1w} // 5px daha aşağı, 10px sağa taşındı body.rotation = 0; head.x = -4 + 5 - 4; // 5px right, 4px left head.y = -body.height / 2 - 45 - 4 - 5 - 4; // 5px up, 4px up head.rotation = 0; larm.x = -body.width / 2 + 5 + 10; // 5px closer to body, 10px right larm.y = -80; //{1k} // 30px up (10px further down) larm.rotation = 0; rarm.x = body.width / 2 - 5; // 5px closer to body rarm.y = -80; //{1n} // 30px up (10px further down) rarm.rotation = 0; lleg.x = -body.width / 4 + 5 - 5 + 3; // moved 5px left, now 3px right lleg.y = body.height / 2 - 15 - 3; lleg.rotation = 0; rleg.x = body.width / 4 + 5 - 5 + 3; // moved 5px left, now 3px right rleg.y = body.height / 2 - 15 - 3; rleg.rotation = 0; gun.x = rarm.x; gun.y = rarm.y + rarm.height; gun.rotation = 0; 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 - 25 // 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: 0, y: 95 }); // Left Arm var larm = self.attachAsset('playerArm', { anchorX: 0.5, anchorY: 0, x: -body.width / 2 - 10 - 5 + 5 + 7, // move 5px right, 7px more right y: -100 + 10 + 10, // move 10px 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, // move 3px right (total 6px closer) // 10px left, 3px 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.5, // 0.5 yerine 0.5 anchorY: 0.5, x: rarm.x - 20, //{2m} // 20px left y: rarm.y + rarm.height + 5, //{2n} // 5px down 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 + 8, y: body.height / 2 - 22, 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, gun]; // 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.x = -12; body.y = 10; // moved 15px down, 5px left from previous body.rotation = 0; head.x = 0; head.y = -body.height / 2 - 45 - 25; // moved 25px up head.rotation = 0; larm.x = -body.width / 2 - 10 - 5 + 5 + 7; // move 5px right, 7px more right larm.y = -100 + 10 + 10; // move 10px down larm.rotation = 0; // Move left arm behind body in display list if (typeof self.setChildIndex === "function") { self.setChildIndex(larm, 0); } rarm.x = body.width / 2 + 10 - 5 - 20 - 5 - 10; // 10px more left rarm.y = -100 + 10 + 15 + 10; // 10px more down, 15px more down, 10px more down rarm.rotation = 0; lleg.x = -body.width / 4 - 10 + 3; // 10px left, 3px right (6px closer) lleg.y = body.height / 2 - 10 + 10; // 10px down lleg.rotation = 0; rleg.x = body.width / 4 - 10 - 3; // 10px left, 3px left (6px closer) rleg.y = body.height / 2 - 10 + 10; // 10px down rleg.rotation = 0; gun.x = rarm.x - 20; //{3b} // 20px left gun.y = rarm.y + rarm.height + 5; //{3c} // 5px down gun.rotation = 0; self.toHolster(); // always start with gun in holster }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2e1a09 }); /**** * Game Code ****/ // Player and enemy bodies (torso, head, arms, legs) as simple shapes // Game state 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 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.5 }]; 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 tween(player.gun, { rotation: -0.5 }, { duration: 80, easing: tween.cubicOut }); tween(player.rarm, { rotation: -0.3 }, { duration: 80, easing: tween.cubicOut }); 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 tween(enemy.gun, { rotation: 0.5 }, { duration: 80, easing: tween.cubicOut }); tween(enemy.rarm, { rotation: 0.3 }, { duration: 80, easing: tween.cubicOut }); 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) if (drawTimeout) { LK.clearTimeout(drawTimeout); } if (duelTimer) { LK.clearTimeout(duelTimer); } if (resultTimeout) { LK.clearTimeout(resultTimeout); } drawTimeout = null; duelTimer = null; resultTimeout = null; // 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() { // 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); } } // Both bullets exist (simultaneous fire) if (playerBullet && enemyBullet) { // Check which bullet hits first 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); if (pdist < 120 && edist < 120) { // Both hit at same time: draw LK.getSound('hit').play(); player.ragdoll(); enemy.ragdoll(); game.removeChild(playerBullet); game.removeChild(enemyBullet); playerBullet = null; enemyBullet = null; duelState = STATE_RESULT; statusTxt.setText("Draw!\nBoth shot!"); statusTxt.visible = true; endRound(false); } else 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); } else if (edist < 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() { 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) { // 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) { // 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) { // 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) { // 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; player.gun.y = player.rarm.y + Math.cos(armRot) * L; // 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) { // 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; enemy.gun.y = enemy.rarm.y + Math.cos(armRot) * L; // 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) { // 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) { if (!playerReady) { statusTxt.setText("Hold holster to start duel"); } else { statusTxt.setText("Wait for music to end…\nthen aim & release"); } } // if (holsterHoldTime >= 4000 && !duelStarted) { // duelStarted = true; // holsterHoldTime = 0; // resetDuel(); // } statusTxt.visible = true; } else { if (duelState === STATE_DRAW) { statusTxt.setText("Aim and SHOOT!"); } 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
@@ -187,14 +187,14 @@
anchorY: 0.5,
x: -12,
y: 10 //{1U} // moved 15px down, 5px left from previous
});
- // bottomthingplayer as child of player, 60px down (moved 30px further down)
+ // bottomthingplayer as child of player, 75px down (moved 15px further down)
var bottomthingplayer = self.attachAsset('bottomthingplayer', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
- y: 80
+ y: 95
});
// Left Arm
var larm = self.attachAsset('playerArm', {
anchorX: 0.5,