/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
persistLanguage: true,
language: "en"
});
/****
* Classes
****/
var MusicNameOverlay = Container.expand(function () {
var self = Container.call(this);
// Text for displaying music name
var musicText = new Text2("", {
size: 110,
fill: 0x000000,
align: "center",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 3,
dropShadowAlpha: 0.5
});
musicText.anchor.set(0.5, 0.5);
musicText.x = 2048 / 2;
musicText.y = 150;
musicText.alpha = 0;
self.addChild(musicText);
// Random fake music names in different languages
var musicNames = {
en: ["Slime Symphony No. 5", "Bouncy Beats", "Gelatinous Groove", "Blob Bop", "Jiggle Jam", "Slimy Sonata", "Elasticity Etude", "Viscous Vibes", "Gooey Grooves", "Jiggly Jazz", "Will anyone read this?"],
es: ["Sinfonía de Slime No. 5", "Ritmos Rebotantes", "Ritmo Gelatinoso", "Bop de Burbuja", "Mermelada Temblorosa", "Sonata Viscosa", "Estudio Elastico", "Vibraciones Viscosas", "Ritmos Pegajosos", "Jazz Tembloroso", "¿Alguien leerá esto?"]
};
// Show a random music name
self.showRandomName = function (language) {
var names = musicNames[language] || musicNames.en;
var randomName = names[Math.floor(Math.random() * names.length)];
// Stop any running animations
tween.stop(musicText);
// Set the text
musicText.setText(randomName);
// Fade in and move up animation sequence
musicText.alpha = 0;
musicText.y = 180;
// First animation: fade in and move to position
tween(musicText, {
alpha: 1,
y: 150
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Wait a bit then fade out and move up
LK.setTimeout(function () {
tween(musicText, {
alpha: 0,
y: 100
}, {
duration: 1200,
easing: tween.easeIn
});
}, 3000);
}
});
};
return self;
});
var Slime = Container.expand(function () {
var self = Container.call(this);
// Create and attach the slime asset with consistent scaling
// We won't set width/height here because we'll set a consistent scale instead
self.slimeAsset = self.attachAsset('ClasicSlime', {
anchorX: 0.5,
anchorY: 0.5
});
// Set consistent scale factor for all slimes
self.baseScale = 3.5; // Reduced base scaling factor
self.lastX = self.lastY = 0;
self.baseX = 0;
self.baseY = 0;
self.setBasePosition = function (x, y) {
self.baseX = x;
self.baseY = y;
self.x = x;
self.y = y;
};
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('Star', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 100
});
self.setColorByRarity = function (rarityLevel) {
// Create a smooth gradient from gray (common) to dark purple (highest rarity)
// Use a gradient color scheme for better visual differentiation
var colors = [0xaaaaaa,
// 1: Gray (Common)
0x8ab4f8,
// 2: Light blue
0x52cca3,
// 3: Teal
0x1e88e5,
// 4: Blue
0x7e57c2,
// 5: Light purple
0xab47bc,
// 6: Purple
0x8e24aa,
// 7: Dark purple
0x6a1b9a,
// 8: Deeper purple
0x4a148c,
// 9: Very dark purple
0x38006b // 10: Darkest purple (Supreme)
];
starGraphics.tint = rarityLevel >= 1 && rarityLevel <= 10 ? colors[rarityLevel - 1] : colors[0];
// Create glow effect with subtle pulsation
self.glowIntensity = 0.2 + rarityLevel / 10;
LK.setTimeout(function () {
tween(starGraphics, {
scaleX: 1 + self.glowIntensity * 0.1,
scaleY: 1 + self.glowIntensity * 0.1
}, {
duration: 1000 + rarityLevel * 100,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
}, Math.random() * 500);
};
return self;
});
var StartScreen = Container.expand(function () {
var self = Container.call(this);
// Create background for start screen
var startBg = self.attachAsset('BGInitial', {
anchorX: 0,
anchorY: 0,
width: 2048,
height: 2732
});
// Add title screen image using TittleAsset
var titleImage = self.attachAsset('TittleAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 300,
scaleX: 1.2,
scaleY: 1.2
});
// Title is now included in the TittleAsset
// No tap to start text - removed as requested
// Make the start screen interactive
self.interactive = true;
// When screen is tapped, trigger the transition
self.down = function () {
if (self.onStart) {
// Clear the auto-start timer if it exists
if (autoStartTimer) {
LK.clearTimeout(autoStartTimer);
}
LK.getSound('InterfazSound').play();
// Create a darkening overlay
var darkOverlay = new Container();
var darkRect = LK.getAsset('transition', {
anchorX: 0,
anchorY: 0,
width: 2048,
height: 2732,
alpha: 0
});
darkOverlay.addChild(darkRect);
self.addChild(darkOverlay);
// Start darkening animation
tween(darkRect, {
alpha: 1.0
}, {
duration: 3000,
easing: tween.easeInOut
});
// Add rotation and falling animation to title image
if (titleImage) {
tween(titleImage, {
rotation: 0.2,
y: titleImage.y + 100
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
// Add pause before falling
LK.setTimeout(function () {
// Accelerate falling
tween(titleImage, {
y: 2732 + 500,
rotation: 0.5
}, {
duration: 1200,
easing: tween.easeIn,
onFinish: function onFinish() {
// Add delay before transitioning to give more time for cube to disappear
LK.setTimeout(function () {
// Call the actual transition
self.onStart();
}, 800);
}
});
}, 1000); // 1 second pause between rotation and falling
}
});
} // Close the if (titleImage) block
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Day/Night detection variables
var isDayTime = true;
var darkTint = 0x404060; // Dark blue-gray tint for night mode
// Function to check if it's day or night
function checkDayTime() {
var now = new Date();
var hours = now.getHours();
// Day is from 6 AM to 6 PM
return hours >= 6 && hours < 18;
}
// Create a container for game content that will appear from center
var gameContent = new Container();
gameContent.y = 0; // Position at normal position
gameContent.alpha = 0; // Start invisible
gameContent.scale.set(0.5); // Start small for zoom effect
// Create BGMenu for bottom half of screen
var bgMenu = LK.getAsset('BGMenu', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2032 / 2,
width: 2048,
height: 3532 / 2
});
// Create BG for top half of screen
var bg = LK.getAsset('BG', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2032 / 2
});
// Create and add start screen
var startScreen = new StartScreen();
game.addChild(startScreen);
// Set up auto-start timer for 10 seconds
var autoStartTimer = LK.setTimeout(function () {
// Only trigger if startScreen still exists and has a parent
if (startScreen && startScreen.parent) {
startScreen.down(); // Simulate tap to start
}
}, 10000);
// Set up the transition function
startScreen.onStart = function () {
// Keep the darkening overlay visible until menu animation completes
// First animate the game content appearing from center
tween(gameContent, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 0,
easing: tween.easeOut,
onFinish: function onFinish() {
// Only after game content is positioned, fade out the start screen
// Add null check before tweening to prevent TypeError
if (startScreen) {
tween(startScreen, {
alpha: 0 // Fade out
}, {
duration: 5000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Remove start screen when animation completes
if (startScreen && startScreen.parent) {
game.removeChild(startScreen);
startScreen = null;
}
}
});
}
}
});
};
// Create interface element at the top of BGMenu
var interfaz = LK.getAsset('Interfaz', {
anchorX: 0.5,
anchorY: 0,
width: 2048,
height: 400
});
// Create sort button at the top right of interface
var sortButton = LK.getAsset('BotonExtras', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
x: 800,
y: -700
});
// Add event handler for sort button
sortButton.interactive = true;
sortButton.down = function () {
// Play interface sound
LK.getSound('InterfazSound').play();
changeSortOrder();
};
// Create sort text to show current sort order
var sortText = new Text2("★↑", {
size: 90,
fill: 0x000000
});
sortText.anchor.set(0.5, 0.5);
sortText.x = sortButton.x;
sortText.y = sortButton.y + 35;
// Position the interface at the top of BGMenu
interfaz.x = bgMenu.width / 2;
interfaz.y = bgMenu.y;
// Create left button
var leftButton = LK.getAsset('BotonChange', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: -1,
// Flip horizontally to point left
x: -800,
y: interfaz.height / 2
});
// Add event handlers for left button
leftButton.interactive = true;
// Create right button
var rightButton = LK.getAsset('BotonChange', {
anchorX: 0.5,
anchorY: 0.5,
x: 800,
y: interfaz.height / 2
});
// Add event handlers for right button
rightButton.interactive = true;
var currentSlimeIndex = 0;
var currentSortOrder = 0; // 0: Ascending by rarity, 1: Descending by rarity, 2: A-Z by name, 3: Z-A by name
// Get language from storage with fallback to browser language or English
var currentLanguage = storage.language;
if (!currentLanguage || currentLanguage !== 'en' && currentLanguage !== 'es') {
// Try to detect browser language, defaulting to English if not supported
var browserLang = navigator && navigator.language ? navigator.language.substring(0, 2) : null;
currentLanguage = browserLang === 'es' ? 'es' : 'en';
storage.language = currentLanguage; // Save initial language to storage
}
// Language selector button
var languageButton = LK.getAsset('BotonExtras', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
x: 800,
y: -900
});
languageButton.interactive = true;
languageButton.down = function () {
// Play interface sound
LK.getSound('InterfazSound').play();
toggleLanguage();
};
// Language text display
var languageText = new Text2(currentLanguage.toUpperCase(), {
size: 70,
fill: 0x000000
});
languageText.anchor.set(0.5, 0.5);
languageText.x = languageButton.x;
languageText.y = languageButton.y + 35;
// Language translations
var translations = {
en: {
sortLabels: ["★↑", "★↓", "A→Z", "Z→A", "⚖↑", "⚖↓"],
categoryTitles: {
"Rarity": "Rarity",
"Size": "Size",
"History": "History",
"Location": "Location",
"Favorite Food": "Favorite Food",
"Ability": "Ability",
"Stats": "Stats",
"Lifespan": "Lifespan"
},
rarityNames: {
1: "Common",
2: "Uncommon",
3: "Infrequent",
4: "Rare",
5: "Epic",
6: "Exceptional",
7: "Legendary",
8: "Mythic",
9: "Arcane",
10: "Supreme"
},
sizeDescriptions: {
tiny: "Tiny",
small: "Small",
medium: "Medium",
large: "Large",
veryLarge: "Very Large",
enormous: "Enormous"
},
statNames: {
strength: "Strength",
agility: "Agility",
defense: "Defense",
magic: "Magic",
luck: "Luck",
mysticism: "Mysticism"
}
},
es: {
sortLabels: ["★↑", "★↓", "A→Z", "Z→A", "⚖↑", "⚖↓"],
categoryTitles: {
"Rarity": "Rareza",
"Size": "Tamaño",
"History": "Historia",
"Location": "Ubicación",
"Favorite Food": "Comida Favorita",
"Ability": "Habilidad",
"Stats": "Estadísticas",
"Lifespan": "Esperanza de vida"
},
rarityNames: {
1: "Común",
2: "Poco Común",
3: "Infrecuente",
4: "Raro",
5: "Épico",
6: "Excepcional",
7: "Legendario",
8: "Mtico",
9: "Arcano",
10: "Supremo"
},
sizeDescriptions: {
tiny: "Diminuto",
small: "Pequeño",
medium: "Mediano",
large: "Grande",
veryLarge: "Muy Grande",
enormous: "Enorme"
},
statNames: {
strength: "Fuerza",
agility: "Agilidad",
defense: "Defensa",
magic: "Magia",
luck: "Suerte",
mysticism: "Misticismo"
}
}
};
// Function to update all language-dependent UI elements
function updateLanguageUI() {
// Update language display
languageText.setText(currentLanguage.toUpperCase());
// Update sort labels
var sortLabels = translations[currentLanguage].sortLabels;
sortText.setText(sortLabels[currentSortOrder]);
// Update slime name display
var displayName = currentLanguage === 'en' ? slimeNames[currentSlimeIndex] : SlimeInfo[currentSlimeIndex].SlimeNameEs || slimeNames[currentSlimeIndex];
slimeNameText.setText(displayName);
// Update info panel with new language content
updateInfoPanel();
// Update music name overlay if visible
if (musicNameOverlay && musicNameOverlay.parent) {
musicNameOverlay.showRandomName(currentLanguage);
}
}
// Function to toggle between languages
function toggleLanguage() {
currentLanguage = currentLanguage === 'en' ? 'es' : 'en';
// Save language preference to storage
storage.language = currentLanguage;
// Update all UI elements with new language
updateLanguageUI();
}
// Function to sort slimes based on current sort order
function changeSortOrder() {
// Change sort order
currentSortOrder = (currentSortOrder + 1) % 6;
// Update sort text with current language
var sortLabels = translations[currentLanguage].sortLabels;
sortText.setText(sortLabels[currentSortOrder]);
// Sort SlimeInfo based on the selected order
if (currentSortOrder === 0) {
// Sort by rarity (ascending)
SlimeInfo.sort(function (a, b) {
return a.Rarity - b.Rarity;
});
} else if (currentSortOrder === 1) {
// Sort by rarity (descending)
SlimeInfo.sort(function (a, b) {
return b.Rarity - a.Rarity;
});
} else if (currentSortOrder === 2) {
// Sort alphabetically (A to Z)
SlimeInfo.sort(function (a, b) {
return a.SlimeName.localeCompare(b.SlimeName);
});
} else if (currentSortOrder === 3) {
// Sort alphabetically (Z to A)
SlimeInfo.sort(function (a, b) {
return b.SlimeName.localeCompare(a.SlimeName);
});
} else if (currentSortOrder === 4) {
// Sort by size (ascending)
SlimeInfo.sort(function (a, b) {
return (a.Size || 1.0) - (b.Size || 1.0);
});
} else {
// Sort by size (descending)
SlimeInfo.sort(function (a, b) {
return (b.Size || 1.0) - (a.Size || 1.0);
});
}
// Update arrays based on the new sorted SlimeInfo
slimes = SlimeInfo.map(function (slime) {
var slimeName = slime.SlimeName.replace(/\s+/g, '');
return slimeName;
});
slimeNames = SlimeInfo.map(function (slime) {
return slime.SlimeName;
});
rarityValues = SlimeInfo.map(function (slime) {
return slime.Rarity;
});
// Reset to first slime
currentSlimeIndex = 0;
updateSlimeAndInfo();
}
// Function to wrap text that exceeds screen width
function wrapText(text, maxWidth, textSize) {
if (!text) {
return "";
}
var words = text.split(' ');
var wrappedText = '',
line = '';
var charsPerLine = Math.floor(maxWidth / (textSize * 0.5));
for (var i = 0; i < words.length; i++) {
var testLine = line + words[i] + ' ';
if (testLine.length > charsPerLine) {
wrappedText += line.trim() + '\n';
line = words[i] + ' ';
} else {
line = testLine;
}
}
return wrappedText + line.trim();
}
// Create structured slime information
var rarityNamesByValue = {
1: "Common",
2: "Unusual",
3: "Uncommon",
4: "Remarkable",
5: "Rare",
6: "Exceptional",
7: "Mythical",
8: "Legendary",
9: "Ancient",
10: "Divine"
};
// Function to sort slimes by rarity from highest to lowest
function sortSlimesByRarity(slimes) {
return slimes.slice().sort(function (a, b) {
return b.Rarity - a.Rarity; // Sort in descending order (highest to lowest)
});
}
// Structured SlimeInfo array with all properties in a single place
var SlimeInfo = [{
SlimeName: 'Clasic Slime',
SlimeNameEs: 'Slime Clásico',
Rarity: 1,
Size: 1.0,
// Medium size (baseline)
History: 'The most common and friendly of all slimes, Clasic Slimes are believed to be the original form from which all other slimes evolved.',
HistoryEs: 'El más común y amigable de todos los slimes, los Slimes Clásicos son considerados la forma original de la que evolucionaron todos los demás slimes.',
Location: 'Meadows, gardens, and anywhere with fresh dew',
LocationEs: 'Praderas, jardines y cualquier lugar con rocío fresco',
FavoriteFood: 'Fresh grass and morning dew',
FavoriteFoodEs: 'Hierba fresca y rocío de la mañana',
Ability: 'Can split into two smaller slimes when threatened',
AbilityEs: 'Puede dividirse en dos slimes más pequeños cuando se siente amenazado',
Stats: {
strength: 3,
agility: 5,
defense: 2,
magic: 1,
luck: 2,
mysticism: 1
},
Lifespan: '5-8 years',
LifespanEs: '5-8 años'
}, {
SlimeName: 'Snowy Slime',
SlimeNameEs: 'Slime Nevado',
Rarity: 2,
Size: 0.9,
// Slightly smaller
History: 'Snowy Slimes are born from snowdrifts touched by moonlight. They are gentle and love cold climates.',
HistoryEs: 'Los Slimes Nevados nacen de ventisqueros tocados por la luz de la luna. Son gentiles y aman los climas fríos.',
Location: 'Snowfields, icy caves, and mountaintops',
LocationEs: 'Campos nevados, cuevas heladas y cimas de montañas',
FavoriteFood: 'Icicles and frozen berries',
FavoriteFoodEs: 'Carámbanos y bayas congeladas',
Ability: 'Can lower the temperature around them, freezing small puddles instantly',
AbilityEs: 'Puede bajar la temperatura a su alrededor, congelando pequeños charcos instantáneamente',
Stats: {
strength: 3,
agility: 2,
defense: 8,
magic: 6,
luck: 4,
mysticism: 5
},
Lifespan: '12-15 years',
LifespanEs: '12-15 años'
}, {
SlimeName: 'Water Slime',
SlimeNameEs: 'Slime Acuático',
Rarity: 3,
Size: 0.8,
// Small and fluid
History: 'Formed from enchanted raindrops, Water Slimes are playful and quick, often found near rivers.',
HistoryEs: 'Formados a partir de gotas de lluvia encantadas, los Slimes Acuáticos son juguetones y rápidos, a menudo encontrados cerca de ríos.',
Location: 'Lakes, rivers, and rainy forests',
LocationEs: 'Lagos, ríos y bosques lluviosos',
FavoriteFood: 'Pure spring water and water lilies',
FavoriteFoodEs: 'Agua pura de manantial y nenúfares',
Ability: 'Can merge with water to become invisible and move swiftly',
AbilityEs: 'Puede fusionarse con el agua para volverse invisible y moverse rápidamente',
Stats: {
strength: 2,
agility: 7,
defense: 1,
magic: 5,
luck: 4,
mysticism: 3
},
Lifespan: '8-12 years',
LifespanEs: '8-12 años'
}, {
SlimeName: 'Rock Slime',
SlimeNameEs: 'Slime Rocoso',
Rarity: 4,
Size: 1.3,
// Bulky and dense
History: 'Rock Slimes are the result of slimes living near mineral-rich caves, slowly absorbing stone and earth.',
HistoryEs: 'Los Slimes Rocosos son el resultado de slimes que viven cerca de cuevas ricas en minerales, absorbiendo lentamente piedra y tierra.',
Location: 'Caves, rocky hills, and mountain bases',
LocationEs: 'Cuevas, colinas rocosas y bases de montañas',
FavoriteFood: 'Pebbles and mineral-rich soil',
FavoriteFoodEs: 'Guijarros y tierra rica en minerales',
Ability: 'Can harden their bodies to become nearly unbreakable for short periods',
AbilityEs: 'Puede endurecer su cuerpo para volverse casi irrompible por cortos períodos',
Stats: {
strength: 8,
agility: 1,
defense: 9,
magic: 2,
luck: 3,
mysticism: 1
},
Lifespan: '20-30 years',
LifespanEs: '20-30 años'
}, {
SlimeName: 'Fire Slime',
SlimeNameEs: 'Slime de Fuego',
Rarity: 5,
Size: 1.1,
// Slightly larger due to heat expansion
History: 'Fire Slimes are born from the embers of ancient volcanoes, carrying a spark of elemental fire within.',
HistoryEs: 'Los Slimes de Fuego nacen de las brasas de antiguos volcanes, llevando una chispa de fuego elemental en su interior.',
Location: 'Volcanoes, hot springs, and scorched plains',
LocationEs: 'Volcanes, aguas termales y llanuras calcinadas',
FavoriteFood: 'Charcoal and spicy peppers',
FavoriteFoodEs: 'Carbón y pimientos picantes',
Ability: 'Can ignite themselves to ward off predators and light dark places',
AbilityEs: 'Puede encenderse para ahuyentar a los depredadores e iluminar lugares oscuros',
Stats: {
strength: 6,
agility: 3,
defense: 4,
magic: 7,
luck: 2,
mysticism: 6
},
Lifespan: '10-15 years'
}, {
SlimeName: 'Shadow Slime',
SlimeNameEs: 'Slime de Sombra',
Rarity: 6,
Size: 1.2,
// Larger and imposing
History: 'Shadow Slimes are born in places untouched by light, absorbing the darkness around them.',
HistoryEs: 'Los Slimes de Sombra nacen en lugares donde la luz nunca llega, absorbiendo la oscuridad a su alrededor.',
Location: 'Caverns, abandoned ruins, and deep forests at night',
LocationEs: 'Cavernas, ruinas abandonadas y bosques profundos durante la noche',
FavoriteFood: 'Shadows and nocturnal insects',
FavoriteFoodEs: 'Sombras e insectos nocturnos',
Ability: 'Can blend into shadows and become nearly invisible',
AbilityEs: 'Puede fundirse con las sombras y volverse casi invisible',
Stats: {
strength: 5,
agility: 8,
defense: 3,
magic: 9,
luck: 6,
mysticism: 8
},
Lifespan: '30-40 years',
LifespanEs: '30-40 años'
}, {
SlimeName: 'Forest Slime',
SlimeNameEs: 'Slime de Bosque',
Rarity: 7,
Size: 1.15,
// Healthy and lush
History: 'Forest Slimes are the guardians of ancient woods, formed from moss and enchanted leaves.',
HistoryEs: 'Los Slimes de Bosque son guardianes de los bosques antiguos, formados de musgo y hojas encantadas.',
Location: 'Dense forests, groves, and magical thickets',
LocationEs: 'Bosques densos, arboledas y matorrales mágicos',
FavoriteFood: 'Moss, leaves, and wildflowers',
FavoriteFoodEs: 'Musgo, hojas y flores silvestres',
Ability: 'Can heal plants and accelerate their growth',
AbilityEs: 'Puede curar plantas y acelerar su crecimiento',
Stats: {
strength: 4,
agility: 6,
defense: 5,
magic: 8,
luck: 5,
mysticism: 7
},
Lifespan: '25-35 years',
LifespanEs: '25-35 años'
}, {
SlimeName: 'Beast Slime',
SlimeNameEs: 'Slime Bestia',
Rarity: 8,
Size: 1.4,
// Large and intimidating
History: 'Beast Slimes are fierce and wild, believed to have evolved by mimicking the strongest animals in their environment.',
HistoryEs: 'Los Slimes Bestia son feroces y salvajes, se cree que evolucionaron imitando a los animales más fuertes de su entorno.',
Location: 'Savannahs, jungles, and wild plains',
LocationEs: 'Sabanas, selvas y llanuras salvajes',
FavoriteFood: 'Raw meat and wild fruits',
FavoriteFoodEs: 'Carne cruda y frutas silvestres',
Ability: 'Can roar to intimidate foes and temporarily boost their own strength',
AbilityEs: 'Puede rugir para intimidar enemigos y aumentar temporalmente su fuerza',
Stats: {
strength: 9,
agility: 7,
defense: 7,
magic: 3,
luck: 8,
mysticism: 2
},
Lifespan: '18-25 years',
LifespanEs: '18-25 años'
}, {
SlimeName: 'Lucky Slime',
SlimeNameEs: 'Slime de la Suerte',
Rarity: 8,
Size: 0.95,
// Medium-small for good luck
History: 'Lucky Slimes are said to be born during rare celestial events, bringing fortune to those who find them.',
HistoryEs: 'Se dice que los Slimes de la Suerte nacen durante eventos celestiales raros, trayendo fortuna a quienes los encuentran.',
Location: 'Rainbow fields, clover patches, and near waterfalls',
LocationEs: 'Campos de arcoíris, parches de tréboles y cerca de cascadas',
FavoriteFood: 'Four-leaf clovers and golden apples',
FavoriteFoodEs: 'Tréboles de cuatro hojas y manzanas doradas',
Ability: 'Can increase the luck of nearby creatures and find hidden treasures',
AbilityEs: 'Puede aumentar la suerte de criaturas cercanas y encontrar tesoros ocultos',
Stats: {
strength: 3,
agility: 5,
defense: 2,
magic: 6,
luck: 10,
mysticism: 4
},
Lifespan: '10-20 years',
LifespanEs: '10-20 años'
}, {
SlimeName: 'Runic Slime',
SlimeNameEs: 'Slime Rúnico',
Rarity: 9,
Size: 1.25,
// Large with ornate runes
History: 'Runic Slimes are ancient beings, their bodies inscribed with glowing runes of power.',
HistoryEs: 'Los Slimes Rúnicos son seres antiguos, sus cuerpos están inscritos con runas brillantes de poder.',
Location: 'Ancient temples, rune circles, and magical libraries',
LocationEs: 'Templos antiguos, círculos de runas y bibliotecas mágicas',
FavoriteFood: 'Enchanted stones and magical scrolls',
FavoriteFoodEs: 'Piedras encantadas y pergaminos mágicos',
Ability: 'Can cast simple spells and decipher ancient languages',
AbilityEs: 'Puede lanzar hechizos simples y descifrar lenguas antiguas',
Stats: {
strength: 5,
agility: 4,
defense: 3,
magic: 9,
luck: 7,
mysticism: 10
},
Lifespan: '50-100 years',
LifespanEs: '50-100 años'
}, {
SlimeName: 'Divine Slime',
SlimeNameEs: 'Slime Divino',
Rarity: 10,
Size: 1.5,
// Majestic and grand
History: 'Divine Slimes are legendary, said to descend from the heavens during times of great need.',
HistoryEs: 'Los Slimes Divinos son legendarios, se dice que descienden de los cielos en tiempos de gran necesidad.',
Location: 'Sacred groves, mountaintops, and places of worship',
LocationEs: 'Arboledas sagradas, cimas de montañas y lugares de culto',
FavoriteFood: 'Nectar from sacred flowers and pure spring water',
FavoriteFoodEs: 'Néctar de flores sagradas y agua de manantial pura',
Ability: 'Can heal wounds and purify water with a touch',
AbilityEs: 'Puede curar heridas y purificar agua con solo tocarla',
Stats: {
strength: 7,
agility: 4,
defense: 6,
magic: 10,
luck: 10,
mysticism: 9
},
Lifespan: 'Unknown, possibly eternal',
LifespanEs: 'Desconocida, posiblemente eterna'
}, {
SlimeName: 'Fruit Slime',
SlimeNameEs: 'Slime Fruta',
Rarity: 5,
Size: 1.05,
// Plump and juicy
History: 'Born from the essence of vibrant orchards, Fruit Slimes emerged when magical runoff seeped into ancient fruit groves.',
HistoryEs: 'Nacidos de la esencia de huertos vibrantes, los Slimes Fruta surgieron cuando la magia se filtró en antiguos huertos de frutas.',
Location: 'Orchards, fruit markets, and gardens with sweet-smelling blossoms',
LocationEs: 'Huertos, mercados de frutas y jardines con flores fragantes',
FavoriteFood: 'Overripe fruits and berry preserves',
FavoriteFoodEs: 'Frutas demasiado maduras y conservas de bayas',
Ability: 'Can change color based on the last fruit consumed, and releases a sweet aroma that calms nearby creatures',
AbilityEs: 'Puede cambiar de color según la última fruta consumida y libera un aroma dulce que calma a las criaturas cercanas',
Stats: {
strength: 4,
agility: 6,
defense: 3,
magic: 7,
luck: 6,
mysticism: 5
},
Lifespan: '15-20 years, longer if fed a varied diet of exotic fruits',
LifespanEs: '15-20 años, más si se alimenta con una dieta variada de frutas exóticas'
}, {
SlimeName: 'Ghost Slime',
SlimeNameEs: 'Slime Fantasma',
Rarity: 7,
Size: 1.1,
// Ethereal and wispy
History: 'Ghost Slimes formed when regular slimes wandered into haunted areas and absorbed spectral essence, gaining ethereal properties.',
HistoryEs: 'Los Slimes Fantasma se formaron cuando slimes comunes vagaron por zonas embrujadas y absorbieron esencia espectral, obteniendo propiedades etéreas.',
Location: 'Abandoned buildings, ancient ruins, and places with strong spiritual energy',
LocationEs: 'Edificios abandonados, ruinas antiguas y lugares con fuerte energía espiritual',
FavoriteFood: 'Emotions, particularly nostalgia and melancholy',
FavoriteFoodEs: 'Emociones, especialmente nostalgia y melancolía',
Ability: 'Can phase through solid objects and temporarily become invisible when threatened',
AbilityEs: 'Puede atravesar objetos sólidos y volverse invisible temporalmente cuando se siente amenazado',
Stats: {
strength: 2,
agility: 7,
defense: 3,
magic: 9,
luck: 6,
mysticism: 8
},
Lifespan: 'Potentially immortal, though they can fade away if they lose their spectral essence',
LifespanEs: 'Potencialmente inmortal, aunque pueden desvanecerse si pierden su esencia espectral'
}, {
SlimeName: 'King Slime',
SlimeNameEs: 'Rey Slime',
Rarity: 9,
Size: 1.6,
// Royal and massive
History: 'The legendary King Slime is said to be born once a century when a slime absorbs royal essence from an ancient crown.',
HistoryEs: 'Se dice que el legendario Rey Slime nace una vez cada siglo cuando un slime absorbe la esencia real de una corona antigua.',
Location: 'Hidden chambers in royal castles and within the deepest parts of enchanted forests',
LocationEs: 'Cámaras ocultas en castillos reales y en las partes más profundas de bosques encantados',
FavoriteFood: 'Precious metals and gems, particularly gold and rubies',
FavoriteFoodEs: 'Metales preciosos y gemas, especialmente oro y rubíes',
Ability: 'Can command lesser slimes and temporarily grow to massive size, becoming nearly invulnerable',
AbilityEs: 'Puede comandar slimes menores y crecer temporalmente a un tamaño masivo, volviéndose casi invulnerable',
Stats: {
strength: 8,
agility: 4,
defense: 8,
magic: 7,
luck: 7,
mysticism: 9
},
Lifespan: 'Over 200 years, with some specimens reported to live for millennia',
LifespanEs: 'Más de 200 años, con algunos ejemplares reportados viviendo milenios'
}, {
SlimeName: 'Golden Slime',
SlimeNameEs: 'Slime Dorado',
Rarity: 10,
Size: 1.35,
// Substantial and solid
History: 'Golden Slimes are incredibly rare mutations that occur when a slime is exposed to concentrated alchemical gold for generations.',
HistoryEs: 'Los Slimes Dorados son mutaciones increíblemente raras que ocurren cuando un slime es expuesto a oro alquímico concentrado durante generaciones.',
Location: 'Ancient treasure vaults, alchemist laboratories, and the hearts of mountains rich with gold deposits',
LocationEs: 'Antiguas bóvedas de tesoros, laboratorios de alquimistas y el corazón de montañas ricas en oro',
FavoriteFood: 'Gold dust and magical essences',
FavoriteFoodEs: 'Polvo de oro y esencias mágicas',
Ability: 'Turns objects it consumes partially to gold and can detect precious metals at great distances',
AbilityEs: 'Convierte parcialmente en oro los objetos que consume y puede detectar metales preciosos a grandes distancias',
Stats: {
strength: 6,
agility: 3,
defense: 9,
magic: 8,
luck: 10,
mysticism: 8
},
Lifespan: 'Virtually immortal as long as they consume small amounts of gold regularly',
LifespanEs: 'Prácticamente inmortal mientras consuma pequeñas cantidades de oro regularmente'
}];
// Sort SlimeInfo by rarity (highest to lowest)
SlimeInfo = sortSlimesByRarity(SlimeInfo);
// Update slimes array based on the new sorted SlimeInfo
slimes = SlimeInfo.map(function (slime, index) {
// Get the appropriate slime asset name based on the SlimeName
var slimeName = slime.SlimeName.replace(/\s+/g, '');
return slimeName;
});
// Extract arrays for backward compatibility and easier access
var slimeNames = SlimeInfo.map(function (slime) {
return slime.SlimeName;
});
// Array for Spanish slime names
var slimeNamesEs = SlimeInfo.map(function (slime) {
return slime.SlimeNameEs || slime.SlimeName;
});
var rarityValues = SlimeInfo.map(function (slime) {
return slime.Rarity;
});
var histories = SlimeInfo.map(function (slime) {
return slime.History;
});
var locations = SlimeInfo.map(function (slime) {
return slime.Location;
});
var favoriteFoods = SlimeInfo.map(function (slime) {
return slime.FavoriteFood;
});
var abilities = SlimeInfo.map(function (slime) {
return slime.Ability;
});
var stats = SlimeInfo.map(function (slime) {
return slime.Stats;
});
var lifespans = SlimeInfo.map(function (slime) {
return slime.Lifespan;
});
// Create text display for slime name
var slimeNameText = new Text2(slimeNames[currentSlimeIndex], {
size: 100,
fill: 0xFFFFFF
});
slimeNameText.anchor.set(0.5, 0.5);
slimeNameText.x = 0;
slimeNameText.y = interfaz.height / 2;
// Create a slime and add it to the scene
var slime = new Slime();
// Position slime at the center of BG but lower down and set base position
var centerX = bg.width / 2;
var centerY = bg.height / 2 + 220; // Lower position
slime.setBasePosition(centerX, centerY);
// Set initial properties for animations
slime.alpha = 1;
slime.scaleX = 1;
slime.scaleY = 1;
// Music array for random background music selection
var musicTracks = ['BGSong', 'BGSong2', 'BGSong3', 'BGSong4', 'BGSong5'];
var currentMusicIndex = -1;
// Music name overlay to display song names
var musicNameOverlay = new MusicNameOverlay();
// Function to play a random music track
function playRandomMusic() {
var newIndex;
// Make sure we don't play the same track twice in a row
do {
newIndex = Math.floor(Math.random() * musicTracks.length);
} while (newIndex === currentMusicIndex && musicTracks.length > 1);
currentMusicIndex = newIndex;
LK.playMusic(musicTracks[currentMusicIndex]);
// Show random music name with current language
// Make a safe call to ensure language is correctly set
if (musicNameOverlay) {
musicNameOverlay.showRandomName(currentLanguage);
}
}
// Play initial random music
playRandomMusic();
// Set up music change timer (1:40 minutes = 100,000 milliseconds)
LK.setInterval(playRandomMusic, 100000);
// --- Info Panel for BGMenu ---
var infoPanelHeight = bgMenu.height - interfaz.height - 40;
var infoPanelWidth = bgMenu.width;
var infoPanelY = bgMenu.y + interfaz.height + 20;
var infoPanelX = bgMenu.x + (bgMenu.width - infoPanelWidth) / 2; // Center horizontally
// Create a container for the info panel
var infoPanel = new Container();
infoPanel.x = infoPanelX;
infoPanel.y = infoPanelY;
// No background for the info panel
// Prepare info categories and data
var infoCategories = [{
title: "Rarity",
get: function get(i) {
var rarityValue = SlimeInfo[i].Rarity;
this.currentRarityValue = rarityValue;
// Return translated rarity name
return translations[currentLanguage].rarityNames[rarityValue];
}
}, {
title: "Size",
get: function get(i) {
var sizeValue = SlimeInfo[i].Size || 1.0;
var sizeKey;
if (sizeValue <= 0.8) {
sizeKey = "tiny";
} else if (sizeValue <= 0.95) {
sizeKey = "small";
} else if (sizeValue <= 1.1) {
sizeKey = "medium";
} else if (sizeValue <= 1.3) {
sizeKey = "large";
} else if (sizeValue <= 1.5) {
sizeKey = "veryLarge";
} else {
sizeKey = "enormous";
}
var sizeDescription = translations[currentLanguage].sizeDescriptions[sizeKey];
return sizeDescription + " (" + sizeValue.toFixed(2) + "x scale)";
}
}, {
title: "History",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].History : SlimeInfo[i].HistoryEs || SlimeInfo[i].History;
}
}, {
title: "Location",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].Location : SlimeInfo[i].LocationEs || SlimeInfo[i].Location;
}
}, {
title: "Favorite Food",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].FavoriteFood : SlimeInfo[i].FavoriteFoodEs || SlimeInfo[i].FavoriteFood;
}
}, {
title: "Ability",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].Ability : SlimeInfo[i].AbilityEs || SlimeInfo[i].Ability;
}
}, {
title: "Stats",
get: function get(i) {
var s = SlimeInfo[i].Stats;
// Create visual stat bars with colored values using actual colors instead of tags
function formatStat(name, value) {
var barChars = "■".repeat(value);
var emptyChars = "□".repeat(10 - value);
// Translate stat name based on current language
var translatedName = translations[currentLanguage].statNames[name.toLowerCase()] || name;
return translatedName + ": " + value + " [" + barChars + emptyChars + "]";
}
// Create a single column with all 6 stats
var statText = "";
statText += formatStat("strength", s.strength) + "\n";
statText += formatStat("agility", s.agility) + "\n";
statText += formatStat("defense", s.defense) + "\n";
statText += formatStat("magic", s.magic) + "\n";
statText += formatStat("luck", s.luck) + "\n";
statText += formatStat("mysticism", s.mysticism);
return statText;
}
}, {
title: "Lifespan",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].Lifespan : SlimeInfo[i].LifespanEs || SlimeInfo[i].Lifespan;
}
}];
// Create a container for the scrollable text
var infoTextContainer = new Container();
infoTextContainer.x = 30;
infoTextContainer.y = 30; // Add top margin
// Function to update info text for current slime
function updateInfoPanel() {
// Remove old children
infoTextContainer.removeChildren();
var y = 0;
for (var c = 0; c < infoCategories.length; c++) {
// Add extra spacing between sections if not the first section
if (c > 0) {
y += 80; // Add extra spacing between sections
}
// Title with gradient effect based on category
var titleColors = {
"Rarity": 0xFFD700,
"History": 0xCF9FFF,
"Location": 0x98FB98,
"Favorite Food": 0xFF7F50,
"Ability": 0x00BFFF,
"Stats": 0xFF1493,
"Lifespan": 0x00FA9A
};
var titleColor = titleColors[infoCategories[c].title] || 0xFFF7B2;
// Get translated title
var translatedTitle = translations[currentLanguage].categoryTitles[infoCategories[c].title] || infoCategories[c].title;
var titleText = new Text2(translatedTitle, {
size: 110,
fill: titleColor,
font: "GillSans-Bold",
align: "center",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 3,
dropShadowAlpha: 0.5
});
titleText.anchor.set(0.5, 0);
titleText.x = infoPanelWidth / 2 - 30;
titleText.y = y;
infoTextContainer.addChild(titleText);
y += titleText.height + 6;
// Info - wrap text to fit screen width
var infoContent = infoCategories[c].get(currentSlimeIndex);
var wrappedText = infoContent;
// Only apply text wrapping if not the stats category (which already has formatting)
if (infoCategories[c].title !== "Stats") {
wrappedText = wrapText(infoContent, infoPanelWidth - 60, 85); // Wrap text with some padding
}
// Choose text color based on category
var textColors = {
"Rarity": 0xFFFACD,
"History": 0xE6E6FA,
"Location": 0xF0FFF0,
"Favorite Food": 0xFFE4E1,
"Ability": 0xE0FFFF,
"Stats": 0xFFE4E1,
"Lifespan": 0xF0FFFF
};
var textColor = textColors[infoCategories[c].title] || 0xFFFFFF;
var infoText = new Text2(wrappedText, {
size: 85,
fill: textColor,
font: "GillSans",
align: infoCategories[c].title === "Stats" ? "left" : "center",
dropShadow: true,
dropShadowColor: 0x333333,
dropShadowDistance: 2,
dropShadowAlpha: 0.3
});
// Set anchor based on content type
if (infoCategories[c].title === "Stats") {
infoText.anchor.set(0.5, 0); // Center align stats too
infoText.x = infoPanelWidth / 2 - 30;
} else {
infoText.anchor.set(0.5, 0); // Center align for other content
infoText.x = infoPanelWidth / 2 - 30;
}
infoText.y = y + 20;
infoTextContainer.addChild(infoText);
// If this is the rarity category, add colored stars
if (infoCategories[c].title === "Rarity" && infoCategories[c].currentRarityValue) {
var starContainer = new Container();
starContainer.x = infoPanelWidth / 2 - 30;
starContainer.y = y + infoText.height + 40;
var rarityValue = infoCategories[c].currentRarityValue;
var starSpacing = 110,
totalWidth = (rarityValue - 1) * starSpacing;
var startX = -totalWidth / 2;
for (var s = 0; s < rarityValue; s++) {
var star = new Star();
star.x = startX + s * starSpacing;
star.y = 20;
star.alpha = 0;
star.scale.x = star.scale.y = 0.5;
star.setColorByRarity(rarityValue);
starContainer.addChild(star);
(function (targetStar, delay) {
LK.setTimeout(function () {
tween(targetStar, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 400,
easing: tween.easeOut
});
}, delay);
})(star, s * 200);
}
infoTextContainer.addChild(starContainer);
y += 80;
}
y += infoText.height + 24;
}
infoTextContainer.totalHeight = y;
}
updateInfoPanel();
// --- Scrolling logic for info panel with visual enhancements ---
var scrollOffset = 0;
var maxScroll = 0;
function updateScrollLimits() {
maxScroll = Math.max(0, infoTextContainer.totalHeight - infoPanelHeight + 40 + 60); // Add 60px to account for top and bottom margins
// Clamp scrollOffset to valid range, no bounce, no tween
if (scrollOffset < 0) {
scrollOffset = 0;
}
if (scrollOffset > maxScroll) {
scrollOffset = maxScroll;
}
// Set position directly, no tween
infoTextContainer.y = 30 - scrollOffset;
}
updateScrollLimits();
// Touch/mouse drag to scroll with inertia and visual feedback
var isScrolling = false,
lastScrollY = 0,
scrollVelocity = 0,
lastScrollTime = 0,
scrollTweenActive = false,
scrollTracker = [];
infoPanel.interactive = true;
infoPanel.down = function (x, y, obj) {
isScrolling = true;
lastScrollY = y;
lastScrollTime = Date.now();
scrollTracker = [];
};
infoPanel.move = function (x, y, obj) {
if (isScrolling) {
var dy = y - lastScrollY;
scrollOffset -= dy;
updateScrollLimits();
lastScrollY = y;
}
};
infoPanel.up = function (x, y, obj) {
if (isScrolling) {
isScrolling = false;
// No inertia, no tween, just clamp and update position
updateScrollLimits();
}
};
// Unified handler for both navigation buttons
function createButtonHandler(direction) {
return function (x, y, obj) {
changeSlime(direction);
updateInfoPanel();
updateScrollLimits();
};
}
leftButton.down = createButtonHandler('prev');
rightButton.down = createButtonHandler('next');
// When changing slime, update info panel and scroll position
function updateSlimeAndInfo() {
// Update slime name text first to fix the name display bug
var displayName = currentLanguage === 'en' ? slimeNames[currentSlimeIndex] : SlimeInfo[currentSlimeIndex].SlimeNameEs || slimeNames[currentSlimeIndex];
slimeNameText.setText(displayName);
// Stop existing tweens before starting new ones to prevent animation conflicts
tween.stop(slime);
// Enhanced slime transition effects with color flash and particle-like animation
tween(slime, {
alpha: 0,
scaleX: 0.8,
scaleY: 0.8,
rotation: -0.1
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Get the current slime asset name
var currentSlimeName = slimes[currentSlimeIndex];
// Remove old slime asset
if (slime.slimeAsset) {
slime.removeChild(slime.slimeAsset);
}
// Get new slime asset
slime.slimeAsset = slime.attachAsset(currentSlimeName, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply day/night effect immediately after creating the new slime
if (!isDayTime && slime.slimeAsset) {
slime.slimeAsset.tint = darkTint;
}
// Get the size multiplier from SlimeInfo and apply it to the base scale
var sizeMultiplier = SlimeInfo[currentSlimeIndex].Size || 1.0;
// Apply the consistent scale to maintain proper sizing, adjusted by slime-specific size
slime.slimeAsset.scale.set(slime.baseScale * sizeMultiplier);
// Reset to base position to prevent drift, but adjust Y position based on size
// This ensures all slimes appear to be on the same baseline regardless of size
slime.x = slime.baseX;
// Calculate Y offset based on size to keep bottom of slime at same level
// Larger slimes need to be positioned higher to maintain same baseline
var yOffset = (sizeMultiplier - 1.0) * slime.slimeAsset.height * slime.baseScale * 0.5;
slime.y = slime.baseY - yOffset;
slime.alpha = 0;
slime.scaleX = 0.3;
slime.scaleY = 0.3;
slime.rotation = 0.1;
// More dynamic entrance animation
tween(slime, {
alpha: 1,
scaleX: 1,
scaleY: 1,
rotation: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(slime, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 500,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Day/night effect already applied before animation
}
});
}
});
}
});
// Update content and scroll position
updateInfoPanel();
scrollOffset = 0;
updateScrollLimits();
// Fade in info container
infoTextContainer.alpha = 0;
tween(infoTextContainer, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}
function changeSlime(direction) {
currentSlimeIndex = direction === 'next' ? (currentSlimeIndex + 1) % slimes.length : (currentSlimeIndex - 1 + slimes.length) % slimes.length;
updateSlimeAndInfo();
// Day/night effect now applied in updateSlimeAndInfo before animation
}
/*
* Asset initialization
*/
// Add elements to game content container instead of directly to game
gameContent.addChild(bgMenu);
gameContent.addChild(infoPanel);
infoPanel.addChild(infoTextContainer);
gameContent.addChild(bg);
gameContent.addChild(interfaz);
interfaz.addChild(leftButton);
interfaz.addChild(rightButton);
interfaz.addChild(slimeNameText);
interfaz.addChild(sortButton);
interfaz.addChild(sortText);
interfaz.addChild(languageButton);
interfaz.addChild(languageText);
gameContent.addChild(slime);
gameContent.addChild(musicNameOverlay);
// Add the game content container to the game
game.addChild(gameContent);
// Initialize with ascending order (1->10) as default sort
currentSortOrder = 0;
SlimeInfo.sort(function (a, b) {
return a.Rarity - b.Rarity;
});
// Update arrays based on the sorted SlimeInfo
slimes = SlimeInfo.map(function (slime) {
var slimeName = slime.SlimeName.replace(/\s+/g, '');
return slimeName;
});
slimeNames = SlimeInfo.map(function (slime) {
return slime.SlimeName;
});
rarityValues = SlimeInfo.map(function (slime) {
return slime.Rarity;
});
// Reset to first slime and update display with proper language
currentSlimeIndex = 0;
updateSlimeAndInfo();
// Initialize all UI elements with correct language
updateLanguageUI();
// Initial day/night check
isDayTime = checkDayTime();
applyDayNightEffect();
// Set up timer to check day/night status every minute
LK.setInterval(function () {
var newIsDayTime = checkDayTime();
if (newIsDayTime !== isDayTime) {
isDayTime = newIsDayTime;
applyDayNightEffect();
}
}, 60000); // Check every minute
// Function to apply day/night effect to background and slimes
function applyDayNightEffect() {
if (isDayTime) {
// Day time - normal colors
bg.tint = 0xFFFFFF;
if (slime && slime.slimeAsset) {
slime.slimeAsset.tint = 0xFFFFFF;
}
} else {
// Night time - darken everything
bg.tint = darkTint;
if (slime && slime.slimeAsset) {
slime.slimeAsset.tint = darkTint;
}
}
} /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
persistLanguage: true,
language: "en"
});
/****
* Classes
****/
var MusicNameOverlay = Container.expand(function () {
var self = Container.call(this);
// Text for displaying music name
var musicText = new Text2("", {
size: 110,
fill: 0x000000,
align: "center",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 3,
dropShadowAlpha: 0.5
});
musicText.anchor.set(0.5, 0.5);
musicText.x = 2048 / 2;
musicText.y = 150;
musicText.alpha = 0;
self.addChild(musicText);
// Random fake music names in different languages
var musicNames = {
en: ["Slime Symphony No. 5", "Bouncy Beats", "Gelatinous Groove", "Blob Bop", "Jiggle Jam", "Slimy Sonata", "Elasticity Etude", "Viscous Vibes", "Gooey Grooves", "Jiggly Jazz", "Will anyone read this?"],
es: ["Sinfonía de Slime No. 5", "Ritmos Rebotantes", "Ritmo Gelatinoso", "Bop de Burbuja", "Mermelada Temblorosa", "Sonata Viscosa", "Estudio Elastico", "Vibraciones Viscosas", "Ritmos Pegajosos", "Jazz Tembloroso", "¿Alguien leerá esto?"]
};
// Show a random music name
self.showRandomName = function (language) {
var names = musicNames[language] || musicNames.en;
var randomName = names[Math.floor(Math.random() * names.length)];
// Stop any running animations
tween.stop(musicText);
// Set the text
musicText.setText(randomName);
// Fade in and move up animation sequence
musicText.alpha = 0;
musicText.y = 180;
// First animation: fade in and move to position
tween(musicText, {
alpha: 1,
y: 150
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
// Wait a bit then fade out and move up
LK.setTimeout(function () {
tween(musicText, {
alpha: 0,
y: 100
}, {
duration: 1200,
easing: tween.easeIn
});
}, 3000);
}
});
};
return self;
});
var Slime = Container.expand(function () {
var self = Container.call(this);
// Create and attach the slime asset with consistent scaling
// We won't set width/height here because we'll set a consistent scale instead
self.slimeAsset = self.attachAsset('ClasicSlime', {
anchorX: 0.5,
anchorY: 0.5
});
// Set consistent scale factor for all slimes
self.baseScale = 3.5; // Reduced base scaling factor
self.lastX = self.lastY = 0;
self.baseX = 0;
self.baseY = 0;
self.setBasePosition = function (x, y) {
self.baseX = x;
self.baseY = y;
self.x = x;
self.y = y;
};
self.update = function () {
self.lastX = self.x;
self.lastY = self.y;
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var starGraphics = self.attachAsset('Star', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 100
});
self.setColorByRarity = function (rarityLevel) {
// Create a smooth gradient from gray (common) to dark purple (highest rarity)
// Use a gradient color scheme for better visual differentiation
var colors = [0xaaaaaa,
// 1: Gray (Common)
0x8ab4f8,
// 2: Light blue
0x52cca3,
// 3: Teal
0x1e88e5,
// 4: Blue
0x7e57c2,
// 5: Light purple
0xab47bc,
// 6: Purple
0x8e24aa,
// 7: Dark purple
0x6a1b9a,
// 8: Deeper purple
0x4a148c,
// 9: Very dark purple
0x38006b // 10: Darkest purple (Supreme)
];
starGraphics.tint = rarityLevel >= 1 && rarityLevel <= 10 ? colors[rarityLevel - 1] : colors[0];
// Create glow effect with subtle pulsation
self.glowIntensity = 0.2 + rarityLevel / 10;
LK.setTimeout(function () {
tween(starGraphics, {
scaleX: 1 + self.glowIntensity * 0.1,
scaleY: 1 + self.glowIntensity * 0.1
}, {
duration: 1000 + rarityLevel * 100,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
}, Math.random() * 500);
};
return self;
});
var StartScreen = Container.expand(function () {
var self = Container.call(this);
// Create background for start screen
var startBg = self.attachAsset('BGInitial', {
anchorX: 0,
anchorY: 0,
width: 2048,
height: 2732
});
// Add title screen image using TittleAsset
var titleImage = self.attachAsset('TittleAsset', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 - 300,
scaleX: 1.2,
scaleY: 1.2
});
// Title is now included in the TittleAsset
// No tap to start text - removed as requested
// Make the start screen interactive
self.interactive = true;
// When screen is tapped, trigger the transition
self.down = function () {
if (self.onStart) {
// Clear the auto-start timer if it exists
if (autoStartTimer) {
LK.clearTimeout(autoStartTimer);
}
LK.getSound('InterfazSound').play();
// Create a darkening overlay
var darkOverlay = new Container();
var darkRect = LK.getAsset('transition', {
anchorX: 0,
anchorY: 0,
width: 2048,
height: 2732,
alpha: 0
});
darkOverlay.addChild(darkRect);
self.addChild(darkOverlay);
// Start darkening animation
tween(darkRect, {
alpha: 1.0
}, {
duration: 3000,
easing: tween.easeInOut
});
// Add rotation and falling animation to title image
if (titleImage) {
tween(titleImage, {
rotation: 0.2,
y: titleImage.y + 100
}, {
duration: 600,
easing: tween.easeIn,
onFinish: function onFinish() {
// Add pause before falling
LK.setTimeout(function () {
// Accelerate falling
tween(titleImage, {
y: 2732 + 500,
rotation: 0.5
}, {
duration: 1200,
easing: tween.easeIn,
onFinish: function onFinish() {
// Add delay before transitioning to give more time for cube to disappear
LK.setTimeout(function () {
// Call the actual transition
self.onStart();
}, 800);
}
});
}, 1000); // 1 second pause between rotation and falling
}
});
} // Close the if (titleImage) block
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Day/Night detection variables
var isDayTime = true;
var darkTint = 0x404060; // Dark blue-gray tint for night mode
// Function to check if it's day or night
function checkDayTime() {
var now = new Date();
var hours = now.getHours();
// Day is from 6 AM to 6 PM
return hours >= 6 && hours < 18;
}
// Create a container for game content that will appear from center
var gameContent = new Container();
gameContent.y = 0; // Position at normal position
gameContent.alpha = 0; // Start invisible
gameContent.scale.set(0.5); // Start small for zoom effect
// Create BGMenu for bottom half of screen
var bgMenu = LK.getAsset('BGMenu', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2032 / 2,
width: 2048,
height: 3532 / 2
});
// Create BG for top half of screen
var bg = LK.getAsset('BG', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: 2048,
height: 2032 / 2
});
// Create and add start screen
var startScreen = new StartScreen();
game.addChild(startScreen);
// Set up auto-start timer for 10 seconds
var autoStartTimer = LK.setTimeout(function () {
// Only trigger if startScreen still exists and has a parent
if (startScreen && startScreen.parent) {
startScreen.down(); // Simulate tap to start
}
}, 10000);
// Set up the transition function
startScreen.onStart = function () {
// Keep the darkening overlay visible until menu animation completes
// First animate the game content appearing from center
tween(gameContent, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 0,
easing: tween.easeOut,
onFinish: function onFinish() {
// Only after game content is positioned, fade out the start screen
// Add null check before tweening to prevent TypeError
if (startScreen) {
tween(startScreen, {
alpha: 0 // Fade out
}, {
duration: 5000,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Remove start screen when animation completes
if (startScreen && startScreen.parent) {
game.removeChild(startScreen);
startScreen = null;
}
}
});
}
}
});
};
// Create interface element at the top of BGMenu
var interfaz = LK.getAsset('Interfaz', {
anchorX: 0.5,
anchorY: 0,
width: 2048,
height: 400
});
// Create sort button at the top right of interface
var sortButton = LK.getAsset('BotonExtras', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
x: 800,
y: -700
});
// Add event handler for sort button
sortButton.interactive = true;
sortButton.down = function () {
// Play interface sound
LK.getSound('InterfazSound').play();
changeSortOrder();
};
// Create sort text to show current sort order
var sortText = new Text2("★↑", {
size: 90,
fill: 0x000000
});
sortText.anchor.set(0.5, 0.5);
sortText.x = sortButton.x;
sortText.y = sortButton.y + 35;
// Position the interface at the top of BGMenu
interfaz.x = bgMenu.width / 2;
interfaz.y = bgMenu.y;
// Create left button
var leftButton = LK.getAsset('BotonChange', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: -1,
// Flip horizontally to point left
x: -800,
y: interfaz.height / 2
});
// Add event handlers for left button
leftButton.interactive = true;
// Create right button
var rightButton = LK.getAsset('BotonChange', {
anchorX: 0.5,
anchorY: 0.5,
x: 800,
y: interfaz.height / 2
});
// Add event handlers for right button
rightButton.interactive = true;
var currentSlimeIndex = 0;
var currentSortOrder = 0; // 0: Ascending by rarity, 1: Descending by rarity, 2: A-Z by name, 3: Z-A by name
// Get language from storage with fallback to browser language or English
var currentLanguage = storage.language;
if (!currentLanguage || currentLanguage !== 'en' && currentLanguage !== 'es') {
// Try to detect browser language, defaulting to English if not supported
var browserLang = navigator && navigator.language ? navigator.language.substring(0, 2) : null;
currentLanguage = browserLang === 'es' ? 'es' : 'en';
storage.language = currentLanguage; // Save initial language to storage
}
// Language selector button
var languageButton = LK.getAsset('BotonExtras', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.8,
scaleY: 0.8,
x: 800,
y: -900
});
languageButton.interactive = true;
languageButton.down = function () {
// Play interface sound
LK.getSound('InterfazSound').play();
toggleLanguage();
};
// Language text display
var languageText = new Text2(currentLanguage.toUpperCase(), {
size: 70,
fill: 0x000000
});
languageText.anchor.set(0.5, 0.5);
languageText.x = languageButton.x;
languageText.y = languageButton.y + 35;
// Language translations
var translations = {
en: {
sortLabels: ["★↑", "★↓", "A→Z", "Z→A", "⚖↑", "⚖↓"],
categoryTitles: {
"Rarity": "Rarity",
"Size": "Size",
"History": "History",
"Location": "Location",
"Favorite Food": "Favorite Food",
"Ability": "Ability",
"Stats": "Stats",
"Lifespan": "Lifespan"
},
rarityNames: {
1: "Common",
2: "Uncommon",
3: "Infrequent",
4: "Rare",
5: "Epic",
6: "Exceptional",
7: "Legendary",
8: "Mythic",
9: "Arcane",
10: "Supreme"
},
sizeDescriptions: {
tiny: "Tiny",
small: "Small",
medium: "Medium",
large: "Large",
veryLarge: "Very Large",
enormous: "Enormous"
},
statNames: {
strength: "Strength",
agility: "Agility",
defense: "Defense",
magic: "Magic",
luck: "Luck",
mysticism: "Mysticism"
}
},
es: {
sortLabels: ["★↑", "★↓", "A→Z", "Z→A", "⚖↑", "⚖↓"],
categoryTitles: {
"Rarity": "Rareza",
"Size": "Tamaño",
"History": "Historia",
"Location": "Ubicación",
"Favorite Food": "Comida Favorita",
"Ability": "Habilidad",
"Stats": "Estadísticas",
"Lifespan": "Esperanza de vida"
},
rarityNames: {
1: "Común",
2: "Poco Común",
3: "Infrecuente",
4: "Raro",
5: "Épico",
6: "Excepcional",
7: "Legendario",
8: "Mtico",
9: "Arcano",
10: "Supremo"
},
sizeDescriptions: {
tiny: "Diminuto",
small: "Pequeño",
medium: "Mediano",
large: "Grande",
veryLarge: "Muy Grande",
enormous: "Enorme"
},
statNames: {
strength: "Fuerza",
agility: "Agilidad",
defense: "Defensa",
magic: "Magia",
luck: "Suerte",
mysticism: "Misticismo"
}
}
};
// Function to update all language-dependent UI elements
function updateLanguageUI() {
// Update language display
languageText.setText(currentLanguage.toUpperCase());
// Update sort labels
var sortLabels = translations[currentLanguage].sortLabels;
sortText.setText(sortLabels[currentSortOrder]);
// Update slime name display
var displayName = currentLanguage === 'en' ? slimeNames[currentSlimeIndex] : SlimeInfo[currentSlimeIndex].SlimeNameEs || slimeNames[currentSlimeIndex];
slimeNameText.setText(displayName);
// Update info panel with new language content
updateInfoPanel();
// Update music name overlay if visible
if (musicNameOverlay && musicNameOverlay.parent) {
musicNameOverlay.showRandomName(currentLanguage);
}
}
// Function to toggle between languages
function toggleLanguage() {
currentLanguage = currentLanguage === 'en' ? 'es' : 'en';
// Save language preference to storage
storage.language = currentLanguage;
// Update all UI elements with new language
updateLanguageUI();
}
// Function to sort slimes based on current sort order
function changeSortOrder() {
// Change sort order
currentSortOrder = (currentSortOrder + 1) % 6;
// Update sort text with current language
var sortLabels = translations[currentLanguage].sortLabels;
sortText.setText(sortLabels[currentSortOrder]);
// Sort SlimeInfo based on the selected order
if (currentSortOrder === 0) {
// Sort by rarity (ascending)
SlimeInfo.sort(function (a, b) {
return a.Rarity - b.Rarity;
});
} else if (currentSortOrder === 1) {
// Sort by rarity (descending)
SlimeInfo.sort(function (a, b) {
return b.Rarity - a.Rarity;
});
} else if (currentSortOrder === 2) {
// Sort alphabetically (A to Z)
SlimeInfo.sort(function (a, b) {
return a.SlimeName.localeCompare(b.SlimeName);
});
} else if (currentSortOrder === 3) {
// Sort alphabetically (Z to A)
SlimeInfo.sort(function (a, b) {
return b.SlimeName.localeCompare(a.SlimeName);
});
} else if (currentSortOrder === 4) {
// Sort by size (ascending)
SlimeInfo.sort(function (a, b) {
return (a.Size || 1.0) - (b.Size || 1.0);
});
} else {
// Sort by size (descending)
SlimeInfo.sort(function (a, b) {
return (b.Size || 1.0) - (a.Size || 1.0);
});
}
// Update arrays based on the new sorted SlimeInfo
slimes = SlimeInfo.map(function (slime) {
var slimeName = slime.SlimeName.replace(/\s+/g, '');
return slimeName;
});
slimeNames = SlimeInfo.map(function (slime) {
return slime.SlimeName;
});
rarityValues = SlimeInfo.map(function (slime) {
return slime.Rarity;
});
// Reset to first slime
currentSlimeIndex = 0;
updateSlimeAndInfo();
}
// Function to wrap text that exceeds screen width
function wrapText(text, maxWidth, textSize) {
if (!text) {
return "";
}
var words = text.split(' ');
var wrappedText = '',
line = '';
var charsPerLine = Math.floor(maxWidth / (textSize * 0.5));
for (var i = 0; i < words.length; i++) {
var testLine = line + words[i] + ' ';
if (testLine.length > charsPerLine) {
wrappedText += line.trim() + '\n';
line = words[i] + ' ';
} else {
line = testLine;
}
}
return wrappedText + line.trim();
}
// Create structured slime information
var rarityNamesByValue = {
1: "Common",
2: "Unusual",
3: "Uncommon",
4: "Remarkable",
5: "Rare",
6: "Exceptional",
7: "Mythical",
8: "Legendary",
9: "Ancient",
10: "Divine"
};
// Function to sort slimes by rarity from highest to lowest
function sortSlimesByRarity(slimes) {
return slimes.slice().sort(function (a, b) {
return b.Rarity - a.Rarity; // Sort in descending order (highest to lowest)
});
}
// Structured SlimeInfo array with all properties in a single place
var SlimeInfo = [{
SlimeName: 'Clasic Slime',
SlimeNameEs: 'Slime Clásico',
Rarity: 1,
Size: 1.0,
// Medium size (baseline)
History: 'The most common and friendly of all slimes, Clasic Slimes are believed to be the original form from which all other slimes evolved.',
HistoryEs: 'El más común y amigable de todos los slimes, los Slimes Clásicos son considerados la forma original de la que evolucionaron todos los demás slimes.',
Location: 'Meadows, gardens, and anywhere with fresh dew',
LocationEs: 'Praderas, jardines y cualquier lugar con rocío fresco',
FavoriteFood: 'Fresh grass and morning dew',
FavoriteFoodEs: 'Hierba fresca y rocío de la mañana',
Ability: 'Can split into two smaller slimes when threatened',
AbilityEs: 'Puede dividirse en dos slimes más pequeños cuando se siente amenazado',
Stats: {
strength: 3,
agility: 5,
defense: 2,
magic: 1,
luck: 2,
mysticism: 1
},
Lifespan: '5-8 years',
LifespanEs: '5-8 años'
}, {
SlimeName: 'Snowy Slime',
SlimeNameEs: 'Slime Nevado',
Rarity: 2,
Size: 0.9,
// Slightly smaller
History: 'Snowy Slimes are born from snowdrifts touched by moonlight. They are gentle and love cold climates.',
HistoryEs: 'Los Slimes Nevados nacen de ventisqueros tocados por la luz de la luna. Son gentiles y aman los climas fríos.',
Location: 'Snowfields, icy caves, and mountaintops',
LocationEs: 'Campos nevados, cuevas heladas y cimas de montañas',
FavoriteFood: 'Icicles and frozen berries',
FavoriteFoodEs: 'Carámbanos y bayas congeladas',
Ability: 'Can lower the temperature around them, freezing small puddles instantly',
AbilityEs: 'Puede bajar la temperatura a su alrededor, congelando pequeños charcos instantáneamente',
Stats: {
strength: 3,
agility: 2,
defense: 8,
magic: 6,
luck: 4,
mysticism: 5
},
Lifespan: '12-15 years',
LifespanEs: '12-15 años'
}, {
SlimeName: 'Water Slime',
SlimeNameEs: 'Slime Acuático',
Rarity: 3,
Size: 0.8,
// Small and fluid
History: 'Formed from enchanted raindrops, Water Slimes are playful and quick, often found near rivers.',
HistoryEs: 'Formados a partir de gotas de lluvia encantadas, los Slimes Acuáticos son juguetones y rápidos, a menudo encontrados cerca de ríos.',
Location: 'Lakes, rivers, and rainy forests',
LocationEs: 'Lagos, ríos y bosques lluviosos',
FavoriteFood: 'Pure spring water and water lilies',
FavoriteFoodEs: 'Agua pura de manantial y nenúfares',
Ability: 'Can merge with water to become invisible and move swiftly',
AbilityEs: 'Puede fusionarse con el agua para volverse invisible y moverse rápidamente',
Stats: {
strength: 2,
agility: 7,
defense: 1,
magic: 5,
luck: 4,
mysticism: 3
},
Lifespan: '8-12 years',
LifespanEs: '8-12 años'
}, {
SlimeName: 'Rock Slime',
SlimeNameEs: 'Slime Rocoso',
Rarity: 4,
Size: 1.3,
// Bulky and dense
History: 'Rock Slimes are the result of slimes living near mineral-rich caves, slowly absorbing stone and earth.',
HistoryEs: 'Los Slimes Rocosos son el resultado de slimes que viven cerca de cuevas ricas en minerales, absorbiendo lentamente piedra y tierra.',
Location: 'Caves, rocky hills, and mountain bases',
LocationEs: 'Cuevas, colinas rocosas y bases de montañas',
FavoriteFood: 'Pebbles and mineral-rich soil',
FavoriteFoodEs: 'Guijarros y tierra rica en minerales',
Ability: 'Can harden their bodies to become nearly unbreakable for short periods',
AbilityEs: 'Puede endurecer su cuerpo para volverse casi irrompible por cortos períodos',
Stats: {
strength: 8,
agility: 1,
defense: 9,
magic: 2,
luck: 3,
mysticism: 1
},
Lifespan: '20-30 years',
LifespanEs: '20-30 años'
}, {
SlimeName: 'Fire Slime',
SlimeNameEs: 'Slime de Fuego',
Rarity: 5,
Size: 1.1,
// Slightly larger due to heat expansion
History: 'Fire Slimes are born from the embers of ancient volcanoes, carrying a spark of elemental fire within.',
HistoryEs: 'Los Slimes de Fuego nacen de las brasas de antiguos volcanes, llevando una chispa de fuego elemental en su interior.',
Location: 'Volcanoes, hot springs, and scorched plains',
LocationEs: 'Volcanes, aguas termales y llanuras calcinadas',
FavoriteFood: 'Charcoal and spicy peppers',
FavoriteFoodEs: 'Carbón y pimientos picantes',
Ability: 'Can ignite themselves to ward off predators and light dark places',
AbilityEs: 'Puede encenderse para ahuyentar a los depredadores e iluminar lugares oscuros',
Stats: {
strength: 6,
agility: 3,
defense: 4,
magic: 7,
luck: 2,
mysticism: 6
},
Lifespan: '10-15 years'
}, {
SlimeName: 'Shadow Slime',
SlimeNameEs: 'Slime de Sombra',
Rarity: 6,
Size: 1.2,
// Larger and imposing
History: 'Shadow Slimes are born in places untouched by light, absorbing the darkness around them.',
HistoryEs: 'Los Slimes de Sombra nacen en lugares donde la luz nunca llega, absorbiendo la oscuridad a su alrededor.',
Location: 'Caverns, abandoned ruins, and deep forests at night',
LocationEs: 'Cavernas, ruinas abandonadas y bosques profundos durante la noche',
FavoriteFood: 'Shadows and nocturnal insects',
FavoriteFoodEs: 'Sombras e insectos nocturnos',
Ability: 'Can blend into shadows and become nearly invisible',
AbilityEs: 'Puede fundirse con las sombras y volverse casi invisible',
Stats: {
strength: 5,
agility: 8,
defense: 3,
magic: 9,
luck: 6,
mysticism: 8
},
Lifespan: '30-40 years',
LifespanEs: '30-40 años'
}, {
SlimeName: 'Forest Slime',
SlimeNameEs: 'Slime de Bosque',
Rarity: 7,
Size: 1.15,
// Healthy and lush
History: 'Forest Slimes are the guardians of ancient woods, formed from moss and enchanted leaves.',
HistoryEs: 'Los Slimes de Bosque son guardianes de los bosques antiguos, formados de musgo y hojas encantadas.',
Location: 'Dense forests, groves, and magical thickets',
LocationEs: 'Bosques densos, arboledas y matorrales mágicos',
FavoriteFood: 'Moss, leaves, and wildflowers',
FavoriteFoodEs: 'Musgo, hojas y flores silvestres',
Ability: 'Can heal plants and accelerate their growth',
AbilityEs: 'Puede curar plantas y acelerar su crecimiento',
Stats: {
strength: 4,
agility: 6,
defense: 5,
magic: 8,
luck: 5,
mysticism: 7
},
Lifespan: '25-35 years',
LifespanEs: '25-35 años'
}, {
SlimeName: 'Beast Slime',
SlimeNameEs: 'Slime Bestia',
Rarity: 8,
Size: 1.4,
// Large and intimidating
History: 'Beast Slimes are fierce and wild, believed to have evolved by mimicking the strongest animals in their environment.',
HistoryEs: 'Los Slimes Bestia son feroces y salvajes, se cree que evolucionaron imitando a los animales más fuertes de su entorno.',
Location: 'Savannahs, jungles, and wild plains',
LocationEs: 'Sabanas, selvas y llanuras salvajes',
FavoriteFood: 'Raw meat and wild fruits',
FavoriteFoodEs: 'Carne cruda y frutas silvestres',
Ability: 'Can roar to intimidate foes and temporarily boost their own strength',
AbilityEs: 'Puede rugir para intimidar enemigos y aumentar temporalmente su fuerza',
Stats: {
strength: 9,
agility: 7,
defense: 7,
magic: 3,
luck: 8,
mysticism: 2
},
Lifespan: '18-25 years',
LifespanEs: '18-25 años'
}, {
SlimeName: 'Lucky Slime',
SlimeNameEs: 'Slime de la Suerte',
Rarity: 8,
Size: 0.95,
// Medium-small for good luck
History: 'Lucky Slimes are said to be born during rare celestial events, bringing fortune to those who find them.',
HistoryEs: 'Se dice que los Slimes de la Suerte nacen durante eventos celestiales raros, trayendo fortuna a quienes los encuentran.',
Location: 'Rainbow fields, clover patches, and near waterfalls',
LocationEs: 'Campos de arcoíris, parches de tréboles y cerca de cascadas',
FavoriteFood: 'Four-leaf clovers and golden apples',
FavoriteFoodEs: 'Tréboles de cuatro hojas y manzanas doradas',
Ability: 'Can increase the luck of nearby creatures and find hidden treasures',
AbilityEs: 'Puede aumentar la suerte de criaturas cercanas y encontrar tesoros ocultos',
Stats: {
strength: 3,
agility: 5,
defense: 2,
magic: 6,
luck: 10,
mysticism: 4
},
Lifespan: '10-20 years',
LifespanEs: '10-20 años'
}, {
SlimeName: 'Runic Slime',
SlimeNameEs: 'Slime Rúnico',
Rarity: 9,
Size: 1.25,
// Large with ornate runes
History: 'Runic Slimes are ancient beings, their bodies inscribed with glowing runes of power.',
HistoryEs: 'Los Slimes Rúnicos son seres antiguos, sus cuerpos están inscritos con runas brillantes de poder.',
Location: 'Ancient temples, rune circles, and magical libraries',
LocationEs: 'Templos antiguos, círculos de runas y bibliotecas mágicas',
FavoriteFood: 'Enchanted stones and magical scrolls',
FavoriteFoodEs: 'Piedras encantadas y pergaminos mágicos',
Ability: 'Can cast simple spells and decipher ancient languages',
AbilityEs: 'Puede lanzar hechizos simples y descifrar lenguas antiguas',
Stats: {
strength: 5,
agility: 4,
defense: 3,
magic: 9,
luck: 7,
mysticism: 10
},
Lifespan: '50-100 years',
LifespanEs: '50-100 años'
}, {
SlimeName: 'Divine Slime',
SlimeNameEs: 'Slime Divino',
Rarity: 10,
Size: 1.5,
// Majestic and grand
History: 'Divine Slimes are legendary, said to descend from the heavens during times of great need.',
HistoryEs: 'Los Slimes Divinos son legendarios, se dice que descienden de los cielos en tiempos de gran necesidad.',
Location: 'Sacred groves, mountaintops, and places of worship',
LocationEs: 'Arboledas sagradas, cimas de montañas y lugares de culto',
FavoriteFood: 'Nectar from sacred flowers and pure spring water',
FavoriteFoodEs: 'Néctar de flores sagradas y agua de manantial pura',
Ability: 'Can heal wounds and purify water with a touch',
AbilityEs: 'Puede curar heridas y purificar agua con solo tocarla',
Stats: {
strength: 7,
agility: 4,
defense: 6,
magic: 10,
luck: 10,
mysticism: 9
},
Lifespan: 'Unknown, possibly eternal',
LifespanEs: 'Desconocida, posiblemente eterna'
}, {
SlimeName: 'Fruit Slime',
SlimeNameEs: 'Slime Fruta',
Rarity: 5,
Size: 1.05,
// Plump and juicy
History: 'Born from the essence of vibrant orchards, Fruit Slimes emerged when magical runoff seeped into ancient fruit groves.',
HistoryEs: 'Nacidos de la esencia de huertos vibrantes, los Slimes Fruta surgieron cuando la magia se filtró en antiguos huertos de frutas.',
Location: 'Orchards, fruit markets, and gardens with sweet-smelling blossoms',
LocationEs: 'Huertos, mercados de frutas y jardines con flores fragantes',
FavoriteFood: 'Overripe fruits and berry preserves',
FavoriteFoodEs: 'Frutas demasiado maduras y conservas de bayas',
Ability: 'Can change color based on the last fruit consumed, and releases a sweet aroma that calms nearby creatures',
AbilityEs: 'Puede cambiar de color según la última fruta consumida y libera un aroma dulce que calma a las criaturas cercanas',
Stats: {
strength: 4,
agility: 6,
defense: 3,
magic: 7,
luck: 6,
mysticism: 5
},
Lifespan: '15-20 years, longer if fed a varied diet of exotic fruits',
LifespanEs: '15-20 años, más si se alimenta con una dieta variada de frutas exóticas'
}, {
SlimeName: 'Ghost Slime',
SlimeNameEs: 'Slime Fantasma',
Rarity: 7,
Size: 1.1,
// Ethereal and wispy
History: 'Ghost Slimes formed when regular slimes wandered into haunted areas and absorbed spectral essence, gaining ethereal properties.',
HistoryEs: 'Los Slimes Fantasma se formaron cuando slimes comunes vagaron por zonas embrujadas y absorbieron esencia espectral, obteniendo propiedades etéreas.',
Location: 'Abandoned buildings, ancient ruins, and places with strong spiritual energy',
LocationEs: 'Edificios abandonados, ruinas antiguas y lugares con fuerte energía espiritual',
FavoriteFood: 'Emotions, particularly nostalgia and melancholy',
FavoriteFoodEs: 'Emociones, especialmente nostalgia y melancolía',
Ability: 'Can phase through solid objects and temporarily become invisible when threatened',
AbilityEs: 'Puede atravesar objetos sólidos y volverse invisible temporalmente cuando se siente amenazado',
Stats: {
strength: 2,
agility: 7,
defense: 3,
magic: 9,
luck: 6,
mysticism: 8
},
Lifespan: 'Potentially immortal, though they can fade away if they lose their spectral essence',
LifespanEs: 'Potencialmente inmortal, aunque pueden desvanecerse si pierden su esencia espectral'
}, {
SlimeName: 'King Slime',
SlimeNameEs: 'Rey Slime',
Rarity: 9,
Size: 1.6,
// Royal and massive
History: 'The legendary King Slime is said to be born once a century when a slime absorbs royal essence from an ancient crown.',
HistoryEs: 'Se dice que el legendario Rey Slime nace una vez cada siglo cuando un slime absorbe la esencia real de una corona antigua.',
Location: 'Hidden chambers in royal castles and within the deepest parts of enchanted forests',
LocationEs: 'Cámaras ocultas en castillos reales y en las partes más profundas de bosques encantados',
FavoriteFood: 'Precious metals and gems, particularly gold and rubies',
FavoriteFoodEs: 'Metales preciosos y gemas, especialmente oro y rubíes',
Ability: 'Can command lesser slimes and temporarily grow to massive size, becoming nearly invulnerable',
AbilityEs: 'Puede comandar slimes menores y crecer temporalmente a un tamaño masivo, volviéndose casi invulnerable',
Stats: {
strength: 8,
agility: 4,
defense: 8,
magic: 7,
luck: 7,
mysticism: 9
},
Lifespan: 'Over 200 years, with some specimens reported to live for millennia',
LifespanEs: 'Más de 200 años, con algunos ejemplares reportados viviendo milenios'
}, {
SlimeName: 'Golden Slime',
SlimeNameEs: 'Slime Dorado',
Rarity: 10,
Size: 1.35,
// Substantial and solid
History: 'Golden Slimes are incredibly rare mutations that occur when a slime is exposed to concentrated alchemical gold for generations.',
HistoryEs: 'Los Slimes Dorados son mutaciones increíblemente raras que ocurren cuando un slime es expuesto a oro alquímico concentrado durante generaciones.',
Location: 'Ancient treasure vaults, alchemist laboratories, and the hearts of mountains rich with gold deposits',
LocationEs: 'Antiguas bóvedas de tesoros, laboratorios de alquimistas y el corazón de montañas ricas en oro',
FavoriteFood: 'Gold dust and magical essences',
FavoriteFoodEs: 'Polvo de oro y esencias mágicas',
Ability: 'Turns objects it consumes partially to gold and can detect precious metals at great distances',
AbilityEs: 'Convierte parcialmente en oro los objetos que consume y puede detectar metales preciosos a grandes distancias',
Stats: {
strength: 6,
agility: 3,
defense: 9,
magic: 8,
luck: 10,
mysticism: 8
},
Lifespan: 'Virtually immortal as long as they consume small amounts of gold regularly',
LifespanEs: 'Prácticamente inmortal mientras consuma pequeñas cantidades de oro regularmente'
}];
// Sort SlimeInfo by rarity (highest to lowest)
SlimeInfo = sortSlimesByRarity(SlimeInfo);
// Update slimes array based on the new sorted SlimeInfo
slimes = SlimeInfo.map(function (slime, index) {
// Get the appropriate slime asset name based on the SlimeName
var slimeName = slime.SlimeName.replace(/\s+/g, '');
return slimeName;
});
// Extract arrays for backward compatibility and easier access
var slimeNames = SlimeInfo.map(function (slime) {
return slime.SlimeName;
});
// Array for Spanish slime names
var slimeNamesEs = SlimeInfo.map(function (slime) {
return slime.SlimeNameEs || slime.SlimeName;
});
var rarityValues = SlimeInfo.map(function (slime) {
return slime.Rarity;
});
var histories = SlimeInfo.map(function (slime) {
return slime.History;
});
var locations = SlimeInfo.map(function (slime) {
return slime.Location;
});
var favoriteFoods = SlimeInfo.map(function (slime) {
return slime.FavoriteFood;
});
var abilities = SlimeInfo.map(function (slime) {
return slime.Ability;
});
var stats = SlimeInfo.map(function (slime) {
return slime.Stats;
});
var lifespans = SlimeInfo.map(function (slime) {
return slime.Lifespan;
});
// Create text display for slime name
var slimeNameText = new Text2(slimeNames[currentSlimeIndex], {
size: 100,
fill: 0xFFFFFF
});
slimeNameText.anchor.set(0.5, 0.5);
slimeNameText.x = 0;
slimeNameText.y = interfaz.height / 2;
// Create a slime and add it to the scene
var slime = new Slime();
// Position slime at the center of BG but lower down and set base position
var centerX = bg.width / 2;
var centerY = bg.height / 2 + 220; // Lower position
slime.setBasePosition(centerX, centerY);
// Set initial properties for animations
slime.alpha = 1;
slime.scaleX = 1;
slime.scaleY = 1;
// Music array for random background music selection
var musicTracks = ['BGSong', 'BGSong2', 'BGSong3', 'BGSong4', 'BGSong5'];
var currentMusicIndex = -1;
// Music name overlay to display song names
var musicNameOverlay = new MusicNameOverlay();
// Function to play a random music track
function playRandomMusic() {
var newIndex;
// Make sure we don't play the same track twice in a row
do {
newIndex = Math.floor(Math.random() * musicTracks.length);
} while (newIndex === currentMusicIndex && musicTracks.length > 1);
currentMusicIndex = newIndex;
LK.playMusic(musicTracks[currentMusicIndex]);
// Show random music name with current language
// Make a safe call to ensure language is correctly set
if (musicNameOverlay) {
musicNameOverlay.showRandomName(currentLanguage);
}
}
// Play initial random music
playRandomMusic();
// Set up music change timer (1:40 minutes = 100,000 milliseconds)
LK.setInterval(playRandomMusic, 100000);
// --- Info Panel for BGMenu ---
var infoPanelHeight = bgMenu.height - interfaz.height - 40;
var infoPanelWidth = bgMenu.width;
var infoPanelY = bgMenu.y + interfaz.height + 20;
var infoPanelX = bgMenu.x + (bgMenu.width - infoPanelWidth) / 2; // Center horizontally
// Create a container for the info panel
var infoPanel = new Container();
infoPanel.x = infoPanelX;
infoPanel.y = infoPanelY;
// No background for the info panel
// Prepare info categories and data
var infoCategories = [{
title: "Rarity",
get: function get(i) {
var rarityValue = SlimeInfo[i].Rarity;
this.currentRarityValue = rarityValue;
// Return translated rarity name
return translations[currentLanguage].rarityNames[rarityValue];
}
}, {
title: "Size",
get: function get(i) {
var sizeValue = SlimeInfo[i].Size || 1.0;
var sizeKey;
if (sizeValue <= 0.8) {
sizeKey = "tiny";
} else if (sizeValue <= 0.95) {
sizeKey = "small";
} else if (sizeValue <= 1.1) {
sizeKey = "medium";
} else if (sizeValue <= 1.3) {
sizeKey = "large";
} else if (sizeValue <= 1.5) {
sizeKey = "veryLarge";
} else {
sizeKey = "enormous";
}
var sizeDescription = translations[currentLanguage].sizeDescriptions[sizeKey];
return sizeDescription + " (" + sizeValue.toFixed(2) + "x scale)";
}
}, {
title: "History",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].History : SlimeInfo[i].HistoryEs || SlimeInfo[i].History;
}
}, {
title: "Location",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].Location : SlimeInfo[i].LocationEs || SlimeInfo[i].Location;
}
}, {
title: "Favorite Food",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].FavoriteFood : SlimeInfo[i].FavoriteFoodEs || SlimeInfo[i].FavoriteFood;
}
}, {
title: "Ability",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].Ability : SlimeInfo[i].AbilityEs || SlimeInfo[i].Ability;
}
}, {
title: "Stats",
get: function get(i) {
var s = SlimeInfo[i].Stats;
// Create visual stat bars with colored values using actual colors instead of tags
function formatStat(name, value) {
var barChars = "■".repeat(value);
var emptyChars = "□".repeat(10 - value);
// Translate stat name based on current language
var translatedName = translations[currentLanguage].statNames[name.toLowerCase()] || name;
return translatedName + ": " + value + " [" + barChars + emptyChars + "]";
}
// Create a single column with all 6 stats
var statText = "";
statText += formatStat("strength", s.strength) + "\n";
statText += formatStat("agility", s.agility) + "\n";
statText += formatStat("defense", s.defense) + "\n";
statText += formatStat("magic", s.magic) + "\n";
statText += formatStat("luck", s.luck) + "\n";
statText += formatStat("mysticism", s.mysticism);
return statText;
}
}, {
title: "Lifespan",
get: function get(i) {
return currentLanguage === 'en' ? SlimeInfo[i].Lifespan : SlimeInfo[i].LifespanEs || SlimeInfo[i].Lifespan;
}
}];
// Create a container for the scrollable text
var infoTextContainer = new Container();
infoTextContainer.x = 30;
infoTextContainer.y = 30; // Add top margin
// Function to update info text for current slime
function updateInfoPanel() {
// Remove old children
infoTextContainer.removeChildren();
var y = 0;
for (var c = 0; c < infoCategories.length; c++) {
// Add extra spacing between sections if not the first section
if (c > 0) {
y += 80; // Add extra spacing between sections
}
// Title with gradient effect based on category
var titleColors = {
"Rarity": 0xFFD700,
"History": 0xCF9FFF,
"Location": 0x98FB98,
"Favorite Food": 0xFF7F50,
"Ability": 0x00BFFF,
"Stats": 0xFF1493,
"Lifespan": 0x00FA9A
};
var titleColor = titleColors[infoCategories[c].title] || 0xFFF7B2;
// Get translated title
var translatedTitle = translations[currentLanguage].categoryTitles[infoCategories[c].title] || infoCategories[c].title;
var titleText = new Text2(translatedTitle, {
size: 110,
fill: titleColor,
font: "GillSans-Bold",
align: "center",
dropShadow: true,
dropShadowColor: 0x000000,
dropShadowDistance: 3,
dropShadowAlpha: 0.5
});
titleText.anchor.set(0.5, 0);
titleText.x = infoPanelWidth / 2 - 30;
titleText.y = y;
infoTextContainer.addChild(titleText);
y += titleText.height + 6;
// Info - wrap text to fit screen width
var infoContent = infoCategories[c].get(currentSlimeIndex);
var wrappedText = infoContent;
// Only apply text wrapping if not the stats category (which already has formatting)
if (infoCategories[c].title !== "Stats") {
wrappedText = wrapText(infoContent, infoPanelWidth - 60, 85); // Wrap text with some padding
}
// Choose text color based on category
var textColors = {
"Rarity": 0xFFFACD,
"History": 0xE6E6FA,
"Location": 0xF0FFF0,
"Favorite Food": 0xFFE4E1,
"Ability": 0xE0FFFF,
"Stats": 0xFFE4E1,
"Lifespan": 0xF0FFFF
};
var textColor = textColors[infoCategories[c].title] || 0xFFFFFF;
var infoText = new Text2(wrappedText, {
size: 85,
fill: textColor,
font: "GillSans",
align: infoCategories[c].title === "Stats" ? "left" : "center",
dropShadow: true,
dropShadowColor: 0x333333,
dropShadowDistance: 2,
dropShadowAlpha: 0.3
});
// Set anchor based on content type
if (infoCategories[c].title === "Stats") {
infoText.anchor.set(0.5, 0); // Center align stats too
infoText.x = infoPanelWidth / 2 - 30;
} else {
infoText.anchor.set(0.5, 0); // Center align for other content
infoText.x = infoPanelWidth / 2 - 30;
}
infoText.y = y + 20;
infoTextContainer.addChild(infoText);
// If this is the rarity category, add colored stars
if (infoCategories[c].title === "Rarity" && infoCategories[c].currentRarityValue) {
var starContainer = new Container();
starContainer.x = infoPanelWidth / 2 - 30;
starContainer.y = y + infoText.height + 40;
var rarityValue = infoCategories[c].currentRarityValue;
var starSpacing = 110,
totalWidth = (rarityValue - 1) * starSpacing;
var startX = -totalWidth / 2;
for (var s = 0; s < rarityValue; s++) {
var star = new Star();
star.x = startX + s * starSpacing;
star.y = 20;
star.alpha = 0;
star.scale.x = star.scale.y = 0.5;
star.setColorByRarity(rarityValue);
starContainer.addChild(star);
(function (targetStar, delay) {
LK.setTimeout(function () {
tween(targetStar, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 400,
easing: tween.easeOut
});
}, delay);
})(star, s * 200);
}
infoTextContainer.addChild(starContainer);
y += 80;
}
y += infoText.height + 24;
}
infoTextContainer.totalHeight = y;
}
updateInfoPanel();
// --- Scrolling logic for info panel with visual enhancements ---
var scrollOffset = 0;
var maxScroll = 0;
function updateScrollLimits() {
maxScroll = Math.max(0, infoTextContainer.totalHeight - infoPanelHeight + 40 + 60); // Add 60px to account for top and bottom margins
// Clamp scrollOffset to valid range, no bounce, no tween
if (scrollOffset < 0) {
scrollOffset = 0;
}
if (scrollOffset > maxScroll) {
scrollOffset = maxScroll;
}
// Set position directly, no tween
infoTextContainer.y = 30 - scrollOffset;
}
updateScrollLimits();
// Touch/mouse drag to scroll with inertia and visual feedback
var isScrolling = false,
lastScrollY = 0,
scrollVelocity = 0,
lastScrollTime = 0,
scrollTweenActive = false,
scrollTracker = [];
infoPanel.interactive = true;
infoPanel.down = function (x, y, obj) {
isScrolling = true;
lastScrollY = y;
lastScrollTime = Date.now();
scrollTracker = [];
};
infoPanel.move = function (x, y, obj) {
if (isScrolling) {
var dy = y - lastScrollY;
scrollOffset -= dy;
updateScrollLimits();
lastScrollY = y;
}
};
infoPanel.up = function (x, y, obj) {
if (isScrolling) {
isScrolling = false;
// No inertia, no tween, just clamp and update position
updateScrollLimits();
}
};
// Unified handler for both navigation buttons
function createButtonHandler(direction) {
return function (x, y, obj) {
changeSlime(direction);
updateInfoPanel();
updateScrollLimits();
};
}
leftButton.down = createButtonHandler('prev');
rightButton.down = createButtonHandler('next');
// When changing slime, update info panel and scroll position
function updateSlimeAndInfo() {
// Update slime name text first to fix the name display bug
var displayName = currentLanguage === 'en' ? slimeNames[currentSlimeIndex] : SlimeInfo[currentSlimeIndex].SlimeNameEs || slimeNames[currentSlimeIndex];
slimeNameText.setText(displayName);
// Stop existing tweens before starting new ones to prevent animation conflicts
tween.stop(slime);
// Enhanced slime transition effects with color flash and particle-like animation
tween(slime, {
alpha: 0,
scaleX: 0.8,
scaleY: 0.8,
rotation: -0.1
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Get the current slime asset name
var currentSlimeName = slimes[currentSlimeIndex];
// Remove old slime asset
if (slime.slimeAsset) {
slime.removeChild(slime.slimeAsset);
}
// Get new slime asset
slime.slimeAsset = slime.attachAsset(currentSlimeName, {
anchorX: 0.5,
anchorY: 0.5
});
// Apply day/night effect immediately after creating the new slime
if (!isDayTime && slime.slimeAsset) {
slime.slimeAsset.tint = darkTint;
}
// Get the size multiplier from SlimeInfo and apply it to the base scale
var sizeMultiplier = SlimeInfo[currentSlimeIndex].Size || 1.0;
// Apply the consistent scale to maintain proper sizing, adjusted by slime-specific size
slime.slimeAsset.scale.set(slime.baseScale * sizeMultiplier);
// Reset to base position to prevent drift, but adjust Y position based on size
// This ensures all slimes appear to be on the same baseline regardless of size
slime.x = slime.baseX;
// Calculate Y offset based on size to keep bottom of slime at same level
// Larger slimes need to be positioned higher to maintain same baseline
var yOffset = (sizeMultiplier - 1.0) * slime.slimeAsset.height * slime.baseScale * 0.5;
slime.y = slime.baseY - yOffset;
slime.alpha = 0;
slime.scaleX = 0.3;
slime.scaleY = 0.3;
slime.rotation = 0.1;
// More dynamic entrance animation
tween(slime, {
alpha: 1,
scaleX: 1,
scaleY: 1,
rotation: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(slime, {
scaleX: 0.8,
scaleY: 0.8
}, {
duration: 500,
easing: tween.elasticOut,
onFinish: function onFinish() {
// Day/night effect already applied before animation
}
});
}
});
}
});
// Update content and scroll position
updateInfoPanel();
scrollOffset = 0;
updateScrollLimits();
// Fade in info container
infoTextContainer.alpha = 0;
tween(infoTextContainer, {
alpha: 1
}, {
duration: 400,
easing: tween.easeOut
});
}
function changeSlime(direction) {
currentSlimeIndex = direction === 'next' ? (currentSlimeIndex + 1) % slimes.length : (currentSlimeIndex - 1 + slimes.length) % slimes.length;
updateSlimeAndInfo();
// Day/night effect now applied in updateSlimeAndInfo before animation
}
/*
* Asset initialization
*/
// Add elements to game content container instead of directly to game
gameContent.addChild(bgMenu);
gameContent.addChild(infoPanel);
infoPanel.addChild(infoTextContainer);
gameContent.addChild(bg);
gameContent.addChild(interfaz);
interfaz.addChild(leftButton);
interfaz.addChild(rightButton);
interfaz.addChild(slimeNameText);
interfaz.addChild(sortButton);
interfaz.addChild(sortText);
interfaz.addChild(languageButton);
interfaz.addChild(languageText);
gameContent.addChild(slime);
gameContent.addChild(musicNameOverlay);
// Add the game content container to the game
game.addChild(gameContent);
// Initialize with ascending order (1->10) as default sort
currentSortOrder = 0;
SlimeInfo.sort(function (a, b) {
return a.Rarity - b.Rarity;
});
// Update arrays based on the sorted SlimeInfo
slimes = SlimeInfo.map(function (slime) {
var slimeName = slime.SlimeName.replace(/\s+/g, '');
return slimeName;
});
slimeNames = SlimeInfo.map(function (slime) {
return slime.SlimeName;
});
rarityValues = SlimeInfo.map(function (slime) {
return slime.Rarity;
});
// Reset to first slime and update display with proper language
currentSlimeIndex = 0;
updateSlimeAndInfo();
// Initialize all UI elements with correct language
updateLanguageUI();
// Initial day/night check
isDayTime = checkDayTime();
applyDayNightEffect();
// Set up timer to check day/night status every minute
LK.setInterval(function () {
var newIsDayTime = checkDayTime();
if (newIsDayTime !== isDayTime) {
isDayTime = newIsDayTime;
applyDayNightEffect();
}
}, 60000); // Check every minute
// Function to apply day/night effect to background and slimes
function applyDayNightEffect() {
if (isDayTime) {
// Day time - normal colors
bg.tint = 0xFFFFFF;
if (slime && slime.slimeAsset) {
slime.slimeAsset.tint = 0xFFFFFF;
}
} else {
// Night time - darken everything
bg.tint = darkTint;
if (slime && slime.slimeAsset) {
slime.slimeAsset.tint = darkTint;
}
}
}
Star cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime verde RPG con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime rojo prendido fuego RPG con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime RPG amarillo y divino con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime fantasmal RPG con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime blanco con una moneda brillante en la frente RPG con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime gris RPG con rocas en su espalda. Estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime RPG nevado con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime de agua RPG con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime bestia peludo RPG con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime morado con runas magicas RPG. Estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Un slime angelical RPG con estilo suave y simple. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Fullscreen medieval landscape banner, 16:9, high definition, for a game titled "Slime Bestiary". Medieval forest with multiple colored slimes. No text on banner!