Code edit (15 edits merged)
Please save this source code
User prompt
Agrega un asset de sonido al momento de obtener un personaje y otro al momento de obtener 10, no modifiques la estrcutura lógica
Code edit (7 edits merged)
Please save this source code
User prompt
Agrega música que suene constantemente en bucle
Code edit (1 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Character = Container.expand(function () {
var self = Container.call(this);
self.init = function (elementId, elementName, rarity, assetId, multiplier) {
// Obtenemos el color directamente de la configuración global
var rColor = GAME_CONFIG.RARITIES[rarity] ? GAME_CONFIG.RARITIES[rarity].colorNum : 0xffffff;
// 1. El Marco (Aura de fondo)
var frame = self.attachAsset('bg_character', {
anchorX: 0.5,
anchorY: 0.55
});
frame.scale.set(0.75, 1);
frame.tint = rColor;
frame.alpha = 0.6; // Resplandor sutil
// 2. El Gráfico del Personaje
var graphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
graphic.scale.set(0.5, 0.5);
// 3. El Nombre
var nameText = new Text2(elementName, {
size: 50,
fill: '#ffffff'
});
nameText.anchor.set(0.5, 0);
nameText.y = 130;
self.addChild(nameText);
// 4. La Rareza
var rarityText = new Text2('[' + rarity + ']', {
size: 45,
fill: rColor
});
rarityText.anchor.set(0.5, 0);
rarityText.y = 170;
self.addChild(rarityText);
// Guardamos referencias para modificarlas fácilmente en la galería
self.frameObj = frame;
self.graphicObj = graphic;
self.nameObj = nameText;
self.rarityObj = rarityText;
};
return self;
});
var FloatingText = Container.expand(function () {
var self = Container.call(this);
self.init = function (textValue, startX, startY, color) {
self.x = startX;
self.y = startY;
var txt = new Text2(textValue, {
size: 48,
fill: color || '#ffffff'
});
txt.anchor.set(0.5, 0.5);
self.addChild(txt);
tween(self, {
y: self.y - 150,
alpha: 0
}, {
duration: 800,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
// Clases de UI: Income Level (AHORA MÁS GRANDE)
var IncomeLevel = Container.expand(function () {
var self = Container.call(this);
self.levelIndex = 0;
self.baseIncome = 0;
self.baseCost = 0;
self.currentCost = 0;
self.init = function (levelIndex, baseIncome) {
self.levelIndex = levelIndex;
self.baseIncome = baseIncome;
self.baseCost = 50 * (levelIndex + 1);
var bg = self.attachAsset('upgrade_button', {
anchorX: 0.5,
anchorY: 0.5
});
// Escala aumentada de 1.5 a 2.0
bg.scale.set(2.0, 2.0);
// Textos aumentados y reposicionados
var levelText = new Text2('', {
size: 38,
fill: '#ffffff'
});
levelText.anchor.set(0.5, 0.5);
levelText.y = -25;
self.addChild(levelText);
self.levelText = levelText;
var costText = new Text2('', {
size: 30,
fill: '#ffffff'
});
costText.anchor.set(0.5, 0.5);
costText.y = 25;
self.addChild(costText);
self.costText = costText;
};
self.updateData = function (purchases) {
self.currentCost = Math.floor(self.baseCost * Math.pow(1.5, purchases));
self.costText.setText('Cost: ' + self.currentCost);
self.levelText.setText('Lvl ' + (self.levelIndex + 1) + ' (x' + purchases + '): +' + self.baseIncome + '/t');
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x6f6fdb
});
/****
* Game Code
****/
var GAME_CONFIG = {
BASE_GACHA_COST: 1000,
GACHA_COST_MULTIPLIER: 1.10,
FPS: 60,
SAVE_INTERVAL: 300,
MAX_EQUIPPED: 6,
ORBIT_RADIUS: 400,
ORBIT_SPEED: 0.008,
// NUEVO: Diccionario centralizado de propiedades por rareza
RARITIES: {
'Common': {
colorNum: 0xFFFFFF,
colorStr: '#FFFFFF',
scale: 0.70
},
'Uncommon': {
colorNum: 0x007700,
colorStr: '#00FF00',
scale: 0.70
},
'Rare': {
colorNum: 0x0078a4,
colorStr: '#00BFFF',
scale: 0.70
},
'Ultra-Rare': {
colorNum: 0x8A2BE2,
colorStr: '#8A2BE2',
scale: 0.70
},
'Special': {
colorNum: 0x1d6a60,
colorStr: '#FF1493',
scale: 1.0
},
'Legendary': {
colorNum: 0xd0b100,
colorStr: '#FFD700',
scale: 1.0
},
'Unique': {
colorNum: 0xFF0000,
colorStr: '#FF0000',
scale: 1.0
}
}
};
var characterDatabase = [{
id: 0,
name: 'Fire',
rarity: 'Common',
asset: 'fire_common',
multiplier: 2
}, {
id: 1,
name: 'Water',
rarity: 'Common',
asset: 'water_common',
multiplier: 2
}, {
id: 2,
name: 'Earth',
rarity: 'Common',
asset: 'earth_common',
multiplier: 2
}, {
id: 3,
name: 'Wind',
rarity: 'Common',
asset: 'wind_common',
multiplier: 2
}, {
id: 4,
name: 'Lightning',
rarity: 'Uncommon',
asset: 'lightning_uncommon',
multiplier: 3
}, {
id: 5,
name: 'Ice',
rarity: 'Uncommon',
asset: 'ice_uncommon',
multiplier: 3
}, {
id: 6,
name: 'Nature',
rarity: 'Uncommon',
asset: 'nature_uncommon',
multiplier: 3
}, {
id: 7,
name: 'Metal',
rarity: 'Uncommon',
asset: 'metal_uncommon',
multiplier: 3
}, {
id: 8,
name: 'Sand',
rarity: 'Uncommon',
asset: 'sand_uncommon',
multiplier: 3
}, {
id: 9,
name: 'Steam',
rarity: 'Uncommon',
asset: 'steam_uncommon',
multiplier: 3
}, {
id: 10,
name: 'Magma',
rarity: 'Rare',
asset: 'magma_rare',
multiplier: 4
}, {
id: 11,
name: 'Frost',
rarity: 'Rare',
asset: 'frost_rare',
multiplier: 4
}, {
id: 12,
name: 'Crystal',
rarity: 'Rare',
asset: 'crystal_rare',
multiplier: 4
}, {
id: 13,
name: 'Storm',
rarity: 'Rare',
asset: 'storm_rare',
multiplier: 4
}, {
id: 14,
name: 'Coral',
rarity: 'Rare',
asset: 'coral_rare',
multiplier: 4
}, {
id: 15,
name: 'Forest',
rarity: 'Rare',
asset: 'forest_rare',
multiplier: 4
}, {
id: 16,
name: 'Shadow',
rarity: 'Rare',
asset: 'shadow_rare',
multiplier: 4
}, {
id: 17,
name: 'Plasma',
rarity: 'Ultra-Rare',
asset: 'plasma_ultra',
multiplier: 5
}, {
id: 18,
name: 'Abyss',
rarity: 'Ultra-Rare',
asset: 'abyss_ultra',
multiplier: 5
}, {
id: 19,
name: 'Aurora',
rarity: 'Ultra-Rare',
asset: 'aurora_ultra',
multiplier: 5
}, {
id: 20,
name: 'Inferno',
rarity: 'Ultra-Rare',
asset: 'inferno_ultra',
multiplier: 5
}, {
id: 21,
name: 'Glacier',
rarity: 'Ultra-Rare',
asset: 'glacier_ultra',
multiplier: 5
}, {
id: 22,
name: 'Mirage',
rarity: 'Ultra-Rare',
asset: 'mirage_ultra',
multiplier: 5
}, {
id: 23,
name: 'Celestial',
rarity: 'Legendary',
asset: 'celestial_legendary',
multiplier: 7
}, {
id: 24,
name: 'Cosmic',
rarity: 'Legendary',
asset: 'cosmic_legendary',
multiplier: 7
}, {
id: 25,
name: 'Void',
rarity: 'Legendary',
asset: 'void_legendary',
multiplier: 7
}, {
id: 26,
name: 'Radiance',
rarity: 'Legendary',
asset: 'radiance_legendary',
multiplier: 7
}, {
id: 27,
name: 'Eclipse',
rarity: 'Legendary',
asset: 'eclipse_legendary',
multiplier: 7
}, {
id: 28,
name: 'Genesis',
rarity: 'Unique',
asset: 'genesis_unique',
multiplier: 10
}, {
id: 29,
name: 'Apocalypse',
rarity: 'Unique',
asset: 'apocalypse_unique',
multiplier: 10
}, {
id: 30,
name: 'Paradox',
rarity: 'Unique',
asset: 'paradox_unique',
multiplier: 10
}, {
id: 31,
name: 'Nova',
rarity: 'Special',
asset: 'nova_special',
multiplier: 6
}, {
id: 32,
name: 'Nebula',
rarity: 'Special',
asset: 'nebula_special',
multiplier: 6
}, {
id: 33,
name: 'Titan',
rarity: 'Special',
asset: 'titan_special',
multiplier: 6
}, {
id: 34,
name: 'Phantom',
rarity: 'Special',
asset: 'phantom_special',
multiplier: 6
}, {
id: 35,
name: 'Sphinx',
rarity: 'Special',
asset: 'sphinx_special',
multiplier: 6
}, {
id: 36,
name: 'Oracle',
rarity: 'Special',
asset: 'oracle_special',
multiplier: 6
}, {
id: 37,
name: 'Dust',
rarity: 'Uncommon',
asset: 'dust_uncommon',
multiplier: 3
}, {
id: 38,
name: 'Spore',
rarity: 'Uncommon',
asset: 'spore_uncommon',
multiplier: 3
}, {
id: 39,
name: 'Tectonic',
rarity: 'Rare',
asset: 'tectonic_rare',
multiplier: 4
}, {
id: 40,
name: 'Biosphere',
rarity: 'Ultra-Rare',
asset: 'biosphere_ultra',
multiplier: 5
}, {
id: 41,
name: 'Pulsar',
rarity: 'Special',
asset: 'pulsar_special',
multiplier: 6
}, {
id: 42,
name: 'Antimatter',
rarity: 'Legendary',
asset: 'antimatter_legendary',
multiplier: 7
}, {
id: 43,
name: 'Singularity',
rarity: 'Legendary',
asset: 'singularity_legendary',
multiplier: 7
}, {
id: 44,
name: 'Entropy',
rarity: 'Unique',
asset: 'entropy_unique',
multiplier: 10
}];
// Definimos los dropRates base SIN los IDs hardcodeados
var dropRates = [{
rarity: 'Common',
chance: 45,
ids: []
}, {
rarity: 'Uncommon',
chance: 20,
ids: []
}, {
rarity: 'Rare',
chance: 15,
ids: []
}, {
rarity: 'Ultra-Rare',
chance: 10,
ids: []
}, {
rarity: 'Special',
chance: 6,
ids: []
}, {
rarity: 'Legendary',
chance: 3,
ids: []
}, {
rarity: 'Unique',
chance: 1,
ids: []
}];
var galleryDisplayOrder = [];
// Función para inicializar los datos dinámicamente
function initializeGameData() {
// 1. Llenar los IDs del Gacha automáticamente
for (var i = 0; i < characterDatabase.length; i++) {
var charData = characterDatabase[i];
for (var j = 0; j < dropRates.length; j++) {
if (dropRates[j].rarity === charData.rarity) {
dropRates[j].ids.push(charData.id);
break;
}
}
}
// 2. Generar el orden de la Galería (Por Rareza y luego por ID)
var rarityWeights = {
'Common': 1,
'Uncommon': 2,
'Rare': 3,
'Ultra-Rare': 4,
'Special': 5,
'Legendary': 6,
'Unique': 7
};
// Clonamos la base de datos para no alterar la original y la ordenamos
var sortedCharacters = characterDatabase.slice().sort(function (a, b) {
if (rarityWeights[a.rarity] !== rarityWeights[b.rarity]) {
return rarityWeights[a.rarity] - rarityWeights[b.rarity];
}
return a.id - b.id;
});
// Extraemos solo los IDs ordenados para la galería
for (var k = 0; k < sortedCharacters.length; k++) {
galleryDisplayOrder.push(sortedCharacters[k].id);
}
}
// Ejecutamos la inicialización
initializeGameData();
// Función de ayuda para obtener IDs por rareza (Útil para el Pity System)
function getIdsByRarity(targetRarity) {
for (var i = 0; i < dropRates.length; i++) {
if (dropRates[i].rarity === targetRarity) {
return dropRates[i].ids;
}
}
return [];
}
var gameState = {
credits: 0,
incomePerTick: 1,
collectedCharacters: {},
totalCharactersCollected: 0,
incomeLevels: [],
tickCounter: 0,
equippedCharacters: [],
pityCounter: 0 // Contador de Lástima
};
// Estado temporal para controlar la vista de la galería
var galleryState = {
currentPage: 0,
itemsPerPage: 9,
// Cuadrícula de 3x3
selectedElementId: 0
};
// --- Funciones Base de Estado ---
function getGachaCost() {
return Math.floor(GAME_CONFIG.BASE_GACHA_COST * Math.pow(GAME_CONFIG.GACHA_COST_MULTIPLIER, gameState.totalCharactersCollected));
}
function recalculateIncome() {
// Recalcula incomePerTick desde cero a partir del estado real del juego.
// Esto evita que el income guardado se desincronice con los personajes y upgrades.
var total = 1; // Base income
// Sumar aportes de personajes colectados
for (var charId in gameState.collectedCharacters) {
if (gameState.collectedCharacters[charId]) {
var cData = characterDatabase[parseInt(charId)];
if (cData) {
total += cData.multiplier;
}
}
}
// Sumar aportes de upgrades comprados
// Cada upgrade de nivel i comprado N veces aporta baseIncome * N
// baseIncome por nivel: [1, 2, 3, 5, 10, 20, 50, 100, 200, 300]
var baseIncomes = [1, 2, 3, 5, 10, 20, 50, 100, 200, 300];
for (var lvl = 0; lvl < gameState.incomeLevels.length; lvl++) {
total += baseIncomes[lvl] * gameState.incomeLevels[lvl];
}
gameState.incomePerTick = total;
}
function loadGame() {
gameState.collectedCharacters = {};
gameState.incomeLevels = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
gameState.equippedCharacters = [];
if (storage.credits !== undefined) {
gameState.credits = storage.credits;
gameState.totalCharactersCollected = storage.totalCharactersCollected;
gameState.tickCounter = storage.tickCounter || 0;
gameState.pityCounter = storage.pityCounter || 0;
var collectedIds = (storage.collectedCharacterIds || '').split(',');
for (var i = 0; i < collectedIds.length; i++) {
if (collectedIds[i] !== '') {
gameState.collectedCharacters[parseInt(collectedIds[i])] = true;
}
}
var upgradedLevels = (storage.upgradedLevelCounts || '').split(',');
for (var j = 0; j < upgradedLevels.length; j++) {
if (upgradedLevels[j] !== '') {
gameState.incomeLevels[j] = parseInt(upgradedLevels[j]) || 0;
}
}
var equippedStr = storage.equippedCharactersIds || '';
if (equippedStr !== '') {
var eqSplit = equippedStr.split(',');
for (var k = 0; k < eqSplit.length; k++) {
if (eqSplit[k] !== '') {
var eqId = parseInt(eqSplit[k]);
// Solo restaurar si el ID existe en la DB y fue colectado
if (characterDatabase[eqId] && gameState.collectedCharacters[eqId]) {
gameState.equippedCharacters.push(eqId);
}
}
}
}
// Recalcular income desde cero en lugar de confiar en el valor guardado
recalculateIncome();
}
}
function saveGame() {
storage.credits = gameState.credits;
// incomePerTick NO se guarda: se recalcula al cargar desde personajes y upgrades
storage.totalCharactersCollected = gameState.totalCharactersCollected;
storage.tickCounter = gameState.tickCounter;
storage.pityCounter = gameState.pityCounter;
var collectedIds = '';
for (var charId in gameState.collectedCharacters) {
if (gameState.collectedCharacters[charId]) {
collectedIds += charId + ',';
}
}
storage.collectedCharacterIds = collectedIds;
var upgradedLevels = '';
for (var i = 0; i < gameState.incomeLevels.length; i++) {
upgradedLevels += gameState.incomeLevels[i] + ',';
}
storage.upgradedLevelCounts = upgradedLevels;
var equippedIds = '';
for (var e = 0; e < gameState.equippedCharacters.length; e++) {
equippedIds += gameState.equippedCharacters[e] + ',';
}
storage.equippedCharactersIds = equippedIds;
}
loadGame();
// --- Play Background Music ---
LK.playMusic('background_music', {
loop: true
});
// --- UI Construction ---
var creditsText = new Text2('Credits: 0', {
size: 100,
fill: '#FFD700'
});
creditsText.anchor.set(0.5, 0);
creditsText.x = 1024;
creditsText.y = 50;
game.addChild(creditsText);
var incomeText = new Text2('Income: 1/tick', {
size: 80,
fill: '#00FF00'
});
incomeText.anchor.set(0.5, 0);
incomeText.x = 1024;
incomeText.y = 160;
game.addChild(incomeText);
var collectionText = new Text2('Collection: 0/' + characterDatabase.length, {
size: 60,
fill: '#87CEEB'
});
collectionText.anchor.set(0.5, 0);
collectionText.x = 1024;
collectionText.y = 250;
game.addChild(collectionText);
// --- SISTEMA DE ÓRBITA (A LA DERECHA) ---
var orbitContainer = new Container();
orbitContainer.x = 1536; // 3/4 de la pantalla
orbitContainer.y = 1366; // Centro vertical
game.addChild(orbitContainer);
var orbitingSprites = [];
var orbitAngle = 0;
function updateEquippedDisplay() {
while (orbitContainer.children.length > 0) {
orbitContainer.children[0].destroy();
}
orbitingSprites = [];
for (var i = 0; i < gameState.equippedCharacters.length; i++) {
var charId = gameState.equippedCharacters[i];
var charData = characterDatabase[charId];
var sprite = LK.getAsset(charData.asset, {
anchorX: 0.5,
anchorY: 0.5
});
sprite.scale.set(0.55, 0.55);
orbitContainer.addChild(sprite);
orbitingSprites.push(sprite);
}
}
updateEquippedDisplay();
// --- Manual Clicker Core (A LA DERECHA) ---
var coreGraphic = LK.getAsset('core_crystal', {
anchorX: 0.5,
anchorY: 0.5
});
var coreButton = new Container();
coreButton.addChild(coreGraphic);
coreButton.x = 1536; // 3/4 de la pantalla
coreButton.y = 1366; // Centro vertical
game.addChild(coreButton);
var coreText = new Text2('TAP', {
size: 50,
fill: '#ffffff'
});
coreText.anchor.set(0.5, 0.5);
coreButton.addChild(coreText);
// --- Botón Gacha Individual (Movido a la Izquierda) ---
var gachaBtnGraphic = LK.getAsset('gacha_button', {
anchorX: 0.5,
anchorY: 0.5
});
gachaBtnGraphic.scale.set(1.6, 1.8);
var gachaButton = new Container();
gachaButton.addChild(gachaBtnGraphic);
gachaButton.x = 600; // Antes 1024
gachaButton.y = 2500;
game.addChild(gachaButton);
var gachaText = new Text2('PULL (' + getGachaCost() + ')', {
size: 55,
fill: '#ffffff'
});
gachaText.anchor.set(0.5, 0.5);
gachaText.y = -20;
gachaButton.addChild(gachaText);
var pityText = new Text2('Pity: 0/10', {
size: 40,
fill: '#FFD700'
});
pityText.anchor.set(0.5, 0.5);
pityText.y = 30;
gachaButton.addChild(pityText);
var gachaEnabled = false;
// --- NUEVO: Botón Gacha x10 (A la Derecha) ---
var gacha10BtnGraphic = LK.getAsset('gacha_button', {
anchorX: 0.5,
anchorY: 0.5
});
gacha10BtnGraphic.scale.set(1.6, 1.8);
var gacha10Button = new Container();
gacha10Button.addChild(gacha10BtnGraphic);
gacha10Button.x = 1448;
gacha10Button.y = 2500;
game.addChild(gacha10Button);
var gacha10Text = new Text2('10x PULL', {
size: 55,
fill: '#ffffff'
});
gacha10Text.anchor.set(0.5, 0.5);
gacha10Text.y = -20;
gacha10Button.addChild(gacha10Text);
var pity10Text = new Text2('1 Guaranteed!', {
size: 40,
fill: '#00FF00'
});
pity10Text.anchor.set(0.5, 0.5);
pity10Text.y = 30;
gacha10Button.addChild(pity10Text);
var gacha10Enabled = false;
// Gallery Button
var galleryBtnGraphic = LK.getAsset('gallery_button', {
anchorX: 0.5,
anchorY: 0.5
});
var galleryButton = new Container();
galleryButton.addChild(galleryBtnGraphic);
galleryButton.x = 1800;
galleryButton.y = 500;
game.addChild(galleryButton);
var galleryText = new Text2('GALLERY', {
size: 50,
fill: '#ffffff'
});
galleryText.anchor.set(0.5, 0.5);
galleryButton.addChild(galleryText);
// Debug Reset Button
/*
var debugBtnGraphic = LK.getAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var debugButton = new Container();
debugButton.addChild(debugBtnGraphic);
debugButton.x = 300;
debugButton.y = 100;
game.addChild(debugButton);
var debugText = new Text2('RESET', {
size: 40,
fill: '#ff4444'
});
debugText.anchor.set(0.5, 0.5);
debugButton.addChild(debugText);*/
// Upgrade Levels Container (A LA IZQUIERDA Y MÁS GRANDES)
var levelContainers = [];
var levelStartY = 500; // Empezamos un poco más arriba
var levelSpacing = 180; // Más espacio vertical porque los botones crecieron
for (var i = 0; i < 10; i++) {
var levelContainer = new IncomeLevel();
levelContainer.init(i, [1, 2, 3, 5, 10, 20, 50, 100, 200, 300][i]);
levelContainer.updateData(gameState.incomeLevels[i]);
levelContainer.x = 512; // 1/4 de la pantalla hacia la izquierda
levelContainer.y = levelStartY + i * levelSpacing;
game.addChild(levelContainer);
levelContainers.push(levelContainer);
}
// Modal Variables
var modalOpen = false;
var modalContainer = null;
// --- Funciones Lógicas ---
function openGallery() {
if (modalOpen) {
return;
}
modalOpen = true;
galleryState.currentPage = 0;
galleryState.selectedElementId = 0;
// Buscar el primer personaje recolectado para mostrarlo por defecto al abrir
for (var s = 0; s < characterDatabase.length; s++) {
if (gameState.collectedCharacters[s]) {
galleryState.selectedElementId = s;
break;
}
}
modalContainer = new Container();
var modalBg = LK.getAsset('modal_bg', {
anchorX: 0.5,
anchorY: 0.5
});
modalContainer.addChild(modalBg);
modalContainer.x = 1024;
modalContainer.y = 1366;
var galleryTitle = new Text2('Element Gallery', {
size: 80,
fill: '#FFD700'
});
galleryTitle.anchor.set(0.5, 0);
galleryTitle.x = 0;
galleryTitle.y = -1100;
modalContainer.addChild(galleryTitle);
var closeBtnGraphic = LK.getAsset('modal_close_btn', {
anchorX: 0.5,
anchorY: 0.5
});
var closeBtn = new Container();
closeBtn.addChild(closeBtnGraphic);
closeBtn.x = 800;
closeBtn.y = -1050;
modalContainer.addChild(closeBtn);
var closeBtnText = new Text2('X', {
size: 60,
fill: '#ffffff'
});
closeBtnText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeBtnText);
closeBtn.down = function () {
closeModal();
LK.getSound('ui_click').play();
};
// Contenedor dinámico que se refresca
var contentContainer = new Container();
modalContainer.addChild(contentContainer);
function renderGalleryContent() {
while (contentContainer.children.length > 0) {
contentContainer.children[0].destroy();
}
var totalItems = galleryDisplayOrder.length;
var totalPages = Math.ceil(totalItems / galleryState.itemsPerPage);
var startIndex = galleryState.currentPage * galleryState.itemsPerPage;
var endIndex = Math.min(startIndex + galleryState.itemsPerPage, totalItems);
// --- PANEL IZQUIERDO: CUADRÍCULA 3x3 ---
var gridStartX = -750;
var gridStartY = -700;
var spacing = 400;
for (var i = startIndex; i < endIndex; i++) {
var localIndex = i - startIndex;
var col = localIndex % 3;
var row = Math.floor(localIndex / 3);
// AHORA BUSCAMOS EL ID BASADO EN EL NUEVO ORDEN
var actualCharId = galleryDisplayOrder[i];
var charData = characterDatabase[actualCharId];
var isCollected = gameState.collectedCharacters[actualCharId];
var displayChar = new Character();
var displayName = isCollected ? charData.name : "???";
// Siempre revelamos la rareza (Spoiler visual)
var displayRarity = charData.rarity;
displayChar.init(actualCharId, displayName, displayRarity, charData.asset, charData.multiplier);
displayChar.x = gridStartX + col * spacing;
displayChar.y = gridStartY + row * (spacing * 1.2);
// Efecto Silueta Inteligente
if (!isCollected) {
displayChar.graphicObj.tint = 0x000000; // Personaje en negro
displayChar.nameObj.fill = '#555555'; // Letras del nombre en gris
displayChar.frameObj.alpha = 0.05; // Apagamos casi todo el brillo del marco
}
// Indicador visual de elemento seleccionado
if (galleryState.selectedElementId === actualCharId) {
displayChar.scale.set(1.15, 1.15); // Ligeramente más grande al seleccionarlo
}
(function (idToSelect) {
displayChar.down = function () {
if (galleryState.selectedElementId !== idToSelect) {
galleryState.selectedElementId = idToSelect;
LK.getSound('ui_click').play();
renderGalleryContent();
}
};
})(actualCharId);
contentContainer.addChild(displayChar);
}
var pageText = new Text2('Page ' + (galleryState.currentPage + 1) + ' / ' + totalPages, {
size: 80,
fill: '#FFFFFF'
});
pageText.anchor.set(0.5, 0.5);
pageText.x = -300;
pageText.y = 800;
contentContainer.addChild(pageText);
var collectionStatus = new Text2('Collected: ' + gameState.totalCharactersCollected + '/' + characterDatabase.length, {
size: 60,
fill: '#87CEEB'
});
collectionStatus.anchor.set(0.5, 0.5);
collectionStatus.x = -300;
collectionStatus.y = 900;
contentContainer.addChild(collectionStatus);
if (galleryState.currentPage > 0) {
var prevBtn = LK.getAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
prevBtn.scale.set(0.6, 0.8);
prevBtn.x = -550;
prevBtn.y = 650;
var prevTxt = new Text2('< PREV', {
size: 70,
fill: '#FFF'
});
prevTxt.anchor.set(0.5, 0.5);
prevBtn.addChild(prevTxt);
prevBtn.down = function () {
galleryState.currentPage--;
LK.getSound('ui_click').play();
renderGalleryContent();
};
contentContainer.addChild(prevBtn);
}
if (galleryState.currentPage < totalPages - 1) {
var nextBtn = LK.getAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
nextBtn.scale.set(0.6, 0.8);
nextBtn.x = -50;
nextBtn.y = 650;
var nextTxt = new Text2('NEXT >', {
size: 70,
fill: '#FFF'
});
nextTxt.anchor.set(0.5, 0.5);
nextBtn.addChild(nextTxt);
nextBtn.down = function () {
galleryState.currentPage++;
LK.getSound('ui_click').play();
renderGalleryContent();
};
contentContainer.addChild(nextBtn);
}
// --- PANEL DERECHO: DETALLES Y EQUIPAR ---
var rightPanelX = 550;
var detailData = characterDatabase[galleryState.selectedElementId];
var isDetailCollected = gameState.collectedCharacters[galleryState.selectedElementId];
if (detailData) {
var bigGraphic = LK.getAsset(detailData.asset, {
anchorX: 0.5,
anchorY: 0.5
});
bigGraphic.scale.set(1.35, 1.35);
bigGraphic.x = rightPanelX;
bigGraphic.y = -250;
if (!isDetailCollected) {
bigGraphic.tint = 0x000000;
}
contentContainer.addChild(bigGraphic);
var detailNameText = isDetailCollected ? detailData.name : "???";
var detailName = new Text2(detailNameText, {
size: 80,
fill: '#FFF'
});
detailName.anchor.set(0.5, 0);
detailName.x = rightPanelX;
detailName.y = 200;
contentContainer.addChild(detailName);
// Mapa de colores String para la UI de detalles
var rarityColorHexStr = GAME_CONFIG.RARITIES[detailData.rarity] ? GAME_CONFIG.RARITIES[detailData.rarity].colorStr : '#FFFFFF';
var detailRarity = new Text2('[' + detailData.rarity + ']', {
size: 60,
fill: rarityColorHexStr
});
detailRarity.anchor.set(0.5, 0);
detailRarity.x = rightPanelX;
detailRarity.y = 280;
contentContainer.addChild(detailRarity);
if (isDetailCollected) {
var incomeInfo = new Text2('Income Boost: +' + detailData.multiplier + '/tick', {
size: 55,
fill: '#00FF00'
});
incomeInfo.anchor.set(0.5, 0);
incomeInfo.x = rightPanelX;
incomeInfo.y = 350;
contentContainer.addChild(incomeInfo);
}
// LÓGICA DEL BOTÓN EQUIPAR
var orbitStatusText = new Text2('Orbiting: ' + gameState.equippedCharacters.length + ' / ' + GAME_CONFIG.MAX_EQUIPPED, {
size: 60,
fill: '#87CEEB'
});
orbitStatusText.anchor.set(0.5, 0);
orbitStatusText.x = rightPanelX;
orbitStatusText.y = 450;
contentContainer.addChild(orbitStatusText);
if (isDetailCollected) {
var isEquipped = gameState.equippedCharacters.indexOf(galleryState.selectedElementId) > -1;
var equipBtnGraphic = LK.getAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
equipBtnGraphic.scale.set(1.5, 1.2);
equipBtnGraphic.tint = isEquipped ? 0xFF4444 : 0x32CD32;
var equipBtn = new Container();
equipBtn.addChild(equipBtnGraphic);
equipBtn.x = rightPanelX;
equipBtn.y = 650;
var equipBtnText = new Text2(isEquipped ? 'UNEQUIP' : 'EQUIP', {
size: 50,
fill: '#ffffff'
});
equipBtnText.anchor.set(0.5, 0.5);
equipBtn.addChild(equipBtnText);
equipBtn.down = function () {
if (isEquipped) {
var index = gameState.equippedCharacters.indexOf(galleryState.selectedElementId);
gameState.equippedCharacters.splice(index, 1);
LK.getSound('ui_click').play();
} else {
if (gameState.equippedCharacters.length >= GAME_CONFIG.MAX_EQUIPPED) {
// Órbita llena: mostrar texto de aviso en lugar de desplazar silenciosamente
var fullMsg = new FloatingText('Orbit full! Unequip one first.', 1024, 1366, '#FF4444');
game.addChild(fullMsg);
return;
}
gameState.equippedCharacters.push(galleryState.selectedElementId);
LK.getSound('ui_click').play();
}
updateEquippedDisplay();
saveGame();
renderGalleryContent();
};
contentContainer.addChild(equipBtn);
} else {
var lockText = new Text2('LOCKED', {
size: 50,
fill: '#FF4444'
});
lockText.anchor.set(0.5, 0.5);
lockText.x = rightPanelX;
lockText.y = 400;
contentContainer.addChild(lockText);
}
}
}
renderGalleryContent();
game.addChild(modalContainer);
}
function closeModal() {
if (modalContainer) {
modalContainer.destroy();
modalOpen = false;
}
}
// --- Lógica de tirada de Gacha centralizada ---
// Retorna una rareza de pity (Special, Legendary o Unique)
function rollPityRarity() {
var pityRoll = Math.random() * 100;
if (pityRoll <= 60) {
return {
rarity: 'Special',
ids: getIdsByRarity('Special')
};
} else if (pityRoll <= 90) {
return {
rarity: 'Legendary',
ids: getIdsByRarity('Legendary')
};
} else {
return {
rarity: 'Unique',
ids: getIdsByRarity('Unique')
};
}
}
// Tirada normal con soft pity: a partir del pull 6, la probabilidad de rarezas altas sube gradualmente
function rollNormalRarity() {
var softBonus = Math.max(0, gameState.pityCounter - 5) * 3;
var dynamicRates = [];
for (var i = 0; i < dropRates.length; i++) {
var rate = {
rarity: dropRates[i].rarity,
ids: dropRates[i].ids,
chance: dropRates[i].chance
};
if (rate.rarity === 'Special') {
rate.chance = Math.min(30, 6 + softBonus);
} else if (rate.rarity === 'Legendary') {
rate.chance = Math.min(20, 3 + softBonus * 0.5);
} else if (rate.rarity === 'Unique') {
rate.chance = Math.min(10, 1 + softBonus * 0.25);
}
dynamicRates.push(rate);
}
var roll = Math.random() * 100;
var cumulativeChance = 0;
for (var j = 0; j < dynamicRates.length; j++) {
cumulativeChance += dynamicRates[j].chance;
if (roll <= cumulativeChance) {
return dynamicRates[j];
}
}
return dynamicRates[0];
}
// Registra un personaje obtenido y retorna si es nuevo
function registerCharacterObtained(charId) {
var charData = characterDatabase[charId];
if (!gameState.collectedCharacters[charId]) {
gameState.collectedCharacters[charId] = true;
gameState.totalCharactersCollected++;
gameState.incomePerTick += charData.multiplier;
return true;
}
return false;
}
function performGachaPull() {
var currentCost = getGachaCost();
if (gameState.credits < currentCost) {
return;
}
gameState.credits -= currentCost;
gameState.pityCounter++;
var selectedRarity = null;
// Hard Pity en 10: garantiza rareza alta
if (gameState.pityCounter >= 10) {
selectedRarity = rollPityRarity();
gameState.pityCounter = 0;
} else {
// Soft pity: probabilidades aumentan gradualmente desde pull 6
selectedRarity = rollNormalRarity();
if (selectedRarity.rarity === 'Special' || selectedRarity.rarity === 'Legendary' || selectedRarity.rarity === 'Unique') {
gameState.pityCounter = 0;
}
}
var characterIdArray = selectedRarity.ids;
var selectedCharacterId = characterIdArray[Math.floor(Math.random() * characterIdArray.length)];
var wasNew = registerCharacterObtained(selectedCharacterId);
var charData = characterDatabase[selectedCharacterId];
saveGame();
LK.getSound('gacha_pull').play();
if (wasNew) {
LK.getSound('gacha_pull_success').play();
}
modalOpen = true; // Bloquear UI durante la animación del resultado
// Consumimos los efectos visuales desde la configuración global
var currentEffect = GAME_CONFIG.RARITIES[charData.rarity] || {
colorNum: 0xFFFFFF,
scale: 0.70
};
var resultMessage = wasNew ? 'NEW: ' + charData.name + '!' : 'Duplicate: ' + charData.name;
var resultColor = wasNew ? '#2d633b' : '#b89e14';
var resultContainer = new Container();
var resultBg = LK.getAsset('pull_bg', {
anchorX: 0.5,
anchorY: 0.5
});
resultContainer.addChild(resultBg);
resultContainer.x = 1024;
resultContainer.y = 1366;
resultContainer.scale.set(0.1, 0.1);
tween(resultContainer, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
var aura = LK.getAsset('core_crystal', {
anchorX: 0.5,
anchorY: 0.5
});
aura.tint = currentEffect.colorNum;
var auraScaleFactor = currentEffect.scale * 2.5;
aura.scale.set(auraScaleFactor, auraScaleFactor);
aura.alpha = 0.5;
resultContainer.addChild(aura);
tween(aura, {
rotation: Math.PI * 2
}, {
duration: 2000
});
var resultGraphic = LK.getAsset(charData.asset, {
anchorX: 0.5,
anchorY: 0.5
});
var scaleTarget = currentEffect.scale;
resultGraphic.scale.set(0.1, 0.1);
tween(resultGraphic, {
scaleX: scaleTarget + 0.05,
scaleY: scaleTarget + 0.05
}, {
duration: 250,
onFinish: function onFinish() {
tween(resultGraphic, {
scaleX: scaleTarget,
scaleY: scaleTarget
}, {
duration: 150
});
}
});
resultGraphic.y = 0;
resultContainer.addChild(resultGraphic);
var safePadding = 720 * scaleTarget / 2 + 80;
var resultTitle = new Text2(resultMessage, {
size: 150,
fill: resultColor
});
resultTitle.anchor.set(0.5, 0.5);
resultTitle.y = -safePadding;
resultContainer.addChild(resultTitle);
var rarityDisplayColor = GAME_CONFIG.RARITIES[charData.rarity] ? GAME_CONFIG.RARITIES[charData.rarity].colorStr : '#FFFFFF';
var resultRarity = new Text2('[' + charData.rarity + ']', {
size: 90,
fill: rarityDisplayColor
});
resultRarity.anchor.set(0.5, 0.5);
resultRarity.y = safePadding;
resultContainer.addChild(resultRarity);
game.addChild(resultContainer);
LK.setTimeout(function () {
tween(resultContainer, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
resultContainer.destroy();
modalOpen = false; // Liberar UI al cerrar el resultado
}
});
}, 2000);
}
function performGachaPull10() {
var singleCost = getGachaCost();
var totalCost = singleCost * 10;
if (gameState.credits < totalCost) {
return;
}
gameState.credits -= totalCost;
var pullResults = [];
// 1. Las 9 tiradas normales (con soft pity activo)
for (var i = 0; i < 9; i++) {
gameState.pityCounter++;
var selectedRarity = rollNormalRarity();
if (selectedRarity.rarity === 'Special' || selectedRarity.rarity === 'Legendary' || selectedRarity.rarity === 'Unique') {
gameState.pityCounter = 0;
}
var charIdArray = selectedRarity.ids;
var selectedCharId = charIdArray[Math.floor(Math.random() * charIdArray.length)];
pullResults.push(characterDatabase[selectedCharId]);
registerCharacterObtained(selectedCharId);
}
// 2. La 10ª tirada (Lástima Garantizada — siempre rareza alta)
var pityRarity = rollPityRarity();
var pityCharIdArray = pityRarity.ids;
var pityCharId = pityCharIdArray[Math.floor(Math.random() * pityCharIdArray.length)];
pullResults.push(characterDatabase[pityCharId]);
registerCharacterObtained(pityCharId);
// Reiniciamos el pity porque acabamos de dar uno garantizado
gameState.pityCounter = 0;
saveGame();
LK.getSound('gacha_pull').play();
showMultiPullResults(pullResults);
}
function showMultiPullResults(results) {
modalOpen = true; // Bloquea la UI de fondo
var resultContainer = new Container();
var modalBg = LK.getAsset('modal_bg', {
anchorX: 0.5,
anchorY: 0.5
});
resultContainer.addChild(modalBg);
resultContainer.x = 1024;
resultContainer.y = 1366;
resultContainer.scale.set(0.1, 0.1);
tween(resultContainer, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
var titleText = new Text2('10x PULL RESULTS', {
size: 100,
fill: '#FFD700'
});
titleText.anchor.set(0.5, 0.5);
titleText.y = -900;
resultContainer.addChild(titleText);
// Configuramos la cuadrícula (2 filas x 5 columnas)
var startX = -600;
var startY = -400;
var spacingX = 300;
var spacingY = 400;
for (var i = 0; i < results.length; i++) {
var charData = results[i];
var col = i % 5;
var row = Math.floor(i / 5);
// Si es de rareza alta, le ponemos un aura detrás
if (charData.rarity === 'Special' || charData.rarity === 'Legendary' || charData.rarity === 'Unique') {
var aura = LK.getAsset('core_crystal', {
anchorX: 0.5,
anchorY: 0.5
});
aura.x = startX + col * spacingX;
aura.y = startY + row * spacingY;
aura.scale.set(1.5, 1.5);
aura.tint = 0xFFD700;
aura.alpha = 0.5;
resultContainer.addChild(aura);
tween(aura, {
rotation: Math.PI * 2
}, {
duration: 2000
});
}
var charGraphic = LK.getAsset(charData.asset, {
anchorX: 0.5,
anchorY: 0.5
});
charGraphic.x = startX + col * spacingX;
charGraphic.y = startY + row * spacingY;
charGraphic.scale.set(0.35, 0.35); // Más pequeños para que quepan
resultContainer.addChild(charGraphic);
}
// Botón para cerrar
var closeBtnGraphic = LK.getAsset('button_bg', {
anchorX: 0.5,
anchorY: 0.5
});
var closeBtn = new Container();
closeBtn.addChild(closeBtnGraphic);
closeBtn.y = 800;
resultContainer.addChild(closeBtn);
var closeText = new Text2('CONTINUE', {
size: 60,
fill: '#FFFFFF'
});
closeText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeText);
closeBtn.down = function () {
LK.getSound('ui_click').play();
tween(resultContainer, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 200,
onFinish: function onFinish() {
resultContainer.destroy();
modalOpen = false; // Liberamos la UI
}
});
};
game.addChild(resultContainer);
}
function upgradeIncomeLevel(levelIndex) {
var level = levelContainers[levelIndex];
if (gameState.credits >= level.currentCost) {
gameState.credits -= level.currentCost;
gameState.incomeLevels[levelIndex]++;
gameState.incomePerTick += level.baseIncome;
level.updateData(gameState.incomeLevels[levelIndex]);
saveGame();
LK.getSound('level_up').play();
// Confirmar visualmente la compra
var floatUpgrade = new FloatingText('+' + level.baseIncome + '/tick', level.x + (Math.random() * 60 - 30), level.y - 60, '#00FF00');
game.addChild(floatUpgrade);
}
}
// --- Event Handlers Directos ---
gachaButton.down = function () {
if (modalOpen) {
return;
}
if (gachaEnabled) {
performGachaPull();
LK.getSound('ui_click').play();
}
};
gacha10Button.down = function () {
if (modalOpen) {
return;
}
if (gacha10Enabled) {
performGachaPull10();
}
};
galleryButton.down = function () {
if (modalOpen) {
return;
}
openGallery();
LK.getSound('ui_click').play();
};
/*
debugButton.down = function () {
if (modalOpen) {
return;
}
gameState.credits = 0;
gameState.incomePerTick = 1;
gameState.collectedCharacters = {};
gameState.totalCharactersCollected = 0;
gameState.incomeLevels = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
gameState.equippedCharacters = [];
for (var i = 0; i < levelContainers.length; i++) {
levelContainers[i].updateData(0);
}
updateEquippedDisplay();
saveGame();
LK.getSound('ui_click').play();
};
*/
coreButton.down = function () {
if (modalOpen) {
return;
}
var clickGain = 1 + Math.floor(gameState.incomePerTick * 0.2);
gameState.credits += clickGain;
var floatText = new FloatingText('+' + clickGain, coreButton.x + (Math.random() * 100 - 50), coreButton.y - 150, '#00ffff');
game.addChild(floatText);
tween(coreGraphic, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 50,
onFinish: function onFinish() {
tween(coreGraphic, {
scaleX: 1,
scaleY: 1
}, {
duration: 50
});
}
});
};
for (var i = 0; i < levelContainers.length; i++) {
(function (index) {
levelContainers[index].down = function () {
if (modalOpen) {
return;
}
upgradeIncomeLevel(index);
};
})(i);
}
// --- Variables para el Main Loop ---
var pulseTimer = 0;
var lastDisplayedCredits = -1;
var lastDisplayedIncome = -1;
var lastDisplayedCollection = -1;
var lastDisplayedGachaCost = -1;
var lastDisplayedPity = -1;
// --- Main Game Loop Optimizado ---
game.update = function () {
gameState.tickCounter++;
// LÓGICA DE ÓRBITA
var numOrbiting = orbitingSprites.length;
if (numOrbiting > 0) {
orbitAngle += GAME_CONFIG.ORBIT_SPEED;
var angleStep = Math.PI * 2 / numOrbiting;
for (var o = 0; o < numOrbiting; o++) {
var currentAngle = orbitAngle + o * angleStep;
orbitingSprites[o].x = Math.cos(currentAngle) * GAME_CONFIG.ORBIT_RADIUS;
orbitingSprites[o].y = Math.sin(currentAngle) * GAME_CONFIG.ORBIT_RADIUS;
//orbitingSprites[o].rotation += 0.01;
}
}
if (gameState.tickCounter % GAME_CONFIG.FPS === 0) {
gameState.credits += gameState.incomePerTick;
}
// --- Actualización de Costos y Textos ---
var currentCredits = Math.floor(gameState.credits);
var currentGachaCost = getGachaCost();
var currentGachaCost10 = currentGachaCost * 10;
// === INICIO DEL BLOQUE FALTANTE ===
if (currentCredits !== lastDisplayedCredits) {
creditsText.setText('Credits: ' + currentCredits);
lastDisplayedCredits = currentCredits;
}
if (gameState.incomePerTick !== lastDisplayedIncome) {
incomeText.setText('Income: ' + gameState.incomePerTick + '/tick');
lastDisplayedIncome = gameState.incomePerTick;
}
if (gameState.totalCharactersCollected !== lastDisplayedCollection) {
// Usamos characterDatabase.length para que se actualice solo si agregas más en el futuro
collectionText.setText('Collection: ' + gameState.totalCharactersCollected + '/' + characterDatabase.length);
lastDisplayedCollection = gameState.totalCharactersCollected;
}
if (currentGachaCost !== lastDisplayedGachaCost || gameState.pityCounter !== lastDisplayedPity) {
// Actualiza textos Botón x1
gachaText.setText('PULL (' + currentGachaCost + ')');
if (gameState.pityCounter >= 9) {
pityText.setText('Pity: READY!');
pityText.fill = '#00FF00';
} else if (gameState.pityCounter >= 6) {
// Soft pity activo: probabilidades subiendo
pityText.setText('Pity: ' + gameState.pityCounter + "/10 \u2191");
pityText.fill = '#FFA500';
} else {
pityText.setText('Pity: ' + gameState.pityCounter + '/10');
pityText.fill = '#FFD700';
}
// Actualiza textos Botón x10
gacha10Text.setText('10x (' + currentGachaCost10 + ')');
lastDisplayedGachaCost = currentGachaCost;
lastDisplayedPity = gameState.pityCounter;
}
// --- Control Visual de Botones Disponibles ---
gachaEnabled = gameState.credits >= currentGachaCost;
gacha10Enabled = gameState.credits >= currentGachaCost10;
// Efectos del Botón x1
if (gachaEnabled) {
gachaBtnGraphic.tint = 0xFF1493;
gachaText.tint = 0xFFFFFF;
pulseTimer += 0.05;
var scaleX = 1.6 + Math.sin(pulseTimer) * 0.05;
var scaleY = 1.8 + Math.sin(pulseTimer) * 0.05;
gachaBtnGraphic.scale.set(scaleX, scaleY);
} else {
gachaBtnGraphic.tint = 0x883366;
gachaText.tint = 0xAAAAAA;
gachaBtnGraphic.scale.set(1.6, 1.8);
}
// Efectos del Botón x10
if (gacha10Enabled) {
gacha10BtnGraphic.tint = 0xFF1493;
gacha10Text.tint = 0xFFFFFF;
var scaleX10 = 1.6 + Math.cos(pulseTimer) * 0.05; // Usamos cos para desfasar el pulso visual
var scaleY10 = 1.8 + Math.cos(pulseTimer) * 0.05;
gacha10BtnGraphic.scale.set(scaleX10, scaleY10);
} else {
gacha10BtnGraphic.tint = 0x883366;
gacha10Text.tint = 0xAAAAAA;
gacha10BtnGraphic.scale.set(1.6, 1.8);
}
for (var j = 0; j < levelContainers.length; j++) {
var level = levelContainers[j];
if (gameState.credits >= level.currentCost) {
level.children[0].tint = 0xffffff;
} else {
level.children[0].tint = 0x525252;
}
}
if (gameState.tickCounter % GAME_CONFIG.SAVE_INTERVAL === 0) {
saveGame();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1277,11 +1277,8 @@
// Reiniciamos el pity porque acabamos de dar uno garantizado
gameState.pityCounter = 0;
saveGame();
LK.getSound('gacha_pull').play();
- if (gameState.totalCharactersCollected >= 10) {
- LK.getSound('milestone_10_pull').play();
- }
showMultiPullResults(pullResults);
}
function showMultiPullResults(results) {
modalOpen = true; // Bloquea la UI de fondo
Crea un rectángulo para asset de botón. Debe ser: color amarillo, rojo, verde, azul, gris, rosa dispuestos en forma diagonal irregular por el rectángulo. Los colores deben ser planos, y los bordes redondeados. In-Game asset. 2d. High contrast. No shadows. anime. simple
Crea un rectángulo para asset de botón. Debe ser: color rojo escarlata con borde en forma de rectángulo. Los colores deben ser planos, y los bordes redondeados. In-Game asset. 2d. High contrast. No shadows. anime. simple
Crea un rectángulo para asset de botón. Debe ser: color verde esmeralda con borde en forma de rectángulo. Los colores deben ser planos, y los bordes redondeados. In-Game asset. 2d. High contrast. No shadows. anime. simple
Crea un fondo de textura verde tipo anime. In-Game asset. 2d. High contrast. No shadows. Background. anime