/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CollectionSlot = Container.expand(function (itemType, rarity, size) {
var self = Container.call(this);
self.itemType = itemType;
self.rarity = rarity;
self.size = size || 1.0;
self.discovered = false;
var slotBg = self.attachAsset('item_slot', {
anchorX: 0.5,
anchorY: 0.5
});
var itemGraphics = self.attachAsset('treasure_' + itemType, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6
});
// Scale item to fit in slot while maintaining aspect ratio
var maxScale = Math.min(1.0, 80 / (80 * self.size));
itemGraphics.scaleX = maxScale;
itemGraphics.scaleY = maxScale;
var rarityColors = {
common: 0xFFFFFF,
rare: 0x4169E1,
epic: 0x9932CC,
legendary: 0xFFD700,
mítico: 0xFF0080,
cósmico: 0x00FFFF,
imposible: 0xFF6600
};
itemGraphics.tint = rarityColors[rarity];
// Add item name text
var itemNameText = new Text2(itemType.toUpperCase(), {
size: 16,
fill: '#FFFFFF'
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.y = 70;
itemNameText.alpha = 0.8;
self.addChild(itemNameText);
// Add discovery indicator
var discoveryIndicator = new Text2('?', {
size: 30,
fill: '#FF0000'
});
discoveryIndicator.anchor.set(0.5, 0.5);
discoveryIndicator.x = 40;
discoveryIndicator.y = -40;
self.addChild(discoveryIndicator);
self.discover = function () {
if (!self.discovered) {
self.discovered = true;
itemGraphics.alpha = 1.0;
itemNameText.alpha = 1.0;
discoveryIndicator.visible = false;
LK.effects.flashObject(self, rarityColors[rarity], 1000);
}
};
return self;
});
var TreasureBox = Container.expand(function (boxType) {
var self = Container.call(this);
self.boxType = boxType;
self.price = getBoxPrice(boxType);
var boxGraphics = self.attachAsset('box_' + boxType, {
anchorX: 0.5,
anchorY: 0.5
});
var priceText = new Text2(self.price + ' coins', {
size: 40,
fill: '#FFFFFF'
});
priceText.anchor.set(0.5, 0.5);
priceText.y = 120;
self.addChild(priceText);
self.down = function (x, y, obj) {
if (playerCoins >= self.price) {
openBox(self.boxType);
} else {
// Visual feedback for insufficient coins
LK.effects.flashObject(self, 0xff0000, 500);
}
};
self.update = function () {
// Update visual state based on affordability
if (playerCoins >= self.price) {
boxGraphics.alpha = 1.0;
priceText.tint = 0x00ff00;
} else {
boxGraphics.alpha = 0.6;
priceText.tint = 0xff0000;
}
};
return self;
});
var TreasureItem = Container.expand(function (itemType, rarity, size) {
var self = Container.call(this);
self.itemType = itemType;
self.rarity = rarity;
self.size = size || 1.0;
self.value = getItemValue(itemType, rarity, size);
var itemGraphics = self.attachAsset('treasure_' + itemType, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply size scaling
itemGraphics.scaleX = self.size;
itemGraphics.scaleY = self.size;
// Apply rarity tint
var rarityColors = {
common: 0xFFFFFF,
rare: 0x4169E1,
epic: 0x9932CC,
legendary: 0xFFD700,
mítico: 0xFF0080,
cósmico: 0x00FFFF,
imposible: 0xFF6600
};
itemGraphics.tint = rarityColors[rarity];
// Add size indicator text if item is larger than normal
if (self.size > 1.5) {
var sizeText = new Text2(self.size.toFixed(1) + 'x', {
size: 30,
fill: '#FFFF00'
});
sizeText.anchor.set(0.5, 0.5);
sizeText.y = itemGraphics.height * self.size / 2 + 20;
self.addChild(sizeText);
}
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game state with safe initialization
var playerCoins = 100;
var discoveredItems = {};
var playerName = '';
var playerDifficulty = 'FÁCIL';
var currentScreen = 'nameInput';
var openingAnimation = false;
var leaderboard = [];
var myBestRarity = 'common';
var myBestSize = 1.0;
// Safe storage operations
function safeStorageGet(key, defaultValue) {
try {
return storage[key] || defaultValue;
} catch (e) {
console.log('Storage get error for', key, ':', e);
return defaultValue;
}
}
function safeStorageSet(key, value) {
try {
storage[key] = value;
} catch (e) {
console.log('Storage set error for', key, ':', e);
}
}
// Initialize game data safely
function initializeGameData() {
playerCoins = safeStorageGet('coins', 100);
discoveredItems = safeStorageGet('discovered', {});
playerName = safeStorageGet('playerName', '');
playerDifficulty = safeStorageGet('playerDifficulty', 'FÁCIL');
myBestRarity = safeStorageGet('myBestRarity', 'common');
myBestSize = safeStorageGet('myBestSize', 1.0);
// Load online leaderboard
loadOnlineLeaderboard();
currentScreen = playerName ? 'menu' : 'nameInput';
}
// Online leaderboard functions
function loadOnlineLeaderboard() {
// Get global leaderboard entries
var globalEntries = safeStorageGet('globalLeaderboard', []);
leaderboard = [];
for (var i = 0; i < globalEntries.length; i++) {
var parts = globalEntries[i].split('|');
if (parts.length === 4) {
leaderboard.push({
name: parts[0],
rarity: parts[1],
size: parseFloat(parts[2]) || 1.0,
timestamp: parseInt(parts[3]) || 0
});
}
}
}
function saveToOnlineLeaderboard(playerEntry) {
// Load current global leaderboard
var globalEntries = safeStorageGet('globalLeaderboard', []);
var leaderboardData = [];
// Convert existing entries to objects
for (var i = 0; i < globalEntries.length; i++) {
var parts = globalEntries[i].split('|');
if (parts.length === 4) {
leaderboardData.push({
name: parts[0],
rarity: parts[1],
size: parseFloat(parts[2]) || 1.0,
timestamp: parseInt(parts[3]) || 0
});
}
}
// Find if player already exists
var existingIndex = -1;
for (var i = 0; i < leaderboardData.length; i++) {
if (leaderboardData[i].name === playerEntry.name) {
existingIndex = i;
break;
}
}
// Add or update player entry
if (existingIndex >= 0) {
leaderboardData[existingIndex] = playerEntry;
} else {
leaderboardData.push(playerEntry);
}
// Sort by rarity and size
var rarityOrder = {
'imposible': 7,
'cósmico': 6,
'mítico': 5,
'legendary': 4,
'epic': 3,
'rare': 2,
'common': 1
};
leaderboardData.sort(function (a, b) {
// Calculate probability for sorting
var aBaseChance = 0;
var bBaseChance = 0;
for (var bType = 0; bType < boxTypes.length; bType++) {
var aBoxChances = getRarityChance(boxTypes[bType]);
var bBoxChances = getRarityChance(boxTypes[bType]);
if (aBoxChances[a.rarity] > 0) {
aBaseChance = aBoxChances[a.rarity];
}
if (bBoxChances[b.rarity] > 0) {
bBaseChance = bBoxChances[b.rarity];
}
}
var aSizeMultiplier = a.size * a.size;
var bSizeMultiplier = b.size * b.size;
var aScaledChance = aBaseChance / aSizeMultiplier;
var bScaledChance = bBaseChance / bSizeMultiplier;
return aScaledChance - bScaledChance;
});
// Keep only top 100 entries
if (leaderboardData.length > 100) {
leaderboardData = leaderboardData.slice(0, 100);
}
// Convert back to flat format and save
var flatData = [];
for (var i = 0; i < leaderboardData.length; i++) {
var entry = leaderboardData[i];
flatData.push(entry.name + '|' + entry.rarity + '|' + entry.size + '|' + entry.timestamp);
}
safeStorageSet('globalLeaderboard', flatData);
// Update local leaderboard
leaderboard = leaderboardData;
}
// Initialize the game data
initializeGameData();
// Treasure definitions
var treasureTypes = ['coin', 'gem', 'diamond', 'ruby', 'crown', 'artifact', 'sword', 'shield', 'ring', 'necklace', 'bracelet', 'earring', 'pendant', 'watch', 'staff', 'orb', 'scroll', 'book', 'potion', 'crystal', 'pearl', 'emerald', 'sapphire', 'topaz', 'amethyst', 'opal', 'jade', 'onyx', 'turquoise', 'garnet', 'chalice', 'goblet', 'scepter', 'tiara', 'dagger', 'armor', 'helmet', 'gauntlets', 'boots', 'cloak', 'amulet', 'talisman', 'rune', 'compass', 'telescope', 'hourglass', 'lantern', 'mirror', 'key', 'chest'];
var rarityLevels = ['common', 'rare', 'epic', 'legendary', 'mítico', 'cósmico', 'imposible'];
// Box definitions
var boxTypes = ['common', 'rare', 'epic', 'legendary', 'mítico', 'cósmico', 'imposible'];
function getBoxPrice(boxType) {
var prices = {
common: 50,
rare: 150,
epic: 400,
legendary: 1000,
mítico: 2500,
cósmico: 5000,
imposible: 10000
};
return prices[boxType];
}
function getItemValue(itemType, rarity, size) {
var baseValues = {
coin: 10,
gem: 25,
diamond: 50,
ruby: 100,
crown: 200,
artifact: 500,
sword: 80,
shield: 75,
ring: 60,
necklace: 90,
bracelet: 70,
earring: 65,
pendant: 85,
watch: 120,
staff: 150,
orb: 180,
scroll: 45,
book: 55,
potion: 40,
crystal: 95,
pearl: 110,
emerald: 140,
sapphire: 160,
topaz: 130,
amethyst: 135,
opal: 125,
jade: 145,
onyx: 105,
turquoise: 115,
garnet: 100,
chalice: 220,
goblet: 200,
scepter: 300,
tiara: 250,
dagger: 85,
armor: 400,
helmet: 180,
gauntlets: 120,
boots: 90,
cloak: 110,
amulet: 170,
talisman: 160,
rune: 190,
compass: 100,
telescope: 150,
hourglass: 140,
lantern: 80,
mirror: 90,
key: 75,
chest: 350
};
var rarityMultipliers = {
common: 1,
rare: 3,
epic: 8,
legendary: 20,
mítico: 50,
cósmico: 100,
imposible: 250
};
size = size || 1.0; // Default size if not provided
var sizeMultiplier = size * size; // Quadratic scaling for value
return Math.floor((baseValues[itemType] || 50) * rarityMultipliers[rarity] * sizeMultiplier);
}
function getRarityChance(boxType) {
var chances = {
common: {
common: 0.5,
rare: 0.35,
epic: 0.12,
legendary: 0.03,
mítico: 0,
cósmico: 0,
imposible: 0
},
rare: {
common: 0.25,
rare: 0.5,
epic: 0.2,
legendary: 0.05,
mítico: 0,
cósmico: 0,
imposible: 0
},
epic: {
common: 0.15,
rare: 0.35,
epic: 0.4,
legendary: 0.1,
mítico: 0,
cósmico: 0,
imposible: 0
},
legendary: {
common: 0.05,
rare: 0.25,
epic: 0.45,
legendary: 0.25,
mítico: 0,
cósmico: 0,
imposible: 0
},
mítico: {
common: 0.02,
rare: 0.15,
epic: 0.28,
legendary: 0.35,
mítico: 0.15,
cósmico: 0.04,
imposible: 0.01
},
cósmico: {
common: 0.01,
rare: 0.1,
epic: 0.2,
legendary: 0.35,
mítico: 0.25,
cósmico: 0.08,
imposible: 0.01
},
imposible: {
common: 0.005,
rare: 0.05,
epic: 0.15,
legendary: 0.25,
mítico: 0.35,
cósmico: 0.15,
imposible: 0.095
}
};
return chances[boxType];
}
function generateRandomItem(boxType) {
var chances = getRarityChance(boxType);
var rand = Math.random();
var rarity = 'common';
if (rand < chances.imposible) {
rarity = 'imposible';
} else if (rand < chances.imposible + chances.cósmico) {
rarity = 'cósmico';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico) {
rarity = 'mítico';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico + chances.legendary) {
rarity = 'legendary';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico + chances.legendary + chances.epic) {
rarity = 'epic';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico + chances.legendary + chances.epic + chances.rare) {
rarity = 'rare';
}
var itemType = treasureTypes[Math.floor(Math.random() * treasureTypes.length)];
// Generate item size based on probability - larger items are more likely now
var sizeRand = Math.random();
var size = 1.0; // Base size
if (sizeRand < 0.01) {
// 1% chance for legendary colossal items
size = 50.0 + Math.random() * 100.0; // 50x to 150x size
} else if (sizeRand < 0.05) {
// 4% chance for colossal items
size = 20.0 + Math.random() * 30.0; // 20x to 50x size
} else if (sizeRand < 0.15) {
// 10% chance for massive items
size = 8.0 + Math.random() * 12.0; // 8x to 20x size
} else if (sizeRand < 0.35) {
// 20% chance for huge items
size = 4.0 + Math.random() * 4.0; // 4x to 8x size
} else if (sizeRand < 0.6) {
// 25% chance for large items
size = 2.0 + Math.random() * 2.0; // 2x to 4x size
} else if (sizeRand < 0.8) {
// 20% chance for medium items
size = 1.5 + Math.random() * 0.5; // 1.5x to 2x size
} else if (sizeRand < 0.95) {
// 15% chance for small+ items
size = 1.2 + Math.random() * 0.3; // 1.2x to 1.5x size
}
// 35% chance for normal size (1.0x)
return {
type: itemType,
rarity: rarity,
size: size
};
}
// UI Elements
var coinsDisplay = new Text2('Coins: ' + playerCoins, {
size: 60,
fill: '#FFD700'
});
coinsDisplay.anchor.set(0, 0);
coinsDisplay.x = 150;
coinsDisplay.y = 50;
LK.gui.topLeft.addChild(coinsDisplay);
var shopButton = new Container();
var shopButtonBg = shopButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var shopButtonText = new Text2('SHOP', {
size: 40,
fill: '#FFFFFF'
});
shopButtonText.anchor.set(0.5, 0.5);
shopButton.addChild(shopButtonText);
shopButton.x = 1024;
shopButton.y = 150;
shopButton.down = function () {
showShop();
};
game.addChild(shopButton);
var collectionButton = new Container();
var collectionButtonBg = collectionButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var collectionButtonText = new Text2('COLLECTION', {
size: 40,
fill: '#FFFFFF'
});
collectionButtonText.anchor.set(0.5, 0.5);
collectionButton.addChild(collectionButtonText);
collectionButton.x = 1024;
collectionButton.y = 250;
collectionButton.down = function () {
showCollection();
};
LK.gui.top.addChild(collectionButton);
var leaderboardButton = new Container();
var leaderboardButtonBg = leaderboardButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var leaderboardButtonText = new Text2('LEADERBOARD', {
size: 40,
fill: '#FFFFFF'
});
leaderboardButtonText.anchor.set(0.5, 0.5);
leaderboardButton.addChild(leaderboardButtonText);
leaderboardButton.x = 1024;
leaderboardButton.y = 350;
leaderboardButton.down = function () {
showLeaderboard();
};
game.addChild(leaderboardButton);
var resetButton = new Container();
var resetButtonBg = resetButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var resetButtonText = new Text2('RESET', {
size: 40,
fill: '#FFFFFF'
});
resetButtonText.anchor.set(0.5, 0.5);
resetButton.addChild(resetButtonText);
resetButton.x = 1024;
resetButton.y = 450;
resetButton.down = function () {
// Reset all game data
playerCoins = 100;
discoveredItems = {};
playerName = '';
playerDifficulty = 'FÁCIL';
myBestRarity = 'common';
myBestSize = 1.0;
leaderboard = [];
// Clear storage
safeStorageSet('coins', 100);
safeStorageSet('discovered', {});
safeStorageSet('playerName', '');
safeStorageSet('playerDifficulty', 'FÁCIL');
safeStorageSet('myBestRarity', 'common');
safeStorageSet('myBestSize', 1.0);
// Note: We don't clear globalLeaderboard as it contains other players' data
// Reset UI
updateCoinsDisplay();
// Clear spawned coins
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
var coin = spawnedCoins[i];
coin.destroy();
}
spawnedCoins = [];
// Reset to name input screen
currentScreen = 'nameInput';
nameInputContainer.visible = true;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
// Refresh all displays
setupNameInput();
setupShop();
setupCollection();
setupLeaderboard();
};
game.addChild(resetButton);
// Game containers
var nameInputContainer = new Container();
var shopContainer = new Container();
var openingContainer = new Container();
var collectionContainer = new Container();
var leaderboardContainer = new Container();
game.addChild(nameInputContainer);
game.addChild(shopContainer);
game.addChild(openingContainer);
game.addChild(collectionContainer);
game.addChild(leaderboardContainer);
// Shop setup
var treasureBoxes = [];
function setupShop() {
shopContainer.removeChildren();
treasureBoxes = [];
// Add shop title
var shopTitle = new Text2('TREASURE SHOP', {
size: 100,
fill: '#FFFFFF'
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.x = 1024;
shopTitle.y = 300;
shopContainer.addChild(shopTitle);
// Add shop description
var shopDesc = new Text2('Buy mystery boxes to discover treasures!', {
size: 50,
fill: '#CCCCCC'
});
shopDesc.anchor.set(0.5, 0.5);
shopDesc.x = 1024;
shopDesc.y = 400;
shopContainer.addChild(shopDesc);
// Add exit button to shop
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 600;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
shopContainer.addChild(exitButton);
// Create boxes with better spacing
for (var i = 0; i < boxTypes.length; i++) {
var box = new TreasureBox(boxTypes[i]);
// Create two rows of boxes
if (i < 4) {
box.x = 200 + i * 400;
box.y = 900;
} else {
box.x = 200 + (i - 4) * 400;
box.y = 1400;
}
shopContainer.addChild(box);
treasureBoxes.push(box);
// Add rarity labels with proper colors
var boxRarityColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var rarityLabel = new Text2(boxTypes[i].toUpperCase() + ' BOX', {
size: 45,
fill: boxRarityColors[boxTypes[i]]
});
rarityLabel.anchor.set(0.5, 0.5);
rarityLabel.x = box.x;
rarityLabel.y = box.y - 150;
shopContainer.addChild(rarityLabel);
// Add difficulty level indicator
var difficultyLevels = {
common: 'FÁCIL',
rare: 'NORMAL',
epic: 'DIFÍCIL',
legendary: 'MUY DIFÍCIL',
mítico: 'EXTREMO',
cósmico: 'IMPOSIBLE',
imposible: 'LEGENDARIO'
};
var difficultyColors = {
common: '#00FF00',
rare: '#FFFF00',
epic: '#FF8000',
legendary: '#FF0000',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var difficultyText = new Text2('DIFICULTAD: ' + difficultyLevels[boxTypes[i]], {
size: 35,
fill: difficultyColors[boxTypes[i]]
});
difficultyText.anchor.set(0.5, 0.5);
difficultyText.x = box.x;
difficultyText.y = box.y - 100;
shopContainer.addChild(difficultyText);
// Add probability display for all rarities
var chanceInfo = getRarityChance(boxTypes[i]);
var probabilities = [{
rarity: 'Common',
chance: chanceInfo.common,
color: '#FFFFFF'
}, {
rarity: 'Rare',
chance: chanceInfo.rare,
color: '#4169E1'
}, {
rarity: 'Epic',
chance: chanceInfo.epic,
color: '#9932CC'
}, {
rarity: 'Legendary',
chance: chanceInfo.legendary,
color: '#FFD700'
}, {
rarity: 'Mítico',
chance: chanceInfo.mítico,
color: '#FF0080'
}, {
rarity: 'Cósmico',
chance: chanceInfo.cósmico,
color: '#00FFFF'
}, {
rarity: 'Imposible',
chance: chanceInfo.imposible,
color: '#FF6600'
}];
for (var p = 0; p < probabilities.length; p++) {
var prob = probabilities[p];
var percentage = Math.round(prob.chance * 100);
var rarityText = '';
if (prob.chance > 0) {
var oneInX = Math.round(1 / prob.chance);
rarityText = prob.rarity + ': ' + percentage + '% (1 entre ' + oneInX + ')';
} else {
rarityText = prob.rarity + ': 0% (1 entre ∞)';
}
var chanceText = new Text2(rarityText, {
size: 40,
fill: prob.color
});
chanceText.anchor.set(0.5, 0.5);
chanceText.x = box.x;
chanceText.y = box.y + 150 + p * 35;
shopContainer.addChild(chanceText);
}
}
}
// Collection setup
var collectionSlots = [];
function setupCollection() {
collectionContainer.removeChildren();
collectionSlots = [];
var collectionBg = collectionContainer.attachAsset('collection_bg', {
anchorX: 0.5,
anchorY: 0.5
});
collectionBg.x = 1024;
collectionBg.y = 1366;
var titleText = new Text2('TREASURE COLLECTION', {
size: 80,
fill: '#FFFFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
collectionContainer.addChild(titleText);
// Add collection statistics
var totalItems = treasureTypes.length * rarityLevels.length;
var discoveredCount = 0;
for (var key in discoveredItems) {
if (discoveredItems[key] && !key.endsWith('_size')) {
discoveredCount++;
}
}
var statsText = new Text2('Discovered: ' + discoveredCount + '/' + totalItems, {
size: 40,
fill: '#CCCCCC'
});
statsText.anchor.set(0.5, 0.5);
statsText.x = 1024;
statsText.y = 370;
collectionContainer.addChild(statsText);
// Add exit button to collection
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 450;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
collectionContainer.addChild(exitButton);
var slotIndex = 0;
var itemsPerRow = 10;
var slotSpacing = 140;
var startX = 200;
var startY = 500;
for (var r = 0; r < rarityLevels.length; r++) {
// Rarity color mapping
var rarityColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var rarityText = new Text2(rarityLevels[r].toUpperCase(), {
size: 50,
fill: rarityColors[rarityLevels[r]]
});
rarityText.anchor.set(0.5, 0.5);
rarityText.x = 1024;
rarityText.y = startY + r * 600;
collectionContainer.addChild(rarityText);
// Add rarity statistics
var rarityCount = 0;
for (var t = 0; t < treasureTypes.length; t++) {
var itemKey = treasureTypes[t] + '_' + rarityLevels[r];
if (discoveredItems[itemKey]) {
rarityCount++;
}
}
var rarityStats = new Text2(rarityCount + '/' + treasureTypes.length, {
size: 35,
fill: '#CCCCCC'
});
rarityStats.anchor.set(0.5, 0.5);
rarityStats.x = 1024;
rarityStats.y = startY + r * 600 + 30;
collectionContainer.addChild(rarityStats);
for (var t = 0; t < treasureTypes.length; t++) {
var itemKey = treasureTypes[t] + '_' + rarityLevels[r];
var itemSize = 1.0;
if (discoveredItems[itemKey + '_size']) {
itemSize = discoveredItems[itemKey + '_size'];
}
var slot = new CollectionSlot(treasureTypes[t], rarityLevels[r], itemSize);
var row = Math.floor(t / itemsPerRow);
var col = t % itemsPerRow;
slot.x = startX + col * slotSpacing;
slot.y = startY + 80 + r * 600 + row * slotSpacing;
collectionContainer.addChild(slot);
collectionSlots.push(slot);
// Check if already discovered
if (discoveredItems[itemKey]) {
slot.discover();
}
}
}
}
function showShop() {
currentScreen = 'shop';
nameInputContainer.visible = false;
shopContainer.visible = true;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
}
function showCollection() {
currentScreen = 'collection';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = true;
leaderboardContainer.visible = false;
setupCollection();
updateCollectionStats();
}
function setupNameInput() {
nameInputContainer.removeChildren();
var nameInputBg = nameInputContainer.attachAsset('collection_bg', {
anchorX: 0.5,
anchorY: 0.5
});
nameInputBg.x = 1024;
nameInputBg.y = 1366;
var titleText = new Text2('ENTER YOUR NAME', {
size: 80,
fill: '#FFFFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
nameInputContainer.addChild(titleText);
var instructionText = new Text2('Tap letters to spell your name', {
size: 50,
fill: '#CCCCCC'
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 900;
nameInputContainer.addChild(instructionText);
var nameDisplay = new Text2('', {
size: 60,
fill: '#FFD700'
});
nameDisplay.anchor.set(0.5, 0.5);
nameDisplay.x = 1024;
nameDisplay.y = 1000;
nameInputContainer.addChild(nameDisplay);
// Create keyboard toggle button
var keyboardToggle = new Container();
var keyboardToggleBg = keyboardToggle.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
// Make the button background larger
keyboardToggleBg.scaleX = 1.8;
keyboardToggleBg.scaleY = 1.5;
var keyboardToggleText = new Text2('KEYBOARD: ' + currentKeyboard, {
size: 45,
fill: '#FFFFFF'
});
keyboardToggleText.anchor.set(0.5, 0.5);
keyboardToggle.addChild(keyboardToggleText);
keyboardToggle.x = 1024;
keyboardToggle.y = 1100;
keyboardToggle.down = function () {
currentKeyboard = currentKeyboard === 'QWERTY' ? 'DVORAK' : 'QWERTY';
keyboardToggleText.setText('KEYBOARD: ' + currentKeyboard);
setupKeyboard();
};
nameInputContainer.addChild(keyboardToggle);
var currentName = '';
var maxNameLength = 12;
var currentKeyboard = 'QWERTY';
// Create keyboard layouts
var keyboardLayouts = {
QWERTY: ['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM'],
DVORAK: ['\'",.PYFGCRL', 'AOEUIDHTNS', ';QJKXBMWVZ']
};
var buttonWidth = 80;
var buttonHeight = 80;
var buttonSpacing = 110;
var startY = 1150;
var rowOffsets = [0, 50, 100]; // Offset each row to mimic real keyboard staggering
var keyboardContainer = new Container();
nameInputContainer.addChild(keyboardContainer);
function setupKeyboard() {
keyboardContainer.removeChildren();
var currentRows = keyboardLayouts[currentKeyboard];
for (var rowIndex = 0; rowIndex < currentRows.length; rowIndex++) {
var row = currentRows[rowIndex];
var rowStartX = 1024 - row.length * buttonSpacing / 2 + buttonSpacing / 2 + rowOffsets[rowIndex];
for (var colIndex = 0; colIndex < row.length; colIndex++) {
var letter = row[colIndex];
var letterButton = new Container();
var letterBg = letterButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
letterBg.scaleX = 1.0;
letterBg.scaleY = 1.0;
var letterText = new Text2(letter, {
size: 80,
fill: '#FFFFFF'
});
letterText.anchor.set(0.5, 0.5);
letterButton.addChild(letterText);
letterButton.x = rowStartX + colIndex * buttonSpacing;
letterButton.y = startY + rowIndex * 110;
letterButton.letter = letter;
letterButton.down = function () {
if (currentName.length < maxNameLength) {
currentName += this.letter;
nameDisplay.setText(currentName);
}
};
keyboardContainer.addChild(letterButton);
}
}
}
// Initialize keyboard
setupKeyboard();
// Create backspace button
var backspaceButton = new Container();
var backspaceBg = backspaceButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var backspaceText = new Text2('DELETE', {
size: 40,
fill: '#FFFFFF'
});
backspaceText.anchor.set(0.5, 0.5);
backspaceButton.addChild(backspaceText);
backspaceButton.x = 1024 - 200;
backspaceButton.y = 1450;
backspaceButton.down = function () {
if (currentName.length > 0) {
currentName = currentName.slice(0, -1);
nameDisplay.setText(currentName);
}
};
nameInputContainer.addChild(backspaceButton);
// Create confirm button
var confirmButton = new Container();
var confirmBg = confirmButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var confirmText = new Text2('CONFIRM', {
size: 40,
fill: '#FFFFFF'
});
confirmText.anchor.set(0.5, 0.5);
confirmButton.addChild(confirmText);
confirmButton.x = 1024 + 200;
confirmButton.y = 1450;
confirmButton.down = function () {
if (currentName.length > 0) {
playerName = currentName;
safeStorageSet('playerName', playerName);
currentScreen = 'menu';
nameInputContainer.visible = false;
}
};
nameInputContainer.addChild(confirmButton);
}
function setupLeaderboard() {
leaderboardContainer.removeChildren();
var leaderboardBg = leaderboardContainer.attachAsset('collection_bg', {
anchorX: 0.5,
anchorY: 0.5
});
leaderboardBg.x = 1024;
leaderboardBg.y = 1366;
var titleText = new Text2('ONLINE LEADERBOARD - RAREST FINDS', {
size: 80,
fill: '#FFFFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
leaderboardContainer.addChild(titleText);
// Add game warning notice
var warningText = new Text2('ADVERTENCIA: Este juego no es global', {
size: 40,
fill: '#FF6600'
});
warningText.anchor.set(0.5, 0.5);
warningText.x = 1024;
warningText.y = 350;
leaderboardContainer.addChild(warningText);
// Add comment request notice
var commentText = new Text2('¡Deja un comentario del objeto más raro que encuentres!', {
size: 35,
fill: '#FFFF00'
});
commentText.anchor.set(0.5, 0.5);
commentText.x = 1024;
commentText.y = 385;
leaderboardContainer.addChild(commentText);
// Add difficulty explanation
var difficultyExplanation = new Text2('Los objetos más raros son más difíciles de conseguir', {
size: 35,
fill: '#CCCCCC'
});
difficultyExplanation.anchor.set(0.5, 0.5);
difficultyExplanation.x = 1024;
difficultyExplanation.y = 390;
leaderboardContainer.addChild(difficultyExplanation);
// Add exit button
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 450;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
leaderboardContainer.addChild(exitButton);
// Sort leaderboard by probability (most improbable first)
leaderboard.sort(function (a, b) {
// Calculate probability for item A
var aBaseChance = 0;
for (var bType = 0; bType < boxTypes.length; bType++) {
var aBoxChances = getRarityChance(boxTypes[bType]);
if (aBoxChances[a.rarity] > 0) {
aBaseChance = aBoxChances[a.rarity];
break;
}
}
var aSizeMultiplier = a.size * a.size;
var aScaledChance = aBaseChance / aSizeMultiplier;
// Calculate probability for item B
var bBaseChance = 0;
for (var bType = 0; bType < boxTypes.length; bType++) {
var bBoxChances = getRarityChance(boxTypes[bType]);
if (bBoxChances[b.rarity] > 0) {
bBaseChance = bBoxChances[b.rarity];
break;
}
}
var bSizeMultiplier = b.size * b.size;
var bScaledChance = bBaseChance / bSizeMultiplier;
// Sort by probability (lower probability = higher rank)
return aScaledChance - bScaledChance;
});
// Display top 10 entries
var displayCount = Math.min(10, leaderboard.length);
for (var i = 0; i < displayCount; i++) {
var entry = leaderboard[i];
var position = i + 1;
var positionText = '';
if (position === 1) {
positionText = '1st';
} else if (position === 2) {
positionText = '2nd';
} else if (position === 3) {
positionText = '3rd';
} else {
positionText = position + 'th';
}
var rarityColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
// Calculate probability for this entry
var baseChance = 0;
// Find the minimum box type that can produce this rarity
var minBoxType = 'common';
for (var b = 0; b < boxTypes.length; b++) {
var boxChances = getRarityChance(boxTypes[b]);
if (boxChances[entry.rarity] > 0) {
minBoxType = boxTypes[b];
baseChance = boxChances[entry.rarity];
break;
}
}
// Scale probability by item size - larger items are much rarer
var sizeMultiplier = entry.size * entry.size;
var scaledChance = baseChance / sizeMultiplier;
var oneInX = Math.round(1 / scaledChance);
var displayText = '';
if (position <= 3) {
// For top 3, show position with player name and probability
displayText = positionText + ' - ' + entry.name + ' (' + entry.rarity.toUpperCase() + ' ' + entry.size.toFixed(1) + 'x) - 1 entre ' + oneInX;
} else {
// For others, show standard format with probability
displayText = positionText + ' - ' + entry.name + ' (' + entry.rarity.toUpperCase() + ' ' + entry.size.toFixed(1) + 'x) - 1 entre ' + oneInX;
}
var entryText = new Text2(displayText, {
size: 35,
fill: rarityColors[entry.rarity]
});
entryText.anchor.set(0.5, 0.5);
entryText.x = 1024;
entryText.y = 600 + i * 60;
leaderboardContainer.addChild(entryText);
}
// Show your best if not in top 10
var yourRank = -1;
for (var i = 0; i < leaderboard.length; i++) {
if (leaderboard[i].name === playerName) {
yourRank = i + 1;
break;
}
}
if (yourRank > 10 || yourRank === -1) {
// Calculate probability for personal best
var baseChance = 0;
// Find the minimum box type that can produce this rarity
var minBoxType = 'common';
for (var b = 0; b < boxTypes.length; b++) {
var boxChances = getRarityChance(boxTypes[b]);
if (boxChances[myBestRarity] > 0) {
minBoxType = boxTypes[b];
baseChance = boxChances[myBestRarity];
break;
}
}
// Scale probability by item size - larger items are much rarer
var sizeMultiplier = myBestSize * myBestSize;
var scaledChance = baseChance / sizeMultiplier;
var oneInX = Math.round(1 / scaledChance);
var yourBestText = new Text2('YOUR BEST: ' + myBestRarity.toUpperCase() + ' (' + myBestSize.toFixed(1) + 'x) - 1 entre ' + oneInX, {
size: 32,
fill: '#CCCCCC'
});
yourBestText.anchor.set(0.5, 0.5);
yourBestText.x = 1024;
yourBestText.y = 1200;
leaderboardContainer.addChild(yourBestText);
}
}
function showLeaderboard() {
currentScreen = 'leaderboard';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = true;
// Refresh online leaderboard data
loadOnlineLeaderboard();
setupLeaderboard();
}
function updateCollectionStats() {
// Update the collection statistics when shown
var totalItems = treasureTypes.length * rarityLevels.length;
var discoveredCount = 0;
for (var key in discoveredItems) {
if (discoveredItems[key] && !key.endsWith('_size')) {
discoveredCount++;
}
}
// Find and update stats text if it exists
for (var i = 0; i < collectionContainer.children.length; i++) {
var child = collectionContainer.children[i];
if (child.text && child.text.includes('Discovered:')) {
child.setText('Discovered: ' + discoveredCount + '/' + totalItems + ' (' + Math.round(discoveredCount / totalItems * 100) + '%)');
break;
}
}
}
function showOpening() {
currentScreen = 'opening';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = true;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
}
function openBox(boxType) {
if (playerCoins < getBoxPrice(boxType)) return;
playerCoins -= getBoxPrice(boxType);
updateCoinsDisplay();
var item = generateRandomItem(boxType);
showOpening();
openingAnimation = true;
openingContainer.removeChildren();
// Create opening animation
var openingBox = new Container();
var boxGraphics = openingBox.attachAsset('box_' + boxType, {
anchorX: 0.5,
anchorY: 0.5
});
openingBox.x = 1024;
openingBox.y = 1000;
openingContainer.addChild(openingBox);
// Add exit button to opening screen
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 1500;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
openingContainer.addChild(exitButton);
LK.getSound('box_open').play();
// Animate box opening
tween(openingBox, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
revealTreasure(item, boxType);
}
});
}
function revealTreasure(item, boxType) {
var treasure = new TreasureItem(item.type, item.rarity, item.size);
treasure.x = 1024;
treasure.y = 600;
treasure.alpha = 0;
treasure.scaleX = 0.1;
treasure.scaleY = 0.1;
openingContainer.addChild(treasure);
// Rarity text with proper color
var rarityTextColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var rarityText = new Text2(item.rarity.toUpperCase() + '!', {
size: 80,
fill: rarityTextColors[item.rarity]
});
rarityText.anchor.set(0.5, 0.5);
rarityText.x = 1024;
rarityText.y = 400;
rarityText.alpha = 0;
openingContainer.addChild(rarityText);
// Size text for larger items
if (item.size > 1.5) {
var sizeText = new Text2('SIZE: ' + item.size.toFixed(1) + 'x', {
size: 50,
fill: '#FFFF00'
});
sizeText.anchor.set(0.5, 0.5);
sizeText.x = 1024;
sizeText.y = 480;
sizeText.alpha = 0;
openingContainer.addChild(sizeText);
tween(sizeText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
}
// Rarity probability text - scaled by item size
var chances = getRarityChance(boxType);
var rarityChance = chances[item.rarity];
var baseOneInX = Math.round(1 / rarityChance);
// Scale probability by item size - larger items are much rarer
var sizeMultiplier = item.size * item.size; // Quadratic scaling
var scaledOneInX = Math.round(baseOneInX * sizeMultiplier);
var probabilityText = new Text2('1 entre ' + scaledOneInX, {
size: 50,
fill: '#CCCCCC'
});
probabilityText.anchor.set(0.5, 0.5);
probabilityText.x = 1024;
probabilityText.y = 750;
probabilityText.alpha = 0;
openingContainer.addChild(probabilityText);
// Value text
var valueText = new Text2('+' + treasure.value + ' coins', {
size: 60,
fill: '#FFD700'
});
valueText.anchor.set(0.5, 0.5);
valueText.x = 1024;
valueText.y = 800;
valueText.alpha = 0;
openingContainer.addChild(valueText);
// Animate treasure reveal
tween(treasure, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 800,
easing: tween.easeOut
});
tween(rarityText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
tween(probabilityText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
tween(valueText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
// Play appropriate sound
if (item.rarity === 'imposible' || item.rarity === 'cósmico' || item.rarity === 'mítico' || item.rarity === 'legendary' || item.rarity === 'epic') {
LK.getSound('rare_find').play();
} else {
LK.getSound('coin_sound').play();
}
// Flash effect for rare items
if (item.rarity === 'imposible') {
LK.effects.flashScreen(0xFF6600, 1500);
} else if (item.rarity === 'cósmico') {
LK.effects.flashScreen(0x00FFFF, 1200);
} else if (item.rarity === 'mítico') {
LK.effects.flashScreen(0xFF0080, 1000);
} else if (item.rarity === 'legendary') {
LK.effects.flashScreen(0xFFD700, 1000);
} else if (item.rarity === 'epic') {
LK.effects.flashScreen(0x9932CC, 800);
}
// Add to collection
var itemKey = item.type + '_' + item.rarity;
if (!discoveredItems[itemKey]) {
discoveredItems[itemKey] = true;
discoveredItems[itemKey + '_size'] = item.size;
safeStorageSet('discovered', discoveredItems);
// Update collection display
for (var i = 0; i < collectionSlots.length; i++) {
var slot = collectionSlots[i];
if (slot && slot.itemType === item.type && slot.rarity === item.rarity) {
slot.discover();
break;
}
}
}
// Update player difficulty based on box type
var boxDifficultyLevels = {
common: 'FÁCIL',
rare: 'NORMAL',
epic: 'DIFÍCIL',
legendary: 'MUY DIFÍCIL',
mítico: 'EXTREMO',
cósmico: 'IMPOSIBLE',
imposible: 'LEGENDARIO'
};
var boxDifficultyOrder = {
'FÁCIL': 1,
'NORMAL': 2,
'DIFÍCIL': 3,
'MUY DIFÍCIL': 4,
'EXTREMO': 5,
'IMPOSIBLE': 6,
'LEGENDARIO': 7
};
var currentBoxDifficulty = boxDifficultyLevels[boxType];
if (boxDifficultyOrder[currentBoxDifficulty] > boxDifficultyOrder[playerDifficulty]) {
playerDifficulty = currentBoxDifficulty;
safeStorageSet('playerDifficulty', playerDifficulty);
}
// Update leaderboard for significant finds
var rarityOrder = {
'imposible': 7,
'cósmico': 6,
'mítico': 5,
'legendary': 4,
'epic': 3,
'rare': 2,
'common': 1
};
var currentRarityLevel = rarityOrder[item.rarity];
var bestRarityLevel = rarityOrder[myBestRarity];
if (currentRarityLevel > bestRarityLevel || currentRarityLevel === bestRarityLevel && item.size > myBestSize) {
// Update personal best
myBestRarity = item.rarity;
myBestSize = item.size;
safeStorageSet('myBestRarity', myBestRarity);
safeStorageSet('myBestSize', myBestSize);
// Save to online leaderboard
var newEntry = {
name: playerName,
rarity: item.rarity,
size: item.size,
timestamp: Date.now()
};
saveToOnlineLeaderboard(newEntry);
}
// Add coins
playerCoins += treasure.value;
updateCoinsDisplay();
// Auto return to shop after 3 seconds
LK.setTimeout(function () {
openingAnimation = false;
showShop();
}, 3000);
}
function updateCoinsDisplay() {
coinsDisplay.setText('Coins: ' + playerCoins);
safeStorageSet('coins', playerCoins);
// Update box affordability when coins change
for (var i = 0; i < treasureBoxes.length; i++) {
var box = treasureBoxes[i];
if (box && box.update) {
box.update();
}
}
}
// Coin spawning system
var spawnedCoins = [];
var coinSpawnTimer = 0;
var coinSpawnInterval = 120; // Spawn every 2 seconds at 60fps
var coinCounter = 0;
function spawnRandomCoin() {
coinCounter++;
var isSpecial = coinCounter % 5 === 0; // Every 5th coin is special
var coin = new Container();
var coinGraphics = coin.attachAsset('treasure_coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Random position at top of screen
coin.x = Math.random() * (2048 - 100) + 50;
coin.y = -50;
coin.speed = 2 + Math.random() * 3; // Random fall speed
coin.value = isSpecial ? 50 : 10;
coin.isSpecial = isSpecial;
coin.lastY = coin.y;
// Special coin effects
if (isSpecial) {
coinGraphics.tint = 0xFFD700; // Gold tint
coinGraphics.scaleX = 1.5;
coinGraphics.scaleY = 1.5;
} else {
coinGraphics.tint = 0xFFA500; // Orange tint
}
coin.down = function (x, y, obj) {
// Collect the coin
playerCoins += coin.value;
updateCoinsDisplay();
// Visual feedback
if (coin.isSpecial) {
LK.effects.flashScreen(0xFFD700, 500);
LK.getSound('rare_find').play();
} else {
LK.getSound('coin_sound').play();
}
// Remove coin from game
coin.destroy();
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
if (spawnedCoins[i] === coin) {
spawnedCoins.splice(i, 1);
break;
}
}
};
coin.update = function () {
coin.y += coin.speed;
// Remove if off screen
if (coin.lastY <= 2800 && coin.y > 2800) {
coin.destroy();
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
if (spawnedCoins[i] === coin) {
spawnedCoins.splice(i, 1);
break;
}
}
}
coin.lastY = coin.y;
};
game.addChild(coin);
spawnedCoins.push(coin);
}
// Initialize game
setupShop();
setupCollection();
setupLeaderboard();
setupNameInput();
// Initialize leaderboard display
setupLeaderboard();
// Start with name input if no name, otherwise menu
if (!playerName) {
currentScreen = 'nameInput';
nameInputContainer.visible = true;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
} else {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
}
game.update = function () {
// Coin spawning system
coinSpawnTimer++;
if (coinSpawnTimer >= coinSpawnInterval) {
spawnRandomCoin();
coinSpawnTimer = 0;
// Vary the spawn interval slightly for randomness
coinSpawnInterval = 90 + Math.random() * 60; // Between 1.5 and 2.5 seconds
}
// Update all spawned coins
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
var coin = spawnedCoins[i];
if (coin.update) {
coin.update();
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CollectionSlot = Container.expand(function (itemType, rarity, size) {
var self = Container.call(this);
self.itemType = itemType;
self.rarity = rarity;
self.size = size || 1.0;
self.discovered = false;
var slotBg = self.attachAsset('item_slot', {
anchorX: 0.5,
anchorY: 0.5
});
var itemGraphics = self.attachAsset('treasure_' + itemType, {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.6
});
// Scale item to fit in slot while maintaining aspect ratio
var maxScale = Math.min(1.0, 80 / (80 * self.size));
itemGraphics.scaleX = maxScale;
itemGraphics.scaleY = maxScale;
var rarityColors = {
common: 0xFFFFFF,
rare: 0x4169E1,
epic: 0x9932CC,
legendary: 0xFFD700,
mítico: 0xFF0080,
cósmico: 0x00FFFF,
imposible: 0xFF6600
};
itemGraphics.tint = rarityColors[rarity];
// Add item name text
var itemNameText = new Text2(itemType.toUpperCase(), {
size: 16,
fill: '#FFFFFF'
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.y = 70;
itemNameText.alpha = 0.8;
self.addChild(itemNameText);
// Add discovery indicator
var discoveryIndicator = new Text2('?', {
size: 30,
fill: '#FF0000'
});
discoveryIndicator.anchor.set(0.5, 0.5);
discoveryIndicator.x = 40;
discoveryIndicator.y = -40;
self.addChild(discoveryIndicator);
self.discover = function () {
if (!self.discovered) {
self.discovered = true;
itemGraphics.alpha = 1.0;
itemNameText.alpha = 1.0;
discoveryIndicator.visible = false;
LK.effects.flashObject(self, rarityColors[rarity], 1000);
}
};
return self;
});
var TreasureBox = Container.expand(function (boxType) {
var self = Container.call(this);
self.boxType = boxType;
self.price = getBoxPrice(boxType);
var boxGraphics = self.attachAsset('box_' + boxType, {
anchorX: 0.5,
anchorY: 0.5
});
var priceText = new Text2(self.price + ' coins', {
size: 40,
fill: '#FFFFFF'
});
priceText.anchor.set(0.5, 0.5);
priceText.y = 120;
self.addChild(priceText);
self.down = function (x, y, obj) {
if (playerCoins >= self.price) {
openBox(self.boxType);
} else {
// Visual feedback for insufficient coins
LK.effects.flashObject(self, 0xff0000, 500);
}
};
self.update = function () {
// Update visual state based on affordability
if (playerCoins >= self.price) {
boxGraphics.alpha = 1.0;
priceText.tint = 0x00ff00;
} else {
boxGraphics.alpha = 0.6;
priceText.tint = 0xff0000;
}
};
return self;
});
var TreasureItem = Container.expand(function (itemType, rarity, size) {
var self = Container.call(this);
self.itemType = itemType;
self.rarity = rarity;
self.size = size || 1.0;
self.value = getItemValue(itemType, rarity, size);
var itemGraphics = self.attachAsset('treasure_' + itemType, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply size scaling
itemGraphics.scaleX = self.size;
itemGraphics.scaleY = self.size;
// Apply rarity tint
var rarityColors = {
common: 0xFFFFFF,
rare: 0x4169E1,
epic: 0x9932CC,
legendary: 0xFFD700,
mítico: 0xFF0080,
cósmico: 0x00FFFF,
imposible: 0xFF6600
};
itemGraphics.tint = rarityColors[rarity];
// Add size indicator text if item is larger than normal
if (self.size > 1.5) {
var sizeText = new Text2(self.size.toFixed(1) + 'x', {
size: 30,
fill: '#FFFF00'
});
sizeText.anchor.set(0.5, 0.5);
sizeText.y = itemGraphics.height * self.size / 2 + 20;
self.addChild(sizeText);
}
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game state with safe initialization
var playerCoins = 100;
var discoveredItems = {};
var playerName = '';
var playerDifficulty = 'FÁCIL';
var currentScreen = 'nameInput';
var openingAnimation = false;
var leaderboard = [];
var myBestRarity = 'common';
var myBestSize = 1.0;
// Safe storage operations
function safeStorageGet(key, defaultValue) {
try {
return storage[key] || defaultValue;
} catch (e) {
console.log('Storage get error for', key, ':', e);
return defaultValue;
}
}
function safeStorageSet(key, value) {
try {
storage[key] = value;
} catch (e) {
console.log('Storage set error for', key, ':', e);
}
}
// Initialize game data safely
function initializeGameData() {
playerCoins = safeStorageGet('coins', 100);
discoveredItems = safeStorageGet('discovered', {});
playerName = safeStorageGet('playerName', '');
playerDifficulty = safeStorageGet('playerDifficulty', 'FÁCIL');
myBestRarity = safeStorageGet('myBestRarity', 'common');
myBestSize = safeStorageGet('myBestSize', 1.0);
// Load online leaderboard
loadOnlineLeaderboard();
currentScreen = playerName ? 'menu' : 'nameInput';
}
// Online leaderboard functions
function loadOnlineLeaderboard() {
// Get global leaderboard entries
var globalEntries = safeStorageGet('globalLeaderboard', []);
leaderboard = [];
for (var i = 0; i < globalEntries.length; i++) {
var parts = globalEntries[i].split('|');
if (parts.length === 4) {
leaderboard.push({
name: parts[0],
rarity: parts[1],
size: parseFloat(parts[2]) || 1.0,
timestamp: parseInt(parts[3]) || 0
});
}
}
}
function saveToOnlineLeaderboard(playerEntry) {
// Load current global leaderboard
var globalEntries = safeStorageGet('globalLeaderboard', []);
var leaderboardData = [];
// Convert existing entries to objects
for (var i = 0; i < globalEntries.length; i++) {
var parts = globalEntries[i].split('|');
if (parts.length === 4) {
leaderboardData.push({
name: parts[0],
rarity: parts[1],
size: parseFloat(parts[2]) || 1.0,
timestamp: parseInt(parts[3]) || 0
});
}
}
// Find if player already exists
var existingIndex = -1;
for (var i = 0; i < leaderboardData.length; i++) {
if (leaderboardData[i].name === playerEntry.name) {
existingIndex = i;
break;
}
}
// Add or update player entry
if (existingIndex >= 0) {
leaderboardData[existingIndex] = playerEntry;
} else {
leaderboardData.push(playerEntry);
}
// Sort by rarity and size
var rarityOrder = {
'imposible': 7,
'cósmico': 6,
'mítico': 5,
'legendary': 4,
'epic': 3,
'rare': 2,
'common': 1
};
leaderboardData.sort(function (a, b) {
// Calculate probability for sorting
var aBaseChance = 0;
var bBaseChance = 0;
for (var bType = 0; bType < boxTypes.length; bType++) {
var aBoxChances = getRarityChance(boxTypes[bType]);
var bBoxChances = getRarityChance(boxTypes[bType]);
if (aBoxChances[a.rarity] > 0) {
aBaseChance = aBoxChances[a.rarity];
}
if (bBoxChances[b.rarity] > 0) {
bBaseChance = bBoxChances[b.rarity];
}
}
var aSizeMultiplier = a.size * a.size;
var bSizeMultiplier = b.size * b.size;
var aScaledChance = aBaseChance / aSizeMultiplier;
var bScaledChance = bBaseChance / bSizeMultiplier;
return aScaledChance - bScaledChance;
});
// Keep only top 100 entries
if (leaderboardData.length > 100) {
leaderboardData = leaderboardData.slice(0, 100);
}
// Convert back to flat format and save
var flatData = [];
for (var i = 0; i < leaderboardData.length; i++) {
var entry = leaderboardData[i];
flatData.push(entry.name + '|' + entry.rarity + '|' + entry.size + '|' + entry.timestamp);
}
safeStorageSet('globalLeaderboard', flatData);
// Update local leaderboard
leaderboard = leaderboardData;
}
// Initialize the game data
initializeGameData();
// Treasure definitions
var treasureTypes = ['coin', 'gem', 'diamond', 'ruby', 'crown', 'artifact', 'sword', 'shield', 'ring', 'necklace', 'bracelet', 'earring', 'pendant', 'watch', 'staff', 'orb', 'scroll', 'book', 'potion', 'crystal', 'pearl', 'emerald', 'sapphire', 'topaz', 'amethyst', 'opal', 'jade', 'onyx', 'turquoise', 'garnet', 'chalice', 'goblet', 'scepter', 'tiara', 'dagger', 'armor', 'helmet', 'gauntlets', 'boots', 'cloak', 'amulet', 'talisman', 'rune', 'compass', 'telescope', 'hourglass', 'lantern', 'mirror', 'key', 'chest'];
var rarityLevels = ['common', 'rare', 'epic', 'legendary', 'mítico', 'cósmico', 'imposible'];
// Box definitions
var boxTypes = ['common', 'rare', 'epic', 'legendary', 'mítico', 'cósmico', 'imposible'];
function getBoxPrice(boxType) {
var prices = {
common: 50,
rare: 150,
epic: 400,
legendary: 1000,
mítico: 2500,
cósmico: 5000,
imposible: 10000
};
return prices[boxType];
}
function getItemValue(itemType, rarity, size) {
var baseValues = {
coin: 10,
gem: 25,
diamond: 50,
ruby: 100,
crown: 200,
artifact: 500,
sword: 80,
shield: 75,
ring: 60,
necklace: 90,
bracelet: 70,
earring: 65,
pendant: 85,
watch: 120,
staff: 150,
orb: 180,
scroll: 45,
book: 55,
potion: 40,
crystal: 95,
pearl: 110,
emerald: 140,
sapphire: 160,
topaz: 130,
amethyst: 135,
opal: 125,
jade: 145,
onyx: 105,
turquoise: 115,
garnet: 100,
chalice: 220,
goblet: 200,
scepter: 300,
tiara: 250,
dagger: 85,
armor: 400,
helmet: 180,
gauntlets: 120,
boots: 90,
cloak: 110,
amulet: 170,
talisman: 160,
rune: 190,
compass: 100,
telescope: 150,
hourglass: 140,
lantern: 80,
mirror: 90,
key: 75,
chest: 350
};
var rarityMultipliers = {
common: 1,
rare: 3,
epic: 8,
legendary: 20,
mítico: 50,
cósmico: 100,
imposible: 250
};
size = size || 1.0; // Default size if not provided
var sizeMultiplier = size * size; // Quadratic scaling for value
return Math.floor((baseValues[itemType] || 50) * rarityMultipliers[rarity] * sizeMultiplier);
}
function getRarityChance(boxType) {
var chances = {
common: {
common: 0.5,
rare: 0.35,
epic: 0.12,
legendary: 0.03,
mítico: 0,
cósmico: 0,
imposible: 0
},
rare: {
common: 0.25,
rare: 0.5,
epic: 0.2,
legendary: 0.05,
mítico: 0,
cósmico: 0,
imposible: 0
},
epic: {
common: 0.15,
rare: 0.35,
epic: 0.4,
legendary: 0.1,
mítico: 0,
cósmico: 0,
imposible: 0
},
legendary: {
common: 0.05,
rare: 0.25,
epic: 0.45,
legendary: 0.25,
mítico: 0,
cósmico: 0,
imposible: 0
},
mítico: {
common: 0.02,
rare: 0.15,
epic: 0.28,
legendary: 0.35,
mítico: 0.15,
cósmico: 0.04,
imposible: 0.01
},
cósmico: {
common: 0.01,
rare: 0.1,
epic: 0.2,
legendary: 0.35,
mítico: 0.25,
cósmico: 0.08,
imposible: 0.01
},
imposible: {
common: 0.005,
rare: 0.05,
epic: 0.15,
legendary: 0.25,
mítico: 0.35,
cósmico: 0.15,
imposible: 0.095
}
};
return chances[boxType];
}
function generateRandomItem(boxType) {
var chances = getRarityChance(boxType);
var rand = Math.random();
var rarity = 'common';
if (rand < chances.imposible) {
rarity = 'imposible';
} else if (rand < chances.imposible + chances.cósmico) {
rarity = 'cósmico';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico) {
rarity = 'mítico';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico + chances.legendary) {
rarity = 'legendary';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico + chances.legendary + chances.epic) {
rarity = 'epic';
} else if (rand < chances.imposible + chances.cósmico + chances.mítico + chances.legendary + chances.epic + chances.rare) {
rarity = 'rare';
}
var itemType = treasureTypes[Math.floor(Math.random() * treasureTypes.length)];
// Generate item size based on probability - larger items are more likely now
var sizeRand = Math.random();
var size = 1.0; // Base size
if (sizeRand < 0.01) {
// 1% chance for legendary colossal items
size = 50.0 + Math.random() * 100.0; // 50x to 150x size
} else if (sizeRand < 0.05) {
// 4% chance for colossal items
size = 20.0 + Math.random() * 30.0; // 20x to 50x size
} else if (sizeRand < 0.15) {
// 10% chance for massive items
size = 8.0 + Math.random() * 12.0; // 8x to 20x size
} else if (sizeRand < 0.35) {
// 20% chance for huge items
size = 4.0 + Math.random() * 4.0; // 4x to 8x size
} else if (sizeRand < 0.6) {
// 25% chance for large items
size = 2.0 + Math.random() * 2.0; // 2x to 4x size
} else if (sizeRand < 0.8) {
// 20% chance for medium items
size = 1.5 + Math.random() * 0.5; // 1.5x to 2x size
} else if (sizeRand < 0.95) {
// 15% chance for small+ items
size = 1.2 + Math.random() * 0.3; // 1.2x to 1.5x size
}
// 35% chance for normal size (1.0x)
return {
type: itemType,
rarity: rarity,
size: size
};
}
// UI Elements
var coinsDisplay = new Text2('Coins: ' + playerCoins, {
size: 60,
fill: '#FFD700'
});
coinsDisplay.anchor.set(0, 0);
coinsDisplay.x = 150;
coinsDisplay.y = 50;
LK.gui.topLeft.addChild(coinsDisplay);
var shopButton = new Container();
var shopButtonBg = shopButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var shopButtonText = new Text2('SHOP', {
size: 40,
fill: '#FFFFFF'
});
shopButtonText.anchor.set(0.5, 0.5);
shopButton.addChild(shopButtonText);
shopButton.x = 1024;
shopButton.y = 150;
shopButton.down = function () {
showShop();
};
game.addChild(shopButton);
var collectionButton = new Container();
var collectionButtonBg = collectionButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var collectionButtonText = new Text2('COLLECTION', {
size: 40,
fill: '#FFFFFF'
});
collectionButtonText.anchor.set(0.5, 0.5);
collectionButton.addChild(collectionButtonText);
collectionButton.x = 1024;
collectionButton.y = 250;
collectionButton.down = function () {
showCollection();
};
LK.gui.top.addChild(collectionButton);
var leaderboardButton = new Container();
var leaderboardButtonBg = leaderboardButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var leaderboardButtonText = new Text2('LEADERBOARD', {
size: 40,
fill: '#FFFFFF'
});
leaderboardButtonText.anchor.set(0.5, 0.5);
leaderboardButton.addChild(leaderboardButtonText);
leaderboardButton.x = 1024;
leaderboardButton.y = 350;
leaderboardButton.down = function () {
showLeaderboard();
};
game.addChild(leaderboardButton);
var resetButton = new Container();
var resetButtonBg = resetButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var resetButtonText = new Text2('RESET', {
size: 40,
fill: '#FFFFFF'
});
resetButtonText.anchor.set(0.5, 0.5);
resetButton.addChild(resetButtonText);
resetButton.x = 1024;
resetButton.y = 450;
resetButton.down = function () {
// Reset all game data
playerCoins = 100;
discoveredItems = {};
playerName = '';
playerDifficulty = 'FÁCIL';
myBestRarity = 'common';
myBestSize = 1.0;
leaderboard = [];
// Clear storage
safeStorageSet('coins', 100);
safeStorageSet('discovered', {});
safeStorageSet('playerName', '');
safeStorageSet('playerDifficulty', 'FÁCIL');
safeStorageSet('myBestRarity', 'common');
safeStorageSet('myBestSize', 1.0);
// Note: We don't clear globalLeaderboard as it contains other players' data
// Reset UI
updateCoinsDisplay();
// Clear spawned coins
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
var coin = spawnedCoins[i];
coin.destroy();
}
spawnedCoins = [];
// Reset to name input screen
currentScreen = 'nameInput';
nameInputContainer.visible = true;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
// Refresh all displays
setupNameInput();
setupShop();
setupCollection();
setupLeaderboard();
};
game.addChild(resetButton);
// Game containers
var nameInputContainer = new Container();
var shopContainer = new Container();
var openingContainer = new Container();
var collectionContainer = new Container();
var leaderboardContainer = new Container();
game.addChild(nameInputContainer);
game.addChild(shopContainer);
game.addChild(openingContainer);
game.addChild(collectionContainer);
game.addChild(leaderboardContainer);
// Shop setup
var treasureBoxes = [];
function setupShop() {
shopContainer.removeChildren();
treasureBoxes = [];
// Add shop title
var shopTitle = new Text2('TREASURE SHOP', {
size: 100,
fill: '#FFFFFF'
});
shopTitle.anchor.set(0.5, 0.5);
shopTitle.x = 1024;
shopTitle.y = 300;
shopContainer.addChild(shopTitle);
// Add shop description
var shopDesc = new Text2('Buy mystery boxes to discover treasures!', {
size: 50,
fill: '#CCCCCC'
});
shopDesc.anchor.set(0.5, 0.5);
shopDesc.x = 1024;
shopDesc.y = 400;
shopContainer.addChild(shopDesc);
// Add exit button to shop
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 600;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
shopContainer.addChild(exitButton);
// Create boxes with better spacing
for (var i = 0; i < boxTypes.length; i++) {
var box = new TreasureBox(boxTypes[i]);
// Create two rows of boxes
if (i < 4) {
box.x = 200 + i * 400;
box.y = 900;
} else {
box.x = 200 + (i - 4) * 400;
box.y = 1400;
}
shopContainer.addChild(box);
treasureBoxes.push(box);
// Add rarity labels with proper colors
var boxRarityColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var rarityLabel = new Text2(boxTypes[i].toUpperCase() + ' BOX', {
size: 45,
fill: boxRarityColors[boxTypes[i]]
});
rarityLabel.anchor.set(0.5, 0.5);
rarityLabel.x = box.x;
rarityLabel.y = box.y - 150;
shopContainer.addChild(rarityLabel);
// Add difficulty level indicator
var difficultyLevels = {
common: 'FÁCIL',
rare: 'NORMAL',
epic: 'DIFÍCIL',
legendary: 'MUY DIFÍCIL',
mítico: 'EXTREMO',
cósmico: 'IMPOSIBLE',
imposible: 'LEGENDARIO'
};
var difficultyColors = {
common: '#00FF00',
rare: '#FFFF00',
epic: '#FF8000',
legendary: '#FF0000',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var difficultyText = new Text2('DIFICULTAD: ' + difficultyLevels[boxTypes[i]], {
size: 35,
fill: difficultyColors[boxTypes[i]]
});
difficultyText.anchor.set(0.5, 0.5);
difficultyText.x = box.x;
difficultyText.y = box.y - 100;
shopContainer.addChild(difficultyText);
// Add probability display for all rarities
var chanceInfo = getRarityChance(boxTypes[i]);
var probabilities = [{
rarity: 'Common',
chance: chanceInfo.common,
color: '#FFFFFF'
}, {
rarity: 'Rare',
chance: chanceInfo.rare,
color: '#4169E1'
}, {
rarity: 'Epic',
chance: chanceInfo.epic,
color: '#9932CC'
}, {
rarity: 'Legendary',
chance: chanceInfo.legendary,
color: '#FFD700'
}, {
rarity: 'Mítico',
chance: chanceInfo.mítico,
color: '#FF0080'
}, {
rarity: 'Cósmico',
chance: chanceInfo.cósmico,
color: '#00FFFF'
}, {
rarity: 'Imposible',
chance: chanceInfo.imposible,
color: '#FF6600'
}];
for (var p = 0; p < probabilities.length; p++) {
var prob = probabilities[p];
var percentage = Math.round(prob.chance * 100);
var rarityText = '';
if (prob.chance > 0) {
var oneInX = Math.round(1 / prob.chance);
rarityText = prob.rarity + ': ' + percentage + '% (1 entre ' + oneInX + ')';
} else {
rarityText = prob.rarity + ': 0% (1 entre ∞)';
}
var chanceText = new Text2(rarityText, {
size: 40,
fill: prob.color
});
chanceText.anchor.set(0.5, 0.5);
chanceText.x = box.x;
chanceText.y = box.y + 150 + p * 35;
shopContainer.addChild(chanceText);
}
}
}
// Collection setup
var collectionSlots = [];
function setupCollection() {
collectionContainer.removeChildren();
collectionSlots = [];
var collectionBg = collectionContainer.attachAsset('collection_bg', {
anchorX: 0.5,
anchorY: 0.5
});
collectionBg.x = 1024;
collectionBg.y = 1366;
var titleText = new Text2('TREASURE COLLECTION', {
size: 80,
fill: '#FFFFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
collectionContainer.addChild(titleText);
// Add collection statistics
var totalItems = treasureTypes.length * rarityLevels.length;
var discoveredCount = 0;
for (var key in discoveredItems) {
if (discoveredItems[key] && !key.endsWith('_size')) {
discoveredCount++;
}
}
var statsText = new Text2('Discovered: ' + discoveredCount + '/' + totalItems, {
size: 40,
fill: '#CCCCCC'
});
statsText.anchor.set(0.5, 0.5);
statsText.x = 1024;
statsText.y = 370;
collectionContainer.addChild(statsText);
// Add exit button to collection
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 450;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
collectionContainer.addChild(exitButton);
var slotIndex = 0;
var itemsPerRow = 10;
var slotSpacing = 140;
var startX = 200;
var startY = 500;
for (var r = 0; r < rarityLevels.length; r++) {
// Rarity color mapping
var rarityColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var rarityText = new Text2(rarityLevels[r].toUpperCase(), {
size: 50,
fill: rarityColors[rarityLevels[r]]
});
rarityText.anchor.set(0.5, 0.5);
rarityText.x = 1024;
rarityText.y = startY + r * 600;
collectionContainer.addChild(rarityText);
// Add rarity statistics
var rarityCount = 0;
for (var t = 0; t < treasureTypes.length; t++) {
var itemKey = treasureTypes[t] + '_' + rarityLevels[r];
if (discoveredItems[itemKey]) {
rarityCount++;
}
}
var rarityStats = new Text2(rarityCount + '/' + treasureTypes.length, {
size: 35,
fill: '#CCCCCC'
});
rarityStats.anchor.set(0.5, 0.5);
rarityStats.x = 1024;
rarityStats.y = startY + r * 600 + 30;
collectionContainer.addChild(rarityStats);
for (var t = 0; t < treasureTypes.length; t++) {
var itemKey = treasureTypes[t] + '_' + rarityLevels[r];
var itemSize = 1.0;
if (discoveredItems[itemKey + '_size']) {
itemSize = discoveredItems[itemKey + '_size'];
}
var slot = new CollectionSlot(treasureTypes[t], rarityLevels[r], itemSize);
var row = Math.floor(t / itemsPerRow);
var col = t % itemsPerRow;
slot.x = startX + col * slotSpacing;
slot.y = startY + 80 + r * 600 + row * slotSpacing;
collectionContainer.addChild(slot);
collectionSlots.push(slot);
// Check if already discovered
if (discoveredItems[itemKey]) {
slot.discover();
}
}
}
}
function showShop() {
currentScreen = 'shop';
nameInputContainer.visible = false;
shopContainer.visible = true;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
}
function showCollection() {
currentScreen = 'collection';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = true;
leaderboardContainer.visible = false;
setupCollection();
updateCollectionStats();
}
function setupNameInput() {
nameInputContainer.removeChildren();
var nameInputBg = nameInputContainer.attachAsset('collection_bg', {
anchorX: 0.5,
anchorY: 0.5
});
nameInputBg.x = 1024;
nameInputBg.y = 1366;
var titleText = new Text2('ENTER YOUR NAME', {
size: 80,
fill: '#FFFFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
nameInputContainer.addChild(titleText);
var instructionText = new Text2('Tap letters to spell your name', {
size: 50,
fill: '#CCCCCC'
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 900;
nameInputContainer.addChild(instructionText);
var nameDisplay = new Text2('', {
size: 60,
fill: '#FFD700'
});
nameDisplay.anchor.set(0.5, 0.5);
nameDisplay.x = 1024;
nameDisplay.y = 1000;
nameInputContainer.addChild(nameDisplay);
// Create keyboard toggle button
var keyboardToggle = new Container();
var keyboardToggleBg = keyboardToggle.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
// Make the button background larger
keyboardToggleBg.scaleX = 1.8;
keyboardToggleBg.scaleY = 1.5;
var keyboardToggleText = new Text2('KEYBOARD: ' + currentKeyboard, {
size: 45,
fill: '#FFFFFF'
});
keyboardToggleText.anchor.set(0.5, 0.5);
keyboardToggle.addChild(keyboardToggleText);
keyboardToggle.x = 1024;
keyboardToggle.y = 1100;
keyboardToggle.down = function () {
currentKeyboard = currentKeyboard === 'QWERTY' ? 'DVORAK' : 'QWERTY';
keyboardToggleText.setText('KEYBOARD: ' + currentKeyboard);
setupKeyboard();
};
nameInputContainer.addChild(keyboardToggle);
var currentName = '';
var maxNameLength = 12;
var currentKeyboard = 'QWERTY';
// Create keyboard layouts
var keyboardLayouts = {
QWERTY: ['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM'],
DVORAK: ['\'",.PYFGCRL', 'AOEUIDHTNS', ';QJKXBMWVZ']
};
var buttonWidth = 80;
var buttonHeight = 80;
var buttonSpacing = 110;
var startY = 1150;
var rowOffsets = [0, 50, 100]; // Offset each row to mimic real keyboard staggering
var keyboardContainer = new Container();
nameInputContainer.addChild(keyboardContainer);
function setupKeyboard() {
keyboardContainer.removeChildren();
var currentRows = keyboardLayouts[currentKeyboard];
for (var rowIndex = 0; rowIndex < currentRows.length; rowIndex++) {
var row = currentRows[rowIndex];
var rowStartX = 1024 - row.length * buttonSpacing / 2 + buttonSpacing / 2 + rowOffsets[rowIndex];
for (var colIndex = 0; colIndex < row.length; colIndex++) {
var letter = row[colIndex];
var letterButton = new Container();
var letterBg = letterButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
letterBg.scaleX = 1.0;
letterBg.scaleY = 1.0;
var letterText = new Text2(letter, {
size: 80,
fill: '#FFFFFF'
});
letterText.anchor.set(0.5, 0.5);
letterButton.addChild(letterText);
letterButton.x = rowStartX + colIndex * buttonSpacing;
letterButton.y = startY + rowIndex * 110;
letterButton.letter = letter;
letterButton.down = function () {
if (currentName.length < maxNameLength) {
currentName += this.letter;
nameDisplay.setText(currentName);
}
};
keyboardContainer.addChild(letterButton);
}
}
}
// Initialize keyboard
setupKeyboard();
// Create backspace button
var backspaceButton = new Container();
var backspaceBg = backspaceButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var backspaceText = new Text2('DELETE', {
size: 40,
fill: '#FFFFFF'
});
backspaceText.anchor.set(0.5, 0.5);
backspaceButton.addChild(backspaceText);
backspaceButton.x = 1024 - 200;
backspaceButton.y = 1450;
backspaceButton.down = function () {
if (currentName.length > 0) {
currentName = currentName.slice(0, -1);
nameDisplay.setText(currentName);
}
};
nameInputContainer.addChild(backspaceButton);
// Create confirm button
var confirmButton = new Container();
var confirmBg = confirmButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var confirmText = new Text2('CONFIRM', {
size: 40,
fill: '#FFFFFF'
});
confirmText.anchor.set(0.5, 0.5);
confirmButton.addChild(confirmText);
confirmButton.x = 1024 + 200;
confirmButton.y = 1450;
confirmButton.down = function () {
if (currentName.length > 0) {
playerName = currentName;
safeStorageSet('playerName', playerName);
currentScreen = 'menu';
nameInputContainer.visible = false;
}
};
nameInputContainer.addChild(confirmButton);
}
function setupLeaderboard() {
leaderboardContainer.removeChildren();
var leaderboardBg = leaderboardContainer.attachAsset('collection_bg', {
anchorX: 0.5,
anchorY: 0.5
});
leaderboardBg.x = 1024;
leaderboardBg.y = 1366;
var titleText = new Text2('ONLINE LEADERBOARD - RAREST FINDS', {
size: 80,
fill: '#FFFFFF'
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
leaderboardContainer.addChild(titleText);
// Add game warning notice
var warningText = new Text2('ADVERTENCIA: Este juego no es global', {
size: 40,
fill: '#FF6600'
});
warningText.anchor.set(0.5, 0.5);
warningText.x = 1024;
warningText.y = 350;
leaderboardContainer.addChild(warningText);
// Add comment request notice
var commentText = new Text2('¡Deja un comentario del objeto más raro que encuentres!', {
size: 35,
fill: '#FFFF00'
});
commentText.anchor.set(0.5, 0.5);
commentText.x = 1024;
commentText.y = 385;
leaderboardContainer.addChild(commentText);
// Add difficulty explanation
var difficultyExplanation = new Text2('Los objetos más raros son más difíciles de conseguir', {
size: 35,
fill: '#CCCCCC'
});
difficultyExplanation.anchor.set(0.5, 0.5);
difficultyExplanation.x = 1024;
difficultyExplanation.y = 390;
leaderboardContainer.addChild(difficultyExplanation);
// Add exit button
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 450;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
leaderboardContainer.addChild(exitButton);
// Sort leaderboard by probability (most improbable first)
leaderboard.sort(function (a, b) {
// Calculate probability for item A
var aBaseChance = 0;
for (var bType = 0; bType < boxTypes.length; bType++) {
var aBoxChances = getRarityChance(boxTypes[bType]);
if (aBoxChances[a.rarity] > 0) {
aBaseChance = aBoxChances[a.rarity];
break;
}
}
var aSizeMultiplier = a.size * a.size;
var aScaledChance = aBaseChance / aSizeMultiplier;
// Calculate probability for item B
var bBaseChance = 0;
for (var bType = 0; bType < boxTypes.length; bType++) {
var bBoxChances = getRarityChance(boxTypes[bType]);
if (bBoxChances[b.rarity] > 0) {
bBaseChance = bBoxChances[b.rarity];
break;
}
}
var bSizeMultiplier = b.size * b.size;
var bScaledChance = bBaseChance / bSizeMultiplier;
// Sort by probability (lower probability = higher rank)
return aScaledChance - bScaledChance;
});
// Display top 10 entries
var displayCount = Math.min(10, leaderboard.length);
for (var i = 0; i < displayCount; i++) {
var entry = leaderboard[i];
var position = i + 1;
var positionText = '';
if (position === 1) {
positionText = '1st';
} else if (position === 2) {
positionText = '2nd';
} else if (position === 3) {
positionText = '3rd';
} else {
positionText = position + 'th';
}
var rarityColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
// Calculate probability for this entry
var baseChance = 0;
// Find the minimum box type that can produce this rarity
var minBoxType = 'common';
for (var b = 0; b < boxTypes.length; b++) {
var boxChances = getRarityChance(boxTypes[b]);
if (boxChances[entry.rarity] > 0) {
minBoxType = boxTypes[b];
baseChance = boxChances[entry.rarity];
break;
}
}
// Scale probability by item size - larger items are much rarer
var sizeMultiplier = entry.size * entry.size;
var scaledChance = baseChance / sizeMultiplier;
var oneInX = Math.round(1 / scaledChance);
var displayText = '';
if (position <= 3) {
// For top 3, show position with player name and probability
displayText = positionText + ' - ' + entry.name + ' (' + entry.rarity.toUpperCase() + ' ' + entry.size.toFixed(1) + 'x) - 1 entre ' + oneInX;
} else {
// For others, show standard format with probability
displayText = positionText + ' - ' + entry.name + ' (' + entry.rarity.toUpperCase() + ' ' + entry.size.toFixed(1) + 'x) - 1 entre ' + oneInX;
}
var entryText = new Text2(displayText, {
size: 35,
fill: rarityColors[entry.rarity]
});
entryText.anchor.set(0.5, 0.5);
entryText.x = 1024;
entryText.y = 600 + i * 60;
leaderboardContainer.addChild(entryText);
}
// Show your best if not in top 10
var yourRank = -1;
for (var i = 0; i < leaderboard.length; i++) {
if (leaderboard[i].name === playerName) {
yourRank = i + 1;
break;
}
}
if (yourRank > 10 || yourRank === -1) {
// Calculate probability for personal best
var baseChance = 0;
// Find the minimum box type that can produce this rarity
var minBoxType = 'common';
for (var b = 0; b < boxTypes.length; b++) {
var boxChances = getRarityChance(boxTypes[b]);
if (boxChances[myBestRarity] > 0) {
minBoxType = boxTypes[b];
baseChance = boxChances[myBestRarity];
break;
}
}
// Scale probability by item size - larger items are much rarer
var sizeMultiplier = myBestSize * myBestSize;
var scaledChance = baseChance / sizeMultiplier;
var oneInX = Math.round(1 / scaledChance);
var yourBestText = new Text2('YOUR BEST: ' + myBestRarity.toUpperCase() + ' (' + myBestSize.toFixed(1) + 'x) - 1 entre ' + oneInX, {
size: 32,
fill: '#CCCCCC'
});
yourBestText.anchor.set(0.5, 0.5);
yourBestText.x = 1024;
yourBestText.y = 1200;
leaderboardContainer.addChild(yourBestText);
}
}
function showLeaderboard() {
currentScreen = 'leaderboard';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = true;
// Refresh online leaderboard data
loadOnlineLeaderboard();
setupLeaderboard();
}
function updateCollectionStats() {
// Update the collection statistics when shown
var totalItems = treasureTypes.length * rarityLevels.length;
var discoveredCount = 0;
for (var key in discoveredItems) {
if (discoveredItems[key] && !key.endsWith('_size')) {
discoveredCount++;
}
}
// Find and update stats text if it exists
for (var i = 0; i < collectionContainer.children.length; i++) {
var child = collectionContainer.children[i];
if (child.text && child.text.includes('Discovered:')) {
child.setText('Discovered: ' + discoveredCount + '/' + totalItems + ' (' + Math.round(discoveredCount / totalItems * 100) + '%)');
break;
}
}
}
function showOpening() {
currentScreen = 'opening';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = true;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
}
function openBox(boxType) {
if (playerCoins < getBoxPrice(boxType)) return;
playerCoins -= getBoxPrice(boxType);
updateCoinsDisplay();
var item = generateRandomItem(boxType);
showOpening();
openingAnimation = true;
openingContainer.removeChildren();
// Create opening animation
var openingBox = new Container();
var boxGraphics = openingBox.attachAsset('box_' + boxType, {
anchorX: 0.5,
anchorY: 0.5
});
openingBox.x = 1024;
openingBox.y = 1000;
openingContainer.addChild(openingBox);
// Add exit button to opening screen
var exitButton = new Container();
var exitButtonBg = exitButton.attachAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var exitButtonText = new Text2('EXIT', {
size: 40,
fill: '#FFFFFF'
});
exitButtonText.anchor.set(0.5, 0.5);
exitButton.addChild(exitButtonText);
exitButton.x = 1024;
exitButton.y = 1500;
exitButton.down = function () {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
};
openingContainer.addChild(exitButton);
LK.getSound('box_open').play();
// Animate box opening
tween(openingBox, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
revealTreasure(item, boxType);
}
});
}
function revealTreasure(item, boxType) {
var treasure = new TreasureItem(item.type, item.rarity, item.size);
treasure.x = 1024;
treasure.y = 600;
treasure.alpha = 0;
treasure.scaleX = 0.1;
treasure.scaleY = 0.1;
openingContainer.addChild(treasure);
// Rarity text with proper color
var rarityTextColors = {
common: '#FFFFFF',
rare: '#4169E1',
epic: '#9932CC',
legendary: '#FFD700',
mítico: '#FF0080',
cósmico: '#00FFFF',
imposible: '#FF6600'
};
var rarityText = new Text2(item.rarity.toUpperCase() + '!', {
size: 80,
fill: rarityTextColors[item.rarity]
});
rarityText.anchor.set(0.5, 0.5);
rarityText.x = 1024;
rarityText.y = 400;
rarityText.alpha = 0;
openingContainer.addChild(rarityText);
// Size text for larger items
if (item.size > 1.5) {
var sizeText = new Text2('SIZE: ' + item.size.toFixed(1) + 'x', {
size: 50,
fill: '#FFFF00'
});
sizeText.anchor.set(0.5, 0.5);
sizeText.x = 1024;
sizeText.y = 480;
sizeText.alpha = 0;
openingContainer.addChild(sizeText);
tween(sizeText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
}
// Rarity probability text - scaled by item size
var chances = getRarityChance(boxType);
var rarityChance = chances[item.rarity];
var baseOneInX = Math.round(1 / rarityChance);
// Scale probability by item size - larger items are much rarer
var sizeMultiplier = item.size * item.size; // Quadratic scaling
var scaledOneInX = Math.round(baseOneInX * sizeMultiplier);
var probabilityText = new Text2('1 entre ' + scaledOneInX, {
size: 50,
fill: '#CCCCCC'
});
probabilityText.anchor.set(0.5, 0.5);
probabilityText.x = 1024;
probabilityText.y = 750;
probabilityText.alpha = 0;
openingContainer.addChild(probabilityText);
// Value text
var valueText = new Text2('+' + treasure.value + ' coins', {
size: 60,
fill: '#FFD700'
});
valueText.anchor.set(0.5, 0.5);
valueText.x = 1024;
valueText.y = 800;
valueText.alpha = 0;
openingContainer.addChild(valueText);
// Animate treasure reveal
tween(treasure, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 800,
easing: tween.easeOut
});
tween(rarityText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
tween(probabilityText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
tween(valueText, {
alpha: 1
}, {
duration: 600,
easing: tween.easeOut
});
// Play appropriate sound
if (item.rarity === 'imposible' || item.rarity === 'cósmico' || item.rarity === 'mítico' || item.rarity === 'legendary' || item.rarity === 'epic') {
LK.getSound('rare_find').play();
} else {
LK.getSound('coin_sound').play();
}
// Flash effect for rare items
if (item.rarity === 'imposible') {
LK.effects.flashScreen(0xFF6600, 1500);
} else if (item.rarity === 'cósmico') {
LK.effects.flashScreen(0x00FFFF, 1200);
} else if (item.rarity === 'mítico') {
LK.effects.flashScreen(0xFF0080, 1000);
} else if (item.rarity === 'legendary') {
LK.effects.flashScreen(0xFFD700, 1000);
} else if (item.rarity === 'epic') {
LK.effects.flashScreen(0x9932CC, 800);
}
// Add to collection
var itemKey = item.type + '_' + item.rarity;
if (!discoveredItems[itemKey]) {
discoveredItems[itemKey] = true;
discoveredItems[itemKey + '_size'] = item.size;
safeStorageSet('discovered', discoveredItems);
// Update collection display
for (var i = 0; i < collectionSlots.length; i++) {
var slot = collectionSlots[i];
if (slot && slot.itemType === item.type && slot.rarity === item.rarity) {
slot.discover();
break;
}
}
}
// Update player difficulty based on box type
var boxDifficultyLevels = {
common: 'FÁCIL',
rare: 'NORMAL',
epic: 'DIFÍCIL',
legendary: 'MUY DIFÍCIL',
mítico: 'EXTREMO',
cósmico: 'IMPOSIBLE',
imposible: 'LEGENDARIO'
};
var boxDifficultyOrder = {
'FÁCIL': 1,
'NORMAL': 2,
'DIFÍCIL': 3,
'MUY DIFÍCIL': 4,
'EXTREMO': 5,
'IMPOSIBLE': 6,
'LEGENDARIO': 7
};
var currentBoxDifficulty = boxDifficultyLevels[boxType];
if (boxDifficultyOrder[currentBoxDifficulty] > boxDifficultyOrder[playerDifficulty]) {
playerDifficulty = currentBoxDifficulty;
safeStorageSet('playerDifficulty', playerDifficulty);
}
// Update leaderboard for significant finds
var rarityOrder = {
'imposible': 7,
'cósmico': 6,
'mítico': 5,
'legendary': 4,
'epic': 3,
'rare': 2,
'common': 1
};
var currentRarityLevel = rarityOrder[item.rarity];
var bestRarityLevel = rarityOrder[myBestRarity];
if (currentRarityLevel > bestRarityLevel || currentRarityLevel === bestRarityLevel && item.size > myBestSize) {
// Update personal best
myBestRarity = item.rarity;
myBestSize = item.size;
safeStorageSet('myBestRarity', myBestRarity);
safeStorageSet('myBestSize', myBestSize);
// Save to online leaderboard
var newEntry = {
name: playerName,
rarity: item.rarity,
size: item.size,
timestamp: Date.now()
};
saveToOnlineLeaderboard(newEntry);
}
// Add coins
playerCoins += treasure.value;
updateCoinsDisplay();
// Auto return to shop after 3 seconds
LK.setTimeout(function () {
openingAnimation = false;
showShop();
}, 3000);
}
function updateCoinsDisplay() {
coinsDisplay.setText('Coins: ' + playerCoins);
safeStorageSet('coins', playerCoins);
// Update box affordability when coins change
for (var i = 0; i < treasureBoxes.length; i++) {
var box = treasureBoxes[i];
if (box && box.update) {
box.update();
}
}
}
// Coin spawning system
var spawnedCoins = [];
var coinSpawnTimer = 0;
var coinSpawnInterval = 120; // Spawn every 2 seconds at 60fps
var coinCounter = 0;
function spawnRandomCoin() {
coinCounter++;
var isSpecial = coinCounter % 5 === 0; // Every 5th coin is special
var coin = new Container();
var coinGraphics = coin.attachAsset('treasure_coin', {
anchorX: 0.5,
anchorY: 0.5
});
// Random position at top of screen
coin.x = Math.random() * (2048 - 100) + 50;
coin.y = -50;
coin.speed = 2 + Math.random() * 3; // Random fall speed
coin.value = isSpecial ? 50 : 10;
coin.isSpecial = isSpecial;
coin.lastY = coin.y;
// Special coin effects
if (isSpecial) {
coinGraphics.tint = 0xFFD700; // Gold tint
coinGraphics.scaleX = 1.5;
coinGraphics.scaleY = 1.5;
} else {
coinGraphics.tint = 0xFFA500; // Orange tint
}
coin.down = function (x, y, obj) {
// Collect the coin
playerCoins += coin.value;
updateCoinsDisplay();
// Visual feedback
if (coin.isSpecial) {
LK.effects.flashScreen(0xFFD700, 500);
LK.getSound('rare_find').play();
} else {
LK.getSound('coin_sound').play();
}
// Remove coin from game
coin.destroy();
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
if (spawnedCoins[i] === coin) {
spawnedCoins.splice(i, 1);
break;
}
}
};
coin.update = function () {
coin.y += coin.speed;
// Remove if off screen
if (coin.lastY <= 2800 && coin.y > 2800) {
coin.destroy();
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
if (spawnedCoins[i] === coin) {
spawnedCoins.splice(i, 1);
break;
}
}
}
coin.lastY = coin.y;
};
game.addChild(coin);
spawnedCoins.push(coin);
}
// Initialize game
setupShop();
setupCollection();
setupLeaderboard();
setupNameInput();
// Initialize leaderboard display
setupLeaderboard();
// Start with name input if no name, otherwise menu
if (!playerName) {
currentScreen = 'nameInput';
nameInputContainer.visible = true;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
} else {
currentScreen = 'menu';
nameInputContainer.visible = false;
shopContainer.visible = false;
openingContainer.visible = false;
collectionContainer.visible = false;
leaderboardContainer.visible = false;
}
game.update = function () {
// Coin spawning system
coinSpawnTimer++;
if (coinSpawnTimer >= coinSpawnInterval) {
spawnRandomCoin();
coinSpawnTimer = 0;
// Vary the spawn interval slightly for randomness
coinSpawnInterval = 90 + Math.random() * 60; // Between 1.5 and 2.5 seconds
}
// Update all spawned coins
for (var i = spawnedCoins.length - 1; i >= 0; i--) {
var coin = spawnedCoins[i];
if (coin.update) {
coin.update();
}
}
};