User prompt
Gain 10 buton yukarı kaydır, gain arrow birazcık aşağıya kaydır. Gain 10 para 2 olduğunda çıksın 10 olduğunda kaybolsun.
User prompt
Sadece Gain 10 butonu biraz yukarı kaydır.
User prompt
Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 butonu Ok işaretini kaydırmadan, baya yukarı kaydır.
User prompt
Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 oku biraz aşağıya kaydır. Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 oku biraz aşağıya kaydır. Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 oku biraz aşağıya kaydır. Gain 10 butonu baya yukarı kaydır.
User prompt
Gain 10 butonunu yukarı kaydır
User prompt
Gain arrow çok hafif yukarı kaydıralım, Hafif sola kaydıralım
User prompt
Gain arrow çok hafif yukarı kaydıralım,
User prompt
Gain arrow çok hafif yukarı kaydıralım,
User prompt
Gain arrow hafif yukarı kaydıralım,
User prompt
Gain arrow hafif yukarı kaydıralım,
User prompt
Gain arrow hafif yukarı kaydıralım,
User prompt
Gain 10 oku biraz aşağı biraz sağa kaydır, gain infoyu yukarıya kaydır
User prompt
Gain info yukarı kaydır, gain oku da biraz sağa kaydır.
User prompt
Gain 10 oku biraz aşağı biraz sağa kaydır, gain infoyu yukarıya kaydır
User prompt
Gain 10 onu birazcık aşağıya kaydır, bir de birazcık sağa kaydır
User prompt
Gain 10 okunu biraz daha yukarıya alalım ve sağa kaydıralım
User prompt
İnfo butonunu income yazısının altına kaydır. Gain 10 okunu da dollars yazan yazınım hizasına ve sağına kaydır.
User prompt
Gain 10 okunu yukarı ve sağa kaydır. Gain 10 butonunu da income yazısının altına biraz sağa kaydır
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Audience = Container.expand(function () { var self = Container.call(this); // Select audience asset randomly without repetition var audienceAssets = ['audience1', 'audience2', 'audience3', 'audience4', 'audience5', 'audience6', 'audience7', 'audience8', 'audience9', 'audience10', 'audience11', 'audience12', 'audience13', 'audience14', 'audience15', 'audience16', 'audience17', 'audience18', 'audience19', 'audience20']; var selectedAsset; // If all assets have been used, refill the available pool if (availableAudienceAssets.length === 0) { for (var i = 1; i <= 20; i++) { availableAudienceAssets.push(i); } } // Pick a random index from available assets var randomIndex = Math.floor(Math.random() * availableAudienceAssets.length); var assetNumber = availableAudienceAssets[randomIndex]; // Remove the used asset from available pool availableAudienceAssets.splice(randomIndex, 1); // Select the asset selectedAsset = 'audience' + assetNumber; audienceCounter++; // Increment counter for next audience self.audienceGraphics = self.attachAsset(selectedAsset, { anchorX: 0.5, anchorY: 0.5 }); self.instrument = null; self.multiplier = 1.2; self.update = function () { // Check if this is a clap tick - use dynamic audienceBPM var ticksPerClap = Math.floor(3600 / (window.audienceBPM || 30)); if (LK.ticks % ticksPerClap === 0) { // Single clap animation only tween(self, { scaleX: 1.03, scaleY: 1.03 }, { duration: 100, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); } }; self.setInstrument = function (type) { if (self.instrument) { self.instrument.destroy(); } self.instrument = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5, x: 30, y: 0 }); }; return self; }); var AutoCymbalstick = Container.expand(function () { var self = Container.call(this); var stickGraphics = self.attachAsset('autocymbalstick', { anchorX: 0.5, anchorY: 0.9 }); self.speed = 60; // 60 BPM (Cymbal Beats per Minute) - synchronized with drum self.income = 100; // 100 gold per hit self.animating = false; self.tickCounter = 0; self.cymbalReference = null; self.update = function () { self.tickCounter++; // Hit based on dynamic BPM var ticksPerHit = Math.floor(3600 / (window.cymbalBPM || 30)); if (self.tickCounter >= ticksPerHit && !self.animating) { self.tickCounter = 0; self.animate(); } }; self.animate = function () { if (self.animating) return; self.animating = true; tween(stickGraphics, { rotation: 0.3 }, { duration: 300, onFinish: function onFinish() { // Generate gold when hitting var startGold = gold; gold += self.income; // Instant gold update displayedGold = gold; // Play cymbal sound if not muted if (!window.cymbalBPMMuted && !window.globalMuted) { LK.getSound('cymbalhit').play(); } // Visual feedback on cymbal if reference exists if (self.cymbalReference) { var cymbalGraphics = self.cymbalReference.children[0]; tween(cymbalGraphics, { scaleX: 1.1, scaleY: 1.1 }, { duration: 50, onFinish: function onFinish() { tween(cymbalGraphics, { scaleX: 1, scaleY: 1 }, { duration: 50 }); } }); } tween(stickGraphics, { rotation: 0 }, { duration: 200, onFinish: function onFinish() { self.animating = false; } }); } }); }; return self; }); var AutoDrumstick = Container.expand(function () { var self = Container.call(this); var stickGraphics = self.attachAsset('autodrumstick', { anchorX: 0.5, anchorY: 0.9 }); self.speed = 1; self.income = 2; // Base income: 2 gold per second per drumstick self.animating = false; self.tickCounter = 0; self.drumReference = null; self.update = function () { self.tickCounter++; // Hit based on dynamic BPM var ticksPerHit = Math.floor(3600 / (window.drumBPM || 60)); if (self.tickCounter >= ticksPerHit && !self.animating) { self.tickCounter = 0; self.animate(); } }; self.animate = function () { if (self.animating) return; self.animating = true; tween(stickGraphics, { rotation: 0.3 }, { duration: 300, onFinish: function onFinish() { // Generate gold when hitting var startGold = gold; gold += self.income; // Instant gold update displayedGold = gold; // Play drum sound if not muted if (!window.drumBPMMuted && !window.globalMuted) { LK.getSound('drumhit').play(); } // Add background shake effect when hitting if (background && !window.backgroundShaking) { window.backgroundShaking = true; // Shake the background vertically with increased amount tween(background, { y: 1366 + 8 // Increased shake amount }, { duration: 40, // Reduced from 50 onFinish: function onFinish() { tween(background, { y: 1366 - 8 // Increased shake amount }, { duration: 40, // Reduced from 50 onFinish: function onFinish() { tween(background, { y: 1366 }, { duration: 40, // Reduced from 50 onFinish: function onFinish() { window.backgroundShaking = false; } }); } }); } }); } // Visual feedback on drum if reference exists if (self.drumReference) { var drumGraphics = self.drumReference.children[0]; tween(drumGraphics, { scaleX: 1.1, scaleY: 1.1 }, { duration: 50, onFinish: function onFinish() { tween(drumGraphics, { scaleX: 1, scaleY: 1 }, { duration: 50 }); } }); } tween(stickGraphics, { rotation: 0 }, { duration: 200, onFinish: function onFinish() { self.animating = false; } }); } }); }; return self; }); var AutoFinger = Container.expand(function () { var self = Container.call(this); var fingerGraphics = self.attachAsset('finger', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, rotation: -Math.PI / 2 // Rotate 90 degrees counterclockwise }); self.speed = 1; self.income = 20; // Higher income than drumstick self.animating = false; self.tickCounter = 0; self.guitarReference = null; self.update = function () { self.tickCounter++; // Click based on dynamic BPM var ticksPerHit = Math.floor(3600 / (window.guitarBPM || 10)); if (self.tickCounter >= ticksPerHit && !self.animating) { self.tickCounter = 0; self.animate(); } }; self.animate = function () { if (self.animating) return; self.animating = true; // Vertical strumming motion - move up more tween(self, { y: self.y - 80 // Increased from 50 to 80 for more upward movement }, { duration: 200, onFinish: function onFinish() { // Play guitar sound if not muted if (!window.guitarBPMMuted && !window.globalMuted) { LK.getSound('guitarhit').play(); } // Visual feedback on guitar if reference exists if (self.guitarReference) { // Call play function without player hit parameter (defaults to false) if (self.guitarReference.play) { self.guitarReference.play(); } var guitarGraphics = self.guitarReference.children[0]; tween(guitarGraphics, { rotation: 0.1 }, { duration: 50, onFinish: function onFinish() { tween(guitarGraphics, { rotation: 0 }, { duration: 50 }); } }); } // Return to original position - move down tween(self, { y: self.y + 80 // Increased from 50 to 80 to match upward movement }, { duration: 200, onFinish: function onFinish() { self.animating = false; } }); } }); }; return self; }); var BuyButton = Container.expand(function () { var self = Container.call(this); var buttonBg = self.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5 }); self.titleText = new Text2('', { size: 40, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); self.titleText.anchor.set(0.5, 0.5); self.titleText.y = -20; self.addChild(self.titleText); self.costText = new Text2('', { size: 30, fill: '#f0bf38', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); self.costText.anchor.set(0.5, 0.5); self.costText.y = 20; self.addChild(self.costText); self.countText = new Text2('', { size: 50, fill: '#f0bf38', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); self.countText.anchor.set(0.5, 0.5); self.countText.x = -150; self.countText.y = -7; // Move down by 3 pixels (from -10 to -7) self.addChild(self.countText); self.lockIcon = null; self.updateButton = function (title, cost, canAfford, count, isLocked, lockMessage) { self.titleText.setText(title); self.costText.setText('$' + cost); // Show count for items that should display count (not undefined and not zero) if (count !== undefined && count !== 0) { self.countText.setText(count.toString()); self.countText.visible = true; } else { self.countText.visible = false; } if (isLocked) { buttonBg.tint = 0x404040; self.interactive = false; // Hide button text when locked self.titleText.visible = false; self.costText.visible = false; self.countText.visible = false; if (!self.lockIcon) { self.lockIcon = self.attachAsset('lock', { anchorX: 0.5, anchorY: 0.5, x: 0, y: -10 }); } self.lockIcon.visible = true; } else { // Show button text when unlocked self.titleText.visible = true; self.costText.visible = true; if (self.lockIcon) { self.lockIcon.visible = false; } // Darken button if player cannot afford it buttonBg.tint = canAfford ? 0xFFFFFF : 0x808080; // Gray tint when can't afford self.interactive = canAfford; // Remove tint filters from text when can afford if (!canAfford) { self.titleText.tint = 0x808080; // Gray tint for title self.costText.tint = 0x808080; // Gray tint for cost self.countText.tint = 0x808080; // Gray tint for count } else { self.titleText.tint = 0xFFFFFF; // No filter for title self.costText.tint = 0xFFFFFF; // No filter for cost self.countText.tint = 0xFFFFFF; // No filter for count } } }; self.down = function () { tween(buttonBg, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, onFinish: function onFinish() { tween(buttonBg, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); }; return self; }); var Cymbal = Container.expand(function () { var self = Container.call(this); var cymbalGraphics = self.attachAsset('cymbal', { anchorX: 0.5, anchorY: 0.5 }); // Add permanent cymbal stick self.cymbalstick = self.attachAsset('playerCymbalstick', { anchorX: 0.5, anchorY: 0.9, x: 250, y: -50, rotation: -0.3 }); self.canPlay = true; self.lastPlayTime = 0; self.cymbalstickAnimating = false; self.play = function () { if (!self.canPlay || self.cymbalstickAnimating) return; var currentTime = Date.now(); var timeSinceLastPlay = currentTime - self.lastPlayTime; self.lastPlayTime = currentTime; // Check for perfect rhythm var perfectTiming = Math.abs(timeSinceLastPlay - 1000) < 100; // Calculate animation speed based on tap speed var tapSpeed = timeSinceLastPlay > 0 ? Math.min(timeSinceLastPlay, 1000) : 1000; var animationSpeed = tapSpeed / 1000; var strikeDuration = Math.max(50, 150 * animationSpeed); var returnDuration = Math.max(100, 200 * animationSpeed); // Set animation state self.cymbalstickAnimating = true; // Animate cymbal stick strike tween(self.cymbalstick, { rotation: -0.6 }, { duration: strikeDuration, easing: tween.easeOut, onFinish: function onFinish() { tween(self.cymbalstick, { rotation: -0.3 }, { duration: returnDuration, easing: tween.easeInOut, onFinish: function onFinish() { self.cymbalstickAnimating = false; } }); } }); // Visual feedback - cymbal scale tween(cymbalGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(cymbalGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Calculate reward var reward = 1; var startGold = gold; gold += reward; // Instant gold update displayedGold = gold; // Light flash effect removed // Create floating text var floatingGold = game.addChild(new FloatingText('+' + reward, perfectTiming ? 0xFFD700 : 0xFFFFFF)); floatingGold.x = self.x + (game.cameraContainer ? game.cameraContainer.x : 0); floatingGold.y = self.y - 50; // Play cymbal sound if not muted if (!window.cymbalBPMMuted && !window.globalMuted) { LK.getSound('cymbalhit').play(); } // Create music note effect if (perfectTiming) { var note = game.addChild(new MusicNote()); note.x = self.x + (Math.random() - 0.5) * 100; note.y = self.y - 100; } }; self.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; self.play(); }; return self; }); var Drum = Container.expand(function () { var self = Container.call(this); var drumGraphics = self.attachAsset('drum', { anchorX: 0.5, anchorY: 0.5 }); // Add permanent drumstick self.drumstick = self.attachAsset('playerDrumstick', { anchorX: 0.5, anchorY: 0.9, x: 210, y: -220, rotation: -0.3 }); self.canTap = true; self.lastTapTime = 0; self.drumstickAnimating = false; self.tap = function () { if (!self.canTap || self.drumstickAnimating) return; // Hide tutorial on first drum hit if (showTutorial) { hideTutorial(); } // Create money gun on first drum hit if (!hasHitDrumOnce) { hasHitDrumOnce = true; // Create money gun container if (!window.moneyGun) { window.moneyGun = game.addChild(new Container()); // Start with transparent alpha for fade-in effect window.moneyGun.alpha = 0; // Create gun asset var gun = window.moneyGun.attachAsset('moneyGun', { anchorX: 0.5, anchorY: 0.9, scaleX: 4.0, scaleY: 4.0, rotation: Math.PI + Math.PI / 4 + Math.PI / 12 + Math.PI / 36 // 180 deg + original rotation }); // Position money gun in bottom left corner - moved left and up (moved up by 60px) window.moneyGun.x = 250; window.moneyGun.y = 540; // Fade in animation tween(window.moneyGun, { alpha: 1 }, { duration: 1500, easing: tween.easeOut }); // Start shooting money window.moneyGunActive = true; // Enable money button when gun is created if (moneyButton && !moneyButton.interactive) { moneyButton.interactive = true; } // Update money button to show it's active if (moneyButtonAsset) { moneyButtonAsset.alpha = 1.0; } // Remove lock icon and shadow ONLY when gun actually starts (not after tutorial) if (window.moneyGun && musicians.length >= 20) { if (window.moneyLockIcon) window.moneyLockIcon.visible = false; if (typeof moneyShadow !== "undefined" && moneyShadow) moneyShadow.visible = false; } } } var currentTime = Date.now(); var timeSinceLastTap = currentTime - self.lastTapTime; self.lastTapTime = currentTime; // Check for perfect rhythm (60 BPM = 1000ms between beats) var perfectTiming = Math.abs(timeSinceLastTap - 1000) < 100; // Calculate animation speed based on tap speed var tapSpeed = timeSinceLastTap > 0 ? Math.min(timeSinceLastTap, 1000) : 1000; var animationSpeed = tapSpeed / 1000; // Normalize to 0-1 range var strikeDuration = Math.max(50, 150 * animationSpeed); // Faster taps = shorter animation var returnDuration = Math.max(100, 200 * animationSpeed); // Visual feedback - drum scale tween(drumGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(drumGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Set animation state self.drumstickAnimating = true; // Animate drumstick strike with dynamic duration - reversed animation tween(self.drumstick, { rotation: -0.6 }, { duration: strikeDuration, easing: tween.easeOut, onFinish: function onFinish() { tween(self.drumstick, { rotation: -0.3 }, { duration: returnDuration, easing: tween.easeInOut, onFinish: function onFinish() { self.drumstickAnimating = false; } }); } }); // Calculate reward var reward = 1; var startGold = gold; gold += reward; // Instant gold update displayedGold = gold; // Light flash effect removed // Create floating text var floatingGold = game.addChild(new FloatingText('+' + reward, perfectTiming ? 0xFFD700 : 0xFFFFFF)); floatingGold.x = self.x + (game.cameraContainer ? game.cameraContainer.x : 0); floatingGold.y = self.y - 50; // Play sound if not muted if (!window.drumBPMMuted && !window.globalMuted) { console.log('Playing drum sound - drumBPMMuted:', window.drumBPMMuted, 'globalMuted:', window.globalMuted); LK.getSound('drumhit').play(); } else { console.log('Drum sound muted - drumBPMMuted:', window.drumBPMMuted, 'globalMuted:', window.globalMuted); } // Create music note effect if (perfectTiming) { var note = game.addChild(new MusicNote()); note.x = self.x + (Math.random() - 0.5) * 100; note.y = self.y - 100; } }; self.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; self.tap(); }; return self; }); var FloatingText = Container.expand(function () { var self = Container.call(this); self.init = function (text, color) { self.textObj = new Text2(text, { size: 60, fill: '#' + color.toString(16).padStart(6, '0'), font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); self.textObj.anchor.set(0.5, 0.5); self.addChild(self.textObj); tween(self, { y: self.y - 100, alpha: 0 }, { duration: 1000, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); var Guitar = Container.expand(function () { var self = Container.call(this); var guitarGraphics = self.attachAsset('guitar', { anchorX: 0.5, anchorY: 0.5 }); self.canPlay = true; self.lastPlayTime = 0; self.play = function (isPlayerHit) { if (!self.canPlay) return; var currentTime = Date.now(); var timeSinceLastPlay = currentTime - self.lastPlayTime; self.lastPlayTime = currentTime; // Check for perfect rhythm var perfectTiming = Math.abs(timeSinceLastPlay - 1000) < 100; // Visual feedback - guitar scale tween(guitarGraphics, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(guitarGraphics, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Calculate reward - only give gold if it's a player hit var reward = isPlayerHit ? 10 : 0; if (reward > 0) { var startGold = gold; gold += reward; // Instant gold update displayedGold = gold; } // Light flash effect removed // Create floating text - only show if there's a reward if (reward > 0) { var floatingGold = game.addChild(new FloatingText('+' + reward, perfectTiming ? 0xFFD700 : 0xFFFFFF)); floatingGold.x = self.x + (game.cameraContainer ? game.cameraContainer.x : 0); floatingGold.y = self.y - 50; } // Play guitar sound if not muted if (!window.guitarBPMMuted && !window.globalMuted) { LK.getSound('guitarhit').play(); } // Create music note effect if (perfectTiming) { var note = game.addChild(new MusicNote()); note.x = self.x + (Math.random() - 0.5) * 100; note.y = self.y - 100; } }; self.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; self.play(true); //{8Q} Pass true to indicate player hit }; return self; }); var LeftConfetti = Container.expand(function () { var self = Container.call(this); self.particles = []; var colors = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1]; // Store initial position var initialX = 0; // Create confetti stick as a visible asset var stick = self.attachAsset('confettiStick', { anchorX: 0.5, anchorY: 0.9, scaleX: 2.0, scaleY: 2.0, x: 0, y: 100, // Move stick down by 100 pixels rotation: Math.PI / 4 // 45 degrees (opposite of right confetti) }); self.stick = stick; // Keep stick visible stick.visible = true; // Animate stick moving right (opposite of left movement) tween(stick, { x: 600 // Move 600 pixels to the right (opposite direction) }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { // After moving right, wait for 1 second before exploding LK.setTimeout(function () { // Play confetti sound when papers explode if (!window.globalMuted) { LK.getSound('confetti').play(); } // Add small shake effect to confetti stick tween(stick, { //{8R_shake1} x: stick.x + 15, y: stick.y - 10 }, { //{8R_shake2} duration: 50, //{8R_shake3} onFinish: function onFinish() { //{8R_shake4} tween(stick, { //{8R_shake5} x: stick.x - 30, y: stick.y + 20 }, { //{8R_shake6} duration: 50, //{8R_shake7} onFinish: function onFinish() { //{8R_shake8} tween(stick, { //{8R_shake9} x: stick.x + 15, y: stick.y - 10 }, { //{8R_shake10} duration: 50 //{8R_shake11} }); //{8R_shake12} } //{8R_shake13} }); //{8R_shake14} } //{8R_shake15} }); //{8R_shake16} // After 0.5 seconds, create confetti particles exploding from exact top of stick // Since anchor is at 0.9 and stick is rotated 45 degrees, calculate the exact tip position var stickHeight = 300; // Original height of confettiStick asset var stickScale = 2.0; // Calculate the length from anchor to tip (90% of total height) var tipDistance = stickHeight * 0.9 * stickScale; // Apply rotation transformation (45 degrees = Math.PI/4) var stickRotation = Math.PI / 4; var stickTipX = stick.x + Math.sin(stickRotation) * tipDistance + 100; // Move 100 pixels more to the right var stickTipY = stick.y - Math.cos(stickRotation) * tipDistance; var paperAssets = ['confettiPaper1', 'confettiPaper2', 'confettiPaper3', 'confettiPaper4', 'confettiPaper5', 'confettiPaper6']; for (var i = 0; i < 50; i++) { // Use confetti paper assets var assetName = paperAssets[Math.floor(Math.random() * paperAssets.length)]; var particle = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5 + Math.random() * 0.5, // Smaller papers (was 2.5 + 1.0) scaleY: 1.5 + Math.random() * 0.5, // Smaller papers x: stickTipX, y: stickTipY }); particle.tint = colors[Math.floor(Math.random() * colors.length)]; // Explosion pattern from stick tip var angle = Math.random() * Math.PI * 2; var force = 5 + Math.random() * 15; particle.vx = Math.cos(angle) * force; particle.vy = Math.sin(angle) * force - 10; particle.gravity = 0.5; particle.rotation = Math.random() * Math.PI * 2; particle.rotationSpeed = (Math.random() - 0.5) * 0.3; self.particles.push(particle); } // After explosion (0.5 seconds), wait remaining 0.5 seconds then move back LK.setTimeout(function () { // Animate stick moving back to spawn position tween(stick, { x: initialX }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { // Make stick disappear stick.visible = false; // Don't destroy the container so papers persist } }); }, 500); // Wait 0.5 seconds after explosion // Set timer to make papers disappear after 5 seconds LK.setTimeout(function () { // Fade out all particles for (var i = 0; i < self.particles.length; i++) { var particle = self.particles[i]; tween(particle, { alpha: 0 }, { duration: 500, onFinish: function (p) { return function () { p.destroy(); }; }(particle) }); } // Clear particles array after fade out LK.setTimeout(function () { self.particles = []; }, 500); }, 5000); // Wait 5 seconds after explosion }, 500); // Wait 0.5 seconds, then explode } }); self.update = function () { for (var i = self.particles.length - 1; i >= 0; i--) { var p = self.particles[i]; p.x += p.vx; p.y += p.vy; p.vy += p.gravity; p.rotation += p.rotationSpeed; // Removed alpha reduction - papers no longer fade // Removed destruction conditions - papers persist indefinitely } }; return self; }); var MusicNote = Container.expand(function () { var self = Container.call(this); var noteGraphics = self.attachAsset('musicNote', { anchorX: 0.5, anchorY: 0.5 }); tween(self, { y: self.y - 200, alpha: 0 }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); tween(noteGraphics, { rotation: Math.PI * 2 }, { duration: 1500 }); return self; }); var Pianist = Container.expand(function () { var self = Container.call(this); var pianistGraphics = self.attachAsset('pianist', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.speed = 1; self.income = 8000; // Very high income per hit self.animating = false; self.tickCounter = 0; self.pianoReference = null; self.update = function () { self.tickCounter++; // Hit based on dynamic BPM var ticksPerHit = Math.floor(3600 / (window.pianoBPM || 10)); if (self.tickCounter >= ticksPerHit && !self.animating) { self.tickCounter = 0; self.animate(); } }; self.animate = function () { if (self.animating) return; self.animating = true; // Generate gold when hitting without animation var startGold = gold; gold += self.income; // Instant gold update displayedGold = gold; // Play piano sound if not muted if (!window.pianoBPMMuted && !window.globalMuted) { LK.getSound('pianohit').play(); } // Visual feedback on piano if reference exists if (self.pianoReference) { var pianoContainer = self.pianoReference; tween(pianoContainer, { scaleX: 2.1, scaleY: 2.1 }, { duration: 50, onFinish: function onFinish() { tween(pianoContainer, { scaleX: 2, scaleY: 2 }, { duration: 50 }); } }); } // Set animation complete immediately self.animating = false; }; return self; }); var RightConfetti = Container.expand(function () { var self = Container.call(this); self.particles = []; var colors = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1]; // Store initial position var initialX = 0; // Create confetti stick as a visible asset var stick = self.attachAsset('confettiStick', { anchorX: 0.5, anchorY: 0.9, scaleX: 2.0, scaleY: 2.0, x: 0, y: 100, // Move stick down by 100 pixels rotation: -Math.PI / 4 }); self.stick = stick; // Keep stick visible stick.visible = true; // Animate stick moving left tween(stick, { x: -600 // Move 600 pixels to the left (increased from 400) }, { duration: 1500, easing: tween.easeOut, onFinish: function onFinish() { // After moving left, wait for 1 second before exploding LK.setTimeout(function () { // Play confetti sound when papers explode if (!window.globalMuted) { LK.getSound('confetti').play(); } // Add small shake effect to confetti stick tween(stick, { //{bD_shake1} x: stick.x - 15, y: stick.y - 10 }, { //{bD_shake2} duration: 50, //{bD_shake3} onFinish: function onFinish() { //{bD_shake4} tween(stick, { //{bD_shake5} x: stick.x + 30, y: stick.y + 20 }, { //{bD_shake6} duration: 50, //{bD_shake7} onFinish: function onFinish() { //{bD_shake8} tween(stick, { //{bD_shake9} x: stick.x - 15, y: stick.y - 10 }, { //{bD_shake10} duration: 50 //{bD_shake11} }); //{bD_shake12} } //{bD_shake13} }); //{bD_shake14} } //{bD_shake15} }); //{bD_shake16} // After 0.5 seconds, create confetti particles exploding from exact top of stick // Since anchor is at 0.9 and stick is rotated -45 degrees, calculate the exact tip position var stickHeight = 300; // Original height of confettiStick asset var stickScale = 2.0; // Calculate the length from anchor to tip (90% of total height) var tipDistance = stickHeight * 0.9 * stickScale; // Apply rotation transformation (-45 degrees = -Math.PI/4) var stickRotation = -Math.PI / 4; var stickTipX = stick.x + Math.sin(stickRotation) * tipDistance - 100; // Move 100 pixels more to the left var stickTipY = stick.y - Math.cos(stickRotation) * tipDistance; var paperAssets = ['confettiPaper1', 'confettiPaper2', 'confettiPaper3', 'confettiPaper4', 'confettiPaper5', 'confettiPaper6']; for (var i = 0; i < 50; i++) { // Use confetti paper assets var assetName = paperAssets[Math.floor(Math.random() * paperAssets.length)]; var particle = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5 + Math.random() * 0.5, // Smaller papers (was 2.5 + 1.0) scaleY: 1.5 + Math.random() * 0.5, // Smaller papers x: stickTipX, y: stickTipY }); particle.tint = colors[Math.floor(Math.random() * colors.length)]; // Explosion pattern from stick tip var angle = Math.random() * Math.PI * 2; var force = 5 + Math.random() * 15; particle.vx = Math.cos(angle) * force; particle.vy = Math.sin(angle) * force - 10; particle.gravity = 0.5; particle.rotation = Math.random() * Math.PI * 2; particle.rotationSpeed = (Math.random() - 0.5) * 0.3; self.particles.push(particle); } // After explosion (0.5 seconds), wait remaining 0.5 seconds then move back LK.setTimeout(function () { // Animate stick moving back to spawn position tween(stick, { x: initialX }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { // Make stick disappear stick.visible = false; // Don't destroy the container so papers persist } }); }, 500); // Wait 0.5 seconds after explosion // Set timer to make papers disappear after 5 seconds LK.setTimeout(function () { // Fade out all particles for (var i = 0; i < self.particles.length; i++) { var particle = self.particles[i]; tween(particle, { alpha: 0 }, { duration: 500, onFinish: function (p) { return function () { p.destroy(); }; }(particle) }); } // Clear particles array after fade out LK.setTimeout(function () { self.particles = []; }, 500); }, 5000); // Wait 5 seconds after explosion }, 500); // Wait 0.5 seconds, then explode } }); self.update = function () { for (var i = self.particles.length - 1; i >= 0; i--) { var p = self.particles[i]; p.x += p.vx; p.y += p.vy; p.vy += p.gravity; p.rotation += p.rotationSpeed; // Removed alpha reduction - papers no longer fade // Removed destruction conditions - papers persist indefinitely } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // Initialize all mute states to false so sounds play by default window.drumBPMMuted = false; window.guitarBPMMuted = false; window.cymbalBPMMuted = false; window.maracasBPMMuted = false; window.pianoBPMMuted = false; window.fluteBPMMuted = false; window.audienceBPMMuted = false; // Game variables var gold = 0; var displayedGold = 0; // Track displayed gold for smooth animation var targetDisplayedGold = 0; // Target value for smooth transitions var goldPerTap = 1; var passiveIncome = 0; var drumsticks = []; var drumsticksPurchased = 0; var musicians = []; var unlockedInstruments = ['drum']; var currentVenue = 0; var currentInstrument = 'drum'; var guitarAsset = null; var cymbalAsset = null; var maracasAsset = null; var pianoAsset = null; var fluteAsset = null; var instrumentsPurchased = 0; var audienceCounter = 0; // Track which audience asset to use next var globalClapCounter = 0; // Track global clap count for double clap pattern var globalClapPhase = 0; // 0-2 = singles, 3 = double, 4-6 = singles, 7 = four times var lastClapTick = -120; // Track last clap tick to prevent multiple claps per cycle var fingers = []; // Track AutoFinger instances var fingersPurchased = 0; // Track fingers purchased var autoCymbalsticks = []; // Track AutoCymbalstick instances var pianists = []; // Track Pianist instances var pianistsPurchased = 0; // Track pianists purchased var pianistCost = 50000; // Cost for pianist var fluteblowsPurchased = 0; // Track fluteblows purchased var fluteblowCost = 750000; // Cost for fluteblow var availableAudienceAssets = []; // Track available audience assets for random selection var hasHitDrumOnce = false; // Track if drum has been hit at least once var hasReached7Audience = false; // Track if we've reached 7 audience members var nextConfettiTime = 0; // Next time to spawn confetti var activeConfettiCount = 0; // Track active confetti animations var lastInstrumentConfettiTime = 0; // Track last time confetti spawned from instrument change var infoAsset = null; // Track info asset var infoArrow = null; // Track info arrow var hasShownInfo = false; // Track if info has been shown // Upgrade costs var drumstickCost = 10; var fingerCost = 200; // Separate cost for fingers var musicianCost = 50; var guitarPurchased = false; // Track if guitar has been purchased var instrumentCosts = { guitar: 700, cymbal: 2000, maracas: 10000 }; // Initialize available audience assets (1-20) for (var i = 1; i <= 20; i++) { availableAudienceAssets.push(i); } // Function to recalculate passive income function recalculatePassiveIncome() { var newPassiveIncome = 0; newPassiveIncome += drumsticksPurchased * 2; newPassiveIncome += fingersPurchased * 20; newPassiveIncome += (typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0) * 100; newPassiveIncome += (typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0) * 300; newPassiveIncome += pianistsPurchased * 8000; newPassiveIncome += fluteblowsPurchased * 500000; // Audience income: 4 per second per audience member newPassiveIncome += 4 * musicians.length; // Only update if the new income is higher if (newPassiveIncome > passiveIncome) { passiveIncome = newPassiveIncome; } } // Function to spawn random confetti() { function spawnRandomConfetti() { // Prevent confetti if within 15s of instrument purchase if (typeof window.lastInstrumentPurchaseTime !== "undefined" && Date.now() - window.lastInstrumentPurchaseTime < 15000) return; // Check if confetti is already active if (activeConfettiCount > 0) return; var rand = Math.random(); // Calculate spawn position based on current camera position var cameraX = cameraContainer.x; var centerX = -cameraX + 1024; // Adjust for camera offset var centerY = 1200; // Consistent Y position, moved up by 100px // Find the index where pianist would be (after piano but before other elements) var confettiIndex = cameraContainer.children.length; // Find piano index to ensure confetti is added after it for (var i = 0; i < cameraContainer.children.length; i++) { if (cameraContainer.children[i] === pianoAsset) { confettiIndex = i + 1; // Add right after piano break; } } if (rand < 0.45) { // 45% chance - spawn left confetti only var leftConfetti = cameraContainer.addChildAt(new LeftConfetti(), confettiIndex); leftConfetti.x = centerX - 1650; leftConfetti.y = centerY; activeConfettiCount++; } else if (rand < 0.9) { // 45% chance - spawn right confetti only var rightConfetti = cameraContainer.addChildAt(new RightConfetti(), confettiIndex); rightConfetti.x = centerX + 1650; rightConfetti.y = centerY; activeConfettiCount++; } else { // 10% chance - spawn both confetti var leftConfetti = cameraContainer.addChildAt(new LeftConfetti(), confettiIndex); leftConfetti.x = centerX - 1650; leftConfetti.y = centerY; var rightConfetti = cameraContainer.addChildAt(new RightConfetti(), confettiIndex + 1); rightConfetti.x = centerX + 1650; rightConfetti.y = centerY; activeConfettiCount += 2; } // Set next spawn time (15-45 seconds from now) nextConfettiTime = Date.now() + 15000 + Math.random() * 30000; // Reset active confetti count after animation completes (about 3 seconds) LK.setTimeout(function () { activeConfettiCount = 0; }, 3000); } window.backgroundShaking = false; // Track background shake state // UI Elements var goldText = new Text2('Dollars: 0', { size: 80, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 3 }); goldText.anchor.set(0.5, 0); goldText.y = 50; LK.gui.top.addChild(goldText); // Move goldText to front LK.gui.top.setChildIndex(goldText, LK.gui.top.children.length - 1); // Add menu button var menuButton = new Container(); var menuBg = menuButton.attachAsset('greenbuybutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, tint: 0x18c510 }); var menuText = new Text2('MENU', { size: 45, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); menuText.anchor.set(0.5, 0.5); menuText.y = -5; // Move text down by 5 pixels from -10 menuButton.addChild(menuText); // Menu and CD buttons are only interactive when tutorial is not shown menuButton.interactive = !showTutorial; LK.gui.topRight.addChild(menuButton); menuButton.x = -140; // Moved 40 pixels to the right (from -180 to -140) menuButton.y = 98; // Moved 5 pixels down (from 93 to 98) // Track global mute state window.globalMuted = false; // Add decorative asset below menu button var menuDecoration = LK.gui.topRight.addChild(new Container()); var decorationAsset = menuDecoration.attachAsset('cd', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, alpha: 0.3 // Start more faded to show it's locked }); menuDecoration.x = -140; menuDecoration.y = 250; // Make CD initially not interactive (locked) menuDecoration.interactive = false; // Add black shadow overlay to CD button var cdShadow = menuDecoration.attachAsset('cd', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4, alpha: 0.7, tint: 0x000000, x: 0, y: 0 }); cdShadow.visible = true; // Add lock icon on CD button var cdLockIcon = menuDecoration.attachAsset('lock', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 0, y: 0 }); cdLockIcon.visible = true; // Track music playing state var isMusicPlaying = false; var cdRotationTween = null; // Ensure music is stopped on game start LK.stopMusic(); var incomeText = new Text2('Income: 0/s', { size: 65, fill: '#f0bf38', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); incomeText.anchor.set(0.5, 0); incomeText.y = 140; LK.gui.top.addChild(incomeText); // Move incomeText to front LK.gui.top.setChildIndex(incomeText, LK.gui.top.children.length - 1); // Add background directly to game (not camera container) so it stays fixed var background = game.addChild(LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 })); // Create camera container for smooth transitions var cameraContainer = game.addChild(new Container()); game.cameraContainer = cameraContainer; // Store reference for other classes var currentCameraX = 0; // Main drum var mainDrum = cameraContainer.addChild(new Drum()); mainDrum.x = 1024; mainDrum.y = 1300; // Store drum reference globally for tutorial window.mainDrum = mainDrum; // Tutorial hand - appears at game start var tutorialHand = null; var tutorialText = null; var showTutorial = true; // Track if tutorial should be shown // Create tutorial elements if (showTutorial) { // Create shadow overlay on GUI layer to ensure it's on top var tutorialShadow = LK.gui.center.addChild(new Container()); window.tutorialShadow = tutorialShadow; // Store reference globally var shadowOverlay = tutorialShadow.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 300, scaleY: 300, alpha: 0.6, x: 0, y: 0 }); shadowOverlay.tint = 0x000000; // Tutorial banner asset instead of text - add to GUI layer to ensure it's on top tutorialText = LK.gui.center.addChild(LK.getAsset('tutorialBanner', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1, x: 0, y: 434 // Moved up by 200 pixels })); // Add drum asset as button on GUI layer above shadow var tutorialDrumButton = LK.gui.center.addChild(new Container()); window.tutorialDrumButton = tutorialDrumButton; var drumButtonAsset = tutorialDrumButton.attachAsset('drum', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.682, scaleY: 0.682 }); tutorialDrumButton.x = 0; tutorialDrumButton.y = -58; // Position drum above center tutorialDrumButton.interactive = true; // Add playerDrumstick button on GUI layer above shadow var tutorialDrumstickButton = LK.gui.center.addChild(new Container()); window.tutorialDrumstickButton = tutorialDrumstickButton; var drumstickButtonAsset = tutorialDrumstickButton.attachAsset('playerDrumstick', { anchorX: 0.5, anchorY: 0.9, scaleX: 0.7, scaleY: 0.7, rotation: -0.3 }); tutorialDrumstickButton.x = 150; // Moved left from 210 tutorialDrumstickButton.y = -200; // Moved down from -250 tutorialDrumstickButton.interactive = true; // Tutorial hand pointing to drum - add to GUI layer LAST to ensure it's on top of everything tutorialHand = LK.gui.center.addChild(LK.getAsset('tutorialHand', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, x: -250, y: -410, rotation: -Math.PI / 4 - Math.PI / 2 // Point toward drum, rotated 90 degrees counterclockwise })); // Make tutorial drum button trigger main drum tap tutorialDrumButton.down = function () { if (window.mainDrum && window.mainDrum.tap) { window.mainDrum.tap(); } }; // Make tutorial drumstick button trigger main drum tap tutorialDrumstickButton.down = function () { if (window.mainDrum && window.mainDrum.tap) { window.mainDrum.tap(); } }; // Animate hand pointing motion var _animateHand = function animateHand() { if (!tutorialHand || !tutorialHand.parent) return; tween(tutorialHand, { x: -200, y: -310 }, { duration: 800, easing: tween.easeInOut, onFinish: function onFinish() { if (!tutorialHand || !tutorialHand.parent) return; tween(tutorialHand, { x: -250, y: -410 }, { duration: 800, easing: tween.easeInOut, onFinish: _animateHand }); } }); }; // Start hand animation _animateHand(); // Animate banner pulsing var _animateText = function animateText() { if (!tutorialText || !tutorialText.parent) return; tween(tutorialText, { scaleX: 0.85, scaleY: 0.85 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { if (!tutorialText || !tutorialText.parent) return; tween(tutorialText, { scaleX: 0.8, scaleY: 0.8 }, { duration: 1000, easing: tween.easeInOut, onFinish: _animateText }); } }); }; // Start banner animation _animateText(); } // Create guitar immediately but position it off-screen to the right var guitarAsset = cameraContainer.addChild(new Guitar()); guitarAsset.scaleX = 3; guitarAsset.scaleY = 3; guitarAsset.x = 3072; // Position to the right (1024 + 2048) guitarAsset.y = 1220; guitarAsset.visible = false; // Hide until purchased // Create cymbal var cymbalAsset = cameraContainer.addChild(new Cymbal()); cymbalAsset.scaleX = 2; cymbalAsset.scaleY = 2; cymbalAsset.x = 5120; // Position further right (3072 + 2048) cymbalAsset.y = 1220; cymbalAsset.visible = false; // Hide until purchased // Create maracas var maracasAsset = cameraContainer.addChild(new Container()); var maracasGraphics = maracasAsset.attachAsset('maracas', { anchorX: 0.5, anchorY: 0.5 }); maracasAsset.scaleX = 2; maracasAsset.scaleY = 2; maracasAsset.x = 7168; // Position further right (5120 + 2048) maracasAsset.y = 1220; maracasAsset.visible = false; // Hide until purchased // Make maracas interactive and play animation/sound on tap maracasAsset.interactive = true; // Separate animation method that doesn't check menu state maracasAsset.animate = function () { // Prevent spamming animation if (maracasAsset._animating) return; maracasAsset._animating = true; // Animate maracas: scale up and back tween(maracasAsset, { scaleX: 2.3, scaleY: 2.3 }, { duration: 100, onFinish: function onFinish() { tween(maracasAsset, { scaleX: 2, scaleY: 2 }, { duration: 100, onFinish: function onFinish() { maracasAsset._animating = false; } }); } }); // Play maracas sound if not muted if (!window.maracasBPMMuted && !window.globalMuted) { LK.getSound('maracashit').play(); } // Optionally, create a floating text or effect var floatingGold = game.addChild(new FloatingText('+0', 0x00FF00)); floatingGold.x = maracasAsset.x + cameraContainer.x; floatingGold.y = maracasAsset.y - 100; }; maracasAsset.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // Call the animation method maracasAsset.animate(); }; // Navigation arrows var arrowForward1 = null; var arrowForward2 = null; var arrowForward3 = null; var arrowForward4 = null; var arrowBack1 = null; var arrowBack2 = null; var arrowBack3 = null; var arrowBack4 = null; var isTransitioning = false; // Prevent arrow clicks during transitions // Stage/Venue display - removed // Create shadow container for button shadows var buttonShadowContainer = LK.gui.bottom.addChild(new Container()); // Add brown shadows for each button var drumstickShadow = buttonShadowContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, x: -460 + 5, y: -600 + 5, scaleX: 1, scaleY: 1, alpha: 0.3 }); drumstickShadow.tint = 0x8B4513; // Brown color var musicianShadow = buttonShadowContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, x: 0 + 5, y: -600 + 5, scaleX: 1, scaleY: 1, alpha: 0.3 }); musicianShadow.tint = 0x8B4513; // Brown color var instrumentShadow = buttonShadowContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, x: 460 + 5, y: -600 + 5, scaleX: 1, scaleY: 1, alpha: 0.3 }); instrumentShadow.tint = 0x8B4513; // Brown color // Buy buttons - Add to GUI layer to ensure they're always on top var buyDrumstickBtn = LK.gui.bottom.addChild(new BuyButton()); buyDrumstickBtn.x = -460; buyDrumstickBtn.y = -600; // Moved down from -632 buyDrumstickBtn.updateButton('Drumstick', drumstickCost, false); var buyMusicianBtn = LK.gui.bottom.addChild(new BuyButton()); buyMusicianBtn.x = 0; buyMusicianBtn.y = -600; // Moved down from -632 buyMusicianBtn.updateButton('Audience', musicianCost, false, 0, true, ''); var buyInstrumentBtn = LK.gui.bottom.addChild(new BuyButton()); buyInstrumentBtn.x = 460; buyInstrumentBtn.y = -600; // Moved down from -632 buyInstrumentBtn.updateButton('Guitar', instrumentCosts.guitar, false, 0, true, '10 Audience'); // Add new button for Maracas special purchase var buyMaracasSpecialBtn = LK.gui.bottom.addChild(new BuyButton()); buyMaracasSpecialBtn.x = 460; // Same position as instrument button buyMaracasSpecialBtn.y = -600; // Moved down from -632 buyMaracasSpecialBtn.visible = false; // Hidden by default buyMaracasSpecialBtn.updateButton('Special', 15000, false, 0, true, '5 Shakes + 30 Audience'); // Add piano button - always at rightmost position var buyPianoBtn = LK.gui.bottom.addChild(new BuyButton()); buyPianoBtn.x = 460; // Same x position as instrument button buyPianoBtn.y = -600; // Moved down from -632 buyPianoBtn.visible = false; // Hidden by default buyPianoBtn.updateButton('Piano', 30000, false, 0, true, '5 Shakes + 30 Audience'); // Update shadow visibility based on button visibility buyMaracasSpecialBtn.on('visible', function () { if (buyMaracasSpecialBtn.visible) { instrumentShadow.visible = true; } }); buyPianoBtn.on('visible', function () { if (buyPianoBtn.visible) { instrumentShadow.visible = true; } }); buyInstrumentBtn.on('visible', function () { instrumentShadow.visible = buyInstrumentBtn.visible; }); // Menu button handler menuButton.down = function () { // Visual feedback tween(menuBg, { scaleX: 0.54, scaleY: 0.54 }, { duration: 100, onFinish: function onFinish() { tween(menuBg, { scaleX: 0.6, scaleY: 0.6 }, { duration: 100 }); } }); }; // Maracas special button handler buyMaracasSpecialBtn.up = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount >= 5 && musicians.length >= 30 && gold >= 15000) { gold -= 15000; if (!window.globalMuted) { LK.getSound('purchase').play(); } // TODO: Add special maracas functionality here // Hide the button after purchase buyMaracasSpecialBtn.visible = false; } }; // Piano button handler - now handles flute in piano view buyPianoBtn.up = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // In piano view, this is the flute purchase if (currentInstrument === 'piano' && pianistsPurchased >= 5 && musicians.length >= 40 && gold >= 500000) { gold -= 500000; if (!window.globalMuted) { LK.getSound('purchase').play(); } // Create flute asset if (!fluteAsset) { fluteAsset = cameraContainer.addChild(new Container()); var fluteGraphics = fluteAsset.attachAsset('flute', { anchorX: 0.5, anchorY: 0.5 }); fluteAsset.scaleX = 3; fluteAsset.scaleY = 3; fluteAsset.x = 11364; // Position further right (9316 + 2048) fluteAsset.y = 1220; fluteAsset.visible = true; // Make flute interactive fluteAsset.interactive = true; fluteAsset.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // Play flute sound if not muted if (!window.fluteBPMMuted && !window.globalMuted) { LK.getSound('flutehit').play(); } // Visual feedback tween(fluteAsset, { scaleX: 3.05, scaleY: 3.05 }, { duration: 100, onFinish: function onFinish() { tween(fluteAsset, { scaleX: 3, scaleY: 3 }, { duration: 100 }); } }); // Generate gold var reward = 1; gold += reward; // Create floating text var floatingGold = game.addChild(new FloatingText('+' + reward, 0x87CEEB)); floatingGold.x = fluteAsset.x + cameraContainer.x; floatingGold.y = fluteAsset.y - 100; }; } // Add flute to unlocked instruments if (!unlockedInstruments.includes('flute')) { unlockedInstruments.push('flute'); } // Update navigation arrows for flute updateNavigationArrows(); // Hide the button after purchase buyPianoBtn.visible = false; } // Original piano purchase logic (from maracas view) else if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount >= 5 && musicians.length >= 30 && gold >= 30000) { gold -= 30000; if (!window.globalMuted) { LK.getSound('purchase').play(); } // Create piano asset if (!pianoAsset) { pianoAsset = cameraContainer.addChild(new Container()); var pianoGraphics = pianoAsset.attachAsset('piano', { anchorX: 0.5, anchorY: 0.5 }); pianoAsset.scaleX = 2; pianoAsset.scaleY = 2; pianoAsset.x = 9316; // Position further right (7168 + 2048) + 100 pixels to the right pianoAsset.y = 1220; pianoAsset.visible = true; // Make piano interactive pianoAsset.interactive = true; pianoAsset.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // Play piano sound if (!window.pianoBPMMuted && !window.globalMuted) { LK.getSound('pianohit').play(); } // Visual feedback tween(pianoAsset, { scaleX: 2.2, scaleY: 2.2 }, { duration: 100, onFinish: function onFinish() { tween(pianoAsset, { scaleX: 2, scaleY: 2 }, { duration: 100 }); } }); // Generate gold var reward = 1; gold += reward; // Create floating text var floatingGold = game.addChild(new FloatingText('+' + reward, 0xFFD700)); floatingGold.x = pianoAsset.x + cameraContainer.x; floatingGold.y = pianoAsset.y - 100; }; } // Add piano to unlocked instruments if (!unlockedInstruments.includes('piano')) { unlockedInstruments.push('piano'); } // Update navigation arrows for piano updateNavigationArrows(); // Hide the button after purchase buyPianoBtn.visible = false; } }; menuButton.up = function () { // Check if menu is already open if (game.menuContainer && game.menuContainer.parent) { // Menu is open, close it game.menuContainer.destroy(); game.menuContainer = null; return; } // Create menu overlay on GUI layer to ensure it's above everything var menuContainer = LK.gui.center.addChild(new Container()); game.menuContainer = menuContainer; // Store reference to check if menu is open // Make menu container interactive to block background clicks menuContainer.interactive = true; // Dark overlay var overlay = menuContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 300, scaleY: 300, alpha: 0.7 }); overlay.tint = 0x000000; // Make overlay interactive to catch all clicks overlay.interactive = true; // Menu box - use new menu container asset var menuBoxBg = menuContainer.attachAsset('menuContainer', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.95, tint: 0xE0E0E0 }); // Menu title using asset var menuTitle = menuContainer.attachAsset('menuasset', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5, x: 0, y: -612 }); // Sound effect controls var soundEffects = [{ name: 'Drum', sound: 'drumhit', unlocked: drumsticksPurchased > 0, cpmVar: 'drumBPM', defaultBPM: 60 }, { name: 'Guitar', sound: 'guitarhit', unlocked: guitarPurchased, cpmVar: 'guitarBPM', defaultBPM: 10 }, { name: 'Cymbal', sound: 'cymbalhit', unlocked: unlockedInstruments.includes('cymbal'), cpmVar: 'cymbalBPM', defaultBPM: 30 }, { name: 'Maracas', sound: 'maracashit', unlocked: unlockedInstruments.includes('maracas'), cpmVar: 'maracasBPM', defaultBPM: 120 }, { name: 'Piano', sound: 'pianohit', unlocked: unlockedInstruments.includes('piano'), cpmVar: 'pianoBPM', defaultBPM: 10 }, { name: 'Flute', sound: 'flutehit', unlocked: unlockedInstruments.includes('flute'), cpmVar: 'fluteBPM', defaultBPM: 15 }, { name: 'Audience', sound: 'clap', unlocked: musicians.length > 0, cpmVar: 'audienceBPM', defaultBPM: 120 }]; var yOffset = -570; for (var i = 0; i < soundEffects.length; i++) { var effect = soundEffects[i]; // Show all effects, both locked and unlocked // Initialize BPM if not set (only for unlocked effects) if (effect.unlocked && typeof window[effect.cpmVar] === 'undefined') { window[effect.cpmVar] = effect.defaultBPM; } // Skip adding sound effects to main menu yOffset += 100; } // Mute button - second position var muteButton = menuContainer.addChild(new Container()); var muteBg = muteButton.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); muteBg.tint = window.globalMuted ? 0xFF0000 : 0xFFFFFF; //{io} // Use white (original) when not muted var muteIcon = muteButton.attachAsset('musicNote', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.6, scaleY: 1.6, x: -135, y: -5 }); muteIcon.tint = window.globalMuted ? 0x666666 : 0xFFFFFF; var muteText = new Text2('MUTE', { size: 56, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); muteText.anchor.set(0.5, 0.5); muteText.x = 30; muteText.y = -5; // Move text up by 10 pixels muteButton.addChild(muteText); muteButton.y = -100; muteButton.interactive = true; // Mute button handlers muteButton.down = function () { tween(muteBg, { scaleX: 1.08, scaleY: 1.08 }, { duration: 100, onFinish: function onFinish() { tween(muteBg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); } }); }; muteButton.up = function () { window.globalMuted = !window.globalMuted; // Update button appearance muteBg.tint = window.globalMuted ? 0xFF0000 : 0xFFFFFF; //{iR} // Use white (original) when not muted muteIcon.tint = window.globalMuted ? 0x666666 : 0xFFFFFF; muteText.tint = window.globalMuted ? 0x666666 : 0xFFFFFF; // Mute/unmute all sounds window.drumBPMMuted = window.globalMuted; window.guitarBPMMuted = window.globalMuted; window.cymbalBPMMuted = window.globalMuted; window.maracasBPMMuted = window.globalMuted; window.pianoBPMMuted = window.globalMuted; window.fluteBPMMuted = window.globalMuted; window.clapBPMMuted = window.globalMuted; // Stop or resume music but keep CD rotating if (window.globalMuted && isMusicPlaying) { LK.stopMusic(); // CD continues rotating when muted } else if (!window.globalMuted && isMusicPlaying) { // Resume music if it was playing LK.playMusic('ambientMusic', { fade: { start: 0, end: 0.7, duration: 1000 } }); } }; // Disco lights control button - third position var muteAllBtn = menuContainer.addChild(new Container()); var muteAllBg = muteAllBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); muteAllBg.tint = window.discoMuted ? 0xFF0000 : 0xFFFFFF; //{j8} // Use white (original) when not muted var muteAllIcon = muteAllBtn.attachAsset('discomutex', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.6, scaleY: 1.6, x: -135, y: -5 }); muteAllIcon.tint = window.discoMuted ? 0x666666 : 0xFFFFFF; // Add Disco text var discoText = new Text2('DISCO', { size: 56, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); discoText.anchor.set(0.5, 0.5); discoText.x = 30; discoText.y = -5; // Move text up by 10 pixels muteAllBtn.addChild(discoText); muteAllBtn.y = 100; muteAllBtn.interactive = true; // Mute all button handlers muteAllBtn.down = function () { tween(muteAllBg, { scaleX: 1.08, scaleY: 1.08 }, { duration: 100, onFinish: function onFinish() { tween(muteAllBg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); } }); }; muteAllBtn.up = function () { // Toggle disco lights visibility state window.discoMuted = !window.discoMuted; muteAllBg.tint = window.discoMuted ? 0xFF0000 : 0xFFFFFF; //{jB} // Use white (original) when not muted muteAllIcon.tint = window.discoMuted ? 0x666666 : 0xFFFFFF; // Control disco lights visibility if (window.discoMuted) { // Hide disco lights if (window.discoLights) { window.discoLights.visible = false; } if (window.topLights) { window.topLights.visible = false; } if (window.partyOverlay) { window.partyOverlay.visible = false; } if (window.discoBallContainer) { window.discoBallContainer.visible = false; } } else if (musicians.length >= 5) { // Show disco lights (disco starts at 5 audience) if (window.discoLights) { window.discoLights.visible = true; } if (window.topLights) { window.topLights.visible = true; } if (window.partyOverlay) { window.partyOverlay.visible = true; } if (window.discoBallContainer) { window.discoBallContainer.visible = true; } } }; // BPM OPTIONS button - first position var bpmOptionsBtn = menuContainer.addChild(new Container()); var bpmOptionsBg = bpmOptionsBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); // Use original asset color var bpmOptionsText = new Text2('BPM OPTIONS', { size: 56, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); bpmOptionsText.anchor.set(0.5, 0.5); bpmOptionsText.y = -10; // Move text up by 10 pixels bpmOptionsBtn.addChild(bpmOptionsText); bpmOptionsBtn.y = -300; bpmOptionsBtn.interactive = true; // Optionally, add a simple feedback animation bpmOptionsBtn.down = function () { tween(bpmOptionsBg, { scaleX: 1.08, scaleY: 1.08 }, { duration: 100, onFinish: function onFinish() { tween(bpmOptionsBg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); } }); }; // Optionally, add a placeholder up handler (no-op or close menu, or open BPM options if implemented) bpmOptionsBtn.up = function () { // Close current menu menuContainer.destroy(); game.menuContainer = null; // Create BPM Options menu overlay var bpmMenuContainer = LK.gui.center.addChild(new Container()); game.menuContainer = bpmMenuContainer; // Store reference // Make BPM menu container interactive to block background clicks bpmMenuContainer.interactive = true; // Make container cover full screen to block all clicks bpmMenuContainer.hitArea = new Rectangle(-2048, -2732, 4096, 5464); // Dark overlay var overlay = bpmMenuContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 300, scaleY: 300, alpha: 0.7 }); overlay.tint = 0x000000; // Make overlay interactive to catch all clicks overlay.interactive = true; // Position overlay to cover entire screen overlay.x = 0; overlay.y = 0; // Menu box var menuBoxBg = bpmMenuContainer.attachAsset('menuContainer', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5, alpha: 0.95, tint: 0xE0E0E0 }); // BPM OPTIONS title using asset var bpmMenuTitle = bpmMenuContainer.attachAsset('bpmoptionsasset', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5, x: 0, y: -614 }); // Back arrow (move to left of BPM OPTIONS) var backArrow = bpmMenuContainer.attachAsset('menubackarrow', { anchorX: 0.5, anchorY: 0.5, x: -350, // moved to left of BPM OPTIONS y: -614, // aligned with BPM OPTIONS title scaleX: 0.7, scaleY: 0.7 }); backArrow.interactive = true; backArrow.down = function () { tween(backArrow, { scaleX: 0.6, scaleY: 0.6 }, { duration: 80, onFinish: function onFinish() { tween(backArrow, { scaleX: 0.7, scaleY: 0.7 }, { duration: 80 }); } }); }; backArrow.up = function () { // Close BPM menu and reopen main menu bpmMenuContainer.destroy(); game.menuContainer = null; menuButton.up(); }; // Show BPM controls for all unlocked effects (copied from main menu, but only unlocked) var soundEffects = [{ name: 'Drum', sound: 'drumhit', unlocked: drumsticksPurchased > 0, cpmVar: 'drumBPM', defaultBPM: 60 }, { name: 'Guitar', sound: 'guitarhit', unlocked: guitarPurchased, cpmVar: 'guitarBPM', defaultBPM: 10 }, { name: 'Cymbal', sound: 'cymbalhit', unlocked: unlockedInstruments.includes('cymbal'), cpmVar: 'cymbalBPM', defaultBPM: 30 }, { name: 'Maracas', sound: 'maracashit', unlocked: unlockedInstruments.includes('maracas'), cpmVar: 'maracasBPM', defaultBPM: 120 }, { name: 'Piano', sound: 'pianohit', unlocked: unlockedInstruments.includes('piano'), cpmVar: 'pianoBPM', defaultBPM: 10 }, { name: 'Flute', sound: 'flutehit', unlocked: unlockedInstruments.includes('flute'), cpmVar: 'fluteBPM', defaultBPM: 15 }, { name: 'Audience', sound: 'clap', unlocked: musicians.length > 0, cpmVar: 'audienceBPM', defaultBPM: 120 }]; var yOffset = -320; // Moved down more and adjusted position // Create ordered array based on purchase order var orderedEffects = []; // Add drum first (if exists) var drumEffect = soundEffects.find(function (e) { return e.name === 'Drum'; }); if (drumEffect) orderedEffects.push(drumEffect); // Add audience second (if exists) - always in second position regardless of lock status var audienceEffect = soundEffects.find(function (e) { return e.name === 'Audience'; }); if (audienceEffect) orderedEffects.push(audienceEffect); // Add other instruments in order: Guitar, Cymbal, Maracas, Piano, Flute (only if unlocked) var guitarEffect = soundEffects.find(function (e) { return e.name === 'Guitar'; }); if (guitarEffect && guitarEffect.unlocked) orderedEffects.push(guitarEffect); var cymbalEffect = soundEffects.find(function (e) { return e.name === 'Cymbal'; }); if (cymbalEffect && cymbalEffect.unlocked) orderedEffects.push(cymbalEffect); var maracasEffect = soundEffects.find(function (e) { return e.name === 'Maracas'; }); if (maracasEffect && maracasEffect.unlocked) orderedEffects.push(maracasEffect); var pianoEffect = soundEffects.find(function (e) { return e.name === 'Piano'; }); if (pianoEffect && pianoEffect.unlocked) orderedEffects.push(pianoEffect); var fluteEffect = soundEffects.find(function (e) { return e.name === 'Flute'; }); if (fluteEffect && fluteEffect.unlocked) orderedEffects.push(fluteEffect); // Add remaining locked effects at the end (except Drum and Audience which are already added) for (var i = 0; i < soundEffects.length; i++) { var effect = soundEffects[i]; if (!effect.unlocked && !orderedEffects.includes(effect) && effect.name !== 'Drum' && effect.name !== 'Audience') { orderedEffects.push(effect); } } // Now process ordered effects for (var i = 0; i < orderedEffects.length; i++) { var effect = orderedEffects[i]; // Show all bars, locked and unlocked var isLocked = !effect.unlocked; // Initialize BPM for all effects (both locked and unlocked) if (typeof window[effect.cpmVar] === 'undefined') { window[effect.cpmVar] = effect.defaultBPM; } var soundContainer = bpmMenuContainer.addChild(new Container()); soundContainer.y = yOffset; soundContainer.x = -70; // Moved a few pixels more to the right // Add instrument name to the left of the bar var instrumentName = new Text2(effect.name, { size: 35, fill: isLocked ? '#666666' : '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); instrumentName.anchor.set(1, 0.5); // Right-aligned // Adjust position based on instrument name if (effect.name === 'Maracas') { instrumentName.x = -40; // Move Maracas text more to the right } else { instrumentName.x = -50; // Position to the left of the bar } soundContainer.addChild(instrumentName); // Add instrument icon to the left of the text var instrumentAssetMap = { 'Drum': 'drum', 'Guitar': 'guitar', 'Cymbal': 'cymbal', 'Maracas': 'maracas', 'Piano': 'piano', 'Flute': 'flute', 'Audience': 'audience1' }; if (instrumentAssetMap[effect.name]) { var iconContainer = soundContainer.addChild(new Container()); iconContainer.x = -245; // Position to the left of the instrument name - moved 5 pixels to the right iconContainer.y = 0; // Increase scale for guitar, cymbal, maracas, and flute var iconScale = 0.08; if (effect.name === 'Guitar' || effect.name === 'Cymbal' || effect.name === 'Maracas' || effect.name === 'Flute') { iconScale = 0.14; // Slightly larger than before } var instrumentIcon = iconContainer.attachAsset(instrumentAssetMap[effect.name], { anchorX: 0.5, anchorY: 0.5, scaleX: iconScale, scaleY: iconScale }); // If locked, add black overlay if (isLocked) { var blackIcon = iconContainer.attachAsset(instrumentAssetMap[effect.name], { anchorX: 0.5, anchorY: 0.5, scaleX: iconScale, scaleY: iconScale }); blackIcon.tint = 0x000000; blackIcon.alpha = 0.9; } } // Icon removed for BPM Options menu // Bar background var barBg = soundContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 0.6, x: 80, y: 0 }); barBg.tint = isLocked ? 0x222222 : 0x666666; // BPM text - always show current value var bpmValue = window[effect.cpmVar]; var cpmText = new Text2(bpmValue + ' BPM', { size: 30, fill: isLocked ? '#888888' : '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); cpmText.anchor.set(0.5, 0.5); cpmText.x = 80; soundContainer.addChild(cpmText); // No animation - just show the actual BPM value immediately // Minus button var minusBtn = soundContainer.addChild(new Container()); var minusBg = minusBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.5 }); minusBg.tint = 0xFF0000; var minusText = new Text2('-', { size: 50, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); minusText.anchor.set(0.5, 0.5); minusText.y = -5; minusBtn.addChild(minusText); minusBtn.x = -80; minusBtn.y = 0; minusBtn.interactive = !isLocked; minusBtn.alpha = isLocked ? 0.3 : 1.0; // Plus button var plusBtn = soundContainer.addChild(new Container()); var plusBg = plusBtn.attachAsset('greenbuybutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.5, tint: 0x18c510 }); var plusText = new Text2('+', { size: 50, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); plusText.anchor.set(0.5, 0.5); plusText.y = -2; plusBtn.addChild(plusText); plusBtn.x = 240; plusBtn.y = 0; plusBtn.interactive = !isLocked; plusBtn.alpha = isLocked ? 0.3 : 1.0; // Mute button var muteVar = effect.name === 'Audience' ? 'audienceBPMMuted' : effect.cpmVar + 'Muted'; if (typeof window[muteVar] === 'undefined') window[muteVar] = false; var muteBtn = soundContainer.addChild(new Container()); var muteBg = muteBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.25, //{o2} // Reduced from 0.3 scaleY: 0.4 //{o3} // Reduced from 0.5 }); muteBg.tint = window[muteVar] ? 0xFF0000 : 0xFFFFFF; //{my} // Use white (original) when not muted var muteIcon = muteBtn.attachAsset('musicNote', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, //{o8} // Reduced from 0.8 scaleY: 0.6 //{o9} // Reduced from 0.8 }); muteIcon.tint = window[muteVar] ? 0x666666 : 0xFFFFFF; muteBtn.x = 430; // Moved 10 pixels to the left (5 more pixels) muteBtn.interactive = !isLocked; muteBtn.alpha = isLocked ? 0.3 : 1.0; // If locked, show a lock icon over the bar if (isLocked) { // Add black overlay to cover the entire bar var blackOverlay = soundContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 0.6, x: 80, y: 0, alpha: 0.8 }); blackOverlay.tint = 0x000000; // Black color var lockIcon = soundContainer.attachAsset('lock', { anchorX: 0.5, anchorY: 0.5, x: 80, y: 0, scaleX: 0.7, scaleY: 0.7 }); // Remove the "KİLİTLİ" text - no lock message shown } // Handlers (only if not locked) if (!isLocked) { (function (effect, cpmText, minusBtn, plusBtn, minusBg, plusBg, muteBtn, muteBg, muteIcon, muteVar) { var minusInterval = null; var plusInterval = null; minusBtn.down = function () { // Visual feedback tween(minusBg, { scaleX: 0.27, scaleY: 0.45 }, { duration: 100 }); // Initial decrement if (window[effect.cpmVar] > 5) { window[effect.cpmVar] -= 5; cpmText.setText(window[effect.cpmVar] + ' BPM'); } // Start continuous decrement minusInterval = LK.setInterval(function () { if (window[effect.cpmVar] > 5) { window[effect.cpmVar] -= 5; cpmText.setText(window[effect.cpmVar] + ' BPM'); } }, 200); // Update every 200ms }; minusBtn.up = function () { // Stop continuous update if (minusInterval) { LK.clearInterval(minusInterval); minusInterval = null; } // Visual feedback tween(minusBg, { scaleX: 0.3, scaleY: 0.5 }, { duration: 100 }); }; plusBtn.down = function () { // Visual feedback tween(plusBg, { scaleX: 0.27, scaleY: 0.45 }, { duration: 100 }); // Initial increment if (window[effect.cpmVar] < 120) { window[effect.cpmVar] += 5; cpmText.setText(window[effect.cpmVar] + ' BPM'); } // Start continuous increment plusInterval = LK.setInterval(function () { if (window[effect.cpmVar] < 120) { window[effect.cpmVar] += 5; cpmText.setText(window[effect.cpmVar] + ' BPM'); } }, 200); // Update every 200ms }; plusBtn.up = function () { // Stop continuous update if (plusInterval) { LK.clearInterval(plusInterval); plusInterval = null; } // Visual feedback tween(plusBg, { scaleX: 0.3, scaleY: 0.5 }, { duration: 100 }); }; muteBtn.down = function () { tween(muteBg, { scaleX: 0.225, //{oV} // Updated for new size scaleY: 0.36 //{oW} // Updated for new size }, { duration: 100, onFinish: function onFinish() { tween(muteBg, { scaleX: 0.25, //{p1} // Updated for new size scaleY: 0.4 //{p2} // Updated for new size }, { duration: 100 }); } }); }; muteBtn.up = function () { window[muteVar] = !window[muteVar]; muteBg.tint = window[muteVar] ? 0xFF0000 : 0xFFFFFF; //{ny} // Use white (original) when not muted muteIcon.tint = window[muteVar] ? 0x666666 : 0xFFFFFF; }; })(effect, cpmText, minusBtn, plusBtn, minusBg, plusBg, muteBtn, muteBg, muteIcon, muteVar); } yOffset += 110; //{pj} // Increased spacing from 100 to 110 } // Reset BPM button - smaller and positioned below BPM controls var resetCPMBtn = bpmMenuContainer.addChild(new Container()); var resetCPMBg = resetCPMBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, // Smaller than original 0.8 scaleY: 0.6 // Smaller than original 0.8 }); resetCPMBg.tint = 0xFF0000; // Red color var resetCPMText = new Text2('RESET BPM', { size: 36, // Smaller than original 48 fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); resetCPMText.anchor.set(0.5, 0.5); resetCPMText.y = 0; // Move text down by 10 pixels (from -10 to 0) resetCPMBtn.addChild(resetCPMText); resetCPMBtn.y = yOffset + 145; // Position further below all BPM controls resetCPMBtn.interactive = true; // Reset CPM button handlers resetCPMBtn.down = function () { tween(resetCPMBg, { scaleX: 0.54, scaleY: 0.54 }, { duration: 100, onFinish: function onFinish() { tween(resetCPMBg, { scaleX: 0.6, scaleY: 0.6 }, { duration: 100 }); } }); }; resetCPMBtn.up = function () { // Check if confirmation is already open if (game.resetBpmConfirmContainer && game.resetBpmConfirmContainer.parent) return; // Don't close BPM menu - keep it open behind confirmation // Create confirmation dialog on GUI layer var confirmContainer = LK.gui.center.addChild(new Container()); game.resetBpmConfirmContainer = confirmContainer; // Store reference to prevent multiple opens // Make container interactive and cover full screen confirmContainer.interactive = true; confirmContainer.hitArea = new Rectangle(-2048, -2732, 4096, 5464); // Store reference to BPM menu container var bpmMenuRef = bpmMenuContainer; // Dark overlay var confirmOverlay = confirmContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 300, scaleY: 300, alpha: 0.7 }); confirmOverlay.tint = 0x000000; // Make overlay interactive to block all clicks confirmOverlay.interactive = true; // Dialog box - darker color to match Reset dialog var dialogBg = confirmContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5, y: 35 // Move dialog background down }); dialogBg.tint = 0x404040; // Dark gray color to match Reset dialog // Confirmation text var confirmText = new Text2('Reset All BPM Values?', { size: 60, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 3 }); confirmText.anchor.set(0.5, 0.5); confirmText.y = -50; confirmContainer.addChild(confirmText); // Yes button - increased spacing var yesBtn = confirmContainer.addChild(new Container()); var yesBg = yesBtn.attachAsset('greenbuybutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, tint: 0x18c510 }); var yesText = new Text2('YES', { size: 40, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); yesText.anchor.set(0.5, 0.5); yesBtn.addChild(yesText); yesBtn.x = -200; // Increased from -150 to -200 yesBtn.y = 80; yesBtn.interactive = true; // No button - increased spacing var noBtn = confirmContainer.addChild(new Container()); var noBg = noBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); noBg.tint = 0xFF0000; var noText = new Text2('NO', { size: 40, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); noText.anchor.set(0.5, 0.5); noBtn.addChild(noText); noBtn.x = 200; // Increased from 150 to 200 noBtn.y = 80; noBtn.interactive = true; // Yes button handlers yesBtn.down = function () { tween(yesBg, { scaleX: 0.7, scaleY: 0.7 }, { duration: 100, onFinish: function onFinish() { tween(yesBg, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100 }); } }); }; yesBtn.up = function () { // Reset all BPM values to defaults window.drumBPM = 60; window.guitarBPM = 10; window.cymbalBPM = 30; window.maracasBPM = 120; window.pianoBPM = 10; window.fluteBPM = 15; window.audienceBPM = 120; // Close confirmation dialog confirmContainer.destroy(); // Clear confirmation reference game.resetBpmConfirmContainer = null; // Store reference to restore menu var bpmMenuToRestore = bpmMenuRef; // Close the BPM menu completely bpmMenuRef.destroy(); game.menuContainer = null; // Recreate the BPM menu with updated values bpmOptionsBtn.up(); }; // No button handlers noBtn.down = function () { tween(noBg, { scaleX: 0.7, scaleY: 0.7 }, { duration: 100, onFinish: function onFinish() { tween(noBg, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100 }); } }); }; noBtn.up = function () { confirmContainer.destroy(); game.resetBpmConfirmContainer = null; // Clear confirmation reference game.menuContainer = bpmMenuRef; // Restore BPM menu reference }; }; }; // Reset button - fourth position var resetBtn = menuContainer.addChild(new Container()); var resetBtnBg = resetBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); resetBtnBg.tint = 0xFF0000; var resetBtnText = new Text2('RESTART', { size: 56, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); resetBtnText.anchor.set(0.5, 0.5); resetBtnText.y = -5; // Move text down resetBtn.addChild(resetBtnText); resetBtn.y = 300; resetBtn.interactive = true; // Close button - same size as Reset BPM button var closeBtn = menuContainer.addChild(new Container()); var closeBtnBg = closeBtn.attachAsset('greenbuybutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, tint: 0x18c510 }); var closeBtnText = new Text2('CLOSE', { size: 36, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); closeBtnText.anchor.set(0.5, 0.5); closeBtnText.y = 0; // Move text down by 10 pixels (from -10 to 0) closeBtn.addChild(closeBtnText); closeBtn.y = 595; // Moved up by 1 pixel closeBtn.interactive = true; // Reset button handler resetBtn.down = function () { tween(resetBtnBg, { scaleX: 1.08, scaleY: 1.08 }, { duration: 100, onFinish: function onFinish() { tween(resetBtnBg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); } }); }; resetBtn.up = function () { // Check if confirmation is already open if (game.restartConfirmContainer && game.restartConfirmContainer.parent) return; // Don't close main menu - keep it open behind confirmation // Create confirmation dialog on GUI layer var confirmContainer = LK.gui.center.addChild(new Container()); game.restartConfirmContainer = confirmContainer; // Store reference to prevent multiple opens // Make container interactive and cover full screen confirmContainer.interactive = true; confirmContainer.hitArea = new Rectangle(-2048, -2732, 4096, 5464); // Store reference to main menu container var mainMenuRef = menuContainer; // Dark overlay var confirmOverlay = confirmContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 300, scaleY: 300, alpha: 0.7 }); confirmOverlay.tint = 0x000000; // Make overlay interactive to block all clicks confirmOverlay.interactive = true; // Dialog box - darker color var dialogBg = confirmContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5, y: 35 // Move dialog background down }); dialogBg.tint = 0x404040; // Dark gray color // Confirmation text var confirmText = new Text2('Reset All Progress?', { size: 60, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 3 }); confirmText.anchor.set(0.5, 0.5); confirmText.y = -50; confirmContainer.addChild(confirmText); // Yes button - increased spacing var yesBtn = confirmContainer.addChild(new Container()); var yesBg = yesBtn.attachAsset('greenbuybutton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8, tint: 0x18c510 }); var yesText = new Text2('YES', { size: 40, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); yesText.anchor.set(0.5, 0.5); yesBtn.addChild(yesText); yesBtn.x = -200; // Increased from -150 to -200 yesBtn.y = 80; yesBtn.interactive = true; // No button - increased spacing var noBtn = confirmContainer.addChild(new Container()); var noBg = noBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); noBg.tint = 0xFF0000; var noText = new Text2('NO', { size: 40, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); noText.anchor.set(0.5, 0.5); noBtn.addChild(noText); noBtn.x = 200; // Increased from 150 to 200 noBtn.y = 80; noBtn.interactive = true; // Yes button handlers yesBtn.down = function () { tween(yesBg, { scaleX: 0.7, scaleY: 0.7 }, { duration: 100, onFinish: function onFinish() { tween(yesBg, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100 }); } }); }; yesBtn.up = function () { // Clear storage storage.gold = null; storage.passiveIncome = null; storage.drumstickCount = null; storage.drumsticksPurchased = null; storage.musicianCount = null; storage.unlockedInstruments = null; storage.instrumentsPurchased = null; // Clear confirmation reference game.restartConfirmContainer = null; // Reload game LK.showGameOver(); }; // No button handlers noBtn.down = function () { tween(noBg, { scaleX: 0.7, scaleY: 0.7 }, { duration: 100, onFinish: function onFinish() { tween(noBg, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100 }); } }); }; noBtn.up = function () { confirmContainer.destroy(); game.restartConfirmContainer = null; // Clear confirmation reference game.menuContainer = mainMenuRef; // Restore main menu reference }; }; // Close button handler closeBtn.down = function () { tween(closeBtnBg, { scaleX: 0.54, scaleY: 0.54 }, { duration: 100, onFinish: function onFinish() { tween(closeBtnBg, { scaleX: 0.6, scaleY: 0.6 }, { duration: 100 }); } }); }; closeBtn.up = function () { menuContainer.destroy(); game.menuContainer = null; }; }; // Function to transition camera to instrument function transitionToInstrument(instrumentName) { if (isTransitioning) return; // Prevent multiple transitions isTransitioning = true; // Set flag to prevent arrow clicks var targetX = 0; switch (instrumentName) { case 'drum': targetX = 0; break; case 'guitar': targetX = -2048; break; case 'cymbal': targetX = -4096; break; case 'maracas': targetX = -6144; break; case 'piano': targetX = -8292; // Adjusted to match new piano position (100 pixels more) currentInstrument = 'piano'; break; case 'flute': targetX = -10340; // Position for flute (11364 - 1024) currentInstrument = 'flute'; break; } // Removed confetti spawning from instrument transitions // Smooth camera transition tween(cameraContainer, { x: targetX }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { currentCameraX = targetX; if (instrumentName !== 'piano') { currentInstrument = instrumentName; } isTransitioning = false; // Clear flag after transition completes updateNavigationArrows(); } }); } // Function to update navigation arrows function updateNavigationArrows() { // Remove all existing arrows if (arrowForward1) { arrowForward1.destroy(); arrowForward1 = null; } if (arrowForward2) { arrowForward2.destroy(); arrowForward2 = null; } if (arrowForward3) { arrowForward3.destroy(); arrowForward3 = null; } if (arrowBack1) { arrowBack1.destroy(); arrowBack1 = null; } if (arrowBack2) { arrowBack2.destroy(); arrowBack2 = null; } if (arrowBack3) { arrowBack3.destroy(); arrowBack3 = null; } if (arrowForward4) { arrowForward4.destroy(); arrowForward4 = null; } if (arrowBack4) { arrowBack4.destroy(); arrowBack4 = null; } // Add appropriate arrows based on current instrument switch (currentInstrument) { case 'drum': if (guitarPurchased) { arrowForward1 = game.addChild(LK.getAsset('arrowforward1', { anchorX: 0.5, anchorY: 0.5, x: 1800, y: 1300 })); arrowForward1.interactive = true; arrowForward1.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('guitar'); }; } break; case 'guitar': arrowBack1 = game.addChild(LK.getAsset('arrowback1', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 1300 })); arrowBack1.interactive = true; arrowBack1.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('drum'); }; if (unlockedInstruments.includes('cymbal')) { arrowForward2 = game.addChild(LK.getAsset('arrowforward2', { anchorX: 0.5, anchorY: 0.5, x: 1800, y: 1300 })); arrowForward2.interactive = true; arrowForward2.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('cymbal'); }; } break; case 'cymbal': arrowBack2 = game.addChild(LK.getAsset('arrowback2', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 1300 })); arrowBack2.interactive = true; arrowBack2.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('guitar'); }; if (unlockedInstruments.includes('maracas')) { arrowForward3 = game.addChild(LK.getAsset('arrowforward3', { anchorX: 0.5, anchorY: 0.5, x: 1800, y: 1300 })); arrowForward3.interactive = true; arrowForward3.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('maracas'); }; } break; case 'maracas': arrowBack3 = game.addChild(LK.getAsset('arrowback3', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 1300 })); arrowBack3.interactive = true; arrowBack3.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('cymbal'); }; if (unlockedInstruments.includes('piano')) { // Create arrow forward 4 for piano arrowForward4 = game.addChild(LK.getAsset('arrowforward4', { anchorX: 0.5, anchorY: 0.5, x: 1800, y: 1300 })); arrowForward4.interactive = true; arrowForward4.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('piano'); }; } break; case 'piano': arrowBack4 = game.addChild(LK.getAsset('arrowback4', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 1300 })); arrowBack4.interactive = true; arrowBack4.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('maracas'); }; if (unlockedInstruments.includes('flute')) { // Create arrow forward to flute arrowForward4 = game.addChild(LK.getAsset('arrowforward4', { anchorX: 0.5, anchorY: 0.5, x: 1800, y: 1300 })); arrowForward4.interactive = true; arrowForward4.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('flute'); }; } break; case 'flute': arrowBack4 = game.addChild(LK.getAsset('arrowback4', { anchorX: 0.5, anchorY: 0.5, x: 200, y: 1300 })); arrowBack4.interactive = true; arrowBack4.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; if (!isTransitioning) transitionToInstrument('piano'); }; break; } } // Button handlers buyDrumstickBtn.up = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // FLUTE FLUTEBLOW PURCHASE LOGIC if (currentInstrument === 'flute') { if (gold >= fluteblowCost) { gold -= fluteblowCost; fluteblowsPurchased++; // Enable automatic flute hitting with 10 BPM window.fluteAutoPlay = true; window.fluteAutoPlayCounter = 0; // Do not set fluteHasHitOnce to false, so it won't sync with drumstick // Recalculate passive income recalculatePassiveIncome(); if (!window.globalMuted) { LK.getSound('purchase').play(); } // Increase fluteblow cost for next purchase fluteblowCost = Math.floor(fluteblowCost * 1.5); // Update button to show new count and cost buyDrumstickBtn.updateButton('Fluteblow', fluteblowCost, gold >= fluteblowCost, fluteblowsPurchased); } return; } // PIANO PIANIST PURCHASE LOGIC if (currentInstrument === 'piano') { if (gold >= pianistCost) { gold -= pianistCost; pianistsPurchased++; // Create pianist if it doesn't exist if (pianists.length === 0) { var newPianist = cameraContainer.addChild(new Pianist()); // Position pianist above piano but lower if (pianoAsset) { newPianist.x = pianoAsset.x; newPianist.y = pianoAsset.y - 195; } else { // Default position if piano doesn't exist newPianist.x = 9316; newPianist.y = 1220 - 200; } // Set piano reference for visual feedback newPianist.pianoReference = pianoAsset; newPianist.hasHitOnce = false; // Initialize first hit flag pianists.push(newPianist); } // Increase pianist cost for next purchase pianistCost = Math.floor(pianistCost * 1.5); // Recalculate passive income recalculatePassiveIncome(); if (!window.globalMuted) { LK.getSound('purchase').play(); } // Update button to show new count and cost buyDrumstickBtn.updateButton('Pianist', pianistCost, gold >= pianistCost, pianistsPurchased); } return; } // MARACAS SHAKE PURCHASE LOGIC if (currentInstrument === 'maracas') { if (typeof window.maracasShakeCost === 'undefined') window.maracasShakeCost = 12000; if (typeof window.maracasShakeCount === 'undefined') window.maracasShakeCount = 0; var maracasShakeCost = window.maracasShakeCost; // Allow purchase if player can afford if (gold >= maracasShakeCost) { gold -= maracasShakeCost; window.maracasShakeCount++; window.maracasHasHitOnce = false; // Initialize first hit flag // Only play purchase sound, no maracas hit animation during purchase if (!window.globalMuted) { LK.getSound('purchase').play(); } // Recalculate passive income recalculatePassiveIncome(); // Increase cost for next purchase window.maracasShakeCost = Math.floor(window.maracasShakeCost * 1.3); // Update button to show new count and cost buyDrumstickBtn.updateButton('Maracas Shake', window.maracasShakeCost, gold >= window.maracasShakeCost, window.maracasShakeCount); } return; } // CYMBALSTICK PURCHASE LOGIC if (currentInstrument === 'cymbal') { if (typeof window.cymbalsticksPurchased === 'undefined') window.cymbalsticksPurchased = 0; if (typeof window.cymbalstickCost === 'undefined') window.cymbalstickCost = 2200; var cymbalstickCount = window.cymbalsticksPurchased; var cymbalstickCost = window.cymbalstickCost; // Check if player has enough fingers if (gold >= cymbalstickCost && fingersPurchased >= 10) { gold -= cymbalstickCost; window.cymbalsticksPurchased++; // Create auto cymbal stick if it doesn't exist if (autoCymbalsticks.length === 0) { var newAutoCymbalstick = cameraContainer.addChild(new AutoCymbalstick()); // Position auto cymbal stick on left side of cymbal if (cymbalAsset) { newAutoCymbalstick.x = cymbalAsset.x - 380; newAutoCymbalstick.y = cymbalAsset.y - 50; } else { // Default position if cymbal doesn't exist newAutoCymbalstick.x = 5120 - 380; newAutoCymbalstick.y = 1220 - 50; } // Set cymbal reference for visual feedback newAutoCymbalstick.cymbalReference = cymbalAsset; newAutoCymbalstick.hasHitOnce = false; // Initialize first hit flag autoCymbalsticks.push(newAutoCymbalstick); // Start CD rotation when first cymbalstick is purchased (if music is playing) if (!cdRotationTween && isMusicPlaying) { var rotateContinuously = function rotateContinuously() { // Check if music is still playing before starting new rotation if (!isMusicPlaying) { // Stop any existing tween if music stopped if (cdRotationTween) { tween.stop(cdRotationTween); cdRotationTween = null; } return; } cdRotationTween = tween(decorationAsset, { rotation: decorationAsset.rotation + Math.PI * 2 }, { duration: 4000, easing: tween.linear, onFinish: function onFinish() { if (isMusicPlaying) { rotateContinuously(); // Continue rotating } else { // Ensure tween is cleared if music stopped during animation cdRotationTween = null; } } }); }; rotateContinuously(); } } // Recalculate passive income recalculatePassiveIncome(); // Increase cost for next cymbalstick (optional, can be fixed if desired) window.cymbalstickCost = Math.floor(window.cymbalstickCost * 1.3); if (!window.globalMuted) { LK.getSound('purchase').play(); } // Update button buyDrumstickBtn.updateButton('Cymbalstick', window.cymbalstickCost, gold >= window.cymbalstickCost, window.cymbalsticksPurchased); } return; } var currentCost = currentInstrument === 'guitar' ? fingerCost : drumstickCost; if (gold >= currentCost) { gold -= currentCost; if (currentInstrument === 'guitar') { fingersPurchased++; // Create finger if it doesn't exist if (fingers.length === 0) { var newFinger = cameraContainer.addChild(new AutoFinger()); // Position finger on right side of guitar if (guitarAsset) { newFinger.x = guitarAsset.x - 250; // Move significantly more to the left newFinger.y = guitarAsset.y + 50; // Move finger up a bit more (reduced from 80 to 50) } else { // If guitar doesn't exist yet, position at default location newFinger.x = 3072 - 250; newFinger.y = 1220 + 50; } // Set guitar reference for visual feedback newFinger.guitarReference = guitarAsset; newFinger.hasHitOnce = false; // Initialize first hit flag fingers.push(newFinger); } // Recalculate passive income recalculatePassiveIncome(); fingerCost = Math.floor(fingerCost * 1.3); } else { drumsticksPurchased++; // Create drumstick if it doesn't exist if (drumsticks.length === 0) { var newStick = cameraContainer.addChild(new AutoDrumstick()); // Position drumstick on left side of drum newStick.x = mainDrum.x - 350; newStick.y = mainDrum.y - 200; // Rotate drumstick to point towards the drum newStick.rotation = 0; // Set drum reference for visual feedback newStick.drumReference = mainDrum; drumsticks.push(newStick); } // Update drumstick income on the drumstick object if (drumsticks.length > 0) { drumsticks[0].income = 2; // Base income per hit } // Recalculate passive income recalculatePassiveIncome(); // Update drumstick cost with 30% increase drumstickCost = Math.floor(drumstickCost * 1.3); } if (!window.globalMuted) { console.log('Playing purchase sound'); LK.getSound('purchase').play(); } else { console.log('Purchase sound muted'); } // Force update button to refresh count display var buttonText = currentInstrument === 'guitar' ? 'Finger' : 'Drumstick'; var purchaseCount = currentInstrument === 'guitar' ? fingersPurchased : drumsticksPurchased; var nextCost = currentInstrument === 'guitar' ? fingerCost : drumstickCost; buyDrumstickBtn.updateButton(buttonText, nextCost, gold >= nextCost, purchaseCount); } }; buyMusicianBtn.up = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; var requiredFingers = guitarPurchased ? 10 : 0; var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased; // Check cymbalstick count for audience lock at 15 var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0; var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10; // Check maracas shake count for audience lock at 25 var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0; var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5; // Check pianist count for audience lock at 50 var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5; var canPurchase = !guitarAvailableButNotPurchased && !audienceLocked15 && !audienceLocked25 && !audienceLocked50 && (guitarPurchased ? fingersPurchased >= requiredFingers : drumsticksPurchased >= 10); if (canPurchase && gold >= musicianCost) { // Helper function for new audience dancing var _startAudienceDancing = function startAudienceDancing(audience) { if (!window.audienceDancing) return; // Create more realistic dance movements var dancePhase = Math.random() < 0.5 ? 'sway' : 'bounce'; if (dancePhase === 'sway') { // Swaying side to side movement var swayDistance = 30 + Math.random() * 40; // 30-70 pixels var swayTime = 800 + Math.random() * 400; // 800-1200ms // Sway to one side tween(audience, { x: audience.originalX + swayDistance, rotation: 0.1 // Slight tilt }, { duration: swayTime, easing: tween.easeInOut, onFinish: function onFinish() { // Sway to other side tween(audience, { x: audience.originalX - swayDistance, rotation: -0.1 // Tilt opposite way }, { duration: swayTime, easing: tween.easeInOut, onFinish: function onFinish() { // Return to center and continue tween(audience, { x: audience.originalX, rotation: 0 }, { duration: swayTime / 2, easing: tween.easeOut, onFinish: function onFinish() { _startAudienceDancing(audience); } }); } }); } }); } else { // Bouncing movement without shape distortion var bounceHeight = 15 + Math.random() * 25; // 15-40 pixels var bounceTime = 400 + Math.random() * 200; // 400-600ms // Bounce up - only move position, no scaling tween(audience, { y: audience.y - bounceHeight }, { duration: bounceTime, easing: tween.easeOut, onFinish: function onFinish() { // Bounce down tween(audience, { y: audience.y + bounceHeight }, { duration: bounceTime, easing: tween.bounceOut, onFinish: function onFinish() { _startAudienceDancing(audience); } }); } }); } }; // Check if this is the first audience purchase var isFirstAudience = musicians.length === 0; gold -= musicianCost; // Add audience to game layer (above cameraContainer) to ensure they're on top var newAudience = game.addChild(new Audience()); // Random spawn position at bottom of screen with slight vertical variation newAudience.x = 200 + Math.random() * 1648; // Random x between 200 and 1848 newAudience.y = 2435 + (Math.random() - 0.5) * 50; // Spawn between 2410-2460 (moved up by 15 pixels total) // Only set instruments if guitar is not purchased if (!guitarPurchased && unlockedInstruments.length > 1) { var randomInstrument = unlockedInstruments[Math.floor(Math.random() * (unlockedInstruments.length - 1)) + 1]; newAudience.setInstrument(randomInstrument); } // If disco is active (5+ audience), start dancing for new member if (musicians.length >= 5 && window.audienceDancing) { newAudience.originalX = newAudience.x; // Start dancing with a slight delay LK.setTimeout(function () { _startAudienceDancing(newAudience); }, 100); } musicians.push(newAudience); goldPerTap = Math.floor(goldPerTap * newAudience.multiplier); // Remove individual audience income - now using multiplier system // Recalculate passive income to include new audience member recalculatePassiveIncome(); // Increase cost by 1.3x (30% increase) musicianCost = Math.floor(musicianCost * 1.3); if (!window.globalMuted) { LK.getSound('purchase').play(); } // Force update button to refresh count display var isLocked = guitarPurchased ? fingersPurchased < 10 : drumsticksPurchased < 10; var lockMessage = guitarPurchased ? '10 Fingers' : '10 Drumsticks'; buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isLocked, musicians.length, isLocked, lockMessage); } }; buyInstrumentBtn.up = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; var nextInstrument = null; var cost = 0; if (!unlockedInstruments.includes('guitar')) { nextInstrument = 'guitar'; cost = instrumentCosts.guitar; } else if (!unlockedInstruments.includes('cymbal')) { nextInstrument = 'cymbal'; cost = instrumentCosts.cymbal; } else if (!unlockedInstruments.includes('maracas')) { nextInstrument = 'maracas'; cost = instrumentCosts.maracas; } if (nextInstrument && gold >= cost && (nextInstrument !== 'guitar' || musicians.length >= 10) && (nextInstrument !== 'cymbal' || musicians.length >= 15 && fingersPurchased >= 10) && (nextInstrument !== 'maracas' || musicians.length >= 25)) { gold -= cost; unlockedInstruments.push(nextInstrument); instrumentsPurchased++; // Set last instrument purchase time to block confetti for 15s window.lastInstrumentPurchaseTime = Date.now(); // Set guitar purchased flag and update musician cost to 500 if (nextInstrument === 'guitar') { guitarPurchased = true; musicianCost = 500; guitarAsset.visible = true; // Show guitar } else if (nextInstrument === 'cymbal') { // Show cymbal cymbalAsset.visible = true; // Music now starts at 10 audience with disco, not on cymbal purchase } else if (nextInstrument === 'maracas') { // Show maracas maracasAsset.visible = true; // Show piano button when maracas is purchased buyPianoBtn.visible = true; } if (!window.globalMuted) { LK.getSound('purchase').play(); } // Show guitar when purchased if (nextInstrument === 'guitar') { // Create finger if purchased but not created yet if (fingersPurchased > 0 && fingers.length === 0) { var newFinger = cameraContainer.addChild(new AutoFinger()); // Position finger on guitar newFinger.x = guitarAsset.x - 250; newFinger.y = guitarAsset.y + 50; newFinger.guitarReference = guitarAsset; fingers.push(newFinger); } } // Update navigation arrows after purchasing any instrument updateNavigationArrows(); // Update button for next instrument if (nextInstrument === 'guitar') { buyInstrumentBtn.updateButton('Cymbal', instrumentCosts.cymbal, gold >= instrumentCosts.cymbal, undefined); } else if (nextInstrument === 'cymbal') { buyInstrumentBtn.updateButton('Maracas', instrumentCosts.maracas, gold >= instrumentCosts.maracas, undefined); } else if (nextInstrument === 'maracas') { // Hide instrument button after maracas buyInstrumentBtn.visible = false; } } }; // Passive income timer var incomeTimer = 0; // Function to hide tutorial elements function hideTutorial() { if (tutorialHand && tutorialHand.parent) { // Fade out and destroy tutorial hand tween(tutorialHand, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 500, onFinish: function onFinish() { if (tutorialHand && tutorialHand.parent) { tutorialHand.destroy(); tutorialHand = null; } } }); } if (tutorialText && tutorialText.parent) { // Fade out and destroy tutorial banner tween(tutorialText, { alpha: 0, scaleX: 0.4, scaleY: 0.4 }, { duration: 500, onFinish: function onFinish() { if (tutorialText && tutorialText.parent) { tutorialText.destroy(); tutorialText = null; } } }); } // Remove shadow overlay if it exists if (window.tutorialShadow && window.tutorialShadow.parent) { tween(window.tutorialShadow, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (window.tutorialShadow && window.tutorialShadow.parent) { window.tutorialShadow.destroy(); window.tutorialShadow = null; } } }); } // Remove tutorial drum button without fade effect if (window.tutorialDrumButton && window.tutorialDrumButton.parent) { window.tutorialDrumButton.destroy(); window.tutorialDrumButton = null; } // Remove tutorial drumstick button without fade effect if (window.tutorialDrumstickButton && window.tutorialDrumstickButton.parent) { window.tutorialDrumstickButton.destroy(); window.tutorialDrumstickButton = null; } showTutorial = false; // Enable Menu and CD buttons after tutorial is hidden if (menuButton) menuButton.interactive = true; if (menuDecoration) menuDecoration.interactive = true; // Do NOT unlock moneygunmute button here; it should only unlock when its own condition is met // Defensive: Do NOT remove moneyLockIcon or moneyShadow here, keep moneygunmute locked until its own unlock condition // (FIXED: moneygunmute lock and shadow are NOT removed here, so button stays locked after tutorial) // (ENFORCED: moneygunmute lock and shadow are NOT removed here, so button stays locked after tutorial, only unlock when gun starts) } // Main game loop game.update = function () { // Check if we need to show info asset when gold reaches 3 if (!hasShownInfo && gold >= 3 && !infoAsset) { // Create info asset as a button-like container using the specific infoasset infoAsset = LK.gui.bottom.addChild(new Container()); // Use infoasset instead of buyButton var infoBg = infoAsset.attachAsset('infoasset', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0 }); // Position the info button below income text and slightly to the right infoAsset.x = 200; infoAsset.y = -1150; // Add "gain $10" text on the info button, moved to the right var infoText = new Text2('gain $10', { size: 50, fill: '#ecdcbf', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); infoText.anchor.set(0.5, 0.5); infoText.x = 50; // Move text to the right infoText.y = -5; infoAsset.addChild(infoText); // Make it non-interactive infoAsset.interactive = false; // Add info arrow infoArrow = LK.gui.bottom.addChild(LK.getAsset('infoarrow', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, rotation: Math.PI, x: 250, y: -1780 })); hasShownInfo = true; } // Check if we need to hide info asset when gold reaches 8 if (infoAsset && gold >= 8) { infoAsset.destroy(); infoAsset = null; infoArrow.destroy(); infoArrow = null; } // Money gun audience gating and dollar drain // Unlock moneygunmute button (remove lock and shadow, make interactive) when audience reaches 20 if (musicians.length >= 20 && (moneyLockIcon && moneyLockIcon.visible || typeof moneyShadow !== "undefined" && moneyShadow && moneyShadow.visible)) { if (moneyLockIcon) moneyLockIcon.visible = false; if (typeof moneyShadow !== "undefined" && moneyShadow) moneyShadow.visible = false; if (moneyButton) moneyButton.interactive = true; if (moneyButtonAsset) moneyButtonAsset.alpha = window.moneyGunActive ? 1.0 : 0.3; } // Automatically start moneygun when audience reaches 20, but only enable toggling via button after that if (musicians.length >= 20 && hasHitDrumOnce && window.moneyGun && !window.moneyGunWasUnlocked) { // Unlock moneygunmute button (remove lock and shadow) ONLY when gun actually starts if (window.moneyLockIcon) window.moneyLockIcon.visible = false; if (typeof moneyShadow !== "undefined" && moneyShadow) moneyShadow.visible = false; if (moneyButton) moneyButton.interactive = true; if (moneyButtonAsset) moneyButtonAsset.alpha = 1.0; if (window.moneyGun) { window.moneyGun.visible = true; // Fade in animation for auto-start window.moneyGun.rotation = Math.PI + Math.PI / 4 + Math.PI / 12 + Math.PI / 36; window.moneyGun.alpha = 0; tween(window.moneyGun, { alpha: 1 }, { duration: 1500, easing: tween.easeOut }); } window.moneyGunActive = true; window.moneyGunWasUnlocked = true; // Only unlock once } // After audience 20, allow toggling moneygun on/off only via button if (window.moneyGunWasUnlocked && window.moneyGun) { // If audience drops below 20, always turn off and hide gun if (musicians.length < 20) { window.moneyGunActive = false; if (moneyButtonAsset) moneyButtonAsset.alpha = 0.3; if (window.moneyGun) window.moneyGun.visible = false; // Destroy all money projectiles when money gun is hidden if (window.moneyProjectiles && window.moneyProjectiles.length > 0) { for (var i = window.moneyProjectiles.length - 1; i >= 0; i--) { var proj = window.moneyProjectiles[i]; proj.destroy(); window.moneyProjectiles.splice(i, 1); } } } } if (window.moneyGunActive) { // Only allow moneygun if audience is at least 20 if (musicians.length < 20) { window.moneyGunActive = false; if (moneyButtonAsset) moneyButtonAsset.alpha = 0.3; if (window.moneyGun) window.moneyGun.visible = false; // Destroy all money projectiles when money gun is hidden if (window.moneyProjectiles && window.moneyProjectiles.length > 0) { for (var i = window.moneyProjectiles.length - 1; i >= 0; i--) { var proj = window.moneyProjectiles[i]; proj.destroy(); window.moneyProjectiles.splice(i, 1); } } } else { // Deduct $500 per second (every 60 frames) if (LK.ticks % 60 === 0) { gold -= 500; if (gold < 0) gold = 0; } } } // Money gun shooting logic if (window.moneyGunActive && window.moneyGun && musicians.length >= 20) { // Shoot money every 10 frames if (LK.ticks % 10 === 0) { // Create money projectile var money = game.addChild(new Container()); // Use only flyingMoney asset with initial 135-degree rotation (head pointing 45 degrees more clockwise) var coin = money.attachAsset('flyingMoney', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.0, scaleY: 3.0, rotation: Math.PI / 4 // Initial 45 degrees clockwise (135 degrees total from up) }); money.coin = coin; // Store reference for rotation control // Start position at top-right of gun money.x = window.moneyGun.x + 120; money.y = window.moneyGun.y - 180; // Random trajectory with wider spread - rotated 30 degrees clockwise var baseAngle = -Math.PI / 3 + Math.PI / 9 + Math.PI / 18; // Add 30 degrees (20 + 10 degrees) clockwise var angle = baseAngle + (Math.random() - 0.5) * Math.PI / 3; // Wider angle range var speed = 12 + Math.random() * 8; // Slightly more initial speed for better spread money.vx = Math.cos(angle) * speed; money.vy = Math.sin(angle) * speed; money.gravity = 0.4; // Lighter gravity for paper money.rotation = 0; // Container rotation money.rotationSpeed = 0; // No rotation speed needed for flip animation money.lifetime = 0; // Add random phase offset for varied swaying patterns money.swayPhase = Math.random() * Math.PI * 2; // Random initial flip offset money.flipOffset = Math.random() * 60; // Add slight random horizontal velocity for initial spread money.vx += (Math.random() - 0.5) * 5; // Store money projectile if (!window.moneyProjectiles) window.moneyProjectiles = []; window.moneyProjectiles.push(money); // Don't animate rotation - will be controlled based on falling state // Animate gun recoil tween(window.moneyGun, { rotation: Math.PI + Math.PI / 4 + Math.PI / 12 + Math.PI / 36 + 0.1 }, { duration: 50, onFinish: function onFinish() { tween(window.moneyGun, { rotation: Math.PI + Math.PI / 4 + Math.PI / 12 + Math.PI / 36 }, { duration: 100 }); } }); } // Update money projectiles if (window.moneyProjectiles) { for (var i = window.moneyProjectiles.length - 1; i >= 0; i--) { var projectile = window.moneyProjectiles[i]; // Paper-like physics // Add air resistance projectile.vx *= 0.98; projectile.vy *= 0.99; // Transition to vertical orientation (90 degrees) when falling if (projectile.vy > 0 && projectile.coin) { // Smoothly transition to vertical (rotation = Math.PI/2) when falling if (!projectile.rotationTweenStarted) { projectile.rotationTweenStarted = true; tween(projectile.coin, { rotation: Math.PI / 2 // 90 degrees (vertical orientation) }, { duration: 300, easing: tween.easeOut }); } } // Add horizontal spreading force as money falls // The spreading increases as the projectile falls down var spreadingForce = 0; if (projectile.vy > 0) { // Calculate how long the projectile has been falling var fallProgress = Math.min(projectile.lifetime / 120, 1); // Reaches max at 2 seconds // Add horizontal spreading based on initial position // Money on the left spreads left, money on the right spreads right var centerX = 1024; // Center of screen var distanceFromCenter = projectile.x - centerX; // Spreading force increases with fall progress spreadingForce = distanceFromCenter / Math.abs(distanceFromCenter || 1) * fallProgress * 2.5; // Add some randomness to make it more natural spreadingForce += (Math.random() - 0.5) * fallProgress * 1.5; } // Only start side-to-side animation when projectile starts falling (vy > 0) var flutter = 0; var secondaryFlutter = 0; if (projectile.vy > 0) { // Calculate amplitude multiplier based on how long the projectile has been falling // Starts at 0 and gradually increases to 1 as projectile falls var fallProgress = Math.min(projectile.lifetime / 120, 1); // Reaches max at 2 seconds (120 frames) // Start with very small amplitude and increase as projectile falls var baseAmplitude = 12; // Maximum amplitude var secondaryAmplitude = 8; // Maximum secondary amplitude flutter = Math.sin(projectile.lifetime * 0.08) * (baseAmplitude * fallProgress * fallProgress); // Quadratic increase secondaryFlutter = Math.cos(projectile.lifetime * 0.12) * (secondaryAmplitude * fallProgress * fallProgress); } projectile.x += projectile.vx + flutter + secondaryFlutter + spreadingForce; projectile.y += projectile.vy; // Gravity with terminal velocity (paper falls slower) if (projectile.vy < 8) { // Terminal velocity for paper projectile.vy += projectile.gravity * 0.3; // Reduced gravity effect } // Flip-based rotation for paper money - horizontal flip // Initialize flip state if not set if (projectile.hasFlipped === undefined) { projectile.hasFlipped = false; projectile.flipStartTime = -1; } //{B0_init} // Only start flip animation after 3 seconds (180 frames) if (projectile.lifetime < 180) { // Keep normal orientation for first 3 seconds projectile.children[0].scaleX = 3.0; } else if (!projectile.hasFlipped) { // Start flip if not already flipped projectile.hasFlipped = true; projectile.flipStartTime = projectile.lifetime; } //{B1_end} // Handle horizontal flip animation if (projectile.hasFlipped && projectile.flipStartTime > 0) { var timeSinceFlipStart = projectile.lifetime - projectile.flipStartTime; var flipDuration = 30; // 0.5 seconds (30 frames) if (timeSinceFlipStart < flipDuration) { // During flip animation - horizontal flip var flipProgress = timeSinceFlipStart / flipDuration; if (flipProgress < 0.5) { // First half of flip - scale X from 1 to -1 projectile.children[0].scaleX = 3.0 * (1 - 2 * flipProgress); } else { // Second half of flip - scale X from -1 to 1 projectile.children[0].scaleX = 3.0 * (-1 + 2 * (flipProgress - 0.5)); } } else { // Flip completed - keep normal orientation projectile.children[0].scaleX = 3.0; // Reset for potential next flip after minimum 1 second (60 frames) if (timeSinceFlipStart >= flipDuration + 60) { projectile.hasFlipped = false; projectile.flipStartTime = -1; } //{B6_reset} } } // Add slight rotation for more natural movement (mostly horizontal) projectile.rotation = Math.sin(projectile.lifetime * 0.05) * 0.15; // Small rotation angle projectile.lifetime++; // Check if projectile is off-screen var isOffScreen = projectile.x < -100 || projectile.x > 2148 || projectile.y > 2832 || projectile.y < -100; if (isOffScreen) { // Remove projectile from array and destroy window.moneyProjectiles.splice(i, 1); projectile.destroy(); } } } } // Initialize audienceBPM if not set if (typeof window.audienceBPM === 'undefined') { window.audienceBPM = 120; } // Check for 7 audience members to start confetti spawning if (!hasReached7Audience && musicians.length >= 7) { hasReached7Audience = true; // Spawn first confetti immediately spawnRandomConfetti(); } // Check if it's time to spawn another confetti if (hasReached7Audience && Date.now() >= nextConfettiTime) { spawnRandomConfetti(); } // Initialize drumBPM if not set to ensure drum sounds play if (typeof window.drumBPM === 'undefined') { window.drumBPM = 60; } // Check if all instruments are purchased (guitar, cymbal, maracas) var allInstrumentsPurchased = unlockedInstruments.includes('guitar') && unlockedInstruments.includes('cymbal') && unlockedInstruments.includes('maracas'); // Unlock CD button when audience reaches 5 (regardless of disco mute state) if (musicians.length >= 5 && (cdLockIcon && cdLockIcon.visible || typeof cdShadow !== "undefined" && cdShadow && cdShadow.visible)) { if (menuDecoration) menuDecoration.interactive = true; if (decorationAsset) { decorationAsset.alpha = 0.6; } if (cdLockIcon) cdLockIcon.visible = false; if (typeof cdShadow !== "undefined" && cdShadow) cdShadow.visible = false; } // Check if audience reached 5 for disco lights if (!window.discoLightsActive && musicians.length >= 5 && !window.discoMuted) { // Enable CD button when disco starts if (menuDecoration && !menuDecoration.interactive) { menuDecoration.interactive = true; // Update alpha to show it's now unlocked if (decorationAsset) { decorationAsset.alpha = 0.6; } // Remove lock icon and shadow if (cdLockIcon) cdLockIcon.visible = false; if (typeof cdShadow !== "undefined" && cdShadow) cdShadow.visible = false; } // Start music when disco begins if not already playing if (!isMusicPlaying && !window.globalMuted) { LK.playMusic('ambientMusic', { fade: { start: 0, end: 0.7, duration: 2000 } }); isMusicPlaying = true; // Remove CD shadow when music starts automatically if (decorationAsset) { decorationAsset.alpha = 1.0; } } // Start audience dancing when disco begins if (!window.audienceDancing) { window.audienceDancing = true; // Start dancing animations for all audience members for (var i = 0; i < musicians.length; i++) { var audience = musicians[i]; // Store original position audience.originalX = audience.x; // Start random movement startAudienceDancing(audience); } } // Function to create continuous swinging motion var startDiscoBallSwing = function startDiscoBallSwing() { var swingRight = function swingRight() { tween(window.discoBallContainer, { rotation: 0.2 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { swingLeft(); } }); }; var swingLeft = function swingLeft() { tween(window.discoBallContainer, { rotation: -0.2 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { swingRight(); } }); }; // Start the swing swingRight(); }; // Create container for random top lights window.discoLightsActive = true; // Start CD rotation when disco begins (5 audience) if (!cdRotationTween && decorationAsset && isMusicPlaying) { var rotateContinuously = function rotateContinuously() { // Check if music is still playing before starting new rotation if (!isMusicPlaying) { // Stop any existing tween if music stopped if (cdRotationTween) { tween.stop(cdRotationTween); cdRotationTween = null; } return; } cdRotationTween = tween(decorationAsset, { rotation: decorationAsset.rotation + Math.PI * 2 }, { duration: 4000, easing: tween.linear, onFinish: function onFinish() { if (isMusicPlaying) { rotateContinuously(); // Continue rotating } else { // Ensure tween is cleared if music stopped during animation cdRotationTween = null; } } }); }; // Start music if not already playing and not globally muted if (!isMusicPlaying && !window.globalMuted) { LK.playMusic('ambientMusic', { fade: { start: 0, end: 0.7, duration: 2000 } }); isMusicPlaying = true; } rotateContinuously(); } // Create disco ball hanging from ceiling - add after background (at index 1) // This ensures it's behind piano (in cameraContainer) and disco lights window.discoBallContainer = game.addChildAt(new Container(), 1); window.discoBallContainer.x = 1024; window.discoBallContainer.y = -150; // Start above screen var discoBall = window.discoBallContainer.attachAsset('discoBall', { anchorX: 0.5, anchorY: 0, scaleX: 1, scaleY: 1 }); // Animate disco ball dropping down tween(window.discoBallContainer, { y: 200 }, { duration: 1500, easing: tween.bounceOut, onFinish: function onFinish() { // Start swinging animation startDiscoBallSwing(); } }); // Create disco light container AFTER disco ball (so lights appear in front) window.discoLights = game.addChild(new Container()); // Create multiple colored lights with more vibrant colors var colors = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1]; // DeepPink, SpringGreen, DodgerBlue, Gold, HotPink, DarkTurquoise window.discoLightAssets = []; for (var i = 0; i < 6; i++) { var light = window.discoLights.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 20, alpha: 0.12, x: 200 + i * 300, y: 300 }); light.tint = colors[i]; window.discoLightAssets.push(light); } window.topLights = game.addChild(new Container()); window.topLightPool = []; // Create persistent party overlay window.partyOverlay = game.addChild(new Container()); var partyLight = window.partyOverlay.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 300, scaleY: 300, alpha: 0, x: 1024, y: 1366 }); partyLight.tint = 0xFFFFFF; window.partyOverlayLight = partyLight; // Create full screen light transition effect var fullScreenFlash = game.addChild(new Container()); var flashOverlay = fullScreenFlash.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 250, scaleY: 250, alpha: 0, x: 1024, y: 1366 }); flashOverlay.tint = 0xFFFFFF; // Animate full screen flash with party overlay tween(flashOverlay, { alpha: 0.25 }, { duration: 50, onFinish: function onFinish() { // Fade in party overlay tween(partyLight, { alpha: 0.05 }, { duration: 100 }); tween(flashOverlay, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { fullScreenFlash.destroy(); } }); } }); } // Audience dancing is now triggered with disco lights at 10 audience members // Function to start dancing animation for an audience member function startAudienceDancing(audience) { if (!window.audienceDancing) return; // Create more realistic dance movements var dancePhase = Math.random() < 0.5 ? 'sway' : 'bounce'; if (dancePhase === 'sway') { // Swaying side to side movement var swayDistance = 30 + Math.random() * 40; // 30-70 pixels var swayTime = 800 + Math.random() * 400; // 800-1200ms // Sway to one side tween(audience, { x: audience.originalX + swayDistance, rotation: 0.1 // Slight tilt }, { duration: swayTime, easing: tween.easeInOut, onFinish: function onFinish() { // Sway to other side tween(audience, { x: audience.originalX - swayDistance, rotation: -0.1 // Tilt opposite way }, { duration: swayTime, easing: tween.easeInOut, onFinish: function onFinish() { // Return to center and continue tween(audience, { x: audience.originalX, rotation: 0 }, { duration: swayTime / 2, easing: tween.easeOut, onFinish: function onFinish() { startAudienceDancing(audience); } }); } }); } }); } else { // Bouncing movement without shape distortion var bounceHeight = 15 + Math.random() * 25; // 15-40 pixels var bounceTime = 400 + Math.random() * 200; // 400-600ms // Bounce up - only move position, no scaling tween(audience, { y: audience.y - bounceHeight }, { duration: bounceTime, easing: tween.easeOut, onFinish: function onFinish() { // Bounce down tween(audience, { y: audience.y + bounceHeight }, { duration: bounceTime, easing: tween.bounceOut, onFinish: function onFinish() { startAudienceDancing(audience); } }); } }); } } // Apply dancing to new audience members if dancing is active if (window.audienceDancing && musicians.length > 0) { // Check for new audience members that don't have dancing animation for (var i = 0; i < musicians.length; i++) { var audience = musicians[i]; if (!audience.originalX) { audience.originalX = audience.x; startAudienceDancing(audience); } } } // Animate disco lights if active if (window.discoLightsActive && window.discoLightAssets) { // Animate party overlay with color transitions if (window.partyOverlayLight) { var partyBeatTick = LK.ticks % 120; if (partyBeatTick === 0) { var partyColors = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1]; var newColor = partyColors[Math.floor(Math.random() * partyColors.length)]; tween(window.partyOverlayLight, { tint: newColor, alpha: Math.random() * 0.12 + 0.06 }, { duration: 1000, onFinish: function onFinish() { tween(window.partyOverlayLight, { alpha: 0.08 }, { duration: 1000 }); } }); } } // Flash lights based on beat var beatTick = LK.ticks % 30; if (beatTick === 0) { for (var i = 0; i < window.discoLightAssets.length; i++) { var light = window.discoLightAssets[i]; // Random flashing effect with much lower alpha tween(light, { alpha: Math.random() * 0.25 + 0.1, scaleX: Math.random() * 15 + 15, scaleY: Math.random() * 15 + 15 }, { duration: 200, onFinish: function (light) { return function () { tween(light, { alpha: 0.12, scaleX: 20, scaleY: 20 }, { duration: 200 }); }; }(light) }); } } // Spawn random top lights if (Math.random() < 0.05 && window.topLightPool.length < 10) { var topLight = window.topLights.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 12, scaleY: 12, alpha: 0, x: 200 + Math.random() * 1648, y: 400 + Math.random() * 300 }); topLight.tint = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1][Math.floor(Math.random() * 6)]; // More vibrant colors window.topLightPool.push(topLight); // Fade in and out animation - much faster disappearance tween(topLight, { alpha: Math.random() * 0.3 + 0.15 }, { duration: 200, onFinish: function onFinish() { tween(topLight, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { var index = window.topLightPool.indexOf(topLight); if (index > -1) { window.topLightPool.splice(index, 1); } topLight.destroy(); } }); } }); } } // Synchronize all purchased automatic players to drum hit if (drumsticks.length > 0) { // Get drumstick hit timing var drumTicksPerHit = Math.floor(3600 / (window.drumBPM || 60)); if (LK.ticks % drumTicksPerHit === 0) { // Force drumstick to hit drumsticks[0].tickCounter = drumTicksPerHit; // Synchronize other instruments' first hit with drumstick if (fingers.length > 0 && !fingers[0].hasHitOnce) { // Force finger to hit with drumstick on first hit fingers[0].tickCounter = Math.floor(3600 / (window.guitarBPM || 10)); fingers[0].hasHitOnce = true; } if (autoCymbalsticks.length > 0 && !autoCymbalsticks[0].hasHitOnce) { // Force cymbalstick to hit with drumstick on first hit autoCymbalsticks[0].tickCounter = Math.floor(3600 / (window.cymbalBPM || 30)); autoCymbalsticks[0].hasHitOnce = true; } if (pianists.length > 0 && !pianists[0].hasHitOnce) { // Force pianist to hit with drumstick on first hit pianists[0].tickCounter = Math.floor(3600 / (window.pianoBPM || 10)); pianists[0].hasHitOnce = true; } // Synchronize maracas if purchased if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount > 0 && maracasAsset && !window.maracasHasHitOnce) { // Trigger maracas animation maracasAsset.animate(); window.maracasHasHitOnce = true; } // Synchronize flute if purchased if (window.fluteAutoPlay && fluteAsset && !window.fluteHasHitOnce) { window.fluteAutoPlayCounter = Math.floor(3600 / (window.fluteBPM || 15)); window.fluteHasHitOnce = true; } } } // Automatic flute playing at dynamic BPM when fluteblow is purchased if (window.fluteAutoPlay && fluteAsset) { // Calculate ticks per hit based on dynamic fluteBPM var fluteTicksPerHit = Math.floor(3600 / (window.fluteBPM || 15)); if (typeof window.fluteAutoPlayCounter === 'undefined') window.fluteAutoPlayCounter = 0; window.fluteAutoPlayCounter++; if (window.fluteAutoPlayCounter >= fluteTicksPerHit) { window.fluteAutoPlayCounter = 0; // Animate flute tween(fluteAsset, { scaleX: 3.1, scaleY: 3.1 }, { duration: 100, onFinish: function onFinish() { tween(fluteAsset, { scaleX: 3, scaleY: 3 }, { duration: 100 }); } }); // Generate gold var fluteIncome = 500000; gold += fluteIncome; // Instant gold update displayedGold = gold; // Play flute sound if not muted if (!window.fluteBPMMuted && !window.globalMuted) { LK.getSound('flutehit').play(); } // Create floating text var floatingGold = game.addChild(new FloatingText('+' + fluteIncome, 0x87CEEB)); floatingGold.x = fluteAsset.x + cameraContainer.x; floatingGold.y = fluteAsset.y - 100; // Create music note effect var note = game.addChild(new MusicNote()); note.x = fluteAsset.x + cameraContainer.x + (Math.random() - 0.5) * 100; note.y = fluteAsset.y - 100; } } // Global clap synchronization - use dynamic audienceBPM with single clap only // Calculate ticks per clap based on dynamic audienceBPM var ticksPerClap = Math.floor(3600 / (window.audienceBPM || 30)); if (LK.ticks % ticksPerClap === 0 && musicians.length > 0) { // Single clap only - no patterns if (!window.audienceBPMMuted && !window.globalMuted) { LK.getSound('clap').play(); } } // Maracas automatic shake based on dynamic BPM if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount > 0 && maracasAsset) { var maracasTicksPerShake = Math.floor(3600 / (window.maracasBPM || 120)); if (LK.ticks % maracasTicksPerShake === 0) { // Trigger maracas animation and sound directly without menu check maracasAsset.animate(); } } // Smooth gold display transition if (targetDisplayedGold !== gold) { targetDisplayedGold = gold; } // Smoothly interpolate displayed gold towards target if (displayedGold !== targetDisplayedGold) { var diff = targetDisplayedGold - displayedGold; var step = diff * 0.1; // Adjust 10% of the difference per frame // Ensure minimum step size for small differences if (Math.abs(step) < 0.1) { step = diff > 0 ? 0.1 : -0.1; } // Update displayed gold displayedGold += step; // Snap to target if very close if (Math.abs(displayedGold - targetDisplayedGold) < 0.5) { displayedGold = targetDisplayedGold; } } // Update UI goldText.setText('Dollars: ' + Math.floor(displayedGold)); incomeText.setText('Income: ' + passiveIncome + '/s'); // Defensive: Disable Menu and CD buttons if tutorial is visible if (typeof showTutorial !== "undefined" && showTutorial) { if (menuButton) menuButton.interactive = false; if (menuDecoration) menuDecoration.interactive = false; } // Update button states // FLUTE LOGIC if (currentInstrument === 'flute') { // Update fluteblow button buyDrumstickBtn.updateButton('Fluteblow', fluteblowCost, gold >= fluteblowCost, fluteblowsPurchased); // Audience lock after 50 var isAudienceLockedFlute = musicians.length >= 50; var audienceLockMessageFlute = isAudienceLockedFlute ? 'Max 50 Audience' : ''; buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLockedFlute, musicians.length, isAudienceLockedFlute, audienceLockMessageFlute); // Hide instrument button in flute view buyInstrumentBtn.visible = false; // Show piano button as locked in flute view buyPianoBtn.visible = true; buyPianoBtn.updateButton('Flute', 500000, false, undefined, true, ''); } // PIANO LOGIC else if (currentInstrument === 'piano') { // Update pianist button buyDrumstickBtn.updateButton('Pianist', pianistCost, gold >= pianistCost, pianistsPurchased); // Update audience button - locked until 5 pianists or if guitar is available but not purchased var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased; // Check cymbalstick count for audience lock at 15 var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0; var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10; // Check maracas shake count for audience lock at 25 var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0; var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5; // Check pianist count for audience lock at 50 var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5; var isAudienceLocked = guitarAvailableButNotPurchased || pianistsPurchased < 5 || audienceLocked15 || audienceLocked25 || audienceLocked50; var audienceLockMessage = guitarAvailableButNotPurchased ? 'Buy Guitar First' : audienceLocked50 ? '5 Pianists' : audienceLocked25 ? '5 Maracas Shake' : audienceLocked15 ? '10 Cymbalstick' : isAudienceLocked ? '5 Pianists' : ''; buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage); // Hide instrument button in piano view buyInstrumentBtn.visible = false; // Update piano button (right button) - locked until 5 pianists and 40 audience buyPianoBtn.visible = true; var isPianoLocked = unlockedInstruments.includes('flute') ? true : pianistsPurchased < 5 || musicians.length < 40; var pianoLockMessage = ''; if (unlockedInstruments.includes('flute')) { pianoLockMessage = ''; } else if (pianistsPurchased < 5) { pianoLockMessage = '5 Pianists'; } else if (musicians.length < 40) { pianoLockMessage = '40 Audience'; } buyPianoBtn.updateButton('Flute', 500000, gold >= 500000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage); } // MARACAS LOGIC else if (currentInstrument === 'maracas') { // Initialize maracas shake cost and count if (typeof window.maracasShakeCost === 'undefined') window.maracasShakeCost = 12000; if (typeof window.maracasShakeCount === 'undefined') window.maracasShakeCount = 0; var maracasShakeCost = window.maracasShakeCost; var canAffordMaracasShake = gold >= maracasShakeCost; // Update buyDrumstickBtn for maracas shake - always show count and allow purchase if can afford buyDrumstickBtn.updateButton('Maracas Shake', maracasShakeCost, canAffordMaracasShake, window.maracasShakeCount); // Update audience button - unlock at 25 audience var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased; // Check cymbalstick count for audience lock at 15 var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0; var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10; // Check maracas shake count for audience lock at 25 var audienceLocked25 = musicians.length >= 25 && window.maracasShakeCount < 5; // Check pianist count for audience lock at 50 var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5; var isAudienceLocked = guitarAvailableButNotPurchased || audienceLocked15 || audienceLocked25 || audienceLocked50; var audienceLockMessage = guitarAvailableButNotPurchased ? 'Buy Guitar First' : audienceLocked50 ? '5 Pianists' : audienceLocked25 ? '5 Maracas Shake' : audienceLocked15 ? '10 Cymbalstick' : ''; buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage); // Hide instrument button in maracas view buyInstrumentBtn.visible = false; // Update piano button in maracas view buyPianoBtn.visible = true; // Always lock if piano or flute is already purchased var isPianoLocked = unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute') ? true : window.maracasShakeCount < 5 || musicians.length < 30; var pianoLockMessage = ''; if (unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute')) { pianoLockMessage = ''; } else if (window.maracasShakeCount < 5) { pianoLockMessage = '5 Shakes'; } else if (musicians.length < 30) { pianoLockMessage = '30 Audience'; } // Show Flute if already purchased, otherwise show Piano var buttonLabel = unlockedInstruments.includes('flute') ? 'Flute' : 'Piano'; buyPianoBtn.updateButton(buttonLabel, 30000, gold >= 30000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage); } else if (currentInstrument === 'cymbal') { // Track cymbalstick purchases if (typeof window.cymbalsticksPurchased === 'undefined') window.cymbalsticksPurchased = 0; if (typeof window.cymbalstickCost === 'undefined') window.cymbalstickCost = 2200; var cymbalstickCount = window.cymbalsticksPurchased; var cymbalstickCost = window.cymbalstickCost; var canAffordCymbalstick = gold >= cymbalstickCost; var cymbalstickLocked = cymbalstickCount < 10; // Check if cymbalstick should be locked based on finger count var isCymbalstickLocked = fingersPurchased < 10; var cymbalstickLockMessage = isCymbalstickLocked ? '10 Fingers' : ''; // Update buyDrumstickBtn for cymbalstick buyDrumstickBtn.updateButton('Cymbalstick', cymbalstickCost, canAffordCymbalstick && !isCymbalstickLocked, window.cymbalsticksPurchased, isCymbalstickLocked, cymbalstickLockMessage); // Update audience button - lock until 10 cymbalsticks are purchased or if guitar is available but not purchased var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased; // Also lock audience if count reached 15 and cymbalsticks < 10 var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10; // Check maracas shake count for audience lock at 25 var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0; var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5; // Check pianist count for audience lock at 50 var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5; var isAudienceLocked = guitarAvailableButNotPurchased || cymbalstickCount < 10 || audienceLocked15 || audienceLocked25 || audienceLocked50; var audienceLockMessage = guitarAvailableButNotPurchased ? 'Buy Guitar First' : audienceLocked50 ? '5 Pianists' : audienceLocked25 ? '5 Maracas Shake' : audienceLocked15 ? '10 Cymbalstick' : isAudienceLocked ? '10 Cymbalstick' : ''; buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage); // Update maracas button - lock until 25 audience members are purchased var isMaracasLocked = musicians.length < 25; var maracasLockMessage = musicians.length < 25 ? '25 Audience' : ''; // Check if maracas is already unlocked to determine if button should be visible if (unlockedInstruments.includes('maracas')) { // Hide instrument button when maracas is already unlocked buyInstrumentBtn.visible = false; // Show piano button if maracas is unlocked buyPianoBtn.visible = true; // Always lock piano in cymbal view until 30 audience var isPianoLocked = true; var pianoLockMessage = '30 Audience'; if (unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute')) { pianoLockMessage = ''; } else if (typeof window.maracasShakeCount === 'undefined' || window.maracasShakeCount < 5) { pianoLockMessage = '5 Shakes'; } else if (musicians.length < 30) { pianoLockMessage = '30 Audience'; } // Show Flute if already purchased, otherwise show Piano var buttonLabel = unlockedInstruments.includes('flute') ? 'Flute' : 'Piano'; buyPianoBtn.updateButton(buttonLabel, 30000, false, undefined, isPianoLocked, pianoLockMessage); } else { buyInstrumentBtn.updateButton('Maracas', instrumentCosts.maracas, gold >= instrumentCosts.maracas && !isMaracasLocked, undefined, isMaracasLocked, maracasLockMessage); buyInstrumentBtn.visible = true; } } else { var buttonText = currentInstrument === 'guitar' ? 'Finger' : 'Drumstick'; var purchaseCount = currentInstrument === 'guitar' ? fingersPurchased : drumsticksPurchased; var currentCost = currentInstrument === 'guitar' ? fingerCost : drumstickCost; buyDrumstickBtn.updateButton(buttonText, currentCost, gold >= currentCost, purchaseCount); // Lock audience if guitar is available but not purchased var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased; // Check cymbalstick count for audience lock at 15 var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0; var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10; // Check maracas shake count for audience lock at 25 var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0; var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5; // Check pianist count for audience lock at 50 var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5; var isAudienceLocked = guitarAvailableButNotPurchased || (guitarPurchased ? fingersPurchased < 10 : drumsticksPurchased < 10) || audienceLocked15 || audienceLocked25 || audienceLocked50 || musicians.length >= 50; var lockMessage = ''; if (musicians.length >= 50) { lockMessage = 'Max 50 Audience'; } else if (guitarAvailableButNotPurchased) { lockMessage = 'Buy Guitar First'; } else if (audienceLocked50) { lockMessage = '5 Pianists'; } else if (audienceLocked25) { lockMessage = '5 Maracas Shake'; } else if (audienceLocked15) { lockMessage = '10 Cymbalstick'; } else if (guitarPurchased) { lockMessage = '10 Fingers'; } else { lockMessage = '10 Drumsticks'; } buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, isAudienceLocked ? lockMessage : ''); } // Update instrument button based on current view if (currentInstrument === 'drum' || currentInstrument === 'guitar') { // Check if audience is locked first var isAudienceLocked = guitarPurchased ? fingersPurchased < 10 : drumsticksPurchased < 10; var nextInstrument = null; var cost = 0; if (!unlockedInstruments.includes('guitar')) { nextInstrument = 'guitar'; cost = instrumentCosts.guitar; } else if (!unlockedInstruments.includes('cymbal')) { nextInstrument = 'cymbal'; cost = instrumentCosts.cymbal; } else if (!unlockedInstruments.includes('maracas')) { nextInstrument = 'maracas'; cost = instrumentCosts.maracas; } if (nextInstrument) { var isGuitarLocked = nextInstrument === 'guitar' && (musicians.length < 10 || isAudienceLocked); var isCymbalLocked = nextInstrument === 'cymbal' && (musicians.length < 15 || fingersPurchased < 10); var isMaracasLocked = nextInstrument === 'maracas' && musicians.length < 25; var isLocked = isGuitarLocked || isCymbalLocked || isMaracasLocked; var lockMessage = ''; if (nextInstrument === 'guitar' && isAudienceLocked) { lockMessage = guitarPurchased ? '10 Fingers' : '10 Drumsticks'; } else if (isGuitarLocked) { lockMessage = '10 Audience'; } else if (isCymbalLocked) { if (fingersPurchased < 10) { lockMessage = '10 Fingers'; } else { lockMessage = '15 Audience'; } } else if (isMaracasLocked) { lockMessage = '25 Audience'; } buyInstrumentBtn.updateButton(nextInstrument.charAt(0).toUpperCase() + nextInstrument.slice(1), cost, gold >= cost && !isLocked, undefined, isLocked, lockMessage); buyInstrumentBtn.visible = true; } else if (unlockedInstruments.includes('maracas')) { // Hide instrument button when all instruments are unlocked buyInstrumentBtn.visible = false; // Show piano button if maracas is unlocked buyPianoBtn.visible = true; // Always lock if piano or flute is already purchased var isPianoLocked = unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute') ? true : typeof window.maracasShakeCount === 'undefined' || window.maracasShakeCount < 5 || musicians.length < 30; var pianoLockMessage = ''; if (unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute')) { pianoLockMessage = ''; } else if (typeof window.maracasShakeCount === 'undefined' || window.maracasShakeCount < 5) { pianoLockMessage = '5 Shakes'; } else if (musicians.length < 30) { pianoLockMessage = '30 Audience'; } // Show Flute if already purchased, otherwise show Piano var buttonLabel = unlockedInstruments.includes('flute') ? 'Flute' : 'Piano'; buyPianoBtn.updateButton(buttonLabel, 30000, gold >= 30000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage); } } // Add passive income smoothly (every tick) if (passiveIncome > 0) { // Add fractional income amount per tick var incomePerTick = passiveIncome / 60; gold += incomePerTick; } // Save functionality removed - game resets on reload }; // Load functionality removed - game starts fresh on each reload // Add visibility change listeners for tab switching LK.on('pause', function () { // Game is paused (tab switched away) if (isMusicPlaying && !window.globalMuted) { LK.stopMusic(); window.musicWasPlaying = true; } }); LK.on('resume', function () { // Game is resumed (tab switched back) if (window.musicWasPlaying && !window.globalMuted) { LK.playMusic('ambientMusic', { fade: { start: 0, end: 0.7, duration: 1000 } }); window.musicWasPlaying = false; } }); // Add money button below CD var moneyButton = LK.gui.topRight.addChild(new Container()); var moneyButtonAsset = moneyButton.attachAsset('moneygunmute', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0, rotation: Math.PI / 2, alpha: 0.3 // Start with low alpha to show it's locked }); moneyButton.x = -137; // Moved 3 pixels to the right (was -140) moneyButton.y = 430; // Moved down by 10 more pixels (was 420) moneyButton.interactive = false; // Start as not interactive (locked) // Add black shadow overlay to moneygunmute button var moneyShadow = moneyButton.attachAsset('moneygunmute', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0, rotation: Math.PI / 2, alpha: 0.7, tint: 0x000000, x: 0, y: 0 }); moneyShadow.visible = true; // Add lock icon on money button var moneyLockIcon = moneyButton.attachAsset('lock', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5, x: 0, y: -30 //{JU} // moved up by 30px }); moneyLockIcon.visible = true; window.moneyLockIcon = moneyLockIcon; // Store globally for access // Money button handlers moneyButton.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // Prevent interaction if moneygunmute is locked (shadow or lock icon visible) if (typeof moneyShadow !== "undefined" && moneyShadow && moneyShadow.visible || typeof moneyLockIcon !== "undefined" && moneyLockIcon && moneyLockIcon.visible) return; // Visual feedback: fade alpha to 0.5 and back, like CD tween(moneyButtonAsset, { alpha: 0.5 }, { duration: 80, onFinish: function onFinish() { // Do not set alpha here, let up handler handle it } }); }; moneyButton.up = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // Prevent interaction if moneygunmute is locked (shadow or lock icon visible) if (typeof moneyShadow !== "undefined" && moneyShadow && moneyShadow.visible || typeof moneyLockIcon !== "undefined" && moneyLockIcon && moneyLockIcon.visible) return; // Toggle money gun on/off, and update button alpha like CD if (window.moneyGunActive) { // Turn off money gun window.moneyGunActive = false; if (moneyButtonAsset) { tween(moneyButtonAsset, { alpha: 0.3 }, { duration: 80 }); } if (window.moneyGun) window.moneyGun.visible = false; // Destroy all money projectiles when money gun is hidden if (window.moneyProjectiles && window.moneyProjectiles.length > 0) { for (var i = window.moneyProjectiles.length - 1; i >= 0; i--) { var proj = window.moneyProjectiles[i]; proj.destroy(); window.moneyProjectiles.splice(i, 1); } } } else if (hasHitDrumOnce && window.moneyGun) { // Only turn on money gun if audience is at least 20 if (musicians.length >= 20) { window.moneyGunActive = true; if (moneyButtonAsset) { tween(moneyButtonAsset, { alpha: 1.0 }, { duration: 80 }); } window.moneyGun.visible = true; // Ensure rotation is correct when toggled on window.moneyGun.rotation = Math.PI + Math.PI / 4 + Math.PI / 12 + Math.PI / 36; // Fade in animation when toggled on window.moneyGun.alpha = 0; tween(window.moneyGun, { alpha: 1 }, { duration: 1500, easing: tween.easeOut }); } } }; // CD click handlers menuDecoration.down = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // Prevent interaction if CD is locked (shadow or lock icon visible) if (typeof cdShadow !== "undefined" && cdShadow && cdShadow.visible || typeof cdLockIcon !== "undefined" && cdLockIcon && cdLockIcon.visible) return; // Visual feedback tween(decorationAsset, { scaleX: 0.36, scaleY: 0.36 }, { duration: 10, onFinish: function onFinish() { tween(decorationAsset, { scaleX: 0.4, scaleY: 0.4 }, { duration: 10 }); } }); }; menuDecoration.up = function () { // Block interaction if menu is open if (game.menuContainer && game.menuContainer.parent) return; // Prevent interaction if CD is locked (shadow or lock icon visible) if (typeof cdShadow !== "undefined" && cdShadow && cdShadow.visible || typeof cdLockIcon !== "undefined" && cdLockIcon && cdLockIcon.visible) return; if (!isMusicPlaying) { // Keep CD transparent, will become visible when music actually starts // Start continuous CD rotation var _rotateContinuously = function rotateContinuously() { // Check if music is still playing before starting new rotation if (!isMusicPlaying) { // Stop any existing tween if music stopped if (cdRotationTween) { tween.stop(cdRotationTween); cdRotationTween = null; } return; } cdRotationTween = tween(decorationAsset, { rotation: decorationAsset.rotation + Math.PI * 2 }, { duration: 4000, easing: tween.linear, onFinish: function onFinish() { if (isMusicPlaying) { _rotateContinuously(); // Continue rotating } else { // Ensure tween is cleared if music stopped during animation cdRotationTween = null; } } }); }; // Start music only if not globally muted if (!window.globalMuted) { LK.playMusic('ambientMusic', { fade: { start: 0, end: 0.7, duration: 2000 } }); } isMusicPlaying = true; // Remove shadow by setting alpha to 1 decorationAsset.alpha = 1.0; // Keep CD at constant transparency _rotateContinuously(); } else { // Stop music LK.stopMusic(); isMusicPlaying = false; // Restore shadow by setting alpha back to 0.6 decorationAsset.alpha = 0.6; // Stop CD rotation immediately at current angle if (cdRotationTween) { tween.stop(cdRotationTween); cdRotationTween = null; } // Force stop any pending animations tween.stop(decorationAsset); // Keep current rotation angle decorationAsset.rotation = decorationAsset.rotation; } };
===================================================================
--- original.js
+++ change.js
@@ -3641,9 +3641,9 @@
scaleX: 1.0,
scaleY: 1.0,
rotation: Math.PI,
x: 250,
- y: -1760
+ y: -1780
}));
hasShownInfo = true;
}
// Check if we need to hide info asset when gold reaches 8
Horizontal drumstick for drum 2d pixelart. In-Game asset. 2d. High contrast. No shadows
Drum 2d pixelart. In-Game asset. 2d. no drums
detailed brunette woman from behind pixel art 2d. In-Game asset. 2d. High contrast. No shadows
man pixel art with different clothes
brown yellow haired man pixel art
yellow plus brown haired man pixel art with different colors of clothing
guitar pixel art 2d horizontal. In-Game asset. 2d. High contrast. No shadows
lock pixel art. In-Game asset. 2d. High contrast. No shadows
cymbal instrument pixel art 2d. In-Game asset. 2d. High contrast. No shadows
straight stick pixel art horizontal 2d. In-Game asset. 2d. High contrast. No shadows
maracas instrument pixelart vertical 2d. In-Game asset. 2d. High contrast. No shadows
piano pixelart 2d. In-Game asset. 2d. High contrast. No shadows
pianist man with hat from behind standing in chair without piano pixel art 2d
flute pixel art 2d vertical. In-Game asset. 2d. High contrast. No shadows
disco ball pixel art 2d. In-Game asset. 2d. High contrast. No shadows
Pixel art style
Confetti stick, 2d pixel art vertical. no papers only stick. In-Game asset. 2d. High contrast. No shadows
disco ball pixel art 2d. In-Game asset. 2d. High contrast. No shadows
Make different variations this pixel art change clothes, change hairstyle
make different variations of this pixel art change hairstyle, clothing
make different hairstyle and clothing, you can use cap etc.
make different hairstyle and clothing
make different hairstyle and clothing
make different hairstyle and clothing, you can make punk
make different clothing, you can make it blonde
make different hairstyle and clothing, you can make man wearing hoodie
One Confetti paper pixelart 2d. In-Game asset. 2d. High contrast. No shadows
Remove band clicker write, make drum in the middle
Make it red
Make it green
Make it blue
make it white
make it purple
#F3D296 colour small arrow pixel art. In-Game asset. 2d. High contrast. No shadows
Change writing to the ''MENU''
Make empty pixel art game card. #f3d296 color. In-Game asset. 2d. High quality. No shadows
Remove ball,
Remove stick, left ball alone
Change writing to the ''BPM OPTIONS'' pixel art
Make audio's lines dark black, audio color dark gray. Make x's lines black and inside color red.
Remove audio, left x
Make it brown
Can you make it lighter
make it #7d522e
Money gun pixel art. Without money, horizontal. In-Game asset. 2d. High contrast. No shadows
Make it red box
Make it resd