User prompt
if I close the target play this track "endlevel" and I won the level change the track "main_menu"1
User prompt
if I won level, stop this track:"endlevel" and play this track "main_menu"
User prompt
increase the level target level 1: 100 level 30: 3000
User prompt
if I click any level button, first play this track:"startlevel" If i have a target/2 play this track:"levelmid" if i have a target play this track "endlevel"
User prompt
if I clicked any button play this sound in collect>"click"
User prompt
if music:on play this track:"main_menu"
User prompt
settings tab>Music:on/off settings tab>Sound:on/off
User prompt
if I in the main menu play this track:"main_menu"
User prompt
add a "setting" button in the main menu
User prompt
play "happy_and_lo-fi" track and loop
User prompt
update the "Assets" tab
User prompt
if i click the regular upit play button, play game "happy_and_lo-fi" track
User prompt
add background in the levels
User prompt
if I click regular upit play button, reset the progress
User prompt
reset the player progress
User prompt
level targets "Level 1: 25 score... Level 30 100 score
User prompt
if I won don't show regular "you win!" tab
User prompt
lock the levels, and put a target for levels "example if i have a 50 score in level 1, unlock level 2
User prompt
Please fix the bug: 'TypeError: storage.save is not a function' in or related to this line: 'storage.save();' Line Number: 661 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
add "5" perks
User prompt
if heart 0<3 return the main menu
User prompt
add a 3 heart for loss
User prompt
remake the game with main menu, "play>select levels 1-30" "shop>Character&perks"
User prompt
remake the game
User prompt
remake
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
coins: 0,
unlockedSkins: ["candyRed"],
selectedSkin: "candyRed",
perks: {
extraLife: false,
slowMotion: false,
magnetCollector: false,
doubleCoins: false,
bonusPoints: false
},
unlockedLevels: [1],
levelScores: {}
});
/****
* Classes
****/
// Candy class
var Candy = Container.expand(function () {
var self = Container.call(this);
// Use selected skin or random unlocked skin
var skin = storage.selectedSkin || 'candyRed';
var candyAsset = self.attachAsset(skin, {
anchorX: 0.5,
anchorY: 0.5
});
self.width = candyAsset.width;
self.height = candyAsset.height;
// Falling speed
self.speed = 10 + Math.random() * 6;
// For swipe detection
self.collected = false;
// For tracking last Y for off-screen detection
self.lastY = self.y;
// For tracking if already counted as missed
self.missed = false;
// For future: skin id
self.skin = skin;
// For future: coin drop
self.hasCoin = Math.random() < 0.15; // 15% chance to drop a coin
// Add coin visual if hasCoin
if (self.hasCoin) {
var coinAsset = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5,
y: 30
});
coinAsset.alpha = 0.8;
}
// Animate in
candyAsset.scaleX = 0.2;
candyAsset.scaleY = 0.2;
tween(candyAsset, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.elasticOut
});
// Update method
self.update = function () {
if (self.collected) return;
self.y += self.speed;
};
return self;
});
// Coin collect animation
var CoinFly = Container.expand(function () {
var self = Container.call(this);
var coin = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = coin.width;
self.height = coin.height;
self.update = function () {};
return self;
});
// Collector class (player's swipe area)
var Collector = Container.expand(function () {
var self = Container.call(this);
var collectorAsset = self.attachAsset('collector', {
anchorX: 0.5,
anchorY: 0.5
});
collectorAsset.alpha = 0.18;
// Apply magnet perk to collector size
var magnetScale = perks[2].effect();
collectorAsset.scaleX = magnetScale;
self.width = collectorAsset.width * magnetScale;
self.height = collectorAsset.height;
self.update = function () {};
return self;
});
// Shop item class
var ShopItem = Container.expand(function () {
var self = Container.call(this);
var box = self.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5
});
self.icon = null;
self.price = 0;
self.skinId = '';
self.owned = false;
self.setSkin = function (skinId, price, owned) {
self.skinId = skinId;
self.price = price;
self.owned = owned;
if (self.icon) self.removeChild(self.icon);
self.icon = self.attachAsset(skinId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.1,
scaleY: 1.1
});
self.icon.y = -20;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222244
});
/****
* Game Code
****/
// Reset all progress when game reinitializes
// Candy shapes - colorful circles for collectible items
// Coin - golden circle for currency
// Collector - white rectangle for player's swipe area
// Shop item - gray box for UI buttons and shop items
// Sound effects
// Background music
storage.coins = 0;
storage.unlockedSkins = ["candyRed"];
storage.selectedSkin = "candyRed";
storage.perks = {
extraLife: false,
slowMotion: false,
magnetCollector: false,
doubleCoins: false,
bonusPoints: false
};
storage.unlockedLevels = [1];
storage.levelScores = {};
// Game states
var gameState = 'mainMenu'; // mainMenu, levelSelect, shop, playing, settings
var currentLevel = 1;
// Audio settings
var musicEnabled = true;
var soundEnabled = true;
// UI containers
var mainMenuContainer = null;
var levelSelectContainer = null;
var shopContainer = null;
var gameplayContainer = null;
var settingsContainer = null;
// Game variables
var score = 0;
var candies = [];
var collector = null;
var candySpawnTimer = 0;
var levelConfig = {};
var lives = 3;
var heartsContainer = null;
// Perks system
var perks = [{
id: 'extraLife',
name: 'Extra Life',
description: '+1 starting life',
price: 250,
effect: function effect() {
return storage.perks.extraLife ? 1 : 0;
}
}, {
id: 'slowMotion',
name: 'Slow Motion',
description: '20% slower candies',
price: 400,
effect: function effect() {
return storage.perks.slowMotion ? 0.8 : 1;
}
}, {
id: 'magnetCollector',
name: 'Magnet',
description: 'Wider collection area',
price: 600,
effect: function effect() {
return storage.perks.magnetCollector ? 1.5 : 1;
}
}, {
id: 'doubleCoins',
name: 'Double Coins',
description: '2x coin drops',
price: 800,
effect: function effect() {
return storage.perks.doubleCoins ? 2 : 1;
}
}, {
id: 'bonusPoints',
name: 'Score Boost',
description: '+1 point per candy',
price: 1000,
effect: function effect() {
return storage.perks.bonusPoints ? 1 : 0;
}
}];
// Score display
var scoreTxt = new Text2('0', {
size: 120,
fill: '#fff'
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
// Coins display
var coinsTxt = new Text2('Coins: ' + storage.coins, {
size: 80,
fill: '#ffd700'
});
coinsTxt.anchor.set(1, 0);
coinsTxt.x = -20;
LK.gui.topRight.addChild(coinsTxt);
// Create main menu
function createMainMenu() {
if (mainMenuContainer) mainMenuContainer.destroy();
mainMenuContainer = new Container();
// Title
var title = new Text2('Candy Catch', {
size: 200,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 600;
mainMenuContainer.addChild(title);
// Play button
var playBtn = mainMenuContainer.addChild(new Container());
var playBg = playBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8,
tint: 0x3bff6e
});
playBtn.x = 1024;
playBtn.y = 1200;
var playTxt = new Text2('PLAY', {
size: 100,
fill: '#ffffff'
});
playTxt.anchor.set(0.5, 0.5);
playBtn.addChild(playTxt);
playBtn.down = function () {
gameState = 'levelSelect';
updateGameState();
};
// Shop button
var shopBtn = mainMenuContainer.addChild(new Container());
var shopBg = shopBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8,
tint: 0xffd700
});
shopBtn.x = 1024;
shopBtn.y = 1500;
var shopTxt = new Text2('SHOP', {
size: 100,
fill: '#ffffff'
});
shopTxt.anchor.set(0.5, 0.5);
shopBtn.addChild(shopTxt);
shopBtn.down = function () {
gameState = 'shop';
updateGameState();
};
// Settings button
var settingsBtn = mainMenuContainer.addChild(new Container());
var settingsBg = settingsBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 0.8,
tint: 0x8888ff
});
settingsBtn.x = 1024;
settingsBtn.y = 1800;
var settingsTxt = new Text2('SETTINGS', {
size: 100,
fill: '#ffffff'
});
settingsTxt.anchor.set(0.5, 0.5);
settingsBtn.addChild(settingsTxt);
settingsBtn.down = function () {
gameState = 'settings';
updateGameState();
};
game.addChild(mainMenuContainer);
}
// Create level select
function createLevelSelect() {
if (levelSelectContainer) levelSelectContainer.destroy();
levelSelectContainer = new Container();
// Title
var title = new Text2('Select Level', {
size: 120,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 200;
levelSelectContainer.addChild(title);
// Back button
var backBtn = levelSelectContainer.addChild(new Container());
var backBg = backBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6,
tint: 0xff6666
});
backBtn.x = 200;
backBtn.y = 200;
var backTxt = new Text2('BACK', {
size: 60,
fill: '#ffffff'
});
backTxt.anchor.set(0.5, 0.5);
backBtn.addChild(backTxt);
backBtn.down = function () {
gameState = 'mainMenu';
updateGameState();
};
// Level buttons grid
var startX = 300;
var startY = 500;
var spacing = 250;
var cols = 6;
for (var i = 0; i < 30; i++) {
var levelBtn = levelSelectContainer.addChild(new Container());
var col = i % cols;
var row = Math.floor(i / cols);
var levelNum = i + 1;
var isUnlocked = storage.unlockedLevels.indexOf(levelNum) !== -1;
var highScore = storage.levelScores[levelNum] || 0;
var targetScore = levelNum === 1 ? 25 : levelNum === 30 ? 100 : 10 + levelNum * 5;
var lvlBg = levelBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
tint: isUnlocked ? i < 10 ? 0x66ff66 : i < 20 ? 0xffff66 : 0xff6666 : 0x444444
});
levelBtn.x = startX + col * spacing;
levelBtn.y = startY + row * spacing;
var lvlTxt = new Text2(isUnlocked ? levelNum.toString() : '🔒', {
size: isUnlocked ? 80 : 60,
fill: isUnlocked ? '#ffffff' : '#888888'
});
lvlTxt.anchor.set(0.5, 0.5);
lvlTxt.y = isUnlocked ? -10 : 0;
levelBtn.addChild(lvlTxt);
// Show score info for unlocked levels
if (isUnlocked && highScore > 0) {
var scoreTxt = new Text2(highScore + '/' + targetScore, {
size: 30,
fill: '#cccccc'
});
scoreTxt.anchor.set(0.5, 0.5);
scoreTxt.y = 50;
levelBtn.addChild(scoreTxt);
}
// Show unlock requirement for locked levels
if (!isUnlocked && levelNum > 1) {
var prevTargetScore = levelNum - 1 === 1 ? 25 : levelNum - 1 === 30 ? 100 : 10 + (levelNum - 1) * 5;
var reqTxt = new Text2('Need ' + prevTargetScore, {
size: 25,
fill: '#ff8888'
});
reqTxt.anchor.set(0.5, 0.5);
reqTxt.y = 50;
levelBtn.addChild(reqTxt);
}
levelBtn.levelNum = levelNum;
levelBtn.isUnlocked = isUnlocked;
levelBtn.down = function () {
if (this.isUnlocked) {
currentLevel = this.levelNum;
gameState = 'playing';
updateGameState();
}
};
}
game.addChild(levelSelectContainer);
}
// Create settings
function createSettings() {
if (settingsContainer) settingsContainer.destroy();
settingsContainer = new Container();
// Title
var title = new Text2('Settings', {
size: 120,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 200;
settingsContainer.addChild(title);
// Back button
var backBtn = settingsContainer.addChild(new Container());
var backBg = backBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6,
tint: 0xff6666
});
backBtn.x = 200;
backBtn.y = 200;
var backTxt = new Text2('BACK', {
size: 60,
fill: '#ffffff'
});
backTxt.anchor.set(0.5, 0.5);
backBtn.addChild(backTxt);
backBtn.down = function () {
gameState = 'mainMenu';
updateGameState();
};
// Music volume control
var musicLabel = new Text2('Music Volume', {
size: 80,
fill: '#ffffff'
});
musicLabel.anchor.set(0.5, 0.5);
musicLabel.x = 1024;
musicLabel.y = 600;
settingsContainer.addChild(musicLabel);
// Music toggle button
var musicBtn = settingsContainer.addChild(new Container());
var musicBg = musicBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.8,
tint: musicEnabled ? 0x66ff66 : 0xff6666
});
musicBtn.x = 1024;
musicBtn.y = 750;
var musicTxt = new Text2(musicEnabled ? 'MUSIC: ON' : 'MUSIC: OFF', {
size: 70,
fill: '#ffffff'
});
musicTxt.anchor.set(0.5, 0.5);
musicBtn.addChild(musicTxt);
musicBtn.musicTxt = musicTxt;
musicBtn.musicBg = musicBg;
musicBtn.down = function () {
musicEnabled = !musicEnabled;
this.musicTxt.setText(musicEnabled ? 'MUSIC: ON' : 'MUSIC: OFF');
this.musicBg.tint = musicEnabled ? 0x66ff66 : 0xff6666;
if (!musicEnabled) {
LK.stopMusic();
} else {
// Play main_menu track when music is enabled
LK.playMusic('main_menu', {
loop: true
});
}
};
// Sound effects volume control
var soundLabel = new Text2('Sound Effects', {
size: 80,
fill: '#ffffff'
});
soundLabel.anchor.set(0.5, 0.5);
soundLabel.x = 1024;
soundLabel.y = 1000;
settingsContainer.addChild(soundLabel);
// Sound toggle button
var soundBtn = settingsContainer.addChild(new Container());
var soundBg = soundBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 0.8,
tint: soundEnabled ? 0x66ff66 : 0xff6666
});
soundBtn.x = 1024;
soundBtn.y = 1150;
var soundTxt = new Text2(soundEnabled ? 'SOUND: ON' : 'SOUND: OFF', {
size: 70,
fill: '#ffffff'
});
soundTxt.anchor.set(0.5, 0.5);
soundBtn.addChild(soundTxt);
soundBtn.soundTxt = soundTxt;
soundBtn.soundBg = soundBg;
soundBtn.down = function () {
soundEnabled = !soundEnabled;
this.soundTxt.setText(soundEnabled ? 'SOUND: ON' : 'SOUND: OFF');
this.soundBg.tint = soundEnabled ? 0x66ff66 : 0xff6666;
};
// Info text
var infoTxt = new Text2('Audio controls are managed by the game platform', {
size: 40,
fill: '#888888'
});
infoTxt.anchor.set(0.5, 0.5);
infoTxt.x = 1024;
infoTxt.y = 1400;
settingsContainer.addChild(infoTxt);
game.addChild(settingsContainer);
}
// Create shop
function createShop() {
if (shopContainer) shopContainer.destroy();
shopContainer = new Container();
// Title
var title = new Text2('Shop', {
size: 120,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 200;
shopContainer.addChild(title);
// Back button
var backBtn = shopContainer.addChild(new Container());
var backBg = backBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 0.6,
tint: 0xff6666
});
backBtn.x = 200;
backBtn.y = 200;
var backTxt = new Text2('BACK', {
size: 60,
fill: '#ffffff'
});
backTxt.anchor.set(0.5, 0.5);
backBtn.addChild(backTxt);
backBtn.down = function () {
gameState = 'mainMenu';
updateGameState();
};
// Character skins
var skins = [{
id: 'candyRed',
price: 0,
name: 'Red'
}, {
id: 'candyBlue',
price: 100,
name: 'Blue'
}, {
id: 'candyGreen',
price: 200,
name: 'Green'
}, {
id: 'candyPurple',
price: 300,
name: 'Purple'
}, {
id: 'candyYellow',
price: 500,
name: 'Yellow'
}];
var skinsTxt = new Text2('Character Skins', {
size: 80,
fill: '#ffffff'
});
skinsTxt.anchor.set(0.5, 0.5);
skinsTxt.x = 1024;
skinsTxt.y = 500;
shopContainer.addChild(skinsTxt);
// Skin items
var startX = 400;
var startY = 700;
var spacing = 300;
for (var i = 0; i < skins.length; i++) {
var skin = skins[i];
var owned = storage.unlockedSkins.indexOf(skin.id) !== -1;
var skinItem = shopContainer.addChild(new Container());
skinItem.x = startX + i * spacing;
skinItem.y = startY;
var itemBg = skinItem.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
tint: owned ? storage.selectedSkin === skin.id ? 0x66ff66 : 0xcccccc : 0x888888
});
var icon = skinItem.attachAsset(skin.id, {
anchorX: 0.5,
anchorY: 0.5,
y: -30
});
var priceTxt = new Text2(owned ? storage.selectedSkin === skin.id ? 'SELECTED' : 'OWNED' : skin.price + ' coins', {
size: 40,
fill: '#ffffff'
});
priceTxt.anchor.set(0.5, 0.5);
priceTxt.y = 60;
skinItem.addChild(priceTxt);
skinItem.skinData = skin;
skinItem.owned = owned;
skinItem.down = function () {
if (this.owned) {
storage.selectedSkin = this.skinData.id;
createShop();
} else if (storage.coins >= this.skinData.price) {
storage.coins -= this.skinData.price;
storage.unlockedSkins.push(this.skinData.id);
storage.selectedSkin = this.skinData.id;
coinsTxt.setText('Coins: ' + storage.coins);
createShop();
}
};
}
// Perks section
var perksTxt = new Text2('Perks', {
size: 80,
fill: '#ffffff'
});
perksTxt.anchor.set(0.5, 0.5);
perksTxt.x = 1024;
perksTxt.y = 1100;
shopContainer.addChild(perksTxt);
// Perk items
var perkStartY = 1300;
var perkSpacing = 180;
for (var p = 0; p < perks.length; p++) {
var perk = perks[p];
var owned = storage.perks[perk.id];
var perkItem = shopContainer.addChild(new Container());
perkItem.x = 1024;
perkItem.y = perkStartY + p * perkSpacing;
var perkBg = perkItem.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 0.7,
tint: owned ? 0x66ff66 : 0x555555
});
var perkName = new Text2(perk.name, {
size: 60,
fill: '#ffffff'
});
perkName.anchor.set(0, 0.5);
perkName.x = -350;
perkItem.addChild(perkName);
var perkDesc = new Text2(perk.description, {
size: 40,
fill: '#cccccc'
});
perkDesc.anchor.set(0, 0.5);
perkDesc.x = -350;
perkDesc.y = 40;
perkItem.addChild(perkDesc);
var perkPrice = new Text2(owned ? 'ACTIVE' : perk.price + ' coins', {
size: 50,
fill: owned ? '#66ff66' : '#ffd700'
});
perkPrice.anchor.set(1, 0.5);
perkPrice.x = 350;
perkItem.addChild(perkPrice);
perkItem.perkData = perk;
perkItem.owned = owned;
perkItem.down = function () {
if (!this.owned && storage.coins >= this.perkData.price) {
storage.coins -= this.perkData.price;
storage.perks[this.perkData.id] = true;
coinsTxt.setText('Coins: ' + storage.coins);
createShop();
}
};
}
// Reset Progress button
var resetBtn = shopContainer.addChild(new Container());
var resetBg = resetBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.5,
scaleY: 0.8,
tint: 0xff4444
});
resetBtn.x = 1024;
resetBtn.y = 2400;
var resetTxt = new Text2('RESET PROGRESS', {
size: 70,
fill: '#ffffff'
});
resetTxt.anchor.set(0.5, 0.5);
resetBtn.addChild(resetTxt);
var confirmReset = false;
resetBtn.down = function () {
if (!confirmReset) {
confirmReset = true;
resetTxt.setText('CONFIRM RESET?');
resetBg.tint = 0xff0000;
// Reset confirmation after 3 seconds
LK.setTimeout(function () {
if (confirmReset) {
confirmReset = false;
resetTxt.setText('RESET PROGRESS');
resetBg.tint = 0xff4444;
}
}, 3000);
} else {
// Reset all progress
storage.coins = 0;
storage.unlockedSkins = ["candyRed"];
storage.selectedSkin = "candyRed";
storage.perks = {
extraLife: false,
slowMotion: false,
magnetCollector: false,
doubleCoins: false,
bonusPoints: false
};
storage.unlockedLevels = [1];
storage.levelScores = {};
// Update UI
coinsTxt.setText('Coins: 0');
confirmReset = false;
resetTxt.setText('PROGRESS RESET!');
resetBg.tint = 0x44ff44;
// Refresh shop after a moment
LK.setTimeout(function () {
createShop();
}, 1000);
}
};
game.addChild(shopContainer);
}
// Start gameplay
function startGameplay() {
if (gameplayContainer) gameplayContainer.destroy();
gameplayContainer = new Container();
game.addChild(gameplayContainer);
// Reset game variables
score = 0;
candies = [];
candySpawnTimer = 0;
lives = 3 + perks[0].effect(); // Apply extra life perk
scoreTxt.setText('0');
scoreTxt.visible = true;
// Level configuration
levelConfig = {
spawnRate: Math.max(30 - currentLevel, 10),
candySpeed: 8 + currentLevel * 0.5,
targetScore: currentLevel === 1 ? 25 : currentLevel === 30 ? 100 : 10 + currentLevel * 5
};
// Set level-specific background colors
var bgColor;
if (currentLevel <= 10) {
// Levels 1-10: Blue gradient
bgColor = 0x2255aa + currentLevel * 0x000505;
} else if (currentLevel <= 20) {
// Levels 11-20: Purple gradient
bgColor = 0x6633aa + (currentLevel - 10) * 0x050005;
} else {
// Levels 21-30: Red gradient
bgColor = 0xaa3355 + (currentLevel - 20) * 0x050000;
}
game.setBackgroundColor(bgColor);
// Add background decorative elements
var bgElements = new Container();
gameplayContainer.addChild(bgElements);
// Add subtle background circles for depth
for (var b = 0; b < 8; b++) {
var bgCircle = bgElements.attachAsset('candyBlue', {
anchorX: 0.5,
anchorY: 0.5,
x: 200 + Math.random() * 1648,
y: 400 + Math.random() * 2000,
scaleX: 2 + Math.random() * 3,
scaleY: 2 + Math.random() * 3,
alpha: 0.05 + Math.random() * 0.05,
tint: 0xffffff
});
}
// Create collector
collector = new Collector();
collector.x = 1024;
collector.y = 2400;
gameplayContainer.addChild(collector);
// Level info
var levelTxt = new Text2('Level ' + currentLevel + ' - Collect ' + levelConfig.targetScore, {
size: 60,
fill: '#ffffff'
});
levelTxt.anchor.set(0.5, 0.5);
levelTxt.x = 1024;
levelTxt.y = 300;
gameplayContainer.addChild(levelTxt);
// Create hearts display
heartsContainer = new Container();
heartsContainer.x = 1024;
heartsContainer.y = 150;
gameplayContainer.addChild(heartsContainer);
// Add hearts based on lives
for (var h = 0; h < lives; h++) {
var heart = heartsContainer.attachAsset('candyRed', {
anchorX: 0.5,
anchorY: 0.5,
x: (h - lives / 2 + 0.5) * 140,
scaleX: 0.8,
scaleY: 0.8,
tint: 0xff6666
});
}
// Back button
var backBtn = gameplayContainer.addChild(new Container());
var backBg = backBtn.attachAsset('shopItem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 0.5,
tint: 0xff6666
});
backBtn.x = 200;
backBtn.y = 200;
var backTxt = new Text2('EXIT', {
size: 50,
fill: '#ffffff'
});
backTxt.anchor.set(0.5, 0.5);
backBtn.addChild(backTxt);
backBtn.down = function () {
gameState = 'levelSelect';
updateGameState();
};
}
// Update game state
function updateGameState() {
// Hide all containers
if (mainMenuContainer) mainMenuContainer.visible = false;
if (levelSelectContainer) levelSelectContainer.visible = false;
if (shopContainer) shopContainer.visible = false;
if (gameplayContainer) gameplayContainer.visible = false;
if (settingsContainer) settingsContainer.visible = false;
scoreTxt.visible = false;
// Show current state
switch (gameState) {
case 'mainMenu':
game.setBackgroundColor(0x222244); // Reset to original background
createMainMenu();
if (musicEnabled) {
LK.playMusic('main_menu', {
loop: true
});
}
break;
case 'levelSelect':
game.setBackgroundColor(0x222244); // Reset to original background
createLevelSelect();
break;
case 'shop':
game.setBackgroundColor(0x222244); // Reset to original background
createShop();
break;
case 'playing':
startGameplay();
if (musicEnabled) {
LK.playMusic('happy_and_lo-fi', {
loop: true
});
}
break;
case 'settings':
game.setBackgroundColor(0x222244); // Reset to original background
createSettings();
break;
}
}
// Game update
game.update = function () {
if (gameState !== 'playing') return;
// Spawn candies
candySpawnTimer--;
if (candySpawnTimer <= 0) {
var candy = new Candy();
candy.x = 200 + Math.random() * 1648;
candy.y = -100;
candy.speed = levelConfig.candySpeed * perks[1].effect(); // Apply slow motion perk
candies.push(candy);
gameplayContainer.addChild(candy);
candySpawnTimer = levelConfig.spawnRate;
}
// Update candies
for (var i = candies.length - 1; i >= 0; i--) {
var candy = candies[i];
candy.update();
// Check collection
if (!candy.collected && candy.intersects(collector)) {
candy.collected = true;
score += 1 + perks[4].effect(); // Apply bonus points perk
scoreTxt.setText(score.toString());
if (soundEnabled) {
LK.getSound('collect').play();
}
// Coin drop
if (candy.hasCoin) {
var coinAmount = 10 * perks[3].effect(); // Apply double coins perk
storage.coins += coinAmount;
coinsTxt.setText('Coins: ' + storage.coins);
// Coin animation
var coin = new CoinFly();
coin.x = candy.x;
coin.y = candy.y;
gameplayContainer.addChild(coin);
tween(coin, {
x: 2048 - 100,
y: 50,
alpha: 0
}, {
duration: 800,
onComplete: function onComplete() {
coin.destroy();
}
});
}
// Remove candy
candy.destroy();
candies.splice(i, 1);
// Check win
if (score >= levelConfig.targetScore) {
// Save high score for current level
if (!storage.levelScores[currentLevel] || score > storage.levelScores[currentLevel]) {
storage.levelScores[currentLevel] = score;
}
// Unlock next level if not already unlocked
var nextLevel = currentLevel + 1;
if (nextLevel <= 30 && storage.unlockedLevels.indexOf(nextLevel) === -1) {
storage.unlockedLevels.push(nextLevel);
}
gameState = 'levelSelect';
updateGameState();
// Don't show regular "you win!" tab
// LK.showYouWin();
}
}
// Remove off-screen
if (candy.y > 2832) {
if (!candy.missed) {
candy.missed = true;
lives--;
// Update hearts display
if (heartsContainer && heartsContainer.children.length > lives) {
var heartToRemove = heartsContainer.children[lives];
tween(heartToRemove, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300,
onComplete: function onComplete() {
heartToRemove.visible = false;
}
});
}
// Check game over
if (lives <= 0) {
gameState = 'mainMenu';
updateGameState();
LK.showGameOver();
}
}
candy.destroy();
candies.splice(i, 1);
}
}
};
// Touch controls for collector
game.down = function (x, y, obj) {
if (gameState === 'playing' && collector) {
collector.x = x;
}
};
game.move = function (x, y, obj) {
if (gameState === 'playing' && collector) {
collector.x = x;
}
};
// Initialize game
updateGameState(); ===================================================================
--- original.js
+++ change.js
@@ -475,14 +475,12 @@
this.musicBg.tint = musicEnabled ? 0x66ff66 : 0xff6666;
if (!musicEnabled) {
LK.stopMusic();
} else {
- // Resume music based on current state
- if (gameState === 'mainMenu') {
- LK.playMusic('main_menu', {
- loop: true
- });
- }
+ // Play main_menu track when music is enabled
+ LK.playMusic('main_menu', {
+ loop: true
+ });
}
};
// Sound effects volume control
var soundLabel = new Text2('Sound Effects', {
red shiny candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
chocolate cupcake, blue detail, cherry. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
wood stick, green&white stripe apple candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
golden coin . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
chocolate ice-cream, cherry. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
chocolate bar, yellow packet. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
sparkle, rainbow. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat