Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught ReferenceError: resultMessage is not defined' in or related to this line: 'var resultTitle = new Text2(resultMessage, {' Line Number: 863
Code edit (9 edits merged)
Please save this source code
User prompt
Please fix the bug: 'orbitContainer.removeAllChildren is not a function' in or related to this line: 'orbitContainer.removeAllChildren();' Line Number: 534
Code edit (1 edits merged)
Please save this source code
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.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);
// Aumentar escala gráfica del botón original
var bg = self.attachAsset('upgrade_button', {
anchorX: 0.5,
anchorY: 0.5
});
bg.scale.set(1.5, 1.5);
var levelText = new Text2('', {
size: 32,
// Tamaño aumentado
fill: '#ffffff'
});
levelText.anchor.set(0.5, 0.5);
levelText.y = -20;
self.addChild(levelText);
self.levelText = levelText;
var costText = new Text2('', {
size: 26,
// Tamaño aumentado
fill: '#FFD700'
});
costText.anchor.set(0.5, 0.5);
costText.y = 20;
self.addChild(costText);
self.costText = costText;
};
self.updateData = function (purchases) {
// Fórmula de escalado exponencial: CostoBase * (1.5 ^ compras)
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 + '/tick');
};
return self;
});
/****
* Initialize Game
****/
// Game state
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
// Load saved state
function loadGame() {
gameState.collectedCharacters = {};
gameState.incomeLevels = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // Ahora guarda enteros
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.upgradedLevelCounts || '').split(',');
for (var j = 0; j < upgradedLevels.length; j++) {
if (upgradedLevels[j] !== '') {
gameState.incomeLevels[j] = parseInt(upgradedLevels[j]) || 0;
}
}
} 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++) {
upgradedLevels += gameState.incomeLevels[i] + ',';
}
storage.upgradedLevelCounts = upgradedLevels; // Nueva variable de persistencia
}
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.updateData(gameState.incomeLevels[i]);
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();
var charData = characterDatabase[selectedCharacterId];
var resultMessage = wasNew ? 'NEW: ' + charData.name + '!' : 'Duplicate: ' + charData.name;
var resultColor = wasNew ? '#00FF00' : '#FFD700';
// Create result popup con ASSET VISUAL
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 = -250;
resultContainer.addChild(resultTitle);
// Mostrar el gráfico del personaje obtenido
var resultGraphic = LK.getAsset(charData.asset, {
anchorX: 0.5,
anchorY: 0.5
});
resultGraphic.scale.set(2, 2); // Escalado para mejor visibilidad en el popup
resultGraphic.y = -50;
resultContainer.addChild(resultGraphic);
var resultRarity = new Text2('[' + charData.rarity + ']', {
size: 60,
fill: '#FFD700'
});
resultRarity.anchor.set(0.5, 0.5);
resultRarity.y = 130;
resultContainer.addChild(resultRarity);
var resultMultiplier = new Text2('Multiplier: +' + charData.multiplier, {
size: 40,
fill: '#FFFFFF'
});
resultMultiplier.anchor.set(0.5, 0.5);
resultMultiplier.y = 200;
resultContainer.addChild(resultMultiplier);
game.addChild(resultContainer);
LK.setTimeout(function () {
resultContainer.destroy();
}, 2000);
tween(gachaBtnGraphic, {
tint: 0xFFFFFF
}, {
duration: 100,
onFinish: function onFinish() {
tween(gachaBtnGraphic, {
tint: 0xFF1493
}, {
duration: 100
});
}
});
}
// --- NUEVO: Botón Debug para reiniciar progreso ---
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 DATA', {
size: 32,
fill: '#ff4444'
});
debugText.anchor.set(0.5, 0.5);
debugButton.addChild(debugText);
// Evento directo del botón debug
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];
storage.credits = 0;
storage.incomePerTick = 1;
storage.totalCharactersCollected = 0;
storage.collectedCharacterIds = '';
storage.upgradedLevelCounts = '0,0,0,0,0,0,0,0,0,0,';
for (var i = 0; i < levelContainers.length; i++) {
levelContainers[i].updateData(0);
}
LK.getSound('ui_click').play();
};
// Upgrade income level
function upgradeIncomeLevel(levelIndex) {
var level = levelContainers[levelIndex];
if (gameState.credits >= level.currentCost) {
gameState.credits -= level.currentCost;
gameState.incomeLevels[levelIndex]++; // Sumar compra
var incomeBonus = level.baseIncome;
gameState.incomePerTick += incomeBonus;
level.updateData(gameState.incomeLevels[levelIndex]); // Actualiza UI de costo y texto
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 % 30 === 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
@@ -44,48 +44,54 @@
});
// Income Level class for upgrade system
var IncomeLevel = Container.expand(function () {
var self = Container.call(this);
- self.level = 0;
+ self.levelIndex = 0;
self.baseIncome = 0;
- self.costMultiplier = 1;
+ self.baseCost = 0;
self.currentCost = 0;
- self.isUpgraded = false;
- self.init = function (level, baseIncome) {
- self.level = level;
+ self.init = function (levelIndex, baseIncome) {
+ self.levelIndex = levelIndex;
self.baseIncome = baseIncome;
- self.costMultiplier = 50 * (level + 1);
- self.currentCost = self.costMultiplier;
+ self.baseCost = 50 * (levelIndex + 1);
+ // Aumentar escala gráfica del botón original
var bg = self.attachAsset('upgrade_button', {
anchorX: 0.5,
anchorY: 0.5
});
- var levelText = new Text2('Level ' + (level + 1) + ': +' + baseIncome + '/tick', {
- size: 24,
+ bg.scale.set(1.5, 1.5);
+ var levelText = new Text2('', {
+ size: 32,
+ // Tamaño aumentado
fill: '#ffffff'
});
levelText.anchor.set(0.5, 0.5);
- levelText.y = -15;
+ levelText.y = -20;
self.addChild(levelText);
- var costText = new Text2('Cost: ' + self.currentCost, {
- size: 18,
+ self.levelText = levelText;
+ var costText = new Text2('', {
+ size: 26,
+ // Tamaño aumentado
fill: '#FFD700'
});
costText.anchor.set(0.5, 0.5);
- costText.y = 15;
+ costText.y = 20;
self.addChild(costText);
self.costText = costText;
};
- self.updateCost = function () {
- self.currentCost = self.costMultiplier * (self.isUpgraded ? 2 : 1);
+ self.updateData = function (purchases) {
+ // Fórmula de escalado exponencial: CostoBase * (1.5 ^ compras)
+ 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 + '/tick');
};
return self;
});
/****
* Initialize Game
****/
+// Game state
var game = new LK.Game({
backgroundColor: 0x0a0a0a
});
@@ -374,11 +380,12 @@
incomeLevels: [],
tickCounter: 0
};
// Load saved state
+// Load saved state
function loadGame() {
gameState.collectedCharacters = {};
- gameState.incomeLevels = [false, false, false, false, false, false, false, false, false, false];
+ gameState.incomeLevels = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // Ahora guarda enteros
if (storage.credits !== undefined) {
gameState.credits = storage.credits;
gameState.incomePerTick = storage.incomePerTick;
gameState.totalCharactersCollected = storage.totalCharactersCollected;
@@ -388,12 +395,12 @@
if (collectedIds[i] !== '') {
gameState.collectedCharacters[parseInt(collectedIds[i])] = true;
}
}
- var upgradedLevels = (storage.upgradedLevelIds || '').split(',');
+ var upgradedLevels = (storage.upgradedLevelCounts || '').split(',');
for (var j = 0; j < upgradedLevels.length; j++) {
if (upgradedLevels[j] !== '') {
- gameState.incomeLevels[parseInt(upgradedLevels[j])] = true;
+ gameState.incomeLevels[j] = parseInt(upgradedLevels[j]) || 0;
}
}
} else {
gameState.credits = 0;
@@ -416,13 +423,11 @@
}
storage.collectedCharacterIds = collectedIds;
var upgradedLevels = '';
for (var i = 0; i < gameState.incomeLevels.length; i++) {
- if (gameState.incomeLevels[i]) {
- upgradedLevels += i + ',';
- }
+ upgradedLevels += gameState.incomeLevels[i] + ',';
}
- storage.upgradedLevelIds = upgradedLevels;
+ storage.upgradedLevelCounts = upgradedLevels; // Nueva variable de persistencia
}
loadGame();
// UI Elements
var creditsText = new Text2('Credits: 0', {
@@ -488,12 +493,9 @@
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.updateData(gameState.incomeLevels[i]);
levelContainer.x = 1024;
levelContainer.y = levelStartY + i * levelSpacing;
game.addChild(levelContainer);
levelContainers.push(levelContainer);
@@ -606,13 +608,12 @@
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
+ // Create result popup con ASSET VISUAL
var resultContainer = new Container();
var resultBg = LK.getAsset('modal_bg', {
anchorX: 0.5,
anchorY: 0.5
@@ -624,29 +625,36 @@
size: 80,
fill: resultColor
});
resultTitle.anchor.set(0.5, 0.5);
- resultTitle.y = -200;
+ resultTitle.y = -250;
resultContainer.addChild(resultTitle);
+ // Mostrar el gráfico del personaje obtenido
+ var resultGraphic = LK.getAsset(charData.asset, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ resultGraphic.scale.set(2, 2); // Escalado para mejor visibilidad en el popup
+ resultGraphic.y = -50;
+ resultContainer.addChild(resultGraphic);
var resultRarity = new Text2('[' + charData.rarity + ']', {
size: 60,
fill: '#FFD700'
});
resultRarity.anchor.set(0.5, 0.5);
- resultRarity.y = 50;
+ resultRarity.y = 130;
resultContainer.addChild(resultRarity);
var resultMultiplier = new Text2('Multiplier: +' + charData.multiplier, {
size: 40,
fill: '#FFFFFF'
});
resultMultiplier.anchor.set(0.5, 0.5);
- resultMultiplier.y = 150;
+ resultMultiplier.y = 200;
resultContainer.addChild(resultMultiplier);
game.addChild(resultContainer);
LK.setTimeout(function () {
resultContainer.destroy();
}, 2000);
- // Flash effect on gacha button
tween(gachaBtnGraphic, {
tint: 0xFFFFFF
}, {
duration: 100,
@@ -658,18 +666,53 @@
});
}
});
}
+// --- NUEVO: Botón Debug para reiniciar progreso ---
+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 DATA', {
+ size: 32,
+ fill: '#ff4444'
+});
+debugText.anchor.set(0.5, 0.5);
+debugButton.addChild(debugText);
+// Evento directo del botón debug
+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];
+ storage.credits = 0;
+ storage.incomePerTick = 1;
+ storage.totalCharactersCollected = 0;
+ storage.collectedCharacterIds = '';
+ storage.upgradedLevelCounts = '0,0,0,0,0,0,0,0,0,0,';
+ for (var i = 0; i < levelContainers.length; i++) {
+ levelContainers[i].updateData(0);
+ }
+ LK.getSound('ui_click').play();
+};
// Upgrade income level
function upgradeIncomeLevel(levelIndex) {
var level = levelContainers[levelIndex];
- if (gameState.credits >= level.currentCost && !gameState.incomeLevels[levelIndex]) {
+ if (gameState.credits >= level.currentCost) {
gameState.credits -= level.currentCost;
- gameState.incomeLevels[levelIndex] = true;
- level.isUpgraded = true;
+ gameState.incomeLevels[levelIndex]++; // Sumar compra
var incomeBonus = level.baseIncome;
gameState.incomePerTick += incomeBonus;
- level.updateCost();
+ level.updateData(gameState.incomeLevels[levelIndex]); // Actualiza UI de costo y texto
saveGame();
LK.getSound('level_up').play();
}
}
@@ -695,24 +738,30 @@
// --- 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 (modalOpen) {
+ return;
+ } // Evitar clics si la galería está abierta
if (gachaEnabled) {
performGachaPull();
LK.getSound('ui_click').play();
}
};
galleryButton.down = function () {
- if (modalOpen) return;
+ 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;
+ if (modalOpen) {
+ return;
+ }
upgradeIncomeLevel(index);
LK.getSound('ui_click').play();
};
})(i);
@@ -735,9 +784,9 @@
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) {
+ if (gameState.tickCounter % 30 === 0) {
gameState.credits += gameState.incomePerTick;
}
// Update UI
creditsText.setText('Credits: ' + Math.floor(gameState.credits));
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