User prompt
remake shop taab
User prompt
reforged the shop tab
User prompt
items description are not touch the gray square
User prompt
I can't read items
User prompt
Make the items visible.
User prompt
change -y shop item desc.
User prompt
delete items names
User prompt
put the "health booster", "slow motion" and "automatic clicker" under
User prompt
fix the items tab
User prompt
add a visual items
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'length')' in or related to this line: 'for (var i = 0; i < shopItemItems.length; i++) {' Line Number: 295
User prompt
add this items "health booster", "slow motion" and "automatic clicker"
User prompt
add shop character and item tabs
User prompt
add a return button for shop and leaderboard
User prompt
pause the game in main menu
User prompt
reforge the game with main menu
User prompt
add a health "3 healt"
User prompt
add a loop
User prompt
pause the game tabs
Code edit (1 edits merged)
Please save this source code
User prompt
Candy Collector Deluxe
Initial prompt
candy, collect all, menu tab, shop tab, high resulation
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
coins: 0,
unlockedSkins: ["candyRed"],
selectedSkin: "candyRed"
});
/****
* 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;
self.width = collectorAsset.width;
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
****/
// Tabs: 0=Game, 1=Shop, 2=Leaderboard
// Candies (different colors/shapes for future shop unlocks)
// Coin
// Collector (player's swipe area)
// Shop item placeholder
// Sounds
// Music
var currentTab = 0;
// GUI tab buttons
var tabBtnGame, tabBtnShop, tabBtnLeaderboard;
// GUI overlays
var coinTxt,
scoreTxt,
shopCoinTxt,
shopTitleTxt,
shopItems = [],
shopGroup,
leaderboardGroup;
// Game state
var candies = [];
var collector;
var isDragging = false;
var dragOffsetX = 0,
dragOffsetY = 0;
var score = 0;
var coins = storage.coins || 0;
var level = 1;
var candiesToCollect = 10;
var candiesCollected = 0;
var gameActive = true;
var candySpawnTimer = 0;
var candySpawnInterval = 36; // frames
// --- Health ---
var health = 3;
var healthTxt = new Text2('❤❤❤', {
size: 90,
fill: '#ff3b3b'
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 0;
LK.gui.top.addChild(healthTxt);
// Shop data
var shopSkins = [{
id: 'candyRed',
price: 0
}, {
id: 'candyGreen',
price: 20
}, {
id: 'candyBlue',
price: 40
}, {
id: 'candyYellow',
price: 60
}, {
id: 'candyPurple',
price: 100
}];
// --- GUI Setup ---
// Coin display (top right)
coinTxt = new Text2(coins + '', {
size: 90,
fill: '#ffe23b'
});
coinTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(coinTxt);
// Score display (top center)
scoreTxt = new Text2('0', {
size: 110,
fill: '#fff'
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Tab buttons (bottom)
tabBtnGame = new Text2('Game', {
size: 80,
fill: '#fff'
});
tabBtnGame.anchor.set(0.5, 1);
tabBtnGame.x = 2048 / 6;
tabBtnGame.y = 0;
tabBtnGame.interactive = true;
tabBtnGame.buttonMode = true;
LK.gui.bottom.addChild(tabBtnGame);
tabBtnShop = new Text2('Shop', {
size: 80,
fill: '#fff'
});
tabBtnShop.anchor.set(0.5, 1);
tabBtnShop.x = 2048 / 2;
tabBtnShop.y = 0;
tabBtnShop.interactive = true;
tabBtnShop.buttonMode = true;
LK.gui.bottom.addChild(tabBtnShop);
tabBtnLeaderboard = new Text2('Leaderboard', {
size: 80,
fill: '#fff'
});
tabBtnLeaderboard.anchor.set(0.5, 1);
tabBtnLeaderboard.x = 2048 * 5 / 6;
tabBtnLeaderboard.y = 0;
tabBtnLeaderboard.interactive = true;
tabBtnLeaderboard.buttonMode = true;
LK.gui.bottom.addChild(tabBtnLeaderboard);
// Shop overlay group
shopGroup = new Container();
shopGroup.visible = false;
game.addChild(shopGroup);
// Shop title
shopTitleTxt = new Text2('Shop', {
size: 120,
fill: '#fff'
});
shopTitleTxt.anchor.set(0.5, 0);
shopTitleTxt.x = 2048 / 2;
shopTitleTxt.y = 120;
shopGroup.addChild(shopTitleTxt);
// Shop coin display (top right in shop)
shopCoinTxt = new Text2('Coins: ' + coins, {
size: 90,
fill: '#ffe23b'
});
shopCoinTxt.anchor.set(1, 0);
shopCoinTxt.x = 2048 - 80;
shopCoinTxt.y = 120;
shopGroup.addChild(shopCoinTxt);
// Shop return button (top left in shop)
var shopReturnBtn = new Text2('Return', {
size: 80,
fill: '#ffe23b'
});
shopReturnBtn.anchor.set(0, 0);
shopReturnBtn.x = 80;
shopReturnBtn.y = 120;
shopReturnBtn.interactive = true;
shopReturnBtn.buttonMode = true;
shopReturnBtn.down = function (x, y, obj) {
shopGroup.visible = false;
mainMenuGroup.visible = true;
shopCurrentTab = 0;
updateShopTab();
setTab(0);
};
shopGroup.addChild(shopReturnBtn);
// Shop tab buttons (centered below title)
var shopTabCharacter = new Text2('Characters', {
size: 80,
fill: '#fff'
});
shopTabCharacter.anchor.set(0.5, 0);
shopTabCharacter.x = 2048 / 2 - 180;
shopTabCharacter.y = 260;
shopTabCharacter.interactive = true;
shopTabCharacter.buttonMode = true;
var shopTabItem = new Text2('Items', {
size: 80,
fill: '#fff'
});
shopTabItem.anchor.set(0.5, 0);
shopTabItem.x = 2048 / 2 + 180;
shopTabItem.y = 260;
shopTabItem.interactive = true;
shopTabItem.buttonMode = true;
shopGroup.addChild(shopTabCharacter);
shopGroup.addChild(shopTabItem);
// Shop tab state: 0 = Characters, 1 = Items
var shopCurrentTab = 0;
// Shop tab switching logic
function updateShopTab() {
// Defensive: ensure shopItemItems is always an array
if (typeof shopItemItems === "undefined" || !shopItemItems) {
shopItemItems = [];
}
// Characters tab
if (shopCurrentTab === 0) {
for (var i = 0; i < shopItems.length; i++) {
shopItems[i].visible = true;
}
for (var i = 0; i < shopItemItems.length; i++) {
shopItemItems[i].visible = false;
}
shopTabCharacter.fill = '#ffe23b';
shopTabItem.fill = '#fff';
}
// Items tab
if (shopCurrentTab === 1) {
for (var i = 0; i < shopItems.length; i++) {
shopItems[i].visible = false;
}
for (var i = 0; i < shopItemItems.length; i++) {
shopItemItems[i].visible = true;
}
// Ensure item shop items are brought to front for visibility
for (var i = 0; i < shopItemItems.length; i++) {
if (shopGroup.children.indexOf(shopItemItems[i]) !== -1) {
shopGroup.removeChild(shopItemItems[i]);
shopGroup.addChild(shopItemItems[i]);
}
}
shopTabCharacter.fill = '#fff';
shopTabItem.fill = '#ffe23b';
}
}
shopTabCharacter.down = function (x, y, obj) {
shopCurrentTab = 0;
updateShopTab();
};
shopTabItem.down = function (x, y, obj) {
shopCurrentTab = 1;
updateShopTab();
};
// Initialize tab highlight
updateShopTab();
// Shop items
shopItems = [];
for (var i = 0; i < shopSkins.length; i++) {
var item = new ShopItem();
var skin = shopSkins[i];
var owned = storage.unlockedSkins.indexOf(skin.id) !== -1;
item.setSkin(skin.id, skin.price, owned);
item.x = 2048 / 2 + (i - 2) * 320;
item.y = 600;
// Price/owned label
var label = new Text2(owned ? 'Owned' : skin.price + ' coins', {
size: 60,
fill: owned ? '#3bff6e' : '#fff'
});
label.anchor.set(0.5, 0);
label.y = 120;
item.addChild(label);
item.label = label;
// Selection highlight
var selectTxt = new Text2('Selected', {
size: 50,
fill: '#ffe23b'
});
selectTxt.anchor.set(0.5, 0);
selectTxt.y = 170;
selectTxt.visible = storage.selectedSkin === skin.id;
item.addChild(selectTxt);
item.selectTxt = selectTxt;
// Touch handler
(function (item, skin, label, selectTxt) {
item.down = function (x, y, obj) {
if (item.owned) {
storage.selectedSkin = skin.id;
for (var j = 0; j < shopItems.length; j++) {
shopItems[j].selectTxt.visible = shopItems[j].skinId === skin.id;
}
} else if (coins >= skin.price) {
coins -= skin.price;
storage.coins = coins;
storage.unlockedSkins.push(skin.id);
item.owned = true;
item.label.setText('Owned');
item.label.fill = '#3bff6e';
item.selectTxt.visible = true;
storage.selectedSkin = skin.id;
for (var j = 0; j < shopItems.length; j++) {
if (shopItems[j] !== item) shopItems[j].selectTxt.visible = false;
}
shopCoinTxt.setText('Coins: ' + coins);
coinTxt.setText(coins);
LK.getSound('shopBuy').play();
}
};
})(item, skin, label, selectTxt);
shopGroup.addChild(item);
shopItems.push(item);
}
// --- Item Shop Items ---
var shopItemItems = [];
// Item shop data
var itemShopData = [{
id: 'healthBooster',
label: '',
desc: '+1 Heart (per game)',
price: 10
}, {
id: 'slowMotion',
label: '',
desc: '-Y: Slow candies (10s)',
price: 15
}, {
id: 'autoClicker',
label: '',
desc: 'Auto collect (10s)',
price: 25
}];
// Track item inventory (permanent for health, consumable for others)
if (!storage.itemInventory) storage.itemInventory = {
healthBooster: 0,
slowMotion: 0,
autoClicker: 0
};
for (var i = 0; i < itemShopData.length; i++) {
(function (i) {
var itemData = itemShopData[i];
var item = new ShopItem();
// Use 'shopItem' asset for all items
item.setSkin('shopItem', itemData.price, false);
item.x = 2048 / 2 + (i - 1) * 320;
item.y = 600;
// --- Visual Item Icon ---
var iconAssetId = null;
if (itemData.id === "healthBooster") iconAssetId = "candyRed";
if (itemData.id === "slowMotion") iconAssetId = "candyBlue";
if (itemData.id === "autoClicker") iconAssetId = "coin";
var iconVisual = null;
if (iconAssetId) {
iconVisual = LK.getAsset(iconAssetId, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: itemData.id === "autoClicker" ? 1.1 : 0.8,
scaleY: itemData.id === "autoClicker" ? 1.1 : 0.8,
y: -60
});
item.addChild(iconVisual);
}
// Icon/label
// Removed item name label (iconTxt)
// Description
var descTxt = new Text2(itemData.desc, {
size: 38,
fill: '#fff'
});
descTxt.anchor.set(0.5, 0);
descTxt.y = 60;
item.addChild(descTxt);
// Price/owned label
var ownedCount = storage.itemInventory[itemData.id] || 0;
var priceLabel = new Text2('x' + ownedCount + ' ' + itemData.price + ' coins', {
size: 48,
fill: '#fff'
});
priceLabel.anchor.set(0.5, 0);
priceLabel.y = 120;
item.addChild(priceLabel);
item.priceLabel = priceLabel;
// Touch handler
item.down = function (x, y, obj) {
if (coins >= itemData.price) {
coins -= itemData.price;
storage.coins = coins;
storage.itemInventory[itemData.id] = (storage.itemInventory[itemData.id] || 0) + 1;
item.priceLabel.setText('x' + storage.itemInventory[itemData.id] + ' ' + itemData.price + ' coins');
shopCoinTxt.setText('Coins: ' + coins);
coinTxt.setText(coins);
LK.getSound('shopBuy').play();
}
};
shopGroup.addChild(item);
item.visible = false;
shopItemItems.push(item);
})(i);
}
// Leaderboard overlay group (placeholder)
leaderboardGroup = new Container();
leaderboardGroup.visible = false;
game.addChild(leaderboardGroup);
var leaderboardTitle = new Text2('Leaderboard', {
size: 120,
fill: '#fff'
});
leaderboardTitle.anchor.set(0.5, 0);
leaderboardTitle.x = 2048 / 2;
leaderboardTitle.y = 180;
leaderboardGroup.addChild(leaderboardTitle);
// Leaderboard return button
var leaderboardReturnBtn = new Text2('Return', {
size: 80,
fill: '#ffe23b'
});
leaderboardReturnBtn.anchor.set(0, 0);
leaderboardReturnBtn.x = 80;
leaderboardReturnBtn.y = 180;
leaderboardReturnBtn.interactive = true;
leaderboardReturnBtn.buttonMode = true;
leaderboardReturnBtn.down = function (x, y, obj) {
leaderboardGroup.visible = false;
mainMenuGroup.visible = true;
setTab(0);
};
leaderboardGroup.addChild(leaderboardReturnBtn);
var leaderboardInfo = new Text2('Check your high score in the system leaderboard!', {
size: 70,
fill: '#fff'
});
leaderboardInfo.anchor.set(0.5, 0);
leaderboardInfo.x = 2048 / 2;
leaderboardInfo.y = 350;
leaderboardGroup.addChild(leaderboardInfo);
// --- Main Menu Overlay ---
var mainMenuGroup = new Container();
mainMenuGroup.visible = true;
game.addChild(mainMenuGroup);
var mainMenuTitle = new Text2('Candy Collector Deluxe', {
size: 160,
fill: '#ffe23b'
});
mainMenuTitle.anchor.set(0.5, 0);
mainMenuTitle.x = 2048 / 2;
mainMenuTitle.y = 400;
mainMenuGroup.addChild(mainMenuTitle);
var mainMenuPlayBtn = new Text2('Play', {
size: 120,
fill: '#fff'
});
mainMenuPlayBtn.anchor.set(0.5, 0.5);
mainMenuPlayBtn.x = 2048 / 2;
mainMenuPlayBtn.y = 900;
mainMenuPlayBtn.interactive = true;
mainMenuPlayBtn.buttonMode = true;
mainMenuGroup.addChild(mainMenuPlayBtn);
var mainMenuShopBtn = new Text2('Shop', {
size: 100,
fill: '#fff'
});
mainMenuShopBtn.anchor.set(0.5, 0.5);
mainMenuShopBtn.x = 2048 / 2;
mainMenuShopBtn.y = 1100;
mainMenuShopBtn.interactive = true;
mainMenuShopBtn.buttonMode = true;
mainMenuGroup.addChild(mainMenuShopBtn);
var mainMenuLeaderboardBtn = new Text2('Leaderboard', {
size: 100,
fill: '#fff'
});
mainMenuLeaderboardBtn.anchor.set(0.5, 0.5);
mainMenuLeaderboardBtn.x = 2048 / 2;
mainMenuLeaderboardBtn.y = 1250;
mainMenuLeaderboardBtn.interactive = true;
mainMenuLeaderboardBtn.buttonMode = true;
mainMenuGroup.addChild(mainMenuLeaderboardBtn);
mainMenuPlayBtn.down = function (x, y, obj) {
mainMenuGroup.visible = false;
setTab(0);
};
mainMenuShopBtn.down = function (x, y, obj) {
mainMenuGroup.visible = false;
setTab(1);
};
mainMenuLeaderboardBtn.down = function (x, y, obj) {
mainMenuGroup.visible = false;
setTab(2);
};
// --- Main Game Setup ---
function resetGame() {
// Remove candies
for (var i = candies.length - 1; i >= 0; i--) {
candies[i].destroy();
candies.splice(i, 1);
}
score = 0;
candiesCollected = 0;
candiesToCollect = 10 + (level - 1) * 2;
candySpawnTimer = 0;
scoreTxt.setText('0');
gameActive = true;
// Reset health, add +1 if health booster owned
health = 3 + (storage.itemInventory && storage.itemInventory.healthBooster ? storage.itemInventory.healthBooster : 0);
var hearts = '';
for (var h = 0; h < health; h++) hearts += '❤';
healthTxt.setText(hearts);
// Collector position
collector.x = 2048 / 2;
collector.y = 2732 - 220;
// Reset item effect timers
slowMotionActive = false;
slowMotionTimer = 0;
autoClickerActive = false;
autoClickerTimer = 0;
}
// Collector (player's swipe area)
collector = new Collector();
collector.x = 2048 / 2;
collector.y = 2732 - 220;
game.addChild(collector);
// --- Tab Switching ---
function setTab(tabIdx) {
currentTab = tabIdx;
// Game tab
if (tabIdx === 0) {
game.visible = true;
shopGroup.visible = false;
leaderboardGroup.visible = false;
coinTxt.visible = true;
scoreTxt.visible = true;
collector.visible = true;
}
// Shop tab
if (tabIdx === 1) {
game.visible = true;
shopGroup.visible = true;
leaderboardGroup.visible = false;
coinTxt.visible = false;
scoreTxt.visible = false;
collector.visible = false;
shopCoinTxt.setText('Coins: ' + coins);
for (var i = 0; i < shopItems.length; i++) {
var owned = storage.unlockedSkins.indexOf(shopItems[i].skinId) !== -1;
shopItems[i].owned = owned;
shopItems[i].label.setText(owned ? 'Owned' : shopSkins[i].price + ' coins');
shopItems[i].label.fill = owned ? '#3bff6e' : '#fff';
shopItems[i].selectTxt.visible = storage.selectedSkin === shopItems[i].skinId;
// Show/hide based on tab
shopItems[i].visible = shopCurrentTab === 0;
}
updateShopTab();
}
// Leaderboard tab
if (tabIdx === 2) {
game.visible = true;
shopGroup.visible = false;
leaderboardGroup.visible = true;
coinTxt.visible = false;
scoreTxt.visible = false;
collector.visible = false;
}
}
// Tab button handlers
tabBtnGame.down = function (x, y, obj) {
setTab(0);
};
tabBtnShop.down = function (x, y, obj) {
setTab(1);
};
tabBtnLeaderboard.down = function (x, y, obj) {
setTab(2);
};
// --- Item Usage Buttons ---
var itemBtnSlow = new Text2('Slow', {
size: 70,
fill: '#3b9bff'
});
itemBtnSlow.anchor.set(0.5, 0);
itemBtnSlow.x = 2048 / 2 - 200;
itemBtnSlow.y = 120;
itemBtnSlow.interactive = true;
itemBtnSlow.buttonMode = true;
LK.gui.top.addChild(itemBtnSlow);
var itemBtnAuto = new Text2('Auto', {
size: 70,
fill: '#3b9bff'
});
itemBtnAuto.anchor.set(0.5, 0);
itemBtnAuto.x = 2048 / 2 + 200;
itemBtnAuto.y = 120;
itemBtnAuto.interactive = true;
itemBtnAuto.buttonMode = true;
LK.gui.top.addChild(itemBtnAuto);
// Effect state
var slowMotionActive = false;
var slowMotionTimer = 0;
var autoClickerActive = false;
var autoClickerTimer = 0;
// Button handlers
itemBtnSlow.down = function (x, y, obj) {
if (!gameActive || mainMenuGroup.visible || currentTab !== 0) return;
if (storage.itemInventory && storage.itemInventory.slowMotion > 0 && !slowMotionActive) {
storage.itemInventory.slowMotion--;
slowMotionActive = true;
slowMotionTimer = 600; // 10 seconds at 60fps
itemBtnSlow.setText('Slow (' + storage.itemInventory.slowMotion + ')');
itemBtnSlow.fill = '#ffe23b';
}
};
itemBtnAuto.down = function (x, y, obj) {
if (!gameActive || mainMenuGroup.visible || currentTab !== 0) return;
if (storage.itemInventory && storage.itemInventory.autoClicker > 0 && !autoClickerActive) {
storage.itemInventory.autoClicker--;
autoClickerActive = true;
autoClickerTimer = 600; // 10 seconds at 60fps
itemBtnAuto.setText('Auto (' + storage.itemInventory.autoClicker + ')');
itemBtnAuto.fill = '#ffe23b';
}
};
// Update button text on game start
itemBtnSlow.setText('Slow (' + (storage.itemInventory && storage.itemInventory.slowMotion || 0) + ')');
itemBtnAuto.setText('Auto (' + (storage.itemInventory && storage.itemInventory.autoClicker || 0) + ')');
itemBtnSlow.fill = '#3b9bff';
itemBtnAuto.fill = '#3b9bff';
// --- Touch Controls ---
// Drag collector
game.down = function (x, y, obj) {
if (mainMenuGroup.visible || currentTab !== 0 || !gameActive) return;
// Only drag if touch is on collector
var local = collector.toLocal({
x: x,
y: y
});
if (local.x > -collector.width / 2 && local.x < collector.width / 2 && local.y > -collector.height / 2 && local.y < collector.height / 2) {
isDragging = true;
dragOffsetX = collector.x - x;
dragOffsetY = collector.y - y;
}
};
game.up = function (x, y, obj) {
if (mainMenuGroup.visible || currentTab !== 0 || !gameActive) return;
isDragging = false;
};
game.move = function (x, y, obj) {
if (mainMenuGroup.visible || currentTab !== 0 || !gameActive) return;
if (isDragging) {
collector.x = Math.max(collector.width / 2, Math.min(2048 - collector.width / 2, x + dragOffsetX));
collector.y = Math.max(collector.height / 2 + 200, Math.min(2732 - collector.height / 2, y + dragOffsetY));
}
// Swipe detection: check for candies under finger
for (var i = candies.length - 1; i >= 0; i--) {
var candy = candies[i];
if (!candy.collected && candy.visible) {
var dx = candy.x - x;
var dy = candy.y - y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < candy.width / 2 + 40) {
collectCandy(candy);
}
}
}
};
// --- Candy Collection ---
function collectCandy(candy) {
if (candy.collected) return;
candy.collected = true;
candiesCollected++;
score++;
scoreTxt.setText(score);
// Animate
tween(candy, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 220,
easing: tween.cubicIn,
onFinish: function onFinish() {
candy.destroy();
}
});
LK.getSound('collect').play();
// Coin drop
if (candy.hasCoin) {
coins++;
storage.coins = coins;
coinTxt.setText(coins);
shopCoinTxt.setText('Coins: ' + coins);
// Coin fly animation
var coinFly = new CoinFly();
coinFly.x = candy.x;
coinFly.y = candy.y;
game.addChild(coinFly);
tween(coinFly, {
x: 2048 - 120,
y: 120,
scaleX: 0.5,
scaleY: 0.5,
alpha: 0
}, {
duration: 600,
easing: tween.cubicIn,
onFinish: function onFinish() {
coinFly.destroy();
}
});
LK.getSound('coin').play();
}
// Remove from candies array
for (var i = 0; i < candies.length; i++) {
if (candies[i] === candy) {
candies.splice(i, 1);
break;
}
}
// Win condition
if (candiesCollected >= candiesToCollect) {
// Save high score
if (!storage.highScore || score > storage.highScore) {
storage.highScore = score;
}
// Loop: advance to next level and reset game state
level++;
resetGame();
setTab(0);
return;
}
}
// --- Game Update Loop ---
game.update = function () {
if (mainMenuGroup.visible || currentTab !== 0 || !gameActive) return;
// --- Item Effects ---
if (slowMotionActive) {
slowMotionTimer--;
if (slowMotionTimer <= 0) {
slowMotionActive = false;
itemBtnSlow.fill = '#3b9bff';
itemBtnSlow.setText('Slow (' + (storage.itemInventory && storage.itemInventory.slowMotion || 0) + ')');
}
}
if (autoClickerActive) {
autoClickerTimer--;
if (autoClickerTimer <= 0) {
autoClickerActive = false;
itemBtnAuto.fill = '#3b9bff';
itemBtnAuto.setText('Auto (' + (storage.itemInventory && storage.itemInventory.autoClicker || 0) + ')');
}
}
// Spawn candies
candySpawnTimer++;
var spawnInterval = slowMotionActive ? Math.round(candySpawnInterval * 1.5) : candySpawnInterval;
if (candies.length < candiesToCollect && candySpawnTimer >= spawnInterval) {
candySpawnTimer = 0;
var candy = new Candy();
// Use selected skin
candy.skin = storage.selectedSkin || 'candyRed';
// Random X, avoid edges
candy.x = 120 + Math.random() * (2048 - 240);
candy.y = -80;
// Randomize speed a bit
candy.speed = (slowMotionActive ? 0.5 : 1) * (10 + Math.random() * 6 + level * 0.5);
candies.push(candy);
game.addChild(candy);
}
// Update candies
for (var i = candies.length - 1; i >= 0; i--) {
var candy = candies[i];
if (slowMotionActive) {
// Slow down falling speed
candy.y += (candy.speed || 12) * 0.5;
} else {
candy.update();
}
// Collector collision
if (!candy.collected && collector.visible) {
var dx = candy.x - collector.x;
var dy = candy.y - collector.y;
if (Math.abs(dx) < candy.width / 2 + collector.width / 2 - 30 && Math.abs(dy) < candy.height / 2 + collector.height / 2 - 30) {
collectCandy(candy);
}
}
// Off-screen (missed)
if (!candy.collected && candy.y > 2732 + 80 && !candy.missed) {
candy.missed = true;
// Animate out
tween(candy, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
candy.destroy();
}
});
// Remove from candies array
candies.splice(i, 1);
// Decrease health and update display
health--;
var hearts = '';
for (var h = 0; h < health; h++) hearts += '❤';
healthTxt.setText(hearts);
LK.effects.flashScreen(0xff0000, 600);
if (health <= 0) {
LK.showGameOver();
gameActive = false;
}
}
}
// --- Auto Clicker effect: auto collect nearest candy ---
if (autoClickerActive && candies.length > 0) {
// Find lowest (closest to bottom) visible, uncollected candy
var best = null,
bestY = -Infinity;
for (var i = 0; i < candies.length; i++) {
if (!candies[i].collected && candies[i].visible && candies[i].y > bestY) {
best = candies[i];
bestY = candies[i].y;
}
}
if (best) {
collectCandy(best);
}
}
};
// --- Music ---
LK.playMusic('bgmusic');
// --- Game Over/Win Handlers ---
LK.on('gameover', function () {
// Reset game state
resetGame();
mainMenuGroup.visible = true;
setTab(0);
});
LK.on('youwin', function () {
// Next level
level++;
resetGame();
mainMenuGroup.visible = true;
setTab(0);
});
// --- Initial State ---
resetGame();
mainMenuGroup.visible = true;
setTab(0); ===================================================================
--- original.js
+++ change.js
@@ -123,15 +123,15 @@
/****
* Game Code
****/
-// Music
-// Sounds
-// Shop item placeholder
-// Collector (player's swipe area)
-// Coin
-// Candies (different colors/shapes for future shop unlocks)
// Tabs: 0=Game, 1=Shop, 2=Leaderboard
+// Candies (different colors/shapes for future shop unlocks)
+// Coin
+// Collector (player's swipe area)
+// Shop item placeholder
+// Sounds
+// Music
var currentTab = 0;
// GUI tab buttons
var tabBtnGame, tabBtnShop, tabBtnLeaderboard;
// GUI overlays
@@ -232,40 +232,67 @@
// Shop overlay group
shopGroup = new Container();
shopGroup.visible = false;
game.addChild(shopGroup);
-// Shop tab buttons
+// Shop title
+shopTitleTxt = new Text2('Shop', {
+ size: 120,
+ fill: '#fff'
+});
+shopTitleTxt.anchor.set(0.5, 0);
+shopTitleTxt.x = 2048 / 2;
+shopTitleTxt.y = 120;
+shopGroup.addChild(shopTitleTxt);
+// Shop coin display (top right in shop)
+shopCoinTxt = new Text2('Coins: ' + coins, {
+ size: 90,
+ fill: '#ffe23b'
+});
+shopCoinTxt.anchor.set(1, 0);
+shopCoinTxt.x = 2048 - 80;
+shopCoinTxt.y = 120;
+shopGroup.addChild(shopCoinTxt);
+// Shop return button (top left in shop)
+var shopReturnBtn = new Text2('Return', {
+ size: 80,
+ fill: '#ffe23b'
+});
+shopReturnBtn.anchor.set(0, 0);
+shopReturnBtn.x = 80;
+shopReturnBtn.y = 120;
+shopReturnBtn.interactive = true;
+shopReturnBtn.buttonMode = true;
+shopReturnBtn.down = function (x, y, obj) {
+ shopGroup.visible = false;
+ mainMenuGroup.visible = true;
+ shopCurrentTab = 0;
+ updateShopTab();
+ setTab(0);
+};
+shopGroup.addChild(shopReturnBtn);
+// Shop tab buttons (centered below title)
var shopTabCharacter = new Text2('Characters', {
size: 80,
fill: '#fff'
});
shopTabCharacter.anchor.set(0.5, 0);
-shopTabCharacter.x = 2048 / 2 - 200;
-shopTabCharacter.y = 320;
+shopTabCharacter.x = 2048 / 2 - 180;
+shopTabCharacter.y = 260;
shopTabCharacter.interactive = true;
shopTabCharacter.buttonMode = true;
var shopTabItem = new Text2('Items', {
size: 80,
fill: '#fff'
});
shopTabItem.anchor.set(0.5, 0);
-shopTabItem.x = 2048 / 2 + 200;
-shopTabItem.y = 320;
+shopTabItem.x = 2048 / 2 + 180;
+shopTabItem.y = 260;
shopTabItem.interactive = true;
shopTabItem.buttonMode = true;
-// Shop tab state: 0 = Characters, 1 = Items
-var shopCurrentTab = 0;
-// Shop title
-shopTitleTxt = new Text2('Shop', {
- size: 120,
- fill: '#fff'
-});
-shopTitleTxt.anchor.set(0.5, 0);
-shopTitleTxt.x = 2048 / 2;
-shopTitleTxt.y = 180;
-shopGroup.addChild(shopTitleTxt);
shopGroup.addChild(shopTabCharacter);
shopGroup.addChild(shopTabItem);
+// Shop tab state: 0 = Characters, 1 = Items
+var shopCurrentTab = 0;
// Shop tab switching logic
function updateShopTab() {
// Defensive: ensure shopItemItems is always an array
if (typeof shopItemItems === "undefined" || !shopItemItems) {
@@ -310,35 +337,8 @@
updateShopTab();
};
// Initialize tab highlight
updateShopTab();
-// Shop return button
-var shopReturnBtn = new Text2('Return', {
- size: 80,
- fill: '#ffe23b'
-});
-shopReturnBtn.anchor.set(0, 0);
-shopReturnBtn.x = 80;
-shopReturnBtn.y = 180;
-shopReturnBtn.interactive = true;
-shopReturnBtn.buttonMode = true;
-shopReturnBtn.down = function (x, y, obj) {
- shopGroup.visible = false;
- mainMenuGroup.visible = true;
- shopCurrentTab = 0;
- updateShopTab();
- setTab(0);
-};
-shopGroup.addChild(shopReturnBtn);
-// Shop coin display
-shopCoinTxt = new Text2('Coins: ' + coins, {
- size: 90,
- fill: '#ffe23b'
-});
-shopCoinTxt.anchor.set(1, 0);
-shopCoinTxt.x = 2048 - 80;
-shopCoinTxt.y = 180;
-shopGroup.addChild(shopCoinTxt);
// Shop items
shopItems = [];
for (var i = 0; i < shopSkins.length; i++) {
var item = new ShopItem();
@@ -447,15 +447,13 @@
// Icon/label
// Removed item name label (iconTxt)
// Description
var descTxt = new Text2(itemData.desc, {
- size: 56,
- fill: '#222244',
- fontWeight: 'bold'
+ size: 38,
+ fill: '#fff'
});
descTxt.anchor.set(0.5, 0);
- // Add extra vertical spacing so text doesn't touch the gray square
- descTxt.y = 75;
+ descTxt.y = 60;
item.addChild(descTxt);
// Price/owned label
var ownedCount = storage.itemInventory[itemData.id] || 0;
var priceLabel = new Text2('x' + ownedCount + ' ' + itemData.price + ' coins', {
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