User prompt
Confetti stick konumunu biraz aşağıya kaydıralım. Kağıtları biraz küçültelim ve stick assetinin tam üst kısmından patlasın.
User prompt
Confetti sticki baya büyütelim, kağıtları da büyütelim.
User prompt
Confetti stick ve kağıtlar kaybolmasın.
User prompt
Confetti stick de asset olacak görünsün.
User prompt
Confettiler asset olacak, assetler bölümünde görünsü.n
User prompt
Stick görünmez oldu stick asset olsun, ve kağıtlar da asset olsun.
User prompt
Stickin animasyonu olmasın, ve spawn olup patladıktan sonra 15 saniye sonra kaybolsun.
User prompt
Confetti için bir de stick yapalım, kağıtlar stickin ucundan patlasın.
User prompt
Drum ilk hitinden 1 saniye sonra patlayan bir confetti ekleyelim, spawn olma konumu drum hizasında olsun.
User prompt
10000000 parayla başlayalım
User prompt
0 parayla başlayalım
User prompt
Confettistick ve kağıtlardan assetleri kaldıralım
User prompt
Yine 45 yönüne doğru patladı kağıtlar. Açılarda kağıtların patladığı yön 315 olsun
User prompt
Kağıtlar 45 dereceye doğru gidiyor Tam tersine gidiyor bunu düzeltelim
User prompt
Confetti kağıtları da ilk patladıklarında 315 açısında çok az gidip sonra ekrana dağılsın.
User prompt
Confettistick 45 derece saat yönünün tersine döndürelim. Ve tam tepesinin baktığı açı 315 derece olsun. 315 dereceye bakarken spawn olsun.
User prompt
Kağıtlar confettinin ucunda değil fix
User prompt
315 derece değil 45 derece olmuş açı. Açılar saat yönünde hesaplanır
User prompt
Kağıtları da assetin tam ucunun geldiği kısma ekleyelim. İlk patladığında birkaç piksel 315 açısıyla gidip sonra dağılsınlar. Kağıtların sayısı biraz artabilir. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
315 derece dedim 90 olmuş ve kağıtlar ucunda değil
User prompt
Confettistick 315 derecelik bir açıyla spawn olsun. Asseti 315 derece yapalım ve kağıtlar yine ucundan patlasın.
User prompt
Konumunu biraz sağa alalım
User prompt
Spawn konumunu biraz aşağıya alalım ve baya sağa alalım
User prompt
Confettistick patlama animasyonu olmasın
User prompt
Confetti span konumu drum ile aynı hizada olsun
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Audience = Container.expand(function () {
var self = Container.call(this);
// Select audience asset randomly without repetition
var audienceAssets = ['audience1', 'audience2', 'audience3', 'audience4', 'audience5', 'audience6', 'audience7', 'audience8', 'audience9', 'audience10', 'audience11', 'audience12', 'audience13', 'audience14', 'audience15', 'audience16', 'audience17', 'audience18', 'audience19', 'audience20'];
var selectedAsset;
// If all assets have been used, refill the available pool
if (availableAudienceAssets.length === 0) {
for (var i = 1; i <= 20; i++) {
availableAudienceAssets.push(i);
}
}
// Pick a random index from available assets
var randomIndex = Math.floor(Math.random() * availableAudienceAssets.length);
var assetNumber = availableAudienceAssets[randomIndex];
// Remove the used asset from available pool
availableAudienceAssets.splice(randomIndex, 1);
// Select the asset
selectedAsset = 'audience' + assetNumber;
audienceCounter++; // Increment counter for next audience
self.audienceGraphics = self.attachAsset(selectedAsset, {
anchorX: 0.5,
anchorY: 0.5
});
self.instrument = null;
self.multiplier = 1.2;
self.update = function () {
// Check if this is a clap tick - use dynamic audienceBPM
var ticksPerClap = Math.floor(3600 / (window.audienceBPM || 30));
if (LK.ticks % ticksPerClap === 0) {
// Single clap animation only
tween(self, {
scaleX: 1.03,
scaleY: 1.03
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
}
};
self.setInstrument = function (type) {
if (self.instrument) {
self.instrument.destroy();
}
self.instrument = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5,
x: 30,
y: 0
});
};
return self;
});
var AutoCymbalstick = Container.expand(function () {
var self = Container.call(this);
var stickGraphics = self.attachAsset('autocymbalstick', {
anchorX: 0.5,
anchorY: 0.9
});
self.speed = 60; // 60 BPM (Cymbal Beats per Minute) - synchronized with drum
self.income = 100; // 100 gold per hit
self.animating = false;
self.tickCounter = 0;
self.cymbalReference = null;
self.update = function () {
self.tickCounter++;
// Hit based on dynamic BPM
var ticksPerHit = Math.floor(3600 / (window.cymbalBPM || 30));
if (self.tickCounter >= ticksPerHit && !self.animating) {
self.tickCounter = 0;
self.animate();
}
};
self.animate = function () {
if (self.animating) return;
self.animating = true;
tween(stickGraphics, {
rotation: 0.3
}, {
duration: 300,
onFinish: function onFinish() {
// Generate gold when hitting
var startGold = gold;
gold += self.income;
// Instant gold update
displayedGold = gold;
// Play cymbal sound if not muted
if (!window.cymbalBPMMuted && !window.globalMuted) {
LK.getSound('cymbalhit').play();
}
// Visual feedback on cymbal if reference exists
if (self.cymbalReference) {
var cymbalGraphics = self.cymbalReference.children[0];
tween(cymbalGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 50,
onFinish: function onFinish() {
tween(cymbalGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 50
});
}
});
}
tween(stickGraphics, {
rotation: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.animating = false;
}
});
}
});
};
return self;
});
var AutoDrumstick = Container.expand(function () {
var self = Container.call(this);
var stickGraphics = self.attachAsset('autodrumstick', {
anchorX: 0.5,
anchorY: 0.9
});
self.speed = 1;
self.income = 2; // Base income: 2 gold per second per drumstick
self.animating = false;
self.tickCounter = 0;
self.drumReference = null;
self.update = function () {
self.tickCounter++;
// Hit based on dynamic BPM
var ticksPerHit = Math.floor(3600 / (window.drumBPM || 60));
if (self.tickCounter >= ticksPerHit && !self.animating) {
self.tickCounter = 0;
self.animate();
}
};
self.animate = function () {
if (self.animating) return;
self.animating = true;
tween(stickGraphics, {
rotation: 0.3
}, {
duration: 300,
onFinish: function onFinish() {
// Generate gold when hitting
var startGold = gold;
gold += self.income;
// Instant gold update
displayedGold = gold;
// Play drum sound if not muted
if (!window.drumBPMMuted && !window.globalMuted) {
LK.getSound('drumhit').play();
}
// Add background shake effect when hitting
if (background && !window.backgroundShaking) {
window.backgroundShaking = true;
// Shake the background vertically with reduced amount
tween(background, {
y: 1366 + 3 // Reduced from 5 to 3
}, {
duration: 40,
// Reduced from 50
onFinish: function onFinish() {
tween(background, {
y: 1366 - 3 // Reduced from 5 to 3
}, {
duration: 40,
// Reduced from 50
onFinish: function onFinish() {
tween(background, {
y: 1366
}, {
duration: 40,
// Reduced from 50
onFinish: function onFinish() {
window.backgroundShaking = false;
}
});
}
});
}
});
}
// Visual feedback on drum if reference exists
if (self.drumReference) {
var drumGraphics = self.drumReference.children[0];
tween(drumGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 50,
onFinish: function onFinish() {
tween(drumGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 50
});
}
});
}
tween(stickGraphics, {
rotation: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.animating = false;
}
});
}
});
};
return self;
});
var AutoFinger = Container.expand(function () {
var self = Container.call(this);
var fingerGraphics = self.attachAsset('finger', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
rotation: -Math.PI / 2 // Rotate 90 degrees counterclockwise
});
self.speed = 1;
self.income = 20; // Higher income than drumstick
self.animating = false;
self.tickCounter = 0;
self.guitarReference = null;
self.update = function () {
self.tickCounter++;
// Click based on dynamic BPM
var ticksPerHit = Math.floor(3600 / (window.guitarBPM || 10));
if (self.tickCounter >= ticksPerHit && !self.animating) {
self.tickCounter = 0;
self.animate();
}
};
self.animate = function () {
if (self.animating) return;
self.animating = true;
// Vertical strumming motion - move up more
tween(self, {
y: self.y - 80 // Increased from 50 to 80 for more upward movement
}, {
duration: 200,
onFinish: function onFinish() {
// Play guitar sound if not muted
if (!window.guitarBPMMuted && !window.globalMuted) {
LK.getSound('guitarhit').play();
}
// Visual feedback on guitar if reference exists
if (self.guitarReference) {
// Call play function without player hit parameter (defaults to false)
if (self.guitarReference.play) {
self.guitarReference.play();
}
var guitarGraphics = self.guitarReference.children[0];
tween(guitarGraphics, {
rotation: 0.1
}, {
duration: 50,
onFinish: function onFinish() {
tween(guitarGraphics, {
rotation: 0
}, {
duration: 50
});
}
});
}
// Return to original position - move down
tween(self, {
y: self.y + 80 // Increased from 50 to 80 to match upward movement
}, {
duration: 200,
onFinish: function onFinish() {
self.animating = false;
}
});
}
});
};
return self;
});
var BuyButton = Container.expand(function () {
var self = Container.call(this);
var buttonBg = self.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.titleText = new Text2('', {
size: 40,
fill: '#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;
}
// Regular colors for all buttons, much darker green if can't afford
buttonBg.tint = canAfford ? 0x4CAF50 : 0x1B5E20; // Green or DarkGreen (darker)
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 = 1;
var startGold = gold;
gold += reward;
// Instant gold update
displayedGold = gold;
// Light flash effect removed
// Create floating text
var floatingGold = game.addChild(new FloatingText('+' + reward, perfectTiming ? 0xFFD700 : 0xFFFFFF));
floatingGold.x = self.x + (game.cameraContainer ? game.cameraContainer.x : 0);
floatingGold.y = self.y - 50;
// Play cymbal sound if not muted
if (!window.cymbalBPMMuted && !window.globalMuted) {
LK.getSound('cymbalhit').play();
}
// Create music note effect
if (perfectTiming) {
var note = game.addChild(new MusicNote());
note.x = self.x + (Math.random() - 0.5) * 100;
note.y = self.y - 100;
}
};
self.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
self.play();
};
return self;
});
var Drum = Container.expand(function () {
var self = Container.call(this);
var drumGraphics = self.attachAsset('drum', {
anchorX: 0.5,
anchorY: 0.5
});
// Add permanent drumstick
self.drumstick = self.attachAsset('playerDrumstick', {
anchorX: 0.5,
anchorY: 0.9,
x: 210,
y: -220,
rotation: -0.3
});
self.canTap = true;
self.lastTapTime = 0;
self.drumstickAnimating = false;
self.tap = function () {
if (!self.canTap || self.drumstickAnimating) return;
// Hide tutorial on first drum hit
if (showTutorial) {
hideTutorial();
}
// --- Confetti effect after first drum tap ---
if (!self._hasTriggeredConfetti) {
self._hasTriggeredConfetti = true;
// Delay 1 second, then show confetti
LK.setTimeout(function () {
// Find drum position in world
var drumX = self.x;
var drumY = self.y;
// Confetti stick
var confettiStick = game.addChild(new Container());
var stickAsset = confettiStick.attachAsset('confettistick', {
anchorX: 0.5,
anchorY: 1.0,
x: 0,
y: 0,
rotation: Math.PI / 4 // Add 45 degrees to get 315 total (270 + 45)
});
confettiStick.x = drumX + 500; // moved 500 pixels to the right
confettiStick.y = drumY + 100; // moved 200 pixels down (from -100 to +100)
// Confetti stick animation removed - no pulsation
// Confetti papers - burst from stick tip
for (var i = 0; i < 8; i++) {
var paperType = ['confettiPaper1', 'confettiPaper2', 'confettiPaper3'][i % 3];
var confetti = game.addChild(new Container());
var paper = confetti.attachAsset(paperType, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
// Position at the exact tip of the stick (stick is at drumX + 500, drumY + 100)
// Stick has anchorY: 1.0, height ~600px, and is rotated 315 degrees total
// Calculate tip position: cos(315°) = 0.707, sin(315°) = -0.707
confetti.x = drumX + 500 + 600 * 0.707; // Move right by 600 * cos(315°)
confetti.y = drumY + 100 - 600 * 0.707; // Move up by 600 * sin(315°)
var angle = Math.PI / 4 + (Math.random() - 0.5) * Math.PI / 2 + (i - 4) * 0.18;
var initialVelocityX = Math.cos(angle) * (15 + Math.random() * 10);
var initialVelocityY = -Math.abs(Math.sin(angle)) * (25 + Math.random() * 15);
var rot = (Math.random() - 0.5) * Math.PI * 2;
var rotSpeed = (Math.random() - 0.5) * 0.2;
// Store physics properties
confetti.velocityX = initialVelocityX;
confetti.velocityY = initialVelocityY;
confetti.rotationSpeed = rotSpeed;
confetti.gravity = 0.8; // Gravity acceleration
confetti.lastY = confetti.y;
// Initial rotation
confetti.rotation = rot;
// Add to global confetti array for tracking
if (!window.activeConfetti) window.activeConfetti = [];
window.activeConfetti.push(confetti);
}
// Play confetti sound
if (!window.globalMuted) {
LK.getSound('confetti').play();
}
// Remove stick after 1.2s
LK.setTimeout(function () {
if (confettiStick && confettiStick.parent) confettiStick.destroy();
}, 1200);
}, 1000);
}
var currentTime = Date.now();
var timeSinceLastTap = currentTime - self.lastTapTime;
self.lastTapTime = currentTime;
// Check for perfect rhythm (60 BPM = 1000ms between beats)
var perfectTiming = Math.abs(timeSinceLastTap - 1000) < 100;
// Calculate animation speed based on tap speed
var tapSpeed = timeSinceLastTap > 0 ? Math.min(timeSinceLastTap, 1000) : 1000;
var animationSpeed = tapSpeed / 1000; // Normalize to 0-1 range
var strikeDuration = Math.max(50, 150 * animationSpeed); // Faster taps = shorter animation
var returnDuration = Math.max(100, 200 * animationSpeed);
// Visual feedback - drum scale
tween(drumGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(drumGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
// Set animation state
self.drumstickAnimating = true;
// Animate drumstick strike with dynamic duration - reversed animation
tween(self.drumstick, {
rotation: -0.6
}, {
duration: strikeDuration,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.drumstick, {
rotation: -0.3
}, {
duration: returnDuration,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.drumstickAnimating = false;
}
});
}
});
// Calculate reward
var reward = 1;
var startGold = gold;
gold += reward;
// Instant gold update
displayedGold = gold;
// Light flash effect removed
// Create floating text
var floatingGold = game.addChild(new FloatingText('+' + reward, perfectTiming ? 0xFFD700 : 0xFFFFFF));
floatingGold.x = self.x + (game.cameraContainer ? game.cameraContainer.x : 0);
floatingGold.y = self.y - 50;
// Play sound if not muted
if (!window.drumBPMMuted && !window.globalMuted) {
console.log('Playing drum sound - drumBPMMuted:', window.drumBPMMuted, 'globalMuted:', window.globalMuted);
LK.getSound('drumhit').play();
} else {
console.log('Drum sound muted - drumBPMMuted:', window.drumBPMMuted, 'globalMuted:', window.globalMuted);
}
// Create music note effect
if (perfectTiming) {
var note = game.addChild(new MusicNote());
note.x = self.x + (Math.random() - 0.5) * 100;
note.y = self.y - 100;
}
};
self.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
self.tap();
};
return self;
});
var FloatingText = Container.expand(function () {
var self = Container.call(this);
self.init = function (text, color) {
self.textObj = new Text2(text, {
size: 60,
fill: '#' + color.toString(16).padStart(6, '0'),
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
self.textObj.anchor.set(0.5, 0.5);
self.addChild(self.textObj);
tween(self, {
y: self.y - 100,
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var Guitar = Container.expand(function () {
var self = Container.call(this);
var guitarGraphics = self.attachAsset('guitar', {
anchorX: 0.5,
anchorY: 0.5
});
self.canPlay = true;
self.lastPlayTime = 0;
self.play = function (isPlayerHit) {
if (!self.canPlay) return;
var currentTime = Date.now();
var timeSinceLastPlay = currentTime - self.lastPlayTime;
self.lastPlayTime = currentTime;
// Check for perfect rhythm
var perfectTiming = Math.abs(timeSinceLastPlay - 1000) < 100;
// Visual feedback - guitar scale
tween(guitarGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(guitarGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
// Calculate reward - only give gold if it's a player hit
var reward = isPlayerHit ? 10 : 0;
if (reward > 0) {
var startGold = gold;
gold += reward;
// Instant gold update
displayedGold = gold;
}
// Light flash effect removed
// Create floating text - only show if there's a reward
if (reward > 0) {
var floatingGold = game.addChild(new FloatingText('+' + reward, perfectTiming ? 0xFFD700 : 0xFFFFFF));
floatingGold.x = self.x + (game.cameraContainer ? game.cameraContainer.x : 0);
floatingGold.y = self.y - 50;
}
// Play guitar sound if not muted
if (!window.guitarBPMMuted && !window.globalMuted) {
LK.getSound('guitarhit').play();
}
// Create music note effect
if (perfectTiming) {
var note = game.addChild(new MusicNote());
note.x = self.x + (Math.random() - 0.5) * 100;
note.y = self.y - 100;
}
};
self.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
self.play(true); //{8Q} Pass true to indicate player hit
};
return self;
});
var MusicNote = Container.expand(function () {
var self = Container.call(this);
var noteGraphics = self.attachAsset('musicNote', {
anchorX: 0.5,
anchorY: 0.5
});
tween(self, {
y: self.y - 200,
alpha: 0
}, {
duration: 1500,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
tween(noteGraphics, {
rotation: Math.PI * 2
}, {
duration: 1500
});
return self;
});
var Pianist = Container.expand(function () {
var self = Container.call(this);
var pianistGraphics = self.attachAsset('pianist', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
self.speed = 1;
self.income = 8000; // Very high income per hit
self.animating = false;
self.tickCounter = 0;
self.pianoReference = null;
self.update = function () {
self.tickCounter++;
// Hit based on dynamic BPM
var ticksPerHit = Math.floor(3600 / (window.pianoBPM || 10));
if (self.tickCounter >= ticksPerHit && !self.animating) {
self.tickCounter = 0;
self.animate();
}
};
self.animate = function () {
if (self.animating) return;
self.animating = true;
// Generate gold when hitting without animation
var startGold = gold;
gold += self.income;
// Instant gold update
displayedGold = gold;
// Play piano sound if not muted
if (!window.pianoBPMMuted && !window.globalMuted) {
LK.getSound('pianohit').play();
}
// Visual feedback on piano if reference exists
if (self.pianoReference) {
var pianoContainer = self.pianoReference;
tween(pianoContainer, {
scaleX: 2.1,
scaleY: 2.1
}, {
duration: 50,
onFinish: function onFinish() {
tween(pianoContainer, {
scaleX: 2,
scaleY: 2
}, {
duration: 50
});
}
});
}
// Set animation complete immediately
self.animating = false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Initialize all mute states to false so sounds play by default
window.drumBPMMuted = false;
window.guitarBPMMuted = false;
window.cymbalBPMMuted = false;
window.maracasBPMMuted = false;
window.pianoBPMMuted = false;
window.fluteBPMMuted = false;
window.audienceBPMMuted = false;
// Game variables
var gold = 10000000;
var displayedGold = 0; // Track displayed gold for smooth animation
var targetDisplayedGold = 0; // Target value for smooth transitions
var goldPerTap = 1;
var passiveIncome = 0;
var drumsticks = [];
var drumsticksPurchased = 0;
var musicians = [];
var unlockedInstruments = ['drum'];
var currentVenue = 0;
var currentInstrument = 'drum';
var guitarAsset = null;
var cymbalAsset = null;
var maracasAsset = null;
var pianoAsset = null;
var fluteAsset = null;
var instrumentsPurchased = 0;
var audienceCounter = 0; // Track which audience asset to use next
var globalClapCounter = 0; // Track global clap count for double clap pattern
var globalClapPhase = 0; // 0-2 = singles, 3 = double, 4-6 = singles, 7 = four times
var lastClapTick = -120; // Track last clap tick to prevent multiple claps per cycle
var fingers = []; // Track AutoFinger instances
var fingersPurchased = 0; // Track fingers purchased
var autoCymbalsticks = []; // Track AutoCymbalstick instances
var pianists = []; // Track Pianist instances
var pianistsPurchased = 0; // Track pianists purchased
var pianistCost = 50000; // Cost for pianist
var fluteblowsPurchased = 0; // Track fluteblows purchased
var fluteblowCost = 750000; // Cost for fluteblow
var availableAudienceAssets = []; // Track available audience assets for random selection
// Upgrade costs
var drumstickCost = 10;
var fingerCost = 200; // Separate cost for fingers
var musicianCost = 50;
var guitarPurchased = false; // Track if guitar has been purchased
var instrumentCosts = {
guitar: 700,
cymbal: 2000,
maracas: 10000
};
// Initialize available audience assets (1-20)
for (var i = 1; i <= 20; i++) {
availableAudienceAssets.push(i);
}
// Function to recalculate passive income
function recalculatePassiveIncome() {
var newPassiveIncome = 0;
newPassiveIncome += drumsticksPurchased * 2;
newPassiveIncome += fingersPurchased * 20;
newPassiveIncome += (typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0) * 100;
newPassiveIncome += (typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0) * 300;
newPassiveIncome += pianistsPurchased * 8000;
newPassiveIncome += fluteblowsPurchased * 25000;
// Audience income: 4 per second per audience member
newPassiveIncome += 4 * musicians.length;
// Only update if the new income is higher
if (newPassiveIncome > passiveIncome) {
passiveIncome = newPassiveIncome;
}
}
window.backgroundShaking = false; // Track background shake state
// 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 = 50;
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 = -190;
menuButton.y = 90;
// Add mute button below menu button
var muteButton = new Container();
var muteBg = muteButton.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
muteBg.tint = 0xFFD700; // Yellow color - same as menu button
var muteIcon = muteButton.attachAsset('musicNote', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
x: -35,
y: 0
});
muteIcon.tint = 0xFFFFFF;
var muteText = new Text2('Mute', {
size: 25,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 1
});
muteText.anchor.set(0.5, 0.5);
muteText.x = 15;
muteButton.addChild(muteText);
muteButton.interactive = true;
LK.gui.topRight.addChild(muteButton);
muteButton.x = -190;
muteButton.y = 200;
// Track global mute state
window.globalMuted = false;
// Mute button handlers
muteButton.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
tween(muteBg, {
scaleX: 0.45,
scaleY: 0.45
}, {
duration: 100,
onFinish: function onFinish() {
tween(muteBg, {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 100
});
}
});
};
muteButton.up = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
window.globalMuted = !window.globalMuted;
// Update button appearance
muteBg.tint = window.globalMuted ? 0xFF0000 : 0xFFD700;
muteIcon.tint = window.globalMuted ? 0x666666 : 0xFFFFFF;
muteText.tint = window.globalMuted ? 0x666666 : 0xFFFFFF;
// Mute/unmute all sounds
window.drumBPMMuted = window.globalMuted;
window.guitarBPMMuted = window.globalMuted;
window.cymbalBPMMuted = window.globalMuted;
window.maracasBPMMuted = window.globalMuted;
window.pianoBPMMuted = window.globalMuted;
window.fluteBPMMuted = window.globalMuted;
window.clapBPMMuted = window.globalMuted;
// Stop or resume music but keep CD rotating
if (window.globalMuted && isMusicPlaying) {
LK.stopMusic();
// CD continues rotating when muted
} else if (!window.globalMuted && isMusicPlaying) {
// Resume music if it was playing
LK.playMusic('ambientMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
}
};
// Add decorative asset below menu button
var menuDecoration = LK.gui.topRight.addChild(new Container());
var decorationAsset = menuDecoration.attachAsset('cd', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4,
alpha: 0.6 //{af_alpha}
});
menuDecoration.x = -191;
menuDecoration.y = 350;
// 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 = 140;
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;
// Store drum reference globally for tutorial
window.mainDrum = mainDrum;
// Tutorial hand - appears at game start
var tutorialHand = null;
var tutorialText = null;
var showTutorial = true; // Track if tutorial should be shown
// Create tutorial elements
if (showTutorial) {
// Create shadow overlay on GUI layer to ensure it's on top
var tutorialShadow = LK.gui.center.addChild(new Container());
window.tutorialShadow = tutorialShadow; // Store reference globally
var shadowOverlay = tutorialShadow.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 300,
scaleY: 300,
alpha: 0.6,
x: 0,
y: 0
});
shadowOverlay.tint = 0x000000;
// Tutorial banner asset instead of text - add to GUI layer to ensure it's on top
tutorialText = LK.gui.center.addChild(LK.getAsset('tutorialBanner', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
x: 0,
y: 434 // Moved up by 200 pixels
}));
// Add drum asset as button on GUI layer above shadow
var tutorialDrumButton = LK.gui.center.addChild(new Container());
window.tutorialDrumButton = tutorialDrumButton;
var drumButtonAsset = tutorialDrumButton.attachAsset('drum', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.682,
scaleY: 0.682
});
tutorialDrumButton.x = 0;
tutorialDrumButton.y = -58; // Position drum above center
tutorialDrumButton.interactive = true;
// Add playerDrumstick button on GUI layer above shadow
var tutorialDrumstickButton = LK.gui.center.addChild(new Container());
window.tutorialDrumstickButton = tutorialDrumstickButton;
var drumstickButtonAsset = tutorialDrumstickButton.attachAsset('playerDrumstick', {
anchorX: 0.5,
anchorY: 0.9,
scaleX: 0.7,
scaleY: 0.7,
rotation: -0.3
});
tutorialDrumstickButton.x = 150; // Moved left from 210
tutorialDrumstickButton.y = -200; // Moved down from -250
tutorialDrumstickButton.interactive = true;
// Tutorial hand pointing to drum - add to GUI layer LAST to ensure it's on top of everything
tutorialHand = LK.gui.center.addChild(LK.getAsset('tutorialHand', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.0,
scaleY: 1.0,
x: -250,
y: -410,
rotation: -Math.PI / 4 - Math.PI / 2 // Point toward drum, rotated 90 degrees counterclockwise
}));
// Make tutorial drum button trigger main drum tap
tutorialDrumButton.down = function () {
if (window.mainDrum && window.mainDrum.tap) {
window.mainDrum.tap();
}
};
// Make tutorial drumstick button trigger main drum tap
tutorialDrumstickButton.down = function () {
if (window.mainDrum && window.mainDrum.tap) {
window.mainDrum.tap();
}
};
// Animate hand pointing motion
var _animateHand = function animateHand() {
if (!tutorialHand || !tutorialHand.parent) return;
tween(tutorialHand, {
x: -200,
y: -310
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!tutorialHand || !tutorialHand.parent) return;
tween(tutorialHand, {
x: -250,
y: -410
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: _animateHand
});
}
});
};
// Start hand animation
_animateHand();
// Animate banner pulsing
var _animateText = function animateText() {
if (!tutorialText || !tutorialText.parent) return;
tween(tutorialText, {
scaleX: 0.85,
scaleY: 0.85
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!tutorialText || !tutorialText.parent) return;
tween(tutorialText, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: _animateText
});
}
});
};
// Start banner animation
_animateText();
}
// Create guitar immediately but position it off-screen to the right
var guitarAsset = cameraContainer.addChild(new Guitar());
guitarAsset.scaleX = 3;
guitarAsset.scaleY = 3;
guitarAsset.x = 3072; // Position to the right (1024 + 2048)
guitarAsset.y = 1220;
guitarAsset.visible = false; // Hide until purchased
// Create cymbal
var cymbalAsset = cameraContainer.addChild(new Cymbal());
cymbalAsset.scaleX = 2;
cymbalAsset.scaleY = 2;
cymbalAsset.x = 5120; // Position further right (3072 + 2048)
cymbalAsset.y = 1220;
cymbalAsset.visible = false; // Hide until purchased
// Create maracas
var maracasAsset = cameraContainer.addChild(new Container());
var maracasGraphics = maracasAsset.attachAsset('maracas', {
anchorX: 0.5,
anchorY: 0.5
});
maracasAsset.scaleX = 2;
maracasAsset.scaleY = 2;
maracasAsset.x = 7168; // Position further right (5120 + 2048)
maracasAsset.y = 1220;
maracasAsset.visible = false; // Hide until purchased
// Make maracas interactive and play animation/sound on tap
maracasAsset.interactive = true;
// Separate animation method that doesn't check menu state
maracasAsset.animate = function () {
// Prevent spamming animation
if (maracasAsset._animating) return;
maracasAsset._animating = true;
// Animate maracas: scale up and back
tween(maracasAsset, {
scaleX: 2.3,
scaleY: 2.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(maracasAsset, {
scaleX: 2,
scaleY: 2
}, {
duration: 100,
onFinish: function onFinish() {
maracasAsset._animating = false;
}
});
}
});
// Play maracas sound if not muted
if (!window.maracasBPMMuted && !window.globalMuted) {
LK.getSound('maracashit').play();
}
// Optionally, create a floating text or effect
var floatingGold = game.addChild(new FloatingText('+0', 0x00FF00));
floatingGold.x = maracasAsset.x + cameraContainer.x;
floatingGold.y = maracasAsset.y - 100;
};
maracasAsset.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
// Call the animation method
maracasAsset.animate();
};
// Navigation arrows
var arrowForward1 = null;
var arrowForward2 = null;
var arrowForward3 = null;
var arrowForward4 = null;
var arrowBack1 = null;
var arrowBack2 = null;
var arrowBack3 = null;
var arrowBack4 = null;
var isTransitioning = false; // Prevent arrow clicks during transitions
// Stage/Venue display - removed
// 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 = -632; // Moved up from -532
buyDrumstickBtn.updateButton('Drumstick', drumstickCost, false);
var buyMusicianBtn = LK.gui.bottom.addChild(new BuyButton());
buyMusicianBtn.x = 0;
buyMusicianBtn.y = -632; // Moved up from -532
buyMusicianBtn.updateButton('Audience', musicianCost, false, 0, true, '');
var buyInstrumentBtn = LK.gui.bottom.addChild(new BuyButton());
buyInstrumentBtn.x = 480;
buyInstrumentBtn.y = -632; // Moved up from -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 = -632; // Moved up from -532
buyMaracasSpecialBtn.visible = false; // Hidden by default
buyMaracasSpecialBtn.updateButton('Special', 15000, false, 0, true, '5 Shakes + 30 Audience');
// Add piano button - always at rightmost position
var buyPianoBtn = LK.gui.bottom.addChild(new BuyButton());
buyPianoBtn.x = 480; // Same x position as instrument button
buyPianoBtn.y = -632; // Moved up from -532
buyPianoBtn.visible = false; // Hidden by default
buyPianoBtn.updateButton('Piano', 30000, 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 >= 15000) {
gold -= 15000;
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// TODO: Add special maracas functionality here
// Hide the button after purchase
buyMaracasSpecialBtn.visible = false;
}
};
// Piano button handler - now handles flute in piano view
buyPianoBtn.up = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
// In piano view, this is the flute purchase
if (currentInstrument === 'piano' && pianistsPurchased >= 5 && musicians.length >= 40 && gold >= 500000) {
gold -= 500000;
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Create flute asset
if (!fluteAsset) {
fluteAsset = cameraContainer.addChild(new Container());
var fluteGraphics = fluteAsset.attachAsset('flute', {
anchorX: 0.5,
anchorY: 0.5
});
fluteAsset.scaleX = 3;
fluteAsset.scaleY = 3;
fluteAsset.x = 11364; // Position further right (9316 + 2048)
fluteAsset.y = 1220;
fluteAsset.visible = true;
// Make flute interactive
fluteAsset.interactive = true;
fluteAsset.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
// Play flute sound if not muted
if (!window.fluteBPMMuted && !window.globalMuted) {
LK.getSound('flutehit').play();
}
// Visual feedback
tween(fluteAsset, {
scaleX: 3.05,
scaleY: 3.05
}, {
duration: 100,
onFinish: function onFinish() {
tween(fluteAsset, {
scaleX: 3,
scaleY: 3
}, {
duration: 100
});
}
});
// Generate gold
var reward = 1;
gold += reward;
// Create floating text
var floatingGold = game.addChild(new FloatingText('+' + reward, 0x87CEEB));
floatingGold.x = fluteAsset.x + cameraContainer.x;
floatingGold.y = fluteAsset.y - 100;
};
}
// Add flute to unlocked instruments
if (!unlockedInstruments.includes('flute')) {
unlockedInstruments.push('flute');
}
// Update navigation arrows for flute
updateNavigationArrows();
// Hide the button after purchase
buyPianoBtn.visible = false;
}
// Original piano purchase logic (from maracas view)
else if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount >= 5 && musicians.length >= 30 && gold >= 30000) {
gold -= 30000;
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Create piano asset
if (!pianoAsset) {
pianoAsset = cameraContainer.addChild(new Container());
var pianoGraphics = pianoAsset.attachAsset('piano', {
anchorX: 0.5,
anchorY: 0.5
});
pianoAsset.scaleX = 2;
pianoAsset.scaleY = 2;
pianoAsset.x = 9316; // Position further right (7168 + 2048) + 100 pixels to the right
pianoAsset.y = 1220;
pianoAsset.visible = true;
// Make piano interactive
pianoAsset.interactive = true;
pianoAsset.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
// Play piano sound
if (!window.pianoBPMMuted && !window.globalMuted) {
LK.getSound('pianohit').play();
}
// Visual feedback
tween(pianoAsset, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(pianoAsset, {
scaleX: 2,
scaleY: 2
}, {
duration: 100
});
}
});
// Generate gold
var reward = 1;
gold += reward;
// Create floating text
var floatingGold = game.addChild(new FloatingText('+' + reward, 0xFFD700));
floatingGold.x = pianoAsset.x + cameraContainer.x;
floatingGold.y = pianoAsset.y - 100;
};
}
// Add piano to unlocked instruments
if (!unlockedInstruments.includes('piano')) {
unlockedInstruments.push('piano');
}
// Update navigation arrows for piano
updateNavigationArrows();
// Hide the button after purchase
buyPianoBtn.visible = false;
}
};
menuButton.up = function () {
// Check if menu is already open
if (game.menuContainer && game.menuContainer.parent) {
// Menu is open, close it
game.menuContainer.destroy();
game.menuContainer = null;
return;
}
// Create menu overlay on GUI layer to ensure it's above everything
var menuContainer = LK.gui.center.addChild(new Container());
game.menuContainer = menuContainer; // Store reference to check if menu is open
// 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 = -720;
menuContainer.addChild(menuTitle);
// Sound effect controls
var soundEffects = [{
name: 'Drum',
sound: 'drumhit',
unlocked: drumsticksPurchased > 0,
cpmVar: 'drumBPM',
defaultBPM: 60
}, {
name: 'Guitar',
sound: 'guitarhit',
unlocked: guitarPurchased,
cpmVar: 'guitarBPM',
defaultBPM: 10
}, {
name: 'Cymbal',
sound: 'cymbalhit',
unlocked: unlockedInstruments.includes('cymbal'),
cpmVar: 'cymbalBPM',
defaultBPM: 30
}, {
name: 'Maracas',
sound: 'maracashit',
unlocked: unlockedInstruments.includes('maracas'),
cpmVar: 'maracasBPM',
defaultBPM: 120
}, {
name: 'Piano',
sound: 'pianohit',
unlocked: unlockedInstruments.includes('piano'),
cpmVar: 'pianoBPM',
defaultBPM: 10
}, {
name: 'Flute',
sound: 'flutehit',
unlocked: unlockedInstruments.includes('flute'),
cpmVar: 'fluteBPM',
defaultBPM: 15
}, {
name: 'Audience',
sound: 'clap',
unlocked: musicians.length > 0,
cpmVar: 'audienceBPM',
defaultBPM: 30
}];
var yOffset = -570;
for (var i = 0; i < soundEffects.length; i++) {
var effect = soundEffects[i];
// Show all effects, both locked and unlocked
// Initialize BPM if not set (only for unlocked effects)
if (effect.unlocked && typeof window[effect.cpmVar] === 'undefined') {
window[effect.cpmVar] = effect.defaultBPM;
}
// 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: -260,
y: 0
});
} 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.name === 'Audience' ? 'audienceBPMMuted' : 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;
// BPM display text
var cpmText = new Text2(window[effect.cpmVar] + ' BPM', {
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 = 445; // Moved slightly more 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] > 5) {
window[effect.cpmVar] -= 5;
cpmText.setText(window[effect.cpmVar] + ' BPM');
}
};
// 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] += 5;
cpmText.setText(window[effect.cpmVar] + ' BPM');
}
};
// 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 {
// Show dark silhouette of the instrument for locked effects
if (assetId) {
var lockedIcon = soundContainer.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: iconScale,
scaleY: iconScale,
x: -258,
y: 0
});
// Make it dark gray for locked state
lockedIcon.tint = 0x404040; // Dark gray tint
}
// Add horizontal bar background for consistency
var barBg = soundContainer.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.6,
x: 80,
y: 0
});
barBg.tint = 0x333333; // Darker gray for locked state
// Lock icon on top of the bar
var lockIcon = soundContainer.attachAsset('lock', {
anchorX: 0.5,
anchorY: 0.5,
x: 80,
y: 0
});
}
yOffset += 100;
}
// Reset BPM 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 BPM', {
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 = 300;
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 BPM 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 BPM values to defaults
window.drumBPM = 60;
window.guitarBPM = 10;
window.cymbalBPM = 30;
window.maracasBPM = 120;
window.pianoBPM = 10;
window.fluteBPM = 10;
window.audienceBPM = 30;
// 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
};
};
// Disco lights control button
var muteAllBtn = menuContainer.addChild(new Container());
var muteAllBg = muteAllBtn.attachAsset('buyButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
muteAllBg.tint = window.discoMuted ? 0xFF0000 : 0xFFAA00;
var muteAllIcon = muteAllBtn.attachAsset('disco', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
x: -60,
y: 0
});
muteAllIcon.tint = window.discoMuted ? 0x666666 : 0xFFFFFF;
// Add Disco text
var discoText = new Text2('Disco', {
size: 30,
fill: '#FFFFFF',
font: "'Impact', 'Arial Black', 'Helvetica Neue', sans-serif",
letterSpacing: 2
});
discoText.anchor.set(0.5, 0.5);
discoText.x = 20;
muteAllBtn.addChild(discoText);
muteAllBtn.y = 145;
muteAllBtn.interactive = true;
// Mute all button handlers
muteAllBtn.down = function () {
tween(muteAllBg, {
scaleX: 0.54,
scaleY: 0.54
}, {
duration: 100,
onFinish: function onFinish() {
tween(muteAllBg, {
scaleX: 0.6,
scaleY: 0.6
}, {
duration: 100
});
}
});
};
muteAllBtn.up = function () {
// Toggle disco lights visibility state
window.discoMuted = !window.discoMuted;
muteAllBg.tint = window.discoMuted ? 0xFF0000 : 0xFFAA00;
muteAllIcon.tint = window.discoMuted ? 0x666666 : 0xFFFFFF;
// Control disco lights visibility
if (window.discoMuted) {
// Hide disco lights
if (window.discoLights) {
window.discoLights.visible = false;
}
if (window.topLights) {
window.topLights.visible = false;
}
if (window.partyOverlay) {
window.partyOverlay.visible = false;
}
if (window.discoBallContainer) {
window.discoBallContainer.visible = false;
}
} else if (musicians.length >= 10) {
// Show disco lights (disco starts at 10 audience)
if (window.discoLights) {
window.discoLights.visible = true;
}
if (window.topLights) {
window.topLights.visible = true;
}
if (window.partyOverlay) {
window.partyOverlay.visible = true;
}
if (window.discoBallContainer) {
window.discoBallContainer.visible = true;
}
}
};
// 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 = 500;
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 = 700;
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++;
// Enable automatic flute hitting with 10 BPM
window.fluteAutoPlay = true;
window.fluteAutoPlayCounter = 0;
// Do not set fluteHasHitOnce to false, so it won't sync with drumstick
// Recalculate passive income
recalculatePassiveIncome();
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Increase fluteblow cost for next purchase
fluteblowCost = Math.floor(fluteblowCost * 1.5);
// Update button to show new count and cost
buyDrumstickBtn.updateButton('Fluteblow', fluteblowCost, gold >= fluteblowCost, fluteblowsPurchased);
}
return;
}
// PIANO PIANIST PURCHASE LOGIC
if (currentInstrument === 'piano') {
if (gold >= pianistCost) {
gold -= pianistCost;
pianistsPurchased++;
// Create pianist if it doesn't exist
if (pianists.length === 0) {
var newPianist = cameraContainer.addChild(new Pianist());
// Position pianist above piano but lower
if (pianoAsset) {
newPianist.x = pianoAsset.x;
newPianist.y = pianoAsset.y - 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;
newPianist.hasHitOnce = false; // Initialize first hit flag
pianists.push(newPianist);
}
// Increase pianist cost for next purchase
pianistCost = Math.floor(pianistCost * 1.5);
// Recalculate passive income
recalculatePassiveIncome();
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Update button to show new count and cost
buyDrumstickBtn.updateButton('Pianist', pianistCost, gold >= pianistCost, pianistsPurchased);
}
return;
}
// MARACAS SHAKE PURCHASE LOGIC
if (currentInstrument === 'maracas') {
if (typeof window.maracasShakeCost === 'undefined') window.maracasShakeCost = 12000;
if (typeof window.maracasShakeCount === 'undefined') window.maracasShakeCount = 0;
var maracasShakeCost = window.maracasShakeCost;
// Allow purchase if player can afford
if (gold >= maracasShakeCost) {
gold -= maracasShakeCost;
window.maracasShakeCount++;
window.maracasHasHitOnce = false; // Initialize first hit flag
// Only play purchase sound, no maracas hit animation during purchase
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Recalculate passive income
recalculatePassiveIncome();
// Increase cost for next purchase
window.maracasShakeCost = Math.floor(window.maracasShakeCost * 1.3);
// Update button to show new count and cost
buyDrumstickBtn.updateButton('Maracas Shake', window.maracasShakeCost, gold >= window.maracasShakeCost, window.maracasShakeCount);
}
return;
}
// CYMBALSTICK PURCHASE LOGIC
if (currentInstrument === 'cymbal') {
if (typeof window.cymbalsticksPurchased === 'undefined') window.cymbalsticksPurchased = 0;
if (typeof window.cymbalstickCost === 'undefined') window.cymbalstickCost = 2200;
var cymbalstickCount = window.cymbalsticksPurchased;
var cymbalstickCost = window.cymbalstickCost;
// Check if player has enough fingers
if (gold >= cymbalstickCost && fingersPurchased >= 10) {
gold -= cymbalstickCost;
window.cymbalsticksPurchased++;
// Create auto cymbal stick if it doesn't exist
if (autoCymbalsticks.length === 0) {
var newAutoCymbalstick = cameraContainer.addChild(new AutoCymbalstick());
// Position auto cymbal stick on left side of cymbal
if (cymbalAsset) {
newAutoCymbalstick.x = cymbalAsset.x - 380;
newAutoCymbalstick.y = cymbalAsset.y - 50;
} else {
// Default position if cymbal doesn't exist
newAutoCymbalstick.x = 5120 - 380;
newAutoCymbalstick.y = 1220 - 50;
}
// Set cymbal reference for visual feedback
newAutoCymbalstick.cymbalReference = cymbalAsset;
newAutoCymbalstick.hasHitOnce = false; // Initialize first hit flag
autoCymbalsticks.push(newAutoCymbalstick);
// Start CD rotation when first cymbalstick is purchased (if music is playing)
if (!cdRotationTween && isMusicPlaying) {
var rotateContinuously = function rotateContinuously() {
// Check if music is still playing before starting new rotation
if (!isMusicPlaying) {
// Stop any existing tween if music stopped
if (cdRotationTween) {
tween.stop(cdRotationTween);
cdRotationTween = null;
}
return;
}
cdRotationTween = tween(decorationAsset, {
rotation: decorationAsset.rotation + Math.PI * 2
}, {
duration: 4000,
easing: tween.linear,
onFinish: function onFinish() {
if (isMusicPlaying) {
rotateContinuously(); // Continue rotating
} else {
// Ensure tween is cleared if music stopped during animation
cdRotationTween = null;
}
}
});
};
rotateContinuously();
}
}
// Recalculate passive income
recalculatePassiveIncome();
// Increase cost for next cymbalstick (optional, can be fixed if desired)
window.cymbalstickCost = Math.floor(window.cymbalstickCost * 1.3);
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Update button
buyDrumstickBtn.updateButton('Cymbalstick', window.cymbalstickCost, gold >= window.cymbalstickCost, window.cymbalsticksPurchased);
}
return;
}
var currentCost = currentInstrument === 'guitar' ? fingerCost : drumstickCost;
if (gold >= currentCost) {
gold -= currentCost;
if (currentInstrument === 'guitar') {
fingersPurchased++;
// Create finger if it doesn't exist
if (fingers.length === 0) {
var newFinger = cameraContainer.addChild(new AutoFinger());
// Position finger on right side of guitar
if (guitarAsset) {
newFinger.x = guitarAsset.x - 250; // Move significantly more to the left
newFinger.y = guitarAsset.y + 50; // Move finger up a bit more (reduced from 80 to 50)
} else {
// If guitar doesn't exist yet, position at default location
newFinger.x = 3072 - 250;
newFinger.y = 1220 + 50;
}
// Set guitar reference for visual feedback
newFinger.guitarReference = guitarAsset;
newFinger.hasHitOnce = false; // Initialize first hit flag
fingers.push(newFinger);
}
// Recalculate passive income
recalculatePassiveIncome();
fingerCost = Math.floor(fingerCost * 1.3);
} else {
drumsticksPurchased++;
// Create drumstick if it doesn't exist
if (drumsticks.length === 0) {
var newStick = cameraContainer.addChild(new AutoDrumstick());
// Position drumstick on left side of drum
newStick.x = mainDrum.x - 350;
newStick.y = mainDrum.y - 200;
// Rotate drumstick to point towards the drum
newStick.rotation = 0;
// Set drum reference for visual feedback
newStick.drumReference = mainDrum;
drumsticks.push(newStick);
}
// Update drumstick income on the drumstick object
if (drumsticks.length > 0) {
drumsticks[0].income = 2; // Base income per hit
}
// Recalculate passive income
recalculatePassiveIncome();
// Update drumstick cost with 30% increase
drumstickCost = Math.floor(drumstickCost * 1.3);
}
if (!window.globalMuted) {
console.log('Playing purchase sound');
LK.getSound('purchase').play();
} else {
console.log('Purchase sound muted');
}
// Force update button to refresh count display
var buttonText = currentInstrument === 'guitar' ? 'Finger' : 'Drumstick';
var purchaseCount = currentInstrument === 'guitar' ? fingersPurchased : drumsticksPurchased;
var nextCost = currentInstrument === 'guitar' ? fingerCost : drumstickCost;
buyDrumstickBtn.updateButton(buttonText, nextCost, gold >= nextCost, purchaseCount);
}
};
buyMusicianBtn.up = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
var requiredFingers = guitarPurchased ? 10 : 0;
var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased;
// Check cymbalstick count for audience lock at 15
var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0;
var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10;
// Check maracas shake count for audience lock at 25
var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0;
var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5;
// Check pianist count for audience lock at 50
var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5;
var canPurchase = !guitarAvailableButNotPurchased && !audienceLocked15 && !audienceLocked25 && !audienceLocked50 && (guitarPurchased ? fingersPurchased >= requiredFingers : drumsticksPurchased >= 10);
if (canPurchase && gold >= musicianCost) {
// Helper function for new audience dancing
var _startAudienceDancing = function startAudienceDancing(audience) {
if (!window.audienceDancing) return;
// Create more realistic dance movements
var dancePhase = Math.random() < 0.5 ? 'sway' : 'bounce';
if (dancePhase === 'sway') {
// Swaying side to side movement
var swayDistance = 30 + Math.random() * 40; // 30-70 pixels
var swayTime = 800 + Math.random() * 400; // 800-1200ms
// Sway to one side
tween(audience, {
x: audience.originalX + swayDistance,
rotation: 0.1 // Slight tilt
}, {
duration: swayTime,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Sway to other side
tween(audience, {
x: audience.originalX - swayDistance,
rotation: -0.1 // Tilt opposite way
}, {
duration: swayTime,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Return to center and continue
tween(audience, {
x: audience.originalX,
rotation: 0
}, {
duration: swayTime / 2,
easing: tween.easeOut,
onFinish: function onFinish() {
_startAudienceDancing(audience);
}
});
}
});
}
});
} else {
// Bouncing movement without shape distortion
var bounceHeight = 15 + Math.random() * 25; // 15-40 pixels
var bounceTime = 400 + Math.random() * 200; // 400-600ms
// Bounce up - only move position, no scaling
tween(audience, {
y: audience.y - bounceHeight
}, {
duration: bounceTime,
easing: tween.easeOut,
onFinish: function onFinish() {
// Bounce down
tween(audience, {
y: audience.y + bounceHeight
}, {
duration: bounceTime,
easing: tween.bounceOut,
onFinish: function onFinish() {
_startAudienceDancing(audience);
}
});
}
});
}
};
// Check if this is the first audience purchase
var isFirstAudience = musicians.length === 0;
gold -= musicianCost;
var newAudience = game.addChild(new Audience());
// Random spawn position at bottom of screen with slight vertical variation
newAudience.x = 200 + Math.random() * 1648; // Random x between 200 and 1848
newAudience.y = 2435 + (Math.random() - 0.5) * 50; // Spawn between 2410-2460 (moved up by 15 pixels total)
// Only set instruments if guitar is not purchased
if (!guitarPurchased && unlockedInstruments.length > 1) {
var randomInstrument = unlockedInstruments[Math.floor(Math.random() * (unlockedInstruments.length - 1)) + 1];
newAudience.setInstrument(randomInstrument);
}
// If disco is active (10+ audience), start dancing for new member
if (musicians.length >= 10 && window.audienceDancing) {
newAudience.originalX = newAudience.x;
// Start dancing with a slight delay
LK.setTimeout(function () {
_startAudienceDancing(newAudience);
}, 100);
}
musicians.push(newAudience);
goldPerTap = Math.floor(goldPerTap * newAudience.multiplier);
// Remove individual audience income - now using multiplier system
// Recalculate passive income to include new audience member
recalculatePassiveIncome();
// Increase cost by 1.3x (30% increase)
musicianCost = Math.floor(musicianCost * 1.3);
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Force update button to refresh count display
var isLocked = guitarPurchased ? fingersPurchased < 10 : drumsticksPurchased < 10;
var lockMessage = guitarPurchased ? '10 Fingers' : '10 Drumsticks';
buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isLocked, musicians.length, isLocked, lockMessage);
}
};
buyInstrumentBtn.up = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
var nextInstrument = null;
var cost = 0;
if (!unlockedInstruments.includes('guitar')) {
nextInstrument = 'guitar';
cost = instrumentCosts.guitar;
} else if (!unlockedInstruments.includes('cymbal')) {
nextInstrument = 'cymbal';
cost = instrumentCosts.cymbal;
} else if (!unlockedInstruments.includes('maracas')) {
nextInstrument = 'maracas';
cost = instrumentCosts.maracas;
}
if (nextInstrument && gold >= cost && (nextInstrument !== 'guitar' || musicians.length >= 10) && (nextInstrument !== 'cymbal' || musicians.length >= 15 && fingersPurchased >= 10) && (nextInstrument !== 'maracas' || musicians.length >= 25)) {
gold -= cost;
unlockedInstruments.push(nextInstrument);
instrumentsPurchased++;
// Set guitar purchased flag and update musician cost to 500
if (nextInstrument === 'guitar') {
guitarPurchased = true;
musicianCost = 500;
guitarAsset.visible = true; // Show guitar
} else if (nextInstrument === 'cymbal') {
// Show cymbal
cymbalAsset.visible = true;
// Music now starts at 10 audience with disco, not on cymbal purchase
} else if (nextInstrument === 'maracas') {
// Show maracas
maracasAsset.visible = true;
// Show piano button when maracas is purchased
buyPianoBtn.visible = true;
}
if (!window.globalMuted) {
LK.getSound('purchase').play();
}
// Show guitar when purchased
if (nextInstrument === 'guitar') {
// Create finger if purchased but not created yet
if (fingersPurchased > 0 && fingers.length === 0) {
var newFinger = cameraContainer.addChild(new AutoFinger());
// Position finger on guitar
newFinger.x = guitarAsset.x - 250;
newFinger.y = guitarAsset.y + 50;
newFinger.guitarReference = guitarAsset;
fingers.push(newFinger);
}
}
// Update navigation arrows after purchasing any instrument
updateNavigationArrows();
// Update button for next instrument
if (nextInstrument === 'guitar') {
buyInstrumentBtn.updateButton('Cymbal', instrumentCosts.cymbal, gold >= instrumentCosts.cymbal, undefined);
} else if (nextInstrument === 'cymbal') {
buyInstrumentBtn.updateButton('Maracas', instrumentCosts.maracas, gold >= instrumentCosts.maracas, undefined);
} else if (nextInstrument === 'maracas') {
// Hide instrument button after maracas
buyInstrumentBtn.visible = false;
}
}
};
// Passive income timer
var incomeTimer = 0;
// Function to hide tutorial elements
function hideTutorial() {
if (tutorialHand && tutorialHand.parent) {
// Fade out and destroy tutorial hand
tween(tutorialHand, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
onFinish: function onFinish() {
if (tutorialHand && tutorialHand.parent) {
tutorialHand.destroy();
tutorialHand = null;
}
}
});
}
if (tutorialText && tutorialText.parent) {
// Fade out and destroy tutorial banner
tween(tutorialText, {
alpha: 0,
scaleX: 0.4,
scaleY: 0.4
}, {
duration: 500,
onFinish: function onFinish() {
if (tutorialText && tutorialText.parent) {
tutorialText.destroy();
tutorialText = null;
}
}
});
}
// Remove shadow overlay if it exists
if (window.tutorialShadow && window.tutorialShadow.parent) {
tween(window.tutorialShadow, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
if (window.tutorialShadow && window.tutorialShadow.parent) {
window.tutorialShadow.destroy();
window.tutorialShadow = null;
}
}
});
}
// Remove tutorial drum button without fade effect
if (window.tutorialDrumButton && window.tutorialDrumButton.parent) {
window.tutorialDrumButton.destroy();
window.tutorialDrumButton = null;
}
// Remove tutorial drumstick button without fade effect
if (window.tutorialDrumstickButton && window.tutorialDrumstickButton.parent) {
window.tutorialDrumstickButton.destroy();
window.tutorialDrumstickButton = null;
}
showTutorial = false;
}
// Main game loop
game.update = function () {
// Initialize audienceBPM if not set
if (typeof window.audienceBPM === 'undefined') {
window.audienceBPM = 120;
}
// Track and clean up confetti papers that exit the screen
if (window.activeConfetti && window.activeConfetti.length > 0) {
for (var i = window.activeConfetti.length - 1; i >= 0; i--) {
var confetti = window.activeConfetti[i];
if (!confetti || !confetti.parent) {
// Remove destroyed confetti from array
window.activeConfetti.splice(i, 1);
continue;
}
// Apply physics to confetti
if (confetti.velocityX !== undefined && confetti.velocityY !== undefined) {
// Update position based on velocity
confetti.x += confetti.velocityX;
confetti.y += confetti.velocityY;
// Apply gravity to vertical velocity
confetti.velocityY += confetti.gravity;
// Apply rotation
if (confetti.rotationSpeed !== undefined) {
confetti.rotation += confetti.rotationSpeed;
}
// Slight air resistance to horizontal movement
confetti.velocityX *= 0.99;
}
// Check if confetti has exited the screen (top, left, right, or bottom)
if (confetti.y < -100 || confetti.y > 2832 || confetti.x < -100 || confetti.x > 2148) {
confetti.destroy();
window.activeConfetti.splice(i, 1);
}
}
}
// Initialize drumBPM if not set to ensure drum sounds play
if (typeof window.drumBPM === 'undefined') {
window.drumBPM = 60;
}
// Check if all instruments are purchased (guitar, cymbal, maracas)
var allInstrumentsPurchased = unlockedInstruments.includes('guitar') && unlockedInstruments.includes('cymbal') && unlockedInstruments.includes('maracas');
// Check if audience reached 10 for disco lights
if (!window.discoLightsActive && musicians.length >= 10 && !window.discoMuted) {
// Start music when disco begins if not already playing
if (!isMusicPlaying && !window.globalMuted) {
LK.playMusic('ambientMusic', {
fade: {
start: 0,
end: 0.7,
duration: 2000
}
});
isMusicPlaying = true;
}
// Start audience dancing when disco begins
if (!window.audienceDancing) {
window.audienceDancing = true;
// Start dancing animations for all audience members
for (var i = 0; i < musicians.length; i++) {
var audience = musicians[i];
// Store original position
audience.originalX = audience.x;
// Start random movement
startAudienceDancing(audience);
}
}
// Function to create continuous swinging motion
var startDiscoBallSwing = function startDiscoBallSwing() {
var swingRight = function swingRight() {
tween(window.discoBallContainer, {
rotation: 0.2
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
swingLeft();
}
});
};
var swingLeft = function swingLeft() {
tween(window.discoBallContainer, {
rotation: -0.2
}, {
duration: 2000,
easing: tween.easeInOut,
onFinish: function onFinish() {
swingRight();
}
});
};
// Start the swing
swingRight();
}; // Create container for random top lights
window.discoLightsActive = true;
// Start CD rotation when disco begins (10 audience)
if (!cdRotationTween && decorationAsset && isMusicPlaying) {
var rotateContinuously = function rotateContinuously() {
// Check if music is still playing before starting new rotation
if (!isMusicPlaying) {
// Stop any existing tween if music stopped
if (cdRotationTween) {
tween.stop(cdRotationTween);
cdRotationTween = null;
}
return;
}
cdRotationTween = tween(decorationAsset, {
rotation: decorationAsset.rotation + Math.PI * 2
}, {
duration: 4000,
easing: tween.linear,
onFinish: function onFinish() {
if (isMusicPlaying) {
rotateContinuously(); // Continue rotating
} else {
// Ensure tween is cleared if music stopped during animation
cdRotationTween = null;
}
}
});
};
// Start music if not already playing and not globally muted
if (!isMusicPlaying && !window.globalMuted) {
LK.playMusic('ambientMusic', {
fade: {
start: 0,
end: 0.7,
duration: 2000
}
});
isMusicPlaying = true;
}
rotateContinuously();
}
// Create disco ball hanging from ceiling - add after background (at index 1)
// This ensures it's behind piano (in cameraContainer) and disco lights
window.discoBallContainer = game.addChildAt(new Container(), 1);
window.discoBallContainer.x = 1024;
window.discoBallContainer.y = -150; // Start above screen
var discoBall = window.discoBallContainer.attachAsset('discoBall', {
anchorX: 0.5,
anchorY: 0,
scaleX: 1,
scaleY: 1
});
// Animate disco ball dropping down
tween(window.discoBallContainer, {
y: 200
}, {
duration: 1500,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Start swinging animation
startDiscoBallSwing();
}
});
// Create disco light container AFTER disco ball (so lights appear in front)
window.discoLights = game.addChild(new Container());
// Create multiple colored lights with more vibrant colors
var colors = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1]; // DeepPink, SpringGreen, DodgerBlue, Gold, HotPink, DarkTurquoise
window.discoLightAssets = [];
for (var i = 0; i < 6; i++) {
var light = window.discoLights.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20,
alpha: 0.12,
x: 200 + i * 300,
y: 300
});
light.tint = colors[i];
window.discoLightAssets.push(light);
}
window.topLights = game.addChild(new Container());
window.topLightPool = [];
// Create persistent party overlay
window.partyOverlay = game.addChild(new Container());
var partyLight = window.partyOverlay.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 300,
scaleY: 300,
alpha: 0,
x: 1024,
y: 1366
});
partyLight.tint = 0xFFFFFF;
window.partyOverlayLight = partyLight;
// Create full screen light transition effect
var fullScreenFlash = game.addChild(new Container());
var flashOverlay = fullScreenFlash.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 250,
scaleY: 250,
alpha: 0,
x: 1024,
y: 1366
});
flashOverlay.tint = 0xFFFFFF;
// Animate full screen flash with party overlay
tween(flashOverlay, {
alpha: 0.25
}, {
duration: 50,
onFinish: function onFinish() {
// Fade in party overlay
tween(partyLight, {
alpha: 0.05
}, {
duration: 100
});
tween(flashOverlay, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
fullScreenFlash.destroy();
}
});
}
});
}
// Audience dancing is now triggered with disco lights at 10 audience members
// Function to start dancing animation for an audience member
function startAudienceDancing(audience) {
if (!window.audienceDancing) return;
// Create more realistic dance movements
var dancePhase = Math.random() < 0.5 ? 'sway' : 'bounce';
if (dancePhase === 'sway') {
// Swaying side to side movement
var swayDistance = 30 + Math.random() * 40; // 30-70 pixels
var swayTime = 800 + Math.random() * 400; // 800-1200ms
// Sway to one side
tween(audience, {
x: audience.originalX + swayDistance,
rotation: 0.1 // Slight tilt
}, {
duration: swayTime,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Sway to other side
tween(audience, {
x: audience.originalX - swayDistance,
rotation: -0.1 // Tilt opposite way
}, {
duration: swayTime,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Return to center and continue
tween(audience, {
x: audience.originalX,
rotation: 0
}, {
duration: swayTime / 2,
easing: tween.easeOut,
onFinish: function onFinish() {
startAudienceDancing(audience);
}
});
}
});
}
});
} else {
// Bouncing movement without shape distortion
var bounceHeight = 15 + Math.random() * 25; // 15-40 pixels
var bounceTime = 400 + Math.random() * 200; // 400-600ms
// Bounce up - only move position, no scaling
tween(audience, {
y: audience.y - bounceHeight
}, {
duration: bounceTime,
easing: tween.easeOut,
onFinish: function onFinish() {
// Bounce down
tween(audience, {
y: audience.y + bounceHeight
}, {
duration: bounceTime,
easing: tween.bounceOut,
onFinish: function onFinish() {
startAudienceDancing(audience);
}
});
}
});
}
}
// Apply dancing to new audience members if dancing is active
if (window.audienceDancing && musicians.length > 0) {
// Check for new audience members that don't have dancing animation
for (var i = 0; i < musicians.length; i++) {
var audience = musicians[i];
if (!audience.originalX) {
audience.originalX = audience.x;
startAudienceDancing(audience);
}
}
}
// Animate disco lights if active
if (window.discoLightsActive && window.discoLightAssets) {
// Animate party overlay with color transitions
if (window.partyOverlayLight) {
var partyBeatTick = LK.ticks % 120;
if (partyBeatTick === 0) {
var partyColors = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1];
var newColor = partyColors[Math.floor(Math.random() * partyColors.length)];
tween(window.partyOverlayLight, {
tint: newColor,
alpha: Math.random() * 0.12 + 0.06
}, {
duration: 1000,
onFinish: function onFinish() {
tween(window.partyOverlayLight, {
alpha: 0.08
}, {
duration: 1000
});
}
});
}
}
// Flash lights based on beat
var beatTick = LK.ticks % 30;
if (beatTick === 0) {
for (var i = 0; i < window.discoLightAssets.length; i++) {
var light = window.discoLightAssets[i];
// Random flashing effect with much lower alpha
tween(light, {
alpha: Math.random() * 0.25 + 0.1,
scaleX: Math.random() * 15 + 15,
scaleY: Math.random() * 15 + 15
}, {
duration: 200,
onFinish: function (light) {
return function () {
tween(light, {
alpha: 0.12,
scaleX: 20,
scaleY: 20
}, {
duration: 200
});
};
}(light)
});
}
}
// Spawn random top lights
if (Math.random() < 0.05 && window.topLightPool.length < 10) {
var topLight = window.topLights.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 12,
scaleY: 12,
alpha: 0,
x: 200 + Math.random() * 1648,
y: 400 + Math.random() * 300
});
topLight.tint = [0xFF1493, 0x00FF7F, 0x1E90FF, 0xFFD700, 0xFF69B4, 0x00CED1][Math.floor(Math.random() * 6)]; // More vibrant colors
window.topLightPool.push(topLight);
// Fade in and out animation - much faster disappearance
tween(topLight, {
alpha: Math.random() * 0.3 + 0.15
}, {
duration: 200,
onFinish: function onFinish() {
tween(topLight, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
var index = window.topLightPool.indexOf(topLight);
if (index > -1) {
window.topLightPool.splice(index, 1);
}
topLight.destroy();
}
});
}
});
}
}
// Synchronize all purchased automatic players to drum hit
if (drumsticks.length > 0) {
// Get drumstick hit timing
var drumTicksPerHit = Math.floor(3600 / (window.drumBPM || 60));
if (LK.ticks % drumTicksPerHit === 0) {
// Force drumstick to hit
drumsticks[0].tickCounter = drumTicksPerHit;
// Synchronize other instruments' first hit with drumstick
if (fingers.length > 0 && !fingers[0].hasHitOnce) {
// Force finger to hit with drumstick on first hit
fingers[0].tickCounter = Math.floor(3600 / (window.guitarBPM || 10));
fingers[0].hasHitOnce = true;
}
if (autoCymbalsticks.length > 0 && !autoCymbalsticks[0].hasHitOnce) {
// Force cymbalstick to hit with drumstick on first hit
autoCymbalsticks[0].tickCounter = Math.floor(3600 / (window.cymbalBPM || 30));
autoCymbalsticks[0].hasHitOnce = true;
}
if (pianists.length > 0 && !pianists[0].hasHitOnce) {
// Force pianist to hit with drumstick on first hit
pianists[0].tickCounter = Math.floor(3600 / (window.pianoBPM || 10));
pianists[0].hasHitOnce = true;
}
// Synchronize maracas if purchased
if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount > 0 && maracasAsset && !window.maracasHasHitOnce) {
// Trigger maracas animation
maracasAsset.animate();
window.maracasHasHitOnce = true;
}
// Synchronize flute if purchased
if (window.fluteAutoPlay && fluteAsset && !window.fluteHasHitOnce) {
window.fluteAutoPlayCounter = Math.floor(3600 / (window.fluteBPM || 15));
window.fluteHasHitOnce = true;
}
}
}
// Automatic flute playing at dynamic BPM when fluteblow is purchased
if (window.fluteAutoPlay && fluteAsset) {
// Calculate ticks per hit based on dynamic fluteBPM
var fluteTicksPerHit = Math.floor(3600 / (window.fluteBPM || 15));
if (typeof window.fluteAutoPlayCounter === 'undefined') window.fluteAutoPlayCounter = 0;
window.fluteAutoPlayCounter++;
if (window.fluteAutoPlayCounter >= fluteTicksPerHit) {
window.fluteAutoPlayCounter = 0;
// Animate flute
tween(fluteAsset, {
scaleX: 3.1,
scaleY: 3.1
}, {
duration: 100,
onFinish: function onFinish() {
tween(fluteAsset, {
scaleX: 3,
scaleY: 3
}, {
duration: 100
});
}
});
// Generate gold
var fluteIncome = 25000;
gold += fluteIncome;
// Instant gold update
displayedGold = gold;
// Play flute sound if not muted
if (!window.fluteBPMMuted && !window.globalMuted) {
LK.getSound('flutehit').play();
}
// Create floating text
var floatingGold = game.addChild(new FloatingText('+' + fluteIncome, 0x87CEEB));
floatingGold.x = fluteAsset.x + cameraContainer.x;
floatingGold.y = fluteAsset.y - 100;
// Create music note effect
var note = game.addChild(new MusicNote());
note.x = fluteAsset.x + cameraContainer.x + (Math.random() - 0.5) * 100;
note.y = fluteAsset.y - 100;
}
}
// Global clap synchronization - use dynamic audienceBPM with single clap only
// Calculate ticks per clap based on dynamic audienceBPM
var ticksPerClap = Math.floor(3600 / (window.audienceBPM || 30));
if (LK.ticks % ticksPerClap === 0 && musicians.length > 0) {
// Single clap only - no patterns
if (!window.audienceBPMMuted && !window.globalMuted) {
LK.getSound('clap').play();
}
}
// Maracas automatic shake based on dynamic BPM
if (typeof window.maracasShakeCount !== 'undefined' && window.maracasShakeCount > 0 && maracasAsset) {
var maracasTicksPerShake = Math.floor(3600 / (window.maracasBPM || 120));
if (LK.ticks % maracasTicksPerShake === 0) {
// Trigger maracas animation and sound directly without menu check
maracasAsset.animate();
}
}
// Smooth gold display transition
if (targetDisplayedGold !== gold) {
targetDisplayedGold = gold;
}
// Smoothly interpolate displayed gold towards target
if (displayedGold !== targetDisplayedGold) {
var diff = targetDisplayedGold - displayedGold;
var step = diff * 0.1; // Adjust 10% of the difference per frame
// Ensure minimum step size for small differences
if (Math.abs(step) < 0.1) {
step = diff > 0 ? 0.1 : -0.1;
}
// Update displayed gold
displayedGold += step;
// Snap to target if very close
if (Math.abs(displayedGold - targetDisplayedGold) < 0.5) {
displayedGold = targetDisplayedGold;
}
}
// Update UI
goldText.setText('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', 500000, false, undefined, true, '');
}
// PIANO LOGIC
else if (currentInstrument === 'piano') {
// Update pianist button
buyDrumstickBtn.updateButton('Pianist', pianistCost, gold >= pianistCost, pianistsPurchased);
// Update audience button - locked until 5 pianists or if guitar is available but not purchased
var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased;
// Check cymbalstick count for audience lock at 15
var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0;
var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10;
// Check maracas shake count for audience lock at 25
var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0;
var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5;
// Check pianist count for audience lock at 50
var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5;
var isAudienceLocked = guitarAvailableButNotPurchased || pianistsPurchased < 5 || audienceLocked15 || audienceLocked25 || audienceLocked50;
var audienceLockMessage = guitarAvailableButNotPurchased ? 'Buy Guitar First' : audienceLocked50 ? '5 Pianists' : audienceLocked25 ? '5 Maracas Shake' : audienceLocked15 ? '10 Cymbalstick' : isAudienceLocked ? '5 Pianists' : '';
buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage);
// Hide instrument button in piano view
buyInstrumentBtn.visible = false;
// Update piano button (right button) - locked until 5 pianists and 40 audience
buyPianoBtn.visible = true;
var isPianoLocked = unlockedInstruments.includes('flute') ? true : pianistsPurchased < 5 || musicians.length < 40;
var pianoLockMessage = '';
if (unlockedInstruments.includes('flute')) {
pianoLockMessage = '';
} else if (pianistsPurchased < 5) {
pianoLockMessage = '5 Pianists';
} else if (musicians.length < 40) {
pianoLockMessage = '40 Audience';
}
buyPianoBtn.updateButton('Flute', 500000, gold >= 500000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage);
}
// MARACAS LOGIC
else if (currentInstrument === 'maracas') {
// Initialize maracas shake cost and count
if (typeof window.maracasShakeCost === 'undefined') window.maracasShakeCost = 12000;
if (typeof window.maracasShakeCount === 'undefined') window.maracasShakeCount = 0;
var maracasShakeCost = window.maracasShakeCost;
var canAffordMaracasShake = gold >= maracasShakeCost;
// Update buyDrumstickBtn for maracas shake - always show count and allow purchase if can afford
buyDrumstickBtn.updateButton('Maracas Shake', maracasShakeCost, canAffordMaracasShake, window.maracasShakeCount);
// Update audience button - unlock at 25 audience
var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased;
// Check cymbalstick count for audience lock at 15
var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0;
var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10;
// Check maracas shake count for audience lock at 25
var audienceLocked25 = musicians.length >= 25 && window.maracasShakeCount < 5;
// Check pianist count for audience lock at 50
var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5;
var isAudienceLocked = guitarAvailableButNotPurchased || audienceLocked15 || audienceLocked25 || audienceLocked50;
var audienceLockMessage = guitarAvailableButNotPurchased ? 'Buy Guitar First' : audienceLocked50 ? '5 Pianists' : audienceLocked25 ? '5 Maracas Shake' : audienceLocked15 ? '10 Cymbalstick' : '';
buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage);
// Hide instrument button in maracas view
buyInstrumentBtn.visible = false;
// Update piano button in maracas view
buyPianoBtn.visible = true;
// Always lock if piano or flute is already purchased
var isPianoLocked = unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute') ? true : window.maracasShakeCount < 5 || musicians.length < 30;
var pianoLockMessage = '';
if (unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute')) {
pianoLockMessage = '';
} else if (window.maracasShakeCount < 5) {
pianoLockMessage = '5 Shakes';
} else if (musicians.length < 30) {
pianoLockMessage = '30 Audience';
}
// Show Flute if already purchased, otherwise show Piano
var buttonLabel = unlockedInstruments.includes('flute') ? 'Flute' : 'Piano';
buyPianoBtn.updateButton(buttonLabel, 30000, gold >= 30000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage);
} else if (currentInstrument === 'cymbal') {
// Track cymbalstick purchases
if (typeof window.cymbalsticksPurchased === 'undefined') window.cymbalsticksPurchased = 0;
if (typeof window.cymbalstickCost === 'undefined') window.cymbalstickCost = 2200;
var cymbalstickCount = window.cymbalsticksPurchased;
var cymbalstickCost = window.cymbalstickCost;
var canAffordCymbalstick = gold >= cymbalstickCost;
var cymbalstickLocked = cymbalstickCount < 10;
// Check if cymbalstick should be locked based on finger count
var isCymbalstickLocked = fingersPurchased < 10;
var cymbalstickLockMessage = isCymbalstickLocked ? '10 Fingers' : '';
// Update buyDrumstickBtn for cymbalstick
buyDrumstickBtn.updateButton('Cymbalstick', cymbalstickCost, canAffordCymbalstick && !isCymbalstickLocked, window.cymbalsticksPurchased, isCymbalstickLocked, cymbalstickLockMessage);
// Update audience button - lock until 10 cymbalsticks are purchased or if guitar is available but not purchased
var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased;
// Also lock audience if count reached 15 and cymbalsticks < 10
var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10;
// Check maracas shake count for audience lock at 25
var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0;
var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5;
// Check pianist count for audience lock at 50
var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5;
var isAudienceLocked = guitarAvailableButNotPurchased || cymbalstickCount < 10 || audienceLocked15 || audienceLocked25 || audienceLocked50;
var audienceLockMessage = guitarAvailableButNotPurchased ? 'Buy Guitar First' : audienceLocked50 ? '5 Pianists' : audienceLocked25 ? '5 Maracas Shake' : audienceLocked15 ? '10 Cymbalstick' : isAudienceLocked ? '10 Cymbalstick' : '';
buyMusicianBtn.updateButton('Audience', musicianCost, gold >= musicianCost && !isAudienceLocked, musicians.length, isAudienceLocked, audienceLockMessage);
// Update maracas button - lock until 25 audience members are purchased
var isMaracasLocked = musicians.length < 25;
var maracasLockMessage = musicians.length < 25 ? '25 Audience' : '';
// Check if maracas is already unlocked to determine if button should be visible
if (unlockedInstruments.includes('maracas')) {
// Hide instrument button when maracas is already unlocked
buyInstrumentBtn.visible = false;
// Show piano button if maracas is unlocked
buyPianoBtn.visible = true;
// Always lock piano in cymbal view until 30 audience
var isPianoLocked = true;
var pianoLockMessage = '30 Audience';
if (unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute')) {
pianoLockMessage = '';
} else if (typeof window.maracasShakeCount === 'undefined' || window.maracasShakeCount < 5) {
pianoLockMessage = '5 Shakes';
} else if (musicians.length < 30) {
pianoLockMessage = '30 Audience';
}
// Show Flute if already purchased, otherwise show Piano
var buttonLabel = unlockedInstruments.includes('flute') ? 'Flute' : 'Piano';
buyPianoBtn.updateButton(buttonLabel, 30000, false, undefined, isPianoLocked, pianoLockMessage);
} else {
buyInstrumentBtn.updateButton('Maracas', instrumentCosts.maracas, gold >= instrumentCosts.maracas && !isMaracasLocked, undefined, isMaracasLocked, maracasLockMessage);
buyInstrumentBtn.visible = true;
}
} else {
var buttonText = currentInstrument === 'guitar' ? 'Finger' : 'Drumstick';
var purchaseCount = currentInstrument === 'guitar' ? fingersPurchased : drumsticksPurchased;
var currentCost = currentInstrument === 'guitar' ? fingerCost : drumstickCost;
buyDrumstickBtn.updateButton(buttonText, currentCost, gold >= currentCost, purchaseCount);
// Lock audience if guitar is available but not purchased
var guitarAvailableButNotPurchased = musicians.length >= 10 && !guitarPurchased;
// Check cymbalstick count for audience lock at 15
var cymbalstickCount = typeof window.cymbalsticksPurchased !== 'undefined' ? window.cymbalsticksPurchased : 0;
var audienceLocked15 = musicians.length >= 15 && cymbalstickCount < 10;
// Check maracas shake count for audience lock at 25
var maracasShakeCount = typeof window.maracasShakeCount !== 'undefined' ? window.maracasShakeCount : 0;
var audienceLocked25 = musicians.length >= 25 && maracasShakeCount < 5;
// Check pianist count for audience lock at 50
var audienceLocked50 = musicians.length >= 50 && pianistsPurchased < 5;
var isAudienceLocked = guitarAvailableButNotPurchased || (guitarPurchased ? fingersPurchased < 10 : drumsticksPurchased < 10) || audienceLocked15 || audienceLocked25 || audienceLocked50;
var lockMessage = guitarAvailableButNotPurchased ? 'Buy Guitar First' : audienceLocked50 ? '5 Pianists' : audienceLocked25 ? '5 Maracas Shake' : audienceLocked15 ? '10 Cymbalstick' : 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' && musicians.length < 25;
var isLocked = isGuitarLocked || isCymbalLocked || isMaracasLocked;
var lockMessage = '';
if (nextInstrument === 'guitar' && isAudienceLocked) {
lockMessage = guitarPurchased ? '10 Fingers' : '10 Drumsticks';
} else if (isGuitarLocked) {
lockMessage = '10 Audience';
} else if (isCymbalLocked) {
if (fingersPurchased < 10) {
lockMessage = '10 Fingers';
} else {
lockMessage = '15 Audience';
}
} else if (isMaracasLocked) {
lockMessage = '25 Audience';
}
buyInstrumentBtn.updateButton(nextInstrument.charAt(0).toUpperCase() + nextInstrument.slice(1), cost, gold >= cost && !isLocked, undefined, isLocked, lockMessage);
buyInstrumentBtn.visible = true;
} else if (unlockedInstruments.includes('maracas')) {
// Hide instrument button when all instruments are unlocked
buyInstrumentBtn.visible = false;
// Show piano button if maracas is unlocked
buyPianoBtn.visible = true;
// Always lock if piano or flute is already purchased
var isPianoLocked = unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute') ? true : typeof window.maracasShakeCount === 'undefined' || window.maracasShakeCount < 5 || musicians.length < 30;
var pianoLockMessage = '';
if (unlockedInstruments.includes('piano') || unlockedInstruments.includes('flute')) {
pianoLockMessage = '';
} else if (typeof window.maracasShakeCount === 'undefined' || window.maracasShakeCount < 5) {
pianoLockMessage = '5 Shakes';
} else if (musicians.length < 30) {
pianoLockMessage = '30 Audience';
}
// Show Flute if already purchased, otherwise show Piano
var buttonLabel = unlockedInstruments.includes('flute') ? 'Flute' : 'Piano';
buyPianoBtn.updateButton(buttonLabel, 30000, gold >= 30000 && !isPianoLocked, undefined, isPianoLocked, pianoLockMessage);
}
}
// Add passive income smoothly (every tick)
if (passiveIncome > 0) {
// Add fractional income amount per tick
var incomePerTick = passiveIncome / 60;
gold += incomePerTick;
}
// Save functionality removed - game resets on reload
};
// Load functionality removed - game starts fresh on each reload
// Add visibility change listeners for tab switching
LK.on('pause', function () {
// Game is paused (tab switched away)
if (isMusicPlaying && !window.globalMuted) {
LK.stopMusic();
window.musicWasPlaying = true;
}
});
LK.on('resume', function () {
// Game is resumed (tab switched back)
if (window.musicWasPlaying && !window.globalMuted) {
LK.playMusic('ambientMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
window.musicWasPlaying = false;
}
});
// CD click handlers
menuDecoration.down = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
// Visual feedback
tween(decorationAsset, {
scaleX: 0.36,
scaleY: 0.36
}, {
duration: 10,
onFinish: function onFinish() {
tween(decorationAsset, {
scaleX: 0.4,
scaleY: 0.4
}, {
duration: 10
});
}
});
};
menuDecoration.up = function () {
// Block interaction if menu is open
if (game.menuContainer && game.menuContainer.parent) return;
if (!isMusicPlaying) {
// Keep CD transparent, will become visible when music actually starts
// Start continuous CD rotation
var _rotateContinuously = function rotateContinuously() {
// Check if music is still playing before starting new rotation
if (!isMusicPlaying) {
// Stop any existing tween if music stopped
if (cdRotationTween) {
tween.stop(cdRotationTween);
cdRotationTween = null;
}
return;
}
cdRotationTween = tween(decorationAsset, {
rotation: decorationAsset.rotation + Math.PI * 2
}, {
duration: 4000,
easing: tween.linear,
onFinish: function onFinish() {
if (isMusicPlaying) {
_rotateContinuously(); // Continue rotating
} else {
// Ensure tween is cleared if music stopped during animation
cdRotationTween = null;
}
}
});
};
// Start music only if not globally muted
if (!window.globalMuted) {
LK.playMusic('ambientMusic', {
fade: {
start: 0,
end: 0.7,
duration: 2000
}
});
}
isMusicPlaying = true;
// Keep CD at constant transparency
_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;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -521,9 +521,10 @@
var stickAsset = confettiStick.attachAsset('confettistick', {
anchorX: 0.5,
anchorY: 1.0,
x: 0,
- y: 0
+ y: 0,
+ rotation: Math.PI / 4 // Add 45 degrees to get 315 total (270 + 45)
});
confettiStick.x = drumX + 500; // moved 500 pixels to the right
confettiStick.y = drumY + 100; // moved 200 pixels down (from -100 to +100)
// Confetti stick animation removed - no pulsation
@@ -537,9 +538,9 @@
x: 0,
y: 0
});
// Position at the exact tip of the stick (stick is at drumX + 500, drumY + 100)
- // Since stick has anchorY: 1.0 and height ~600px, tip is at 315 degrees (45 degrees counterclockwise)
+ // Stick has anchorY: 1.0, height ~600px, and is rotated 315 degrees total
// Calculate tip position: cos(315°) = 0.707, sin(315°) = -0.707
confetti.x = drumX + 500 + 600 * 0.707; // Move right by 600 * cos(315°)
confetti.y = drumY + 100 - 600 * 0.707; // Move up by 600 * sin(315°)
var angle = Math.PI / 4 + (Math.random() - 0.5) * Math.PI / 2 + (i - 4) * 0.18;
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