User prompt
Please fix the bug: 'levelContainer.updateCost is not a function' in or related to this line: 'levelContainer.updateCost();' Line Number: 549
Code edit (1 edits merged)
Please save this source code
User prompt
Corrige: - Disminuye la velocidad de los ticks a una cuarta parte. - Los botones de los niveles no funcionan, deben gastar creditos y aumentar la velocidad de la ganancia por tick. - El pull del gacha no funciona, debe de indicar que personaje ganaste - La galeria de personajes no despliega nada
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.gameState = gameState;' Line Number: 441 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Elemental Idle: Character Gacha
Initial prompt
Haremos un juego tipo idle/gacha, donde se obtienen personajes tipo anime, la subinspiración serán los elementos naturales, con la rareza: - Tierra (común) - Agua (común) - Fuego (común) - Viento (común) - Planta (poco común) - Lava (poco común) - Arena (poco común) - Vapor (poco común) - Lodo (poco común) - Ceniza (poco común) - Hielo (raro) - Metal (raro) - Electricidad (raro) - Arena (raro) - Cristal (raro) - Veneno (raro) - Niebla (raro) - Sangre (raro) - Sonido (ultrararo) - Luz (ultrararo) - Obscuridad (ultrararo) - Plasma (ultrararo) - Magnetismo (ultrararo) - Gravedad (ultrararo) - Espejismo (ultrararo) - Radiación (ultrararo) - Vida (legendario) - Muerte (legendario) - Tiempo (legendario) - Espacio (legendario) - Alma (legendario) -Sueño (legendario) - Vacío (único) - Éter (único) - Caos (único) - Orden (único) Se inicia sin personajes, y se puede realizar una tirada aleatoria cada 1000 creditos. En cada tirada se puede obtener un personaje repetido, en ese caso no se desbloquea nada nuevo. Los personajes desbloqueados se pueden ver en una ventana emergente que se despliega con un botón. Los porcentajes de obtención son: 50% común 20% poco común 15% raro 10% ultrararo 4% legendario 1% único Cada rareza da un multiplicador general: común - x2 raro - x3 poco común Al ser un idle, se debe mejorar con créditos ciertos niveles (de momento solo crea 10 niveles genéricos que sumen créditos +1, +2, +3, +5, +10, +20, +50, +100, +200, +300) De momento como no hay sprites se crea un asset con el nombre del elemento que representan.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Character class for displaying collected elements
var Character = Container.expand(function () {
var self = Container.call(this);
self.elementId = null;
self.elementName = '';
self.rarity = '';
self.assetId = '';
self.incomeMultiplier = 1;
self.init = function (elementId, elementName, rarity, assetId, multiplier) {
self.elementId = elementId;
self.elementName = elementName;
self.rarity = rarity;
self.assetId = assetId;
self.incomeMultiplier = multiplier;
var graphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
var nameText = new Text2(elementName, {
size: 28,
fill: '#ffffff'
});
nameText.anchor.set(0.5, 0);
nameText.y = 70;
self.addChild(nameText);
var rarityText = new Text2(rarity, {
size: 20,
fill: '#FFD700'
});
rarityText.anchor.set(0.5, 0);
rarityText.y = 100;
self.addChild(rarityText);
};
return self;
});
// Income Level class for upgrade system
var IncomeLevel = Container.expand(function () {
var self = Container.call(this);
self.level = 0;
self.baseIncome = 0;
self.costMultiplier = 1;
self.currentCost = 0;
self.isUpgraded = false;
self.init = function (level, baseIncome) {
self.level = level;
self.baseIncome = baseIncome;
self.costMultiplier = 50 * (level + 1);
self.currentCost = self.costMultiplier;
var bg = self.attachAsset('upgrade_button', {
anchorX: 0.5,
anchorY: 0.5
});
var levelText = new Text2('Level ' + (level + 1) + ': +' + baseIncome + '/tick', {
size: 24,
fill: '#ffffff'
});
levelText.anchor.set(0.5, 0.5);
levelText.y = -15;
self.addChild(levelText);
var costText = new Text2('Cost: ' + self.currentCost, {
size: 18,
fill: '#FFD700'
});
costText.anchor.set(0.5, 0.5);
costText.y = 15;
self.addChild(costText);
self.costText = costText;
};
self.updateCost = function () {
self.currentCost = self.costMultiplier * (self.isUpgraded ? 2 : 1);
self.costText.setText('Cost: ' + self.currentCost);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0a0a0a
});
/****
* Game Code
****/
// Sound Effects
// UI Elements
// Special Elements
// Unique Elements
// Legendary Elements
// Ultra-Rare Elements
// Rare Elements
// Uncommon Elements
// Common Elements
// Character database with all elements
var characterDatabase = [
// Common (4) - 2x multiplier
{
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
},
// Uncommon (6) - 3x multiplier
{
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
},
// Rare (7) - 4x multiplier
{
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
},
// Ultra-Rare (6) - 5x multiplier
{
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
},
// Legendary (5) - 7x multiplier
{
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
},
// Unique (3) - 10x multiplier
{
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
},
// Special (6) - 6x multiplier
{
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
}];
// Gacha drop rates
var dropRates = [{
rarity: 'Common',
chance: 50,
ids: [0, 1, 2, 3]
}, {
rarity: 'Uncommon',
chance: 20,
ids: [4, 5, 6, 7, 8, 9]
}, {
rarity: 'Rare',
chance: 15,
ids: [10, 11, 12, 13, 14, 15, 16]
}, {
rarity: 'Ultra-Rare',
chance: 10,
ids: [17, 18, 19, 20, 21, 22]
}, {
rarity: 'Legendary',
chance: 4,
ids: [23, 24, 25, 26, 27]
}, {
rarity: 'Unique',
chance: 1,
ids: [28, 29, 30]
}];
// Game state
var gameState = {
credits: 0,
incomePerTick: 1,
collectedCharacters: {},
totalCharactersCollected: 0,
incomeLevels: [],
tickCounter: 0
};
// Load saved state
function loadGame() {
gameState.collectedCharacters = {};
gameState.incomeLevels = [false, false, false, false, false, false, false, false, false, false];
if (storage.credits !== undefined) {
gameState.credits = storage.credits;
gameState.incomePerTick = storage.incomePerTick;
gameState.totalCharactersCollected = storage.totalCharactersCollected;
gameState.tickCounter = storage.tickCounter || 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.upgradedLevelIds || '').split(',');
for (var j = 0; j < upgradedLevels.length; j++) {
if (upgradedLevels[j] !== '') {
gameState.incomeLevels[parseInt(upgradedLevels[j])] = true;
}
}
} else {
gameState.credits = 0;
gameState.incomePerTick = 1;
gameState.totalCharactersCollected = 0;
gameState.tickCounter = 0;
}
}
// Save game state
function saveGame() {
storage.credits = gameState.credits;
storage.incomePerTick = gameState.incomePerTick;
storage.totalCharactersCollected = gameState.totalCharactersCollected;
storage.tickCounter = gameState.tickCounter;
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++) {
if (gameState.incomeLevels[i]) {
upgradedLevels += i + ',';
}
}
storage.upgradedLevelIds = upgradedLevels;
}
loadGame();
// UI Elements
var creditsText = new Text2('Credits: 0', {
size: 60,
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: 40,
fill: '#00FF00'
});
incomeText.anchor.set(0.5, 0);
incomeText.x = 1024;
incomeText.y = 140;
game.addChild(incomeText);
var collectionText = new Text2('Collection: 0/37', {
size: 40,
fill: '#87CEEB'
});
collectionText.anchor.set(0.5, 0);
collectionText.x = 1024;
collectionText.y = 210;
game.addChild(collectionText);
// Gacha pull button
var gachaBtnGraphic = LK.getAsset('gacha_button', {
anchorX: 0.5,
anchorY: 0.5
});
var gachaButton = new Container();
gachaButton.addChild(gachaBtnGraphic);
gachaButton.x = 1024;
gachaButton.y = 2500;
game.addChild(gachaButton);
var gachaText = new Text2('PULL (1000)', {
size: 48,
fill: '#ffffff'
});
gachaText.anchor.set(0.5, 0.5);
gachaButton.addChild(gachaText);
var gachaEnabled = false;
// Gallery button
var galleryBtnGraphic = LK.getAsset('gallery_button', {
anchorX: 0.5,
anchorY: 0.5
});
var galleryButton = new Container();
galleryButton.addChild(galleryBtnGraphic);
galleryButton.x = 300;
galleryButton.y = 2550;
game.addChild(galleryButton);
var galleryText = new Text2('GALLERY', {
size: 28,
fill: '#ffffff'
});
galleryText.anchor.set(0.5, 0.5);
galleryButton.addChild(galleryText);
// Income upgrade level containers
var levelContainers = [];
var levelStartY = 350;
var levelSpacing = 100;
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.isUpgraded = gameState.incomeLevels[i];
if (levelContainer.isUpgraded) {
levelContainer.updateCost();
}
levelContainer.x = 1024;
levelContainer.y = levelStartY + i * levelSpacing;
game.addChild(levelContainer);
levelContainers.push(levelContainer);
}
// Modal for gallery
var modalOpen = false;
var modalContainer = null;
function openGallery() {
if (modalOpen) {
return;
}
modalOpen = true;
modalContainer = new Container();
var modalBg = LK.getAsset('modal_bg', {
anchorX: 0.5,
anchorY: 0.5
});
modalContainer.addChild(modalBg);
modalContainer.x = 1024;
modalContainer.y = 1366;
// Gallery title
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);
// Close button
var closeBtnGraphic = LK.getAsset('modal_close_btn', {
anchorX: 0.5,
anchorY: 0.5
});
var closeBtn = new Container();
closeBtn.addChild(closeBtnGraphic);
closeBtn.x = 850;
closeBtn.y = -1050;
modalContainer.addChild(closeBtn);
var closeBtnText = new Text2('X', {
size: 50,
fill: '#ffffff'
});
closeBtnText.anchor.set(0.5, 0.5);
closeBtn.addChild(closeBtnText);
// Display collected characters
var yOffset = -950;
var xOffset = -750;
var colCount = 0;
for (var charId = 0; charId < characterDatabase.length; charId++) {
if (gameState.collectedCharacters[charId]) {
var charData = characterDatabase[charId];
var displayChar = new Character();
displayChar.init(charId, charData.name, charData.rarity, charData.asset, charData.multiplier);
displayChar.x = xOffset + colCount % 5 * 320;
displayChar.y = yOffset + Math.floor(colCount / 5) * 280;
modalContainer.addChild(displayChar);
colCount++;
}
}
// Show uncollected count
var uncollectedText = new Text2('Uncollected: ' + (37 - gameState.totalCharactersCollected), {
size: 32,
fill: '#FF6666'
});
uncollectedText.anchor.set(0.5, 0);
uncollectedText.x = 0;
uncollectedText.y = 900;
modalContainer.addChild(uncollectedText);
game.addChild(modalContainer);
// Close on button click
game.down = function (x, y, obj) {
if (closeBtn.intersects(obj)) {
modalContainer.destroy();
modalOpen = false;
game.down = handleGameDown;
}
};
}
function closeModal() {
if (modalContainer) {
modalContainer.destroy();
modalOpen = false;
}
}
// Gacha pull function
function performGachaPull() {
if (gameState.credits < 1000) {
return;
}
gameState.credits -= 1000;
var roll = Math.random() * 100;
var selectedRarity = null;
var cumulativeChance = 0;
for (var i = 0; i < dropRates.length; i++) {
cumulativeChance += dropRates[i].chance;
if (roll <= cumulativeChance) {
selectedRarity = dropRates[i];
break;
}
}
var characterIdArray = selectedRarity.ids;
var selectedCharacterId = characterIdArray[Math.floor(Math.random() * characterIdArray.length)];
var wasNew = false;
if (!gameState.collectedCharacters[selectedCharacterId]) {
gameState.collectedCharacters[selectedCharacterId] = true;
gameState.totalCharactersCollected++;
wasNew = true;
var charData = characterDatabase[selectedCharacterId];
gameState.incomePerTick += charData.multiplier;
}
saveGame();
LK.getSound('gacha_pull').play();
// Display pull result
var charData = characterDatabase[selectedCharacterId];
var resultMessage = wasNew ? 'NEW: ' + charData.name + '!' : 'Duplicate: ' + charData.name;
var resultColor = wasNew ? '#00FF00' : '#FFD700';
// Create result popup
var resultContainer = new Container();
var resultBg = LK.getAsset('modal_bg', {
anchorX: 0.5,
anchorY: 0.5
});
resultContainer.addChild(resultBg);
resultContainer.x = 1024;
resultContainer.y = 1366;
var resultTitle = new Text2(resultMessage, {
size: 80,
fill: resultColor
});
resultTitle.anchor.set(0.5, 0.5);
resultTitle.y = -200;
resultContainer.addChild(resultTitle);
var resultRarity = new Text2('[' + charData.rarity + ']', {
size: 60,
fill: '#FFD700'
});
resultRarity.anchor.set(0.5, 0.5);
resultRarity.y = 50;
resultContainer.addChild(resultRarity);
var resultMultiplier = new Text2('Multiplier: +' + charData.multiplier, {
size: 40,
fill: '#FFFFFF'
});
resultMultiplier.anchor.set(0.5, 0.5);
resultMultiplier.y = 150;
resultContainer.addChild(resultMultiplier);
game.addChild(resultContainer);
LK.setTimeout(function () {
resultContainer.destroy();
}, 2000);
// Flash effect on gacha button
tween(gachaBtnGraphic, {
tint: 0xFFFFFF
}, {
duration: 100,
onFinish: function onFinish() {
tween(gachaBtnGraphic, {
tint: 0xFF1493
}, {
duration: 100
});
}
});
}
// Upgrade income level
function upgradeIncomeLevel(levelIndex) {
var level = levelContainers[levelIndex];
if (gameState.credits >= level.currentCost && !gameState.incomeLevels[levelIndex]) {
gameState.credits -= level.currentCost;
gameState.incomeLevels[levelIndex] = true;
level.isUpgraded = true;
var incomeBonus = level.baseIncome;
gameState.incomePerTick += incomeBonus;
level.updateCost();
saveGame();
LK.getSound('level_up').play();
}
}
// Event handlers
function handleGameDown(x, y, obj) {
if (gachaButton.intersects(obj) && gachaEnabled) {
performGachaPull();
LK.getSound('ui_click').play();
} else if (galleryButton.intersects(obj)) {
openGallery();
LK.getSound('ui_click').play();
} else {
for (var i = 0; i < levelContainers.length; i++) {
if (levelContainers[i].intersects(obj)) {
upgradeIncomeLevel(i);
LK.getSound('ui_click').play();
break;
}
}
}
}
game.down = handleGameDown;
// --- CORRECCIÓN 1 y 2: Event handlers directos en lugar de globales ---
// En lugar de un game.down global que falla al detectar contenedores,
// asignamos los eventos de clic directamente a los botones.
gachaButton.down = function () {
if (modalOpen) return; // Evitar clics si la galería está abierta
if (gachaEnabled) {
performGachaPull();
LK.getSound('ui_click').play();
}
};
galleryButton.down = function () {
if (modalOpen) return;
openGallery();
LK.getSound('ui_click').play();
};
// Asignar el clic a cada botón de nivel
for (var i = 0; i < levelContainers.length; i++) {
(function (index) {
levelContainers[index].down = function () {
if (modalOpen) return;
upgradeIncomeLevel(index);
LK.getSound('ui_click').play();
};
})(i);
}
// Actualizamos openGallery para que el botón de cerrar funcione bien
var originalOpenGallery = openGallery;
openGallery = function openGallery() {
originalOpenGallery();
if (modalContainer) {
// Encontrar el closeBtn dentro del modalContainer y asignarle el evento directo
var closeBtn = modalContainer.children[2]; // El botón de cerrar es el 3er hijo
if (closeBtn) {
closeBtn.down = function () {
closeModal();
};
}
}
};
// --- CORRECCIÓN 3: Main game loop y velocidad de Tick ---
game.update = function () {
gameState.tickCounter++;
// CORRECCIÓN: Disminuye la velocidad de los ticks.
// En lugar de sumar cada frame, sumamos 1 vez cada 60 frames (1 segundo aprox).
if (gameState.tickCounter % 60 === 0) {
gameState.credits += gameState.incomePerTick;
}
// Update UI
creditsText.setText('Credits: ' + Math.floor(gameState.credits));
incomeText.setText('Income: ' + gameState.incomePerTick + '/tick');
collectionText.setText('Collection: ' + gameState.totalCharactersCollected + '/37');
// Check if gacha button should be enabled
gachaEnabled = gameState.credits >= 1000;
if (gachaEnabled) {
gachaBtnGraphic.tint = 0xFF1493;
gachaText.tint = 0xFFFFFF;
} else {
gachaBtnGraphic.tint = 0x883366;
gachaText.tint = 0xAAAAAA;
}
// Update level buttons visual state
for (var i = 0; i < levelContainers.length; i++) {
var level = levelContainers[i];
if (level.isUpgraded) {
level.children[0].tint = 0x228B22; // Verde oscuro (Comprado)
level.costText.setText('MAXED');
} else if (gameState.credits >= level.currentCost) {
level.children[0].tint = 0x32CD32; // Verde claro (Comprable)
} else {
level.children[0].tint = 0x666666; // Gris (Sin fondos)
}
}
// Save periodically
if (gameState.tickCounter % 300 === 0) {
saveGame();
}
}; ===================================================================
--- original.js
+++ change.js
@@ -501,9 +501,11 @@
// Modal for gallery
var modalOpen = false;
var modalContainer = null;
function openGallery() {
- if (modalOpen) return;
+ if (modalOpen) {
+ return;
+ }
modalOpen = true;
modalContainer = new Container();
var modalBg = LK.getAsset('modal_bg', {
anchorX: 0.5,
@@ -578,9 +580,11 @@
}
}
// Gacha pull function
function performGachaPull() {
- if (gameState.credits < 1000) return;
+ if (gameState.credits < 1000) {
+ return;
+ }
gameState.credits -= 1000;
var roll = Math.random() * 100;
var selectedRarity = null;
var cumulativeChance = 0;
@@ -687,13 +691,55 @@
}
}
}
game.down = handleGameDown;
-// Main game loop
+// --- CORRECCIÓN 1 y 2: Event handlers directos en lugar de globales ---
+// En lugar de un game.down global que falla al detectar contenedores,
+// asignamos los eventos de clic directamente a los botones.
+gachaButton.down = function () {
+ if (modalOpen) return; // Evitar clics si la galería está abierta
+ if (gachaEnabled) {
+ performGachaPull();
+ LK.getSound('ui_click').play();
+ }
+};
+galleryButton.down = function () {
+ if (modalOpen) return;
+ openGallery();
+ LK.getSound('ui_click').play();
+};
+// Asignar el clic a cada botón de nivel
+for (var i = 0; i < levelContainers.length; i++) {
+ (function (index) {
+ levelContainers[index].down = function () {
+ if (modalOpen) return;
+ upgradeIncomeLevel(index);
+ LK.getSound('ui_click').play();
+ };
+ })(i);
+}
+// Actualizamos openGallery para que el botón de cerrar funcione bien
+var originalOpenGallery = openGallery;
+openGallery = function openGallery() {
+ originalOpenGallery();
+ if (modalContainer) {
+ // Encontrar el closeBtn dentro del modalContainer y asignarle el evento directo
+ var closeBtn = modalContainer.children[2]; // El botón de cerrar es el 3er hijo
+ if (closeBtn) {
+ closeBtn.down = function () {
+ closeModal();
+ };
+ }
+ }
+};
+// --- CORRECCIÓN 3: Main game loop y velocidad de Tick ---
game.update = function () {
gameState.tickCounter++;
- // Generate credits (reduced to 1/4 speed)
- gameState.credits += gameState.incomePerTick * 0.25;
+ // CORRECCIÓN: Disminuye la velocidad de los ticks.
+ // En lugar de sumar cada frame, sumamos 1 vez cada 60 frames (1 segundo aprox).
+ if (gameState.tickCounter % 60 === 0) {
+ gameState.credits += gameState.incomePerTick;
+ }
// Update UI
creditsText.setText('Credits: ' + Math.floor(gameState.credits));
incomeText.setText('Income: ' + gameState.incomePerTick + '/tick');
collectionText.setText('Collection: ' + gameState.totalCharactersCollected + '/37');
@@ -709,13 +755,14 @@
// Update level buttons visual state
for (var i = 0; i < levelContainers.length; i++) {
var level = levelContainers[i];
if (level.isUpgraded) {
- level.children[0].tint = 0x228B22;
+ level.children[0].tint = 0x228B22; // Verde oscuro (Comprado)
+ level.costText.setText('MAXED');
} else if (gameState.credits >= level.currentCost) {
- level.children[0].tint = 0x32CD32;
+ level.children[0].tint = 0x32CD32; // Verde claro (Comprable)
} else {
- level.children[0].tint = 0x666666;
+ level.children[0].tint = 0x666666; // Gris (Sin fondos)
}
}
// Save periodically
if (gameState.tickCounter % 300 === 0) {
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