User prompt
Clap cpm 60 olarak ayarla
User prompt
Menüdeki cpm ayarı 5 ve katları olsun
User prompt
audience clap animasyonunu hafiflet, arka plan sallanmasını biraz hafiflet, disko ışıklarını birazcık daha belirgin yap
User prompt
cd, satın aldıktan 0,3 saniye sonra başlasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ilk drumstick aldığımız anda cd dönerek song başlasın ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
maracasshake 1 olduktan sonra arkaplan titreşimi olsun parti büyüsün ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
maracas shake satın alındığı andan sonra arkaplan çok hafif ritimle titresin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
audience 25e geldiği zaman assetler dans etsin sağa sola doğru random gezsinler
User prompt
flute mend cpm ayarları çalışmıyor
User prompt
ceyi çok hafif sola alalım. cdye tıklama animasyonu çok hızlı bitsin ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Fluteblow assetini silelim. Fluteblow butonunu satın aldığımızda, flute kendi kendine 10 CBM ile hit olsun
User prompt
fluteblow assetini silelim. Flute kendi kendine 10 CBM ile çalsın
User prompt
cymbal ekranında piano butonu kilitli görünsün
User prompt
piyanonun kilidi, cymbal ekranında 30 audience de açıldı onu da 50 yapalım
User prompt
pianonun kilidi audience 50 olunca açılsın, audience 50ye vardığı zaman 5 pianist olana kadar kilitlensin
User prompt
Maracas, audience 25 olduğu zaman kilidinden kurtulacak
User prompt
Audience 25te kilitlensin, maracas shake 5 olmadan kilidi açılmasın. Maracas audience 25 olduğunda kilidi açılsın.
User prompt
audience 15 olduğunda kilitlensin, ve cymbalstick 10 tane olana kadar kilitli kalsın
User prompt
cymbalstick 10 olana kadar audience kilitli kalsın
User prompt
cymbal açılıp satın alınana kadar audience kilitlensin ve kilitli görünsün
User prompt
cymbal kilidi açılıp satın alınana kadar audience kilitlensin
User prompt
guitar kilidi açılınca guitar satın alınana kadar audience kilitlensin
User prompt
drum ekranında audience maximum 10 adet alınabilsin daha sonra kilitlensin
User prompt
ışıkların spawn olma konumlarını biraz aşağıya kaydıralım ve boyutlarını hafif büyütelim
User prompt
transparent biraz daha olsun, random spawning ışıklar çok hızlı kaybolsun ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * 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 sequentially var audienceAssets = ['audience1', 'audience2', 'audience3', 'audience4', 'audience5', 'audience6', 'audience7', 'audience8']; var selectedAsset; // If guitar is purchased, use reverse order starting from audience8 if (guitarPurchased) { // Reverse order: audience8, audience7, audience6, etc. selectedAsset = audienceAssets[7 - audienceCounter % audienceAssets.length]; } else { // Normal order for initial audiences selectedAsset = audienceAssets[audienceCounter % audienceAssets.length]; } 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 clapCPM var ticksPerClap = Math.floor(3600 / (window.clapCPM || 120)); if (LK.ticks % ticksPerClap === 0) { // Determine clap pattern based on cycle var clapCycle = Math.floor(LK.ticks / ticksPerClap) % 16; if (clapCycle === 6 || clapCycle === 7) { // Double clap animation (bigger) tween(self, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); } else if (clapCycle === 14 || clapCycle === 15) { // Four times clap animation (biggest) tween(self, { scaleX: 1.15, scaleY: 1.15 }, { duration: 100, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); } else { // Single clap animation (smaller) tween(self, { scaleX: 1.05, scaleY: 1.05 }, { 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 CBM (Cymbal Beats per Minute) - synchronized with drum self.income = 10; // 10 gold per hit self.animating = false; self.tickCounter = 0; self.cymbalReference = null; self.update = function () { self.tickCounter++; // Hit based on dynamic CPM var ticksPerHit = Math.floor(3600 / (window.cymbalCPM || 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; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Play cymbal sound if not muted if (!window.cymbalCPMMuted) { 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 = 1; self.animating = false; self.tickCounter = 0; self.drumReference = null; self.update = function () { self.tickCounter++; // Hit based on dynamic CPM var ticksPerHit = Math.floor(3600 / (window.drumCPM || 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; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Play drum sound if not muted if (!window.drumCPMMuted) { LK.getSound('drumhit').play(); } // 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 = 1500; // Higher income than drumstick self.animating = false; self.tickCounter = 0; self.guitarReference = null; self.update = function () { self.tickCounter++; // Click based on dynamic CPM var ticksPerHit = Math.floor(3600 / (window.guitarCPM || 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() { // Generate gold when strumming var startGold = gold; gold += self.income; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Play guitar sound if not muted if (!window.guitarCPMMuted) { LK.getSound('guitarhit').play(); } // Visual feedback on guitar if reference exists if (self.guitarReference) { 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 AutoFluteblow = Container.expand(function () { var self = Container.call(this); var blowGraphics = self.attachAsset('fluteblowNew', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1; self.income = 3000; // Higher income than pianist self.animating = false; self.tickCounter = 0; self.fluteReference = null; self.update = function () { self.tickCounter++; // Hit based on dynamic CPM var ticksPerHit = Math.floor(3600 / (window.fluteCPM || 10)); if (self.tickCounter >= ticksPerHit && !self.animating) { self.tickCounter = 0; self.animate(); } }; self.animate = function () { if (self.animating) return; self.animating = true; // Move up first tween(self, { y: self.y - 20 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Then move down for hit tween(self, { y: self.y + 40 }, { duration: 150, easing: tween.easeIn, onFinish: function onFinish() { // Generate gold when hitting var startGold = gold; gold += self.income; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Play flute sound if not muted if (!window.fluteCPMMuted) { LK.getSound('flutehit').play(); } // Visual feedback removed // Return to original position tween(self, { y: self.y - 20 }, { duration: 150, easing: tween.easeOut, 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: '#ffffff', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); self.titleText.anchor.set(0.5, 0.5); self.titleText.y = -15; self.addChild(self.titleText); self.costText = new Text2('', { size: 30, fill: '#ffffff', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); self.costText.anchor.set(0.5, 0.5); self.costText.y = 15; self.addChild(self.costText); self.countText = new Text2('', { size: 50, fill: '#FFD700', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); self.countText.anchor.set(0.5, 0.5); self.countText.x = -150; 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; } buttonBg.tint = canAfford ? 0x4CAF50 : 0x808080; self.interactive = canAfford; } }; 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 = perfectTiming ? goldPerTap * 2 : goldPerTap; var startGold = gold; gold += reward; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Create light flash effect var lightFlash = self.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3, alpha: 0.8 }); lightFlash.tint = perfectTiming ? 0xFFD700 : 0xFFFFFF; tween(lightFlash, { scaleX: 5, scaleY: 5, alpha: 0 }, { duration: 300, onFinish: function onFinish() { lightFlash.destroy(); } }); // 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.cymbalCPMMuted) { 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; 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 = perfectTiming ? goldPerTap * 2 : goldPerTap; var startGold = gold; gold += reward; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Create light flash effect var lightFlash = self.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 10, alpha: 0.8 }); lightFlash.tint = perfectTiming ? 0xFFD700 : 0xFFFFFF; tween(lightFlash, { scaleX: 15, scaleY: 15, alpha: 0 }, { duration: 300, onFinish: function onFinish() { lightFlash.destroy(); } }); // 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.drumCPMMuted) { LK.getSound('drumhit').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.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 () { 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 var reward = perfectTiming ? goldPerTap * 2 : goldPerTap; var startGold = gold; gold += reward; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Create light flash effect var lightFlash = self.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3, alpha: 0.8 }); lightFlash.tint = perfectTiming ? 0xFFD700 : 0xFFFFFF; tween(lightFlash, { scaleX: 5, scaleY: 5, alpha: 0 }, { duration: 300, onFinish: function onFinish() { lightFlash.destroy(); } }); // 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 guitar sound if not muted if (!window.guitarCPMMuted) { 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(); }; 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 = 2000; // Higher income than other auto-players self.animating = false; self.tickCounter = 0; self.pianoReference = null; self.update = function () { self.tickCounter++; // Hit based on dynamic CPM var ticksPerHit = Math.floor(3600 / (window.pianoCPM || 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; // Smooth gold animation tween({ value: displayedGold }, { value: gold }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { displayedGold = gold; } }); var tweenObj = { value: displayedGold }; tween(tweenObj, { value: gold }, { duration: 300, easing: tween.easeOut }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); // Play piano sound if not muted if (!window.pianoCPMMuted) { 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; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a1a }); /**** * Game Code ****/ // Game variables var gold = 0; var displayedGold = 0; // Track displayed gold for smooth animation var goldPerTap = 20000; 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 = 5000; // Cost for pianist var fluteblows = []; // Track AutoFluteblow instances var fluteblowsPurchased = 0; // Track fluteblows purchased var fluteblowCost = 8000; // Cost for fluteblow // Upgrade costs var drumstickCost = 10; var fingerCost = 300; // Separate cost for fingers var musicianCost = 100; var guitarPurchased = false; // Track if guitar has been purchased var instrumentCosts = { guitar: 500, cymbal: 1000, maracas: 2000 }; // UI Elements var goldText = new Text2('Gold: 0', { size: 80, fill: '#FFD700', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 3 }); goldText.anchor.set(0.5, 0); goldText.y = 10; LK.gui.top.addChild(goldText); // Add menu button var menuButton = new Container(); var menuBg = menuButton.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); menuBg.tint = 0xFFD700; // Yellow color var menuText = new Text2('Menu', { size: 50, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); menuText.anchor.set(0.5, 0.5); menuButton.addChild(menuText); menuButton.interactive = true; LK.gui.topRight.addChild(menuButton); menuButton.x = -170; menuButton.y = 70; // 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 }); menuDecoration.x = -165; menuDecoration.y = 320; // Make CD interactive menuDecoration.interactive = 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: 50, fill: '#ffffff', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); incomeText.anchor.set(0.5, 0); incomeText.y = 100; LK.gui.top.addChild(incomeText); // 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; // 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.maracasCPMMuted) { 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 // Buy buttons - Add to GUI layer to ensure they're always on top var buyDrumstickBtn = LK.gui.bottom.addChild(new BuyButton()); buyDrumstickBtn.x = -480; buyDrumstickBtn.y = -532; buyDrumstickBtn.updateButton('Drumstick', drumstickCost, false); var buyMusicianBtn = LK.gui.bottom.addChild(new BuyButton()); buyMusicianBtn.x = 0; buyMusicianBtn.y = -532; buyMusicianBtn.updateButton('Audience', musicianCost, false, 0, true, ''); var buyInstrumentBtn = LK.gui.bottom.addChild(new BuyButton()); buyInstrumentBtn.x = 480; buyInstrumentBtn.y = -532; 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 = 480; // Same position as instrument button buyMaracasSpecialBtn.y = -532; buyMaracasSpecialBtn.visible = false; // Hidden by default buyMaracasSpecialBtn.updateButton('Special', 5000, false, 0, true, '5 Shakes + 30 Audience'); // Add piano button - always at rightmost position var buyPianoBtn = LK.gui.bottom.addChild(new BuyButton()); buyPianoBtn.x = 480; // Same x position as instrument button buyPianoBtn.y = -532; buyPianoBtn.visible = false; // Hidden by default buyPianoBtn.updateButton('Piano', 10000, false, 0, true, '5 Shakes + 30 Audience'); // Menu button handler menuButton.down = function () { // Visual feedback tween(menuBg, { scaleX: 0.72, scaleY: 0.72 }, { duration: 100, onFinish: function onFinish() { tween(menuBg, { scaleX: 0.8, scaleY: 0.8 }, { 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 >= 5000) { gold -= 5000; 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 >= 50 && gold >= 20000) { gold -= 20000; 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.fluteCPMMuted) { 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 = goldPerTap * 4; // Flute gives 4x reward 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 >= 10000) { gold -= 10000; 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 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 = goldPerTap * 3; // Piano gives 3x reward 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 // Dark overlay var overlay = menuContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 200, scaleY: 200, alpha: 0.7 }); overlay.tint = 0x000000; // 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 - pixelart style with bold font var menuTitle = new Text2('MENU', { size: 150, fill: '#3E2723', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 5 }); menuTitle.anchor.set(0.5, 0.5); menuTitle.y = -650; menuContainer.addChild(menuTitle); // Sound effect controls var soundEffects = [{ name: 'Drum', sound: 'drumhit', unlocked: drumsticksPurchased > 0, cpmVar: 'drumCPM', defaultCPM: 60 }, { name: 'Guitar', sound: 'guitarhit', unlocked: guitarPurchased, cpmVar: 'guitarCPM', defaultCPM: 10 }, { name: 'Cymbal', sound: 'cymbalhit', unlocked: unlockedInstruments.includes('cymbal'), cpmVar: 'cymbalCPM', defaultCPM: 30 }, { name: 'Maracas', sound: 'maracashit', unlocked: unlockedInstruments.includes('maracas'), cpmVar: 'maracasCPM', defaultCPM: 120 }, { name: 'Piano', sound: 'pianohit', unlocked: unlockedInstruments.includes('piano'), cpmVar: 'pianoCPM', defaultCPM: 10 }, { name: 'Flute', sound: 'flutehit', unlocked: unlockedInstruments.includes('flute'), cpmVar: 'fluteCPM', defaultCPM: 10 }, { name: 'Audience', sound: 'clap', unlocked: musicians.length > 0, cpmVar: 'clapCPM', defaultCPM: 120 }]; var yOffset = -520; for (var i = 0; i < soundEffects.length; i++) { var effect = soundEffects[i]; // Show all effects, both locked and unlocked // Initialize CPM if not set (only for unlocked effects) if (effect.unlocked && typeof window[effect.cpmVar] === 'undefined') { window[effect.cpmVar] = effect.defaultCPM; } // Sound effect container var soundContainer = menuContainer.addChild(new Container()); soundContainer.y = yOffset; soundContainer.x = -50; // Move container slightly to the left // Sound icon instead of text var assetId = ''; var iconScale = 0.08; switch (effect.name) { case 'Drum': assetId = 'drum'; break; case 'Guitar': assetId = 'guitar'; iconScale = 0.15; break; case 'Cymbal': assetId = 'cymbal'; iconScale = 0.12; break; case 'Maracas': assetId = 'maracas'; iconScale = 0.1; break; case 'Piano': assetId = 'piano'; iconScale = 0.1; break; case 'Flute': assetId = 'flute'; iconScale = 0.15; break; case 'Audience': assetId = 'audience1'; iconScale = 0.08; break; } if (assetId) { var soundIcon = soundContainer.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5, scaleX: iconScale, scaleY: iconScale, x: -300, y: 0 }); if (!effect.unlocked) { soundIcon.tint = 0x808080; // Gray tint for locked items } } else { // Fallback to text if no asset var soundName = new Text2(effect.name, { size: 40, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); soundName.anchor.set(0, 0.5); soundName.x = -300; soundContainer.addChild(soundName); } // Show controls only for unlocked effects if (effect.unlocked) { // Initialize mute state if not set var muteVar = effect.cpmVar + 'Muted'; if (typeof window[muteVar] === 'undefined') { window[muteVar] = false; } // Horizontal 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 = 0x666666; // CPM display text var cpmText = new Text2(window[effect.cpmVar] + ' CPM', { size: 30, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); cpmText.anchor.set(0.5, 0.5); cpmText.x = 80; soundContainer.addChild(cpmText); // 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: 40, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); minusText.anchor.set(0.5, 0.5); minusBtn.addChild(minusText); minusBtn.x = -80; minusBtn.interactive = true; // Plus button var plusBtn = soundContainer.addChild(new Container()); var plusBg = plusBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.5 }); plusBg.tint = 0x66FF66; var plusText = new Text2('+', { size: 40, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); plusText.anchor.set(0.5, 0.5); plusBtn.addChild(plusText); plusBtn.x = 240; plusBtn.interactive = true; // Mute button var muteBtn = soundContainer.addChild(new Container()); var muteBg = muteBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.5 }); muteBg.tint = window[muteVar] ? 0xFF0000 : 0xFFAA00; // Add mute icon instead of text var muteIcon = muteBtn.attachAsset('musicNote', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); muteIcon.tint = window[muteVar] ? 0x666666 : 0xFFFFFF; muteBtn.x = 465; // Moved further left muteBtn.interactive = true; // Create closure to capture variables (function (effect, cpmText, minusBtn, plusBtn, minusBg, plusBg, muteBtn, muteBg, muteIcon, muteVar) { // Minus button handlers minusBtn.down = function () { tween(minusBg, { scaleX: 0.25, scaleY: 0.45 }, { duration: 100, onFinish: function onFinish() { tween(minusBg, { scaleX: 0.3, scaleY: 0.5 }, { duration: 100 }); } }); }; minusBtn.up = function () { if (window[effect.cpmVar] > 10) { window[effect.cpmVar] -= 10; cpmText.setText(window[effect.cpmVar] + ' CPM'); } }; // Plus button handlers plusBtn.down = function () { tween(plusBg, { scaleX: 0.25, scaleY: 0.45 }, { duration: 100, onFinish: function onFinish() { tween(plusBg, { scaleX: 0.3, scaleY: 0.5 }, { duration: 100 }); } }); }; plusBtn.up = function () { if (window[effect.cpmVar] < 200) { window[effect.cpmVar] += 10; cpmText.setText(window[effect.cpmVar] + ' CPM'); } }; // Mute button handlers muteBtn.down = function () { tween(muteBg, { scaleX: 0.25, scaleY: 0.45 }, { duration: 100, onFinish: function onFinish() { tween(muteBg, { scaleX: 0.3, scaleY: 0.5 }, { duration: 100 }); } }); }; muteBtn.up = function () { window[muteVar] = !window[muteVar]; muteBg.tint = window[muteVar] ? 0xFF0000 : 0xFFAA00; muteIcon.tint = window[muteVar] ? 0x666666 : 0xFFFFFF; }; })(effect, cpmText, minusBtn, plusBtn, minusBg, plusBg, muteBtn, muteBg, muteIcon, muteVar); } else { // Add lock overlay for locked effects // Dark overlay for locked effects var lockOverlay = soundContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 20, scaleY: 1, alpha: 0.5, x: 0, y: 0 }); lockOverlay.tint = 0x000000; // Lock icon var lockIcon = soundContainer.attachAsset('lock', { anchorX: 0.5, anchorY: 0.5, x: 50, y: 0 }); } yOffset += 100; } // Reset CPM button var resetCPMBtn = menuContainer.addChild(new Container()); var resetCPMBg = resetCPMBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); resetCPMBg.tint = 0xFFAA00; var resetCPMText = new Text2('Reset CPM', { size: 48, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); resetCPMText.anchor.set(0.5, 0.5); resetCPMBtn.addChild(resetCPMText); resetCPMBtn.y = 250; resetCPMBtn.interactive = true; // Reset CPM button handlers resetCPMBtn.down = function () { tween(resetCPMBg, { scaleX: 1.08, scaleY: 1.08 }, { duration: 100, onFinish: function onFinish() { tween(resetCPMBg, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100 }); } }); }; resetCPMBtn.up = function () { // Close menu first menuContainer.destroy(); game.menuContainer = null; // Create confirmation dialog on GUI layer var confirmContainer = LK.gui.center.addChild(new Container()); // Dark overlay var confirmOverlay = confirmContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 200, scaleY: 200, alpha: 0.7 }); confirmOverlay.tint = 0x000000; // Dialog box - darker color var dialogBg = confirmContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); dialogBg.tint = 0x404040; // Dark gray color // Confirmation text var confirmText = new Text2('Reset All CPM Values?', { size: 60, fill: '#FFFFFF', 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('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); yesBg.tint = 0x4CAF50; var yesText = new Text2('Yes', { size: 40, fill: '#FFFFFF', 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: '#FFFFFF', 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 CPM values to defaults window.drumCPM = 60; window.guitarCPM = 10; window.cymbalCPM = 30; window.maracasCPM = 120; window.pianoCPM = 10; window.fluteCPM = 10; window.clapCPM = 120; // Close confirmation dialog confirmContainer.destroy(); // Reopen menu to refresh display menuButton.up(); // Reopen menu }; // 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(); // Reopen menu menuButton.up(); // Reopen menu }; }; // Reset button - smaller and moved down 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: 48, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); resetBtnText.anchor.set(0.5, 0.5); resetBtn.addChild(resetBtnText); resetBtn.y = 448; resetBtn.interactive = true; // Close button - smaller and moved down var closeBtn = menuContainer.addChild(new Container()); var closeBtnBg = closeBtn.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); closeBtnBg.tint = 0x4CAF50; var closeBtnText = new Text2('Close', { size: 48, fill: '#FFFFFF', font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif", letterSpacing: 2 }); closeBtnText.anchor.set(0.5, 0.5); closeBtn.addChild(closeBtnText); closeBtn.y = 640; 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 () { // Close menu first menuContainer.destroy(); game.menuContainer = null; // Create confirmation dialog on GUI layer var confirmContainer = LK.gui.center.addChild(new Container()); // Dark overlay var confirmOverlay = confirmContainer.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 200, scaleY: 200, alpha: 0.7 }); confirmOverlay.tint = 0x000000; // Dialog box - darker color var dialogBg = confirmContainer.attachAsset('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.5, scaleY: 2.5 }); dialogBg.tint = 0x404040; // Dark gray color // Confirmation text var confirmText = new Text2('Reset All Progress?', { size: 60, fill: '#FFFFFF', 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('buyButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); yesBg.tint = 0x4CAF50; var yesText = new Text2('Yes', { size: 40, fill: '#FFFFFF', 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: '#FFFFFF', 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; // 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(); }; }; // Close button handler closeBtn.down = function () { tween(closeBtnBg, { scaleX: 1.08, scaleY: 1.08 }, { duration: 100, onFinish: function onFinish() { tween(closeBtnBg, { scaleX: 1.2, scaleY: 1.2 }, { 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; } // 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++; // Create fluteblow if it doesn't exist if (fluteblows.length === 0) { var newFluteblow = cameraContainer.addChild(new AutoFluteblow()); // Position fluteblow at upper part of flute if (fluteAsset) { newFluteblow.x = fluteAsset.x; newFluteblow.y = fluteAsset.y - 450; // Position higher at upper part of flute } else { // Default position if flute doesn't exist newFluteblow.x = 11364; newFluteblow.y = 1220 - 450; } // Set flute reference for visual feedback newFluteblow.fluteReference = fluteAsset; fluteblows.push(newFluteblow); } passiveIncome += 24; // Fluteblow generates 24 gold per second LK.getSound('purchase').play(); // 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 - 200; } else { // Default position if piano doesn't exist newPianist.x = 9316; newPianist.y = 1220 - 200; } // Set piano reference for visual feedback newPianist.pianoReference = pianoAsset; pianists.push(newPianist); } passiveIncome += 16; // Pianist generates 16 gold per second 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 = 700; 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++; // Play maracas sound and animate if (maracasAsset) { // Trigger maracas animation directly maracasAsset.animate(); } LK.getSound('purchase').play(); // 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 = 600; 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; autoCymbalsticks.push(newAutoCymbalstick); } passiveIncome += 10; // Auto cymbal stick generates 10 gold per second // Increase cost for next cymbalstick (optional, can be fixed if desired) window.cymbalstickCost = Math.floor(window.cymbalstickCost * 1.3); 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; fingers.push(newFinger); } passiveIncome += 4; // Fingers generate 4 gold per second 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); } passiveIncome += 1; drumstickCost = Math.floor(drumstickCost * 1.3); } LK.getSound('purchase').play(); // 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 canPurchase = guitarPurchased ? fingersPurchased >= requiredFingers : drumsticksPurchased >= 10; if (canPurchase && gold >= musicianCost) { gold -= musicianCost; var newAudience = game.addChild(new Audience()); // Random spawn position at bottom of screen newAudience.x = 200 + Math.random() * 1648; // Random x between 200 and 1848 newAudience.y = 2400; // Fixed y position for horizontal alignment // 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); } musicians.push(newAudience); goldPerTap = Math.floor(goldPerTap * newAudience.multiplier); passiveIncome += 4; // Each audience generates 4 gold per second // Increase cost by 1.3x before guitar, 1.3x (30%) after guitar musicianCost = Math.floor(musicianCost * 1.3); 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' || typeof window.cymbalsticksPurchased !== 'undefined' && window.cymbalsticksPurchased >= 10)) { gold -= cost; unlockedInstruments.push(nextInstrument); instrumentsPurchased++; // Set guitar purchased flag and update musician cost to 2000 if (nextInstrument === 'guitar') { guitarPurchased = true; musicianCost = 2000; guitarAsset.visible = true; // Show guitar } else if (nextInstrument === 'cymbal') { // Show cymbal cymbalAsset.visible = true; } else if (nextInstrument === 'maracas') { // Show maracas maracasAsset.visible = true; // Show piano button when maracas is purchased buyPianoBtn.visible = true; } 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; // Main game loop game.update = function () { // Check if all instruments are purchased (guitar, cymbal, maracas) var allInstrumentsPurchased = unlockedInstruments.includes('guitar') && unlockedInstruments.includes('cymbal') && unlockedInstruments.includes('maracas'); // Check if audience reached 15 for disco lights if (!window.discoLightsActive && musicians.length >= 15) { window.discoLightsActive = true; // Create disco light container window.discoLights = game.addChild(new Container()); // Create multiple colored lights var colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF]; window.discoLightAssets = []; for (var i = 0; i < 6; i++) { var light = window.discoLights.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5, scaleX: 15, scaleY: 15, alpha: 0.08, x: 200 + i * 300, y: 300 }); light.tint = colors[i]; window.discoLightAssets.push(light); } // Create container for random top lights window.topLights = game.addChild(new Container()); window.topLightPool = []; } // Animate disco lights if active if (window.discoLightsActive && window.discoLightAssets) { // 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.15 + 0.05, scaleX: Math.random() * 10 + 10, scaleY: Math.random() * 10 + 10 }, { duration: 200, onFinish: function (light) { return function () { tween(light, { alpha: 0.08, scaleX: 15, scaleY: 15 }, { 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: 8, scaleY: 8, alpha: 0, x: 200 + Math.random() * 1648, y: 100 + Math.random() * 200 }); topLight.tint = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF][Math.floor(Math.random() * 6)]; window.topLightPool.push(topLight); // Fade in and out animation - much faster disappearance tween(topLight, { alpha: Math.random() * 0.2 + 0.1 }, { 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 automatic players to drum hit (60 BPM = every 60 ticks) if (allInstrumentsPurchased && LK.ticks % 60 === 0) { // Force all automatic players to hit at the same time if (drumsticks.length > 0) { drumsticks[0].tickCounter = 60; // Force drumstick to hit } if (fingers.length > 0) { // Adjust finger to hit every 6 drum beats (360 ticks) if (LK.ticks % 360 === 0) { fingers[0].tickCounter = 360; // Force finger to hit } } if (autoCymbalsticks.length > 0) { // Adjust cymbalstick to hit at 30 BPM (120 ticks) - half speed if (LK.ticks % 120 === 0) { autoCymbalsticks[0].tickCounter = 120; // Force cymbalstick to hit } } if (pianists.length > 0) { // Adjust pianist to hit every 120 ticks (0.5 hits per second) if (LK.ticks % 120 === 0) { pianists[0].tickCounter = 120; // Force pianist to hit } } if (fluteblows.length > 0) { // Adjust fluteblow to hit every 120 ticks (0.5 hits per second) if (LK.ticks % 120 === 0) { fluteblows[0].tickCounter = 120; // Force fluteblow to hit } } } // Global clap synchronization - use dynamic clapCPM from menu // Calculate ticks per clap based on clapCPM var ticksPerClap = Math.floor(3600 / (window.clapCPM || 120)); // Default 120 CPM if (LK.ticks % ticksPerClap === 0 && musicians.length > 0) { // Determine clap pattern based on global counter var clapCycle = Math.floor(LK.ticks / ticksPerClap) % 16; globalClapPhase = clapCycle; if (clapCycle === 6 || clapCycle === 7) { // Double clap (7th and 8th in pattern) - faster with rapid clap-clap if (!window.clapCPMMuted) { LK.getSound('clap').play(); LK.setTimeout(function () { if (!window.clapCPMMuted) { LK.getSound('clap').play(); } }, 100); // Faster delay for rapid double clap effect } } else if (clapCycle === 14 || clapCycle === 15) { // Four times clap (15th and 16th in pattern) - slightly slower rapid clap-clap if (!window.clapCPMMuted) { LK.getSound('clap').play(); LK.setTimeout(function () { if (!window.clapCPMMuted) { LK.getSound('clap').play(); } }, 80); // Slightly slower for controlled rapid clap-clap LK.setTimeout(function () { if (!window.clapCPMMuted) { LK.getSound('clap').play(); } }, 160); LK.setTimeout(function () { if (!window.clapCPMMuted) { LK.getSound('clap').play(); } }, 240); } } else { // Single clap (other phases) if (!window.clapCPMMuted) { LK.getSound('clap').play(); } } } // Maracas automatic shake based on dynamic CPM if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount > 0 && maracasAsset) { var maracasTicksPerShake = Math.floor(3600 / (window.maracasCPM || 120)); if (LK.ticks % maracasTicksPerShake === 0) { // Trigger maracas animation and sound directly without menu check maracasAsset.animate(); } } // Update UI goldText.setText('Gold: ' + Math.floor(displayedGold)); incomeText.setText('Income: ' + passiveIncome + '/s'); // Update button states // FLUTE LOGIC if (currentInstrument === 'flute') { // Update fluteblow button buyDrumstickBtn.updateButton('Fluteblow', fluteblowCost, gold >= fluteblowCost, fluteblowsPurchased); // Update audience button - always unlocked in flute view buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost, musicians.length, false, ''); // Hide instrument button in flute view buyInstrumentBtn.visible = false; // Show piano button as locked in flute view buyPianoBtn.visible = true; buyPianoBtn.updateButton('Flute', 20000, 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 var isAudienceLocked = pianistsPurchased < 5; var audienceLockMessage = 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 50 audience buyPianoBtn.visible = true; var isPianoLocked = unlockedInstruments.includes('flute') ? true : pianistsPurchased < 5 || musicians.length < 50; var pianoLockMessage = ''; if (unlockedInstruments.includes('flute')) { pianoLockMessage = ''; } else if (pianistsPurchased < 5) { pianoLockMessage = '5 Pianists'; } else if (musicians.length < 50) { pianoLockMessage = '50 Audience'; } buyPianoBtn.updateButton('Flute', 20000, gold >= 20000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage); } // MARACAS LOGIC else if (currentInstrument === 'maracas') { // Initialize maracas shake cost and count if (typeof window.maracasShakeCost === 'undefined') window.maracasShakeCost = 700; 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 when maracas shake count reaches 5 var isAudienceLocked = window.maracasShakeCount < 5; var audienceLockMessage = isAudienceLocked ? '5 Maracas Shake' : ''; 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, 10000, gold >= 10000 && !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 = 600; 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 var isAudienceLocked = cymbalstickCount < 10; var audienceLockMessage = isAudienceLocked ? '10 Cymbalstick' : ''; buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage); // Update maracas button - lock until 20 audience members are purchased OR if audience is locked var isMaracasLocked = musicians.length < 20 || isAudienceLocked; var maracasLockMessage = isAudienceLocked ? audienceLockMessage : musicians.length < 20 ? '20 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 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, 10000, gold >= 10000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage); } else { buyInstrumentBtn.updateButton('Maracas', 2000, gold >= 2000 && !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); var isAudienceLocked = guitarPurchased ? fingersPurchased < 10 : drumsticksPurchased < 10; var lockMessage = guitarPurchased ? '10 Fingers' : '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' && (typeof window.cymbalsticksPurchased === 'undefined' || window.cymbalsticksPurchased < 10); 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 = '10 Cymbalstick'; } 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, 10000, gold >= 10000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage); } } // Smooth passive income animation if (passiveIncome > 0 && Math.abs(gold - displayedGold) < 0.1) { // Start a new tween for the next second of income var targetGold = gold + passiveIncome; gold = targetGold; // Update actual gold value tween({ value: displayedGold }, { value: targetGold }, { duration: 1000, onFinish: function onFinish() { displayedGold = targetGold; } }); // Update displayedGold during tween var tweenObj = { value: displayedGold }; tween(tweenObj, { value: targetGold }, { duration: 1000, easing: tween.linear, onFinish: function onFinish() { displayedGold = tweenObj.value; } }); Object.defineProperty(tweenObj, 'value', { get: function get() { return displayedGold; }, set: function set(v) { displayedGold = v; } }); } // Save functionality removed - game resets on reload }; // Load functionality removed - game starts fresh on each reload // CD click handlers menuDecoration.down = function () { // Visual feedback tween(decorationAsset, { scaleX: 0.36, scaleY: 0.36 }, { duration: 100, onFinish: function onFinish() { tween(decorationAsset, { scaleX: 0.4, scaleY: 0.4 }, { duration: 100 }); } }); }; menuDecoration.up = function () { if (!isMusicPlaying) { // 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 and rotation LK.playMusic('ambientMusic', { fade: { start: 0, end: 0.7, duration: 2000 } }); isMusicPlaying = true; _rotateContinuously(); } else { // Stop music LK.stopMusic(); isMusicPlaying = false; // 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; } };
/****
* 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 sequentially
var audienceAssets = ['audience1', 'audience2', 'audience3', 'audience4', 'audience5', 'audience6', 'audience7', 'audience8'];
var selectedAsset;
// If guitar is purchased, use reverse order starting from audience8
if (guitarPurchased) {
// Reverse order: audience8, audience7, audience6, etc.
selectedAsset = audienceAssets[7 - audienceCounter % audienceAssets.length];
} else {
// Normal order for initial audiences
selectedAsset = audienceAssets[audienceCounter % audienceAssets.length];
}
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 clapCPM
var ticksPerClap = Math.floor(3600 / (window.clapCPM || 120));
if (LK.ticks % ticksPerClap === 0) {
// Determine clap pattern based on cycle
var clapCycle = Math.floor(LK.ticks / ticksPerClap) % 16;
if (clapCycle === 6 || clapCycle === 7) {
// Double clap animation (bigger)
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
} else if (clapCycle === 14 || clapCycle === 15) {
// Four times clap animation (biggest)
tween(self, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
} else {
// Single clap animation (smaller)
tween(self, {
scaleX: 1.05,
scaleY: 1.05
}, {
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 CBM (Cymbal Beats per Minute) - synchronized with drum
self.income = 10; // 10 gold per hit
self.animating = false;
self.tickCounter = 0;
self.cymbalReference = null;
self.update = function () {
self.tickCounter++;
// Hit based on dynamic CPM
var ticksPerHit = Math.floor(3600 / (window.cymbalCPM || 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;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Play cymbal sound if not muted
if (!window.cymbalCPMMuted) {
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 = 1;
self.animating = false;
self.tickCounter = 0;
self.drumReference = null;
self.update = function () {
self.tickCounter++;
// Hit based on dynamic CPM
var ticksPerHit = Math.floor(3600 / (window.drumCPM || 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;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Play drum sound if not muted
if (!window.drumCPMMuted) {
LK.getSound('drumhit').play();
}
// 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 = 1500; // Higher income than drumstick
self.animating = false;
self.tickCounter = 0;
self.guitarReference = null;
self.update = function () {
self.tickCounter++;
// Click based on dynamic CPM
var ticksPerHit = Math.floor(3600 / (window.guitarCPM || 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() {
// Generate gold when strumming
var startGold = gold;
gold += self.income;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Play guitar sound if not muted
if (!window.guitarCPMMuted) {
LK.getSound('guitarhit').play();
}
// Visual feedback on guitar if reference exists
if (self.guitarReference) {
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 AutoFluteblow = Container.expand(function () {
var self = Container.call(this);
var blowGraphics = self.attachAsset('fluteblowNew', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.income = 3000; // Higher income than pianist
self.animating = false;
self.tickCounter = 0;
self.fluteReference = null;
self.update = function () {
self.tickCounter++;
// Hit based on dynamic CPM
var ticksPerHit = Math.floor(3600 / (window.fluteCPM || 10));
if (self.tickCounter >= ticksPerHit && !self.animating) {
self.tickCounter = 0;
self.animate();
}
};
self.animate = function () {
if (self.animating) return;
self.animating = true;
// Move up first
tween(self, {
y: self.y - 20
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Then move down for hit
tween(self, {
y: self.y + 40
}, {
duration: 150,
easing: tween.easeIn,
onFinish: function onFinish() {
// Generate gold when hitting
var startGold = gold;
gold += self.income;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Play flute sound if not muted
if (!window.fluteCPMMuted) {
LK.getSound('flutehit').play();
}
// Visual feedback removed
// Return to original position
tween(self, {
y: self.y - 20
}, {
duration: 150,
easing: tween.easeOut,
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: '#ffffff',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
self.titleText.anchor.set(0.5, 0.5);
self.titleText.y = -15;
self.addChild(self.titleText);
self.costText = new Text2('', {
size: 30,
fill: '#ffffff',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
self.costText.anchor.set(0.5, 0.5);
self.costText.y = 15;
self.addChild(self.costText);
self.countText = new Text2('', {
size: 50,
fill: '#FFD700',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
self.countText.anchor.set(0.5, 0.5);
self.countText.x = -150;
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;
}
buttonBg.tint = canAfford ? 0x4CAF50 : 0x808080;
self.interactive = canAfford;
}
};
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 = perfectTiming ? goldPerTap * 2 : goldPerTap;
var startGold = gold;
gold += reward;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Create light flash effect
var lightFlash = self.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3,
alpha: 0.8
});
lightFlash.tint = perfectTiming ? 0xFFD700 : 0xFFFFFF;
tween(lightFlash, {
scaleX: 5,
scaleY: 5,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
lightFlash.destroy();
}
});
// 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.cymbalCPMMuted) {
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;
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 = perfectTiming ? goldPerTap * 2 : goldPerTap;
var startGold = gold;
gold += reward;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Create light flash effect
var lightFlash = self.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 10,
scaleY: 10,
alpha: 0.8
});
lightFlash.tint = perfectTiming ? 0xFFD700 : 0xFFFFFF;
tween(lightFlash, {
scaleX: 15,
scaleY: 15,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
lightFlash.destroy();
}
});
// 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.drumCPMMuted) {
LK.getSound('drumhit').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.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 () {
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
var reward = perfectTiming ? goldPerTap * 2 : goldPerTap;
var startGold = gold;
gold += reward;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Create light flash effect
var lightFlash = self.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3,
alpha: 0.8
});
lightFlash.tint = perfectTiming ? 0xFFD700 : 0xFFFFFF;
tween(lightFlash, {
scaleX: 5,
scaleY: 5,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
lightFlash.destroy();
}
});
// 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 guitar sound if not muted
if (!window.guitarCPMMuted) {
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();
};
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 = 2000; // Higher income than other auto-players
self.animating = false;
self.tickCounter = 0;
self.pianoReference = null;
self.update = function () {
self.tickCounter++;
// Hit based on dynamic CPM
var ticksPerHit = Math.floor(3600 / (window.pianoCPM || 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;
// Smooth gold animation
tween({
value: displayedGold
}, {
value: gold
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
displayedGold = gold;
}
});
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: gold
}, {
duration: 300,
easing: tween.easeOut
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
// Play piano sound if not muted
if (!window.pianoCPMMuted) {
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;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game variables
var gold = 0;
var displayedGold = 0; // Track displayed gold for smooth animation
var goldPerTap = 20000;
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 = 5000; // Cost for pianist
var fluteblows = []; // Track AutoFluteblow instances
var fluteblowsPurchased = 0; // Track fluteblows purchased
var fluteblowCost = 8000; // Cost for fluteblow
// Upgrade costs
var drumstickCost = 10;
var fingerCost = 300; // Separate cost for fingers
var musicianCost = 100;
var guitarPurchased = false; // Track if guitar has been purchased
var instrumentCosts = {
guitar: 500,
cymbal: 1000,
maracas: 2000
};
// UI Elements
var goldText = new Text2('Gold: 0', {
size: 80,
fill: '#FFD700',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 3
});
goldText.anchor.set(0.5, 0);
goldText.y = 10;
LK.gui.top.addChild(goldText);
// Add menu button
var menuButton = new Container();
var menuBg = menuButton.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
menuBg.tint = 0xFFD700; // Yellow color
var menuText = new Text2('Menu', {
size: 50,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
menuText.anchor.set(0.5, 0.5);
menuButton.addChild(menuText);
menuButton.interactive = true;
LK.gui.topRight.addChild(menuButton);
menuButton.x = -170;
menuButton.y = 70;
// 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
});
menuDecoration.x = -165;
menuDecoration.y = 320;
// Make CD interactive
menuDecoration.interactive = 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: 50,
fill: '#ffffff',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
incomeText.anchor.set(0.5, 0);
incomeText.y = 100;
LK.gui.top.addChild(incomeText);
// 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;
// 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.maracasCPMMuted) {
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
// Buy buttons - Add to GUI layer to ensure they're always on top
var buyDrumstickBtn = LK.gui.bottom.addChild(new BuyButton());
buyDrumstickBtn.x = -480;
buyDrumstickBtn.y = -532;
buyDrumstickBtn.updateButton('Drumstick', drumstickCost, false);
var buyMusicianBtn = LK.gui.bottom.addChild(new BuyButton());
buyMusicianBtn.x = 0;
buyMusicianBtn.y = -532;
buyMusicianBtn.updateButton('Audience', musicianCost, false, 0, true, '');
var buyInstrumentBtn = LK.gui.bottom.addChild(new BuyButton());
buyInstrumentBtn.x = 480;
buyInstrumentBtn.y = -532;
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 = 480; // Same position as instrument button
buyMaracasSpecialBtn.y = -532;
buyMaracasSpecialBtn.visible = false; // Hidden by default
buyMaracasSpecialBtn.updateButton('Special', 5000, false, 0, true, '5 Shakes + 30 Audience');
// Add piano button - always at rightmost position
var buyPianoBtn = LK.gui.bottom.addChild(new BuyButton());
buyPianoBtn.x = 480; // Same x position as instrument button
buyPianoBtn.y = -532;
buyPianoBtn.visible = false; // Hidden by default
buyPianoBtn.updateButton('Piano', 10000, false, 0, true, '5 Shakes + 30 Audience');
// Menu button handler
menuButton.down = function () {
// Visual feedback
tween(menuBg, {
scaleX: 0.72,
scaleY: 0.72
}, {
duration: 100,
onFinish: function onFinish() {
tween(menuBg, {
scaleX: 0.8,
scaleY: 0.8
}, {
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 >= 5000) {
gold -= 5000;
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 >= 50 && gold >= 20000) {
gold -= 20000;
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.fluteCPMMuted) {
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 = goldPerTap * 4; // Flute gives 4x reward
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 >= 10000) {
gold -= 10000;
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
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 = goldPerTap * 3; // Piano gives 3x reward
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
// Dark overlay
var overlay = menuContainer.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 200,
scaleY: 200,
alpha: 0.7
});
overlay.tint = 0x000000;
// 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 - pixelart style with bold font
var menuTitle = new Text2('MENU', {
size: 150,
fill: '#3E2723',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 5
});
menuTitle.anchor.set(0.5, 0.5);
menuTitle.y = -650;
menuContainer.addChild(menuTitle);
// Sound effect controls
var soundEffects = [{
name: 'Drum',
sound: 'drumhit',
unlocked: drumsticksPurchased > 0,
cpmVar: 'drumCPM',
defaultCPM: 60
}, {
name: 'Guitar',
sound: 'guitarhit',
unlocked: guitarPurchased,
cpmVar: 'guitarCPM',
defaultCPM: 10
}, {
name: 'Cymbal',
sound: 'cymbalhit',
unlocked: unlockedInstruments.includes('cymbal'),
cpmVar: 'cymbalCPM',
defaultCPM: 30
}, {
name: 'Maracas',
sound: 'maracashit',
unlocked: unlockedInstruments.includes('maracas'),
cpmVar: 'maracasCPM',
defaultCPM: 120
}, {
name: 'Piano',
sound: 'pianohit',
unlocked: unlockedInstruments.includes('piano'),
cpmVar: 'pianoCPM',
defaultCPM: 10
}, {
name: 'Flute',
sound: 'flutehit',
unlocked: unlockedInstruments.includes('flute'),
cpmVar: 'fluteCPM',
defaultCPM: 10
}, {
name: 'Audience',
sound: 'clap',
unlocked: musicians.length > 0,
cpmVar: 'clapCPM',
defaultCPM: 120
}];
var yOffset = -520;
for (var i = 0; i < soundEffects.length; i++) {
var effect = soundEffects[i];
// Show all effects, both locked and unlocked
// Initialize CPM if not set (only for unlocked effects)
if (effect.unlocked && typeof window[effect.cpmVar] === 'undefined') {
window[effect.cpmVar] = effect.defaultCPM;
}
// Sound effect container
var soundContainer = menuContainer.addChild(new Container());
soundContainer.y = yOffset;
soundContainer.x = -50; // Move container slightly to the left
// Sound icon instead of text
var assetId = '';
var iconScale = 0.08;
switch (effect.name) {
case 'Drum':
assetId = 'drum';
break;
case 'Guitar':
assetId = 'guitar';
iconScale = 0.15;
break;
case 'Cymbal':
assetId = 'cymbal';
iconScale = 0.12;
break;
case 'Maracas':
assetId = 'maracas';
iconScale = 0.1;
break;
case 'Piano':
assetId = 'piano';
iconScale = 0.1;
break;
case 'Flute':
assetId = 'flute';
iconScale = 0.15;
break;
case 'Audience':
assetId = 'audience1';
iconScale = 0.08;
break;
}
if (assetId) {
var soundIcon = soundContainer.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: iconScale,
scaleY: iconScale,
x: -300,
y: 0
});
if (!effect.unlocked) {
soundIcon.tint = 0x808080; // Gray tint for locked items
}
} else {
// Fallback to text if no asset
var soundName = new Text2(effect.name, {
size: 40,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
soundName.anchor.set(0, 0.5);
soundName.x = -300;
soundContainer.addChild(soundName);
}
// Show controls only for unlocked effects
if (effect.unlocked) {
// Initialize mute state if not set
var muteVar = effect.cpmVar + 'Muted';
if (typeof window[muteVar] === 'undefined') {
window[muteVar] = false;
}
// Horizontal 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 = 0x666666;
// CPM display text
var cpmText = new Text2(window[effect.cpmVar] + ' CPM', {
size: 30,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
cpmText.anchor.set(0.5, 0.5);
cpmText.x = 80;
soundContainer.addChild(cpmText);
// 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: 40,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
minusText.anchor.set(0.5, 0.5);
minusBtn.addChild(minusText);
minusBtn.x = -80;
minusBtn.interactive = true;
// Plus button
var plusBtn = soundContainer.addChild(new Container());
var plusBg = plusBtn.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.5
});
plusBg.tint = 0x66FF66;
var plusText = new Text2('+', {
size: 40,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
plusText.anchor.set(0.5, 0.5);
plusBtn.addChild(plusText);
plusBtn.x = 240;
plusBtn.interactive = true;
// Mute button
var muteBtn = soundContainer.addChild(new Container());
var muteBg = muteBtn.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.5
});
muteBg.tint = window[muteVar] ? 0xFF0000 : 0xFFAA00;
// Add mute icon instead of text
var muteIcon = muteBtn.attachAsset('musicNote', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
muteIcon.tint = window[muteVar] ? 0x666666 : 0xFFFFFF;
muteBtn.x = 465; // Moved further left
muteBtn.interactive = true;
// Create closure to capture variables
(function (effect, cpmText, minusBtn, plusBtn, minusBg, plusBg, muteBtn, muteBg, muteIcon, muteVar) {
// Minus button handlers
minusBtn.down = function () {
tween(minusBg, {
scaleX: 0.25,
scaleY: 0.45
}, {
duration: 100,
onFinish: function onFinish() {
tween(minusBg, {
scaleX: 0.3,
scaleY: 0.5
}, {
duration: 100
});
}
});
};
minusBtn.up = function () {
if (window[effect.cpmVar] > 10) {
window[effect.cpmVar] -= 10;
cpmText.setText(window[effect.cpmVar] + ' CPM');
}
};
// Plus button handlers
plusBtn.down = function () {
tween(plusBg, {
scaleX: 0.25,
scaleY: 0.45
}, {
duration: 100,
onFinish: function onFinish() {
tween(plusBg, {
scaleX: 0.3,
scaleY: 0.5
}, {
duration: 100
});
}
});
};
plusBtn.up = function () {
if (window[effect.cpmVar] < 200) {
window[effect.cpmVar] += 10;
cpmText.setText(window[effect.cpmVar] + ' CPM');
}
};
// Mute button handlers
muteBtn.down = function () {
tween(muteBg, {
scaleX: 0.25,
scaleY: 0.45
}, {
duration: 100,
onFinish: function onFinish() {
tween(muteBg, {
scaleX: 0.3,
scaleY: 0.5
}, {
duration: 100
});
}
});
};
muteBtn.up = function () {
window[muteVar] = !window[muteVar];
muteBg.tint = window[muteVar] ? 0xFF0000 : 0xFFAA00;
muteIcon.tint = window[muteVar] ? 0x666666 : 0xFFFFFF;
};
})(effect, cpmText, minusBtn, plusBtn, minusBg, plusBg, muteBtn, muteBg, muteIcon, muteVar);
} else {
// Add lock overlay for locked effects
// Dark overlay for locked effects
var lockOverlay = soundContainer.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 1,
alpha: 0.5,
x: 0,
y: 0
});
lockOverlay.tint = 0x000000;
// Lock icon
var lockIcon = soundContainer.attachAsset('lock', {
anchorX: 0.5,
anchorY: 0.5,
x: 50,
y: 0
});
}
yOffset += 100;
}
// Reset CPM button
var resetCPMBtn = menuContainer.addChild(new Container());
var resetCPMBg = resetCPMBtn.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
resetCPMBg.tint = 0xFFAA00;
var resetCPMText = new Text2('Reset CPM', {
size: 48,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
resetCPMText.anchor.set(0.5, 0.5);
resetCPMBtn.addChild(resetCPMText);
resetCPMBtn.y = 250;
resetCPMBtn.interactive = true;
// Reset CPM button handlers
resetCPMBtn.down = function () {
tween(resetCPMBg, {
scaleX: 1.08,
scaleY: 1.08
}, {
duration: 100,
onFinish: function onFinish() {
tween(resetCPMBg, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100
});
}
});
};
resetCPMBtn.up = function () {
// Close menu first
menuContainer.destroy();
game.menuContainer = null;
// Create confirmation dialog on GUI layer
var confirmContainer = LK.gui.center.addChild(new Container());
// Dark overlay
var confirmOverlay = confirmContainer.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 200,
scaleY: 200,
alpha: 0.7
});
confirmOverlay.tint = 0x000000;
// Dialog box - darker color
var dialogBg = confirmContainer.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
dialogBg.tint = 0x404040; // Dark gray color
// Confirmation text
var confirmText = new Text2('Reset All CPM Values?', {
size: 60,
fill: '#FFFFFF',
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('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
yesBg.tint = 0x4CAF50;
var yesText = new Text2('Yes', {
size: 40,
fill: '#FFFFFF',
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: '#FFFFFF',
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 CPM values to defaults
window.drumCPM = 60;
window.guitarCPM = 10;
window.cymbalCPM = 30;
window.maracasCPM = 120;
window.pianoCPM = 10;
window.fluteCPM = 10;
window.clapCPM = 120;
// Close confirmation dialog
confirmContainer.destroy();
// Reopen menu to refresh display
menuButton.up(); // Reopen menu
};
// 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();
// Reopen menu
menuButton.up(); // Reopen menu
};
};
// Reset button - smaller and moved down
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: 48,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
resetBtnText.anchor.set(0.5, 0.5);
resetBtn.addChild(resetBtnText);
resetBtn.y = 448;
resetBtn.interactive = true;
// Close button - smaller and moved down
var closeBtn = menuContainer.addChild(new Container());
var closeBtnBg = closeBtn.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
closeBtnBg.tint = 0x4CAF50;
var closeBtnText = new Text2('Close', {
size: 48,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
closeBtnText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeBtnText);
closeBtn.y = 640;
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 () {
// Close menu first
menuContainer.destroy();
game.menuContainer = null;
// Create confirmation dialog on GUI layer
var confirmContainer = LK.gui.center.addChild(new Container());
// Dark overlay
var confirmOverlay = confirmContainer.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 200,
scaleY: 200,
alpha: 0.7
});
confirmOverlay.tint = 0x000000;
// Dialog box - darker color
var dialogBg = confirmContainer.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 2.5
});
dialogBg.tint = 0x404040; // Dark gray color
// Confirmation text
var confirmText = new Text2('Reset All Progress?', {
size: 60,
fill: '#FFFFFF',
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('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8
});
yesBg.tint = 0x4CAF50;
var yesText = new Text2('Yes', {
size: 40,
fill: '#FFFFFF',
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: '#FFFFFF',
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;
// 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();
};
};
// Close button handler
closeBtn.down = function () {
tween(closeBtnBg, {
scaleX: 1.08,
scaleY: 1.08
}, {
duration: 100,
onFinish: function onFinish() {
tween(closeBtnBg, {
scaleX: 1.2,
scaleY: 1.2
}, {
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;
}
// 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++;
// Create fluteblow if it doesn't exist
if (fluteblows.length === 0) {
var newFluteblow = cameraContainer.addChild(new AutoFluteblow());
// Position fluteblow at upper part of flute
if (fluteAsset) {
newFluteblow.x = fluteAsset.x;
newFluteblow.y = fluteAsset.y - 450; // Position higher at upper part of flute
} else {
// Default position if flute doesn't exist
newFluteblow.x = 11364;
newFluteblow.y = 1220 - 450;
}
// Set flute reference for visual feedback
newFluteblow.fluteReference = fluteAsset;
fluteblows.push(newFluteblow);
}
passiveIncome += 24; // Fluteblow generates 24 gold per second
LK.getSound('purchase').play();
// 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 - 200;
} else {
// Default position if piano doesn't exist
newPianist.x = 9316;
newPianist.y = 1220 - 200;
}
// Set piano reference for visual feedback
newPianist.pianoReference = pianoAsset;
pianists.push(newPianist);
}
passiveIncome += 16; // Pianist generates 16 gold per second
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 = 700;
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++;
// Play maracas sound and animate
if (maracasAsset) {
// Trigger maracas animation directly
maracasAsset.animate();
}
LK.getSound('purchase').play();
// 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 = 600;
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;
autoCymbalsticks.push(newAutoCymbalstick);
}
passiveIncome += 10; // Auto cymbal stick generates 10 gold per second
// Increase cost for next cymbalstick (optional, can be fixed if desired)
window.cymbalstickCost = Math.floor(window.cymbalstickCost * 1.3);
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;
fingers.push(newFinger);
}
passiveIncome += 4; // Fingers generate 4 gold per second
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);
}
passiveIncome += 1;
drumstickCost = Math.floor(drumstickCost * 1.3);
}
LK.getSound('purchase').play();
// 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 canPurchase = guitarPurchased ? fingersPurchased >= requiredFingers : drumsticksPurchased >= 10;
if (canPurchase && gold >= musicianCost) {
gold -= musicianCost;
var newAudience = game.addChild(new Audience());
// Random spawn position at bottom of screen
newAudience.x = 200 + Math.random() * 1648; // Random x between 200 and 1848
newAudience.y = 2400; // Fixed y position for horizontal alignment
// 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);
}
musicians.push(newAudience);
goldPerTap = Math.floor(goldPerTap * newAudience.multiplier);
passiveIncome += 4; // Each audience generates 4 gold per second
// Increase cost by 1.3x before guitar, 1.3x (30%) after guitar
musicianCost = Math.floor(musicianCost * 1.3);
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' || typeof window.cymbalsticksPurchased !== 'undefined' && window.cymbalsticksPurchased >= 10)) {
gold -= cost;
unlockedInstruments.push(nextInstrument);
instrumentsPurchased++;
// Set guitar purchased flag and update musician cost to 2000
if (nextInstrument === 'guitar') {
guitarPurchased = true;
musicianCost = 2000;
guitarAsset.visible = true; // Show guitar
} else if (nextInstrument === 'cymbal') {
// Show cymbal
cymbalAsset.visible = true;
} else if (nextInstrument === 'maracas') {
// Show maracas
maracasAsset.visible = true;
// Show piano button when maracas is purchased
buyPianoBtn.visible = true;
}
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;
// Main game loop
game.update = function () {
// Check if all instruments are purchased (guitar, cymbal, maracas)
var allInstrumentsPurchased = unlockedInstruments.includes('guitar') && unlockedInstruments.includes('cymbal') && unlockedInstruments.includes('maracas');
// Check if audience reached 15 for disco lights
if (!window.discoLightsActive && musicians.length >= 15) {
window.discoLightsActive = true;
// Create disco light container
window.discoLights = game.addChild(new Container());
// Create multiple colored lights
var colors = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF];
window.discoLightAssets = [];
for (var i = 0; i < 6; i++) {
var light = window.discoLights.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 15,
scaleY: 15,
alpha: 0.08,
x: 200 + i * 300,
y: 300
});
light.tint = colors[i];
window.discoLightAssets.push(light);
}
// Create container for random top lights
window.topLights = game.addChild(new Container());
window.topLightPool = [];
}
// Animate disco lights if active
if (window.discoLightsActive && window.discoLightAssets) {
// 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.15 + 0.05,
scaleX: Math.random() * 10 + 10,
scaleY: Math.random() * 10 + 10
}, {
duration: 200,
onFinish: function (light) {
return function () {
tween(light, {
alpha: 0.08,
scaleX: 15,
scaleY: 15
}, {
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: 8,
scaleY: 8,
alpha: 0,
x: 200 + Math.random() * 1648,
y: 100 + Math.random() * 200
});
topLight.tint = [0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF][Math.floor(Math.random() * 6)];
window.topLightPool.push(topLight);
// Fade in and out animation - much faster disappearance
tween(topLight, {
alpha: Math.random() * 0.2 + 0.1
}, {
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 automatic players to drum hit (60 BPM = every 60 ticks)
if (allInstrumentsPurchased && LK.ticks % 60 === 0) {
// Force all automatic players to hit at the same time
if (drumsticks.length > 0) {
drumsticks[0].tickCounter = 60; // Force drumstick to hit
}
if (fingers.length > 0) {
// Adjust finger to hit every 6 drum beats (360 ticks)
if (LK.ticks % 360 === 0) {
fingers[0].tickCounter = 360; // Force finger to hit
}
}
if (autoCymbalsticks.length > 0) {
// Adjust cymbalstick to hit at 30 BPM (120 ticks) - half speed
if (LK.ticks % 120 === 0) {
autoCymbalsticks[0].tickCounter = 120; // Force cymbalstick to hit
}
}
if (pianists.length > 0) {
// Adjust pianist to hit every 120 ticks (0.5 hits per second)
if (LK.ticks % 120 === 0) {
pianists[0].tickCounter = 120; // Force pianist to hit
}
}
if (fluteblows.length > 0) {
// Adjust fluteblow to hit every 120 ticks (0.5 hits per second)
if (LK.ticks % 120 === 0) {
fluteblows[0].tickCounter = 120; // Force fluteblow to hit
}
}
}
// Global clap synchronization - use dynamic clapCPM from menu
// Calculate ticks per clap based on clapCPM
var ticksPerClap = Math.floor(3600 / (window.clapCPM || 120)); // Default 120 CPM
if (LK.ticks % ticksPerClap === 0 && musicians.length > 0) {
// Determine clap pattern based on global counter
var clapCycle = Math.floor(LK.ticks / ticksPerClap) % 16;
globalClapPhase = clapCycle;
if (clapCycle === 6 || clapCycle === 7) {
// Double clap (7th and 8th in pattern) - faster with rapid clap-clap
if (!window.clapCPMMuted) {
LK.getSound('clap').play();
LK.setTimeout(function () {
if (!window.clapCPMMuted) {
LK.getSound('clap').play();
}
}, 100); // Faster delay for rapid double clap effect
}
} else if (clapCycle === 14 || clapCycle === 15) {
// Four times clap (15th and 16th in pattern) - slightly slower rapid clap-clap
if (!window.clapCPMMuted) {
LK.getSound('clap').play();
LK.setTimeout(function () {
if (!window.clapCPMMuted) {
LK.getSound('clap').play();
}
}, 80); // Slightly slower for controlled rapid clap-clap
LK.setTimeout(function () {
if (!window.clapCPMMuted) {
LK.getSound('clap').play();
}
}, 160);
LK.setTimeout(function () {
if (!window.clapCPMMuted) {
LK.getSound('clap').play();
}
}, 240);
}
} else {
// Single clap (other phases)
if (!window.clapCPMMuted) {
LK.getSound('clap').play();
}
}
}
// Maracas automatic shake based on dynamic CPM
if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount > 0 && maracasAsset) {
var maracasTicksPerShake = Math.floor(3600 / (window.maracasCPM || 120));
if (LK.ticks % maracasTicksPerShake === 0) {
// Trigger maracas animation and sound directly without menu check
maracasAsset.animate();
}
}
// Update UI
goldText.setText('Gold: ' + Math.floor(displayedGold));
incomeText.setText('Income: ' + passiveIncome + '/s');
// Update button states
// FLUTE LOGIC
if (currentInstrument === 'flute') {
// Update fluteblow button
buyDrumstickBtn.updateButton('Fluteblow', fluteblowCost, gold >= fluteblowCost, fluteblowsPurchased);
// Update audience button - always unlocked in flute view
buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost, musicians.length, false, '');
// Hide instrument button in flute view
buyInstrumentBtn.visible = false;
// Show piano button as locked in flute view
buyPianoBtn.visible = true;
buyPianoBtn.updateButton('Flute', 20000, 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
var isAudienceLocked = pianistsPurchased < 5;
var audienceLockMessage = 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 50 audience
buyPianoBtn.visible = true;
var isPianoLocked = unlockedInstruments.includes('flute') ? true : pianistsPurchased < 5 || musicians.length < 50;
var pianoLockMessage = '';
if (unlockedInstruments.includes('flute')) {
pianoLockMessage = '';
} else if (pianistsPurchased < 5) {
pianoLockMessage = '5 Pianists';
} else if (musicians.length < 50) {
pianoLockMessage = '50 Audience';
}
buyPianoBtn.updateButton('Flute', 20000, gold >= 20000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage);
}
// MARACAS LOGIC
else if (currentInstrument === 'maracas') {
// Initialize maracas shake cost and count
if (typeof window.maracasShakeCost === 'undefined') window.maracasShakeCost = 700;
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 when maracas shake count reaches 5
var isAudienceLocked = window.maracasShakeCount < 5;
var audienceLockMessage = isAudienceLocked ? '5 Maracas Shake' : '';
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, 10000, gold >= 10000 && !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 = 600;
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
var isAudienceLocked = cymbalstickCount < 10;
var audienceLockMessage = isAudienceLocked ? '10 Cymbalstick' : '';
buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage);
// Update maracas button - lock until 20 audience members are purchased OR if audience is locked
var isMaracasLocked = musicians.length < 20 || isAudienceLocked;
var maracasLockMessage = isAudienceLocked ? audienceLockMessage : musicians.length < 20 ? '20 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 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, 10000, gold >= 10000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage);
} else {
buyInstrumentBtn.updateButton('Maracas', 2000, gold >= 2000 && !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);
var isAudienceLocked = guitarPurchased ? fingersPurchased < 10 : drumsticksPurchased < 10;
var lockMessage = guitarPurchased ? '10 Fingers' : '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' && (typeof window.cymbalsticksPurchased === 'undefined' || window.cymbalsticksPurchased < 10);
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 = '10 Cymbalstick';
}
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, 10000, gold >= 10000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage);
}
}
// Smooth passive income animation
if (passiveIncome > 0 && Math.abs(gold - displayedGold) < 0.1) {
// Start a new tween for the next second of income
var targetGold = gold + passiveIncome;
gold = targetGold; // Update actual gold value
tween({
value: displayedGold
}, {
value: targetGold
}, {
duration: 1000,
onFinish: function onFinish() {
displayedGold = targetGold;
}
});
// Update displayedGold during tween
var tweenObj = {
value: displayedGold
};
tween(tweenObj, {
value: targetGold
}, {
duration: 1000,
easing: tween.linear,
onFinish: function onFinish() {
displayedGold = tweenObj.value;
}
});
Object.defineProperty(tweenObj, 'value', {
get: function get() {
return displayedGold;
},
set: function set(v) {
displayedGold = v;
}
});
}
// Save functionality removed - game resets on reload
};
// Load functionality removed - game starts fresh on each reload
// CD click handlers
menuDecoration.down = function () {
// Visual feedback
tween(decorationAsset, {
scaleX: 0.36,
scaleY: 0.36
}, {
duration: 100,
onFinish: function onFinish() {
tween(decorationAsset, {
scaleX: 0.4,
scaleY: 0.4
}, {
duration: 100
});
}
});
};
menuDecoration.up = function () {
if (!isMusicPlaying) {
// 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 and rotation
LK.playMusic('ambientMusic', {
fade: {
start: 0,
end: 0.7,
duration: 2000
}
});
isMusicPlaying = true;
_rotateContinuously();
} else {
// Stop music
LK.stopMusic();
isMusicPlaying = false;
// 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;
}
};
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