/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Battler = Container.expand(function () {
var self = Container.call(this);
var battlerGraphics = self.attachAsset('battler', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.consumedItems = [];
self.bodyParts = [];
self.evolutionCount = 0;
self.speed = 3;
// Initialize with random starting body parts
self.initializeBodyParts = function () {
var initialParts = 2 + Math.floor(Math.random() * 3); // 2-4 starting parts
for (var i = 0; i < initialParts; i++) {
var offsetX = (Math.random() - 0.5) * 80;
var offsetY = (Math.random() - 0.5) * 80;
var partType = Math.floor(Math.random() * 6);
var bodyPart = new BodyPart(partType, offsetX, offsetY);
bodyPart.x = offsetX;
bodyPart.y = offsetY;
self.addChild(bodyPart);
self.bodyParts.push(bodyPart);
}
};
self.consumeItem = function (item) {
self.consumedItems.push(item.itemType);
item.collect();
// Visual feedback
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
};
self.evolve = function (prompt1, prompt2) {
self.evolutionCount++;
LK.getSound('evolve').play();
// Evolve existing body parts
for (var i = 0; i < self.bodyParts.length; i++) {
var part = self.bodyParts[i];
part.evolve({
prompt1: prompt1,
prompt2: prompt2,
consumedItems: self.consumedItems
});
}
// Add new AI-generated body parts based on evolution level
var evolutionComplexity = Math.min(5, Math.floor(self.evolutionCount / 2) + 1);
var newPartsCount = evolutionComplexity + Math.floor(Math.random() * evolutionComplexity);
for (var j = 0; j < newPartsCount; j++) {
var offsetX = (Math.random() - 0.5) * (120 + self.evolutionCount * 20);
var offsetY = (Math.random() - 0.5) * (120 + self.evolutionCount * 20);
// Generate AI body part type
var aiPartData = AIBodyPartGenerator.generateUniqueBodyPart(self.evolutionCount, prompt1, prompt2, self.consumedItems);
var partType = (aiPartData.id - 1) % 6;
var newBodyPart = new BodyPart(partType, offsetX, offsetY);
newBodyPart.x = offsetX;
newBodyPart.y = offsetY;
newBodyPart.alpha = 0;
// Apply AI characteristics immediately
newBodyPart.attributes.specialAbility = aiPartData.specialAbility;
newBodyPart.scaleX = aiPartData.size;
newBodyPart.scaleY = aiPartData.size;
newBodyPart.tint = aiPartData.color;
self.addChild(newBodyPart);
self.bodyParts.push(newBodyPart);
// Fade in new part with AI-enhanced animation
tween(newBodyPart, {
alpha: 1
}, {
duration: 1000 + j * 200
});
}
// Boost stats based on evolution count and body parts
self.maxHealth = 100 + self.evolutionCount * 30 + self.bodyParts.length * 10;
self.health = self.maxHealth;
};
self.takeDamage = function (damage) {
self.health = Math.max(0, self.health - damage);
// Visual damage feedback on all body parts
for (var i = 0; i < self.bodyParts.length; i++) {
var part = self.bodyParts[i];
tween(part, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(part, {
tint: 0xffffff
}, {
duration: 200
});
}
});
}
tween(battlerGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(battlerGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
};
// Initialize body parts when created
self.initializeBodyParts();
return self;
});
var BodyPart = Container.expand(function (partType, offsetX, offsetY) {
var self = Container.call(this);
self.partType = partType;
self.offsetX = offsetX || 0;
self.offsetY = offsetY || 0;
self.evolutionLevel = 0;
self.attributes = {
size: 1,
color: 0xffffff,
rotation: 0,
shape: 'ellipse'
};
var partGraphics = self.attachAsset('bodyPart' + (partType + 1), {
anchorX: 0.5,
anchorY: 0.5
});
self.evolve = function (evolutionData) {
self.evolutionLevel++;
// Use AI generation system for evolution
var aiCharacteristics = AIBodyPartGenerator.generateUniqueBodyPart(self.evolutionLevel, evolutionData.prompt1, evolutionData.prompt2, evolutionData.consumedItems);
// Apply AI-generated characteristics
self.attributes.size = aiCharacteristics.size;
self.attributes.color = aiCharacteristics.color;
self.attributes.rotation = (Math.random() - 0.5) * Math.PI;
self.attributes.specialAbility = aiCharacteristics.specialAbility;
// Create new AI-generated body part asset if this is a major evolution
if (self.evolutionLevel % 2 === 0) {
// Replace with AI-generated part
partGraphics.destroy();
partGraphics = self.attachAsset('aiBodyPart' + aiCharacteristics.id, {
anchorX: 0.5,
anchorY: 0.5
});
}
tween(partGraphics, {
scaleX: aiCharacteristics.size,
scaleY: aiCharacteristics.size,
tint: aiCharacteristics.color,
rotation: self.attributes.rotation
}, {
duration: 800,
easing: tween.easeInOut
});
// Organic growth positioning
var growthFactor = 1 + self.evolutionLevel * 0.1;
var newOffsetX = self.offsetX + (Math.random() - 0.5) * 40 * growthFactor;
var newOffsetY = self.offsetY + (Math.random() - 0.5) * 40 * growthFactor;
tween(self, {
x: newOffsetX,
y: newOffsetY
}, {
duration: 800
});
self.offsetX = newOffsetX;
self.offsetY = newOffsetY;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 80;
self.maxHealth = 80;
self.damage = 15;
self.takeDamage = function (damage) {
self.health = Math.max(0, self.health - damage);
// Visual damage feedback
tween(enemyGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
};
return self;
});
var Item = Container.expand(function (itemType) {
var self = Container.call(this);
self.itemType = itemType;
var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57];
var itemGraphics = self.attachAsset('item' + (itemType + 1), {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.collect = function () {
if (!self.collected) {
self.collected = true;
LK.getSound('pickup').play();
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
}
};
return self;
});
var KeyboardKey = Container.expand(function (_char) {
var self = Container.call(this);
self["char"] = _char;
var keyBg = LK.getAsset('item1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
keyBg.tint = 0xecf0f1;
self.addChild(keyBg);
var keyText = new Text2(_char, {
size: 30,
fill: 0x2C3E50
});
keyText.anchor.set(0.5, 0.5);
self.addChild(keyText);
self.down = function (x, y, obj) {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
if (currentInput && currentInput.addChar) {
currentInput.addChar(self["char"]);
}
};
return self;
});
var TextInput = Container.expand(function (placeholder) {
var self = Container.call(this);
self.text = '';
self.maxLength = 20;
var inputBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.5
});
self.addChild(inputBg);
self.displayText = new Text2(placeholder || 'Enter text...', {
size: 40,
fill: 0x333333
});
self.displayText.anchor.set(0.5, 0.5);
self.addChild(self.displayText);
self.updateDisplay = function () {
if (self.text.length > 0) {
self.displayText.setText(self.text);
} else {
self.displayText.setText(placeholder || 'Enter text...');
}
};
self.addChar = function (_char2) {
if (self.text.length < self.maxLength) {
self.text += _char2;
self.updateDisplay();
}
};
self.backspace = function () {
if (self.text.length > 0) {
self.text = self.text.slice(0, -1);
self.updateDisplay();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
// AI-generated body part assets with infinite variations
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) throw o;
}
}
};
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
var AIBodyPartGenerator = {
generateUniqueBodyPart: function generateUniqueBodyPart(evolutionLevel, prompt1, prompt2, consumedItems) {
// Generate AI-influenced body part based on prompts and evolution
var partId = this.generatePartId(prompt1, prompt2, evolutionLevel);
var characteristics = this.analyzePrompts(prompt1, prompt2, consumedItems);
return {
id: partId,
size: characteristics.size,
color: characteristics.color,
shape: characteristics.shape,
specialAbility: characteristics.ability,
evolutionTier: evolutionLevel
};
},
generatePartId: function generatePartId(prompt1, prompt2, evolutionLevel) {
// Generate unique ID based on prompts and evolution level
var hash = 0;
var combined = (prompt1 + prompt2 + evolutionLevel).toLowerCase();
for (var i = 0; i < combined.length; i++) {
hash = (hash << 5) - hash + combined.charCodeAt(i) & 0xffffffff;
}
return Math.abs(hash) % 8 + 1; // Return 1-8 for aiBodyPart assets
},
analyzePrompts: function analyzePrompts(prompt1, prompt2, consumedItems) {
var characteristics = {
size: 1.0,
color: 0xffffff,
shape: 'ellipse',
ability: 'none'
};
var allText = (prompt1 + ' ' + prompt2).toLowerCase();
// Size analysis
if (allText.includes('big') || allText.includes('large') || allText.includes('huge')) {
characteristics.size = 1.5 + Math.random() * 0.8;
} else if (allText.includes('small') || allText.includes('tiny') || allText.includes('mini')) {
characteristics.size = 0.4 + Math.random() * 0.4;
} else {
characteristics.size = 0.8 + Math.random() * 0.6;
}
// Color analysis based on prompt keywords
if (allText.includes('fire') || allText.includes('red') || allText.includes('flame')) {
characteristics.color = 0xff4757;
} else if (allText.includes('ice') || allText.includes('blue') || allText.includes('cold')) {
characteristics.color = 0x3742fa;
} else if (allText.includes('nature') || allText.includes('green') || allText.includes('plant')) {
characteristics.color = 0x2ed573;
} else if (allText.includes('electric') || allText.includes('yellow') || allText.includes('lightning')) {
characteristics.color = 0xffa502;
} else {
// Generate color based on consumed items
var colorBase = 0x000000;
for (var i = 0; i < consumedItems.length; i++) {
colorBase += consumedItems[i] * 123456;
}
characteristics.color = Math.abs(colorBase) % 0xffffff;
}
// Shape analysis
if (allText.includes('sharp') || allText.includes('spike') || allText.includes('blade')) {
characteristics.shape = 'box';
} else if (allText.includes('round') || allText.includes('smooth') || allText.includes('soft')) {
characteristics.shape = 'ellipse';
}
// Special ability analysis
if (allText.includes('weapon') || allText.includes('attack') || allText.includes('damage')) {
characteristics.ability = 'attack';
} else if (allText.includes('shield') || allText.includes('defense') || allText.includes('armor')) {
characteristics.ability = 'defense';
} else if (allText.includes('speed') || allText.includes('fast') || allText.includes('quick')) {
characteristics.ability = 'speed';
} else if (allText.includes('heal') || allText.includes('regenerate') || allText.includes('recover')) {
characteristics.ability = 'healing';
}
return characteristics;
}
};
var AIEnemyGenerator = {
generateEnemy: function generateEnemy(battlerEvolutionLevel, enemyLevel) {
var enemyType = this.determineEnemyType(battlerEvolutionLevel, enemyLevel);
var stats = this.generateEnemyStats(enemyLevel, battlerEvolutionLevel);
return {
type: enemyType,
health: stats.health,
damage: stats.damage,
scale: stats.scale,
color: stats.color,
abilities: stats.abilities
};
},
determineEnemyType: function determineEnemyType(battlerEvolution, enemyLevel) {
var types = ['basic', 'armored', 'swift', 'giant', 'elemental', 'shapeshifter'];
var typeIndex = (battlerEvolution + enemyLevel) % types.length;
return types[typeIndex];
},
generateEnemyStats: function generateEnemyStats(enemyLevel, battlerEvolution) {
var baseHealth = 80;
var baseDamage = 15;
var baseScale = 1.0;
// Scale based on both enemy level and battler evolution
var healthMultiplier = 1 + (enemyLevel - 1) * 0.5 + battlerEvolution * 0.3;
var damageMultiplier = 1 + (enemyLevel - 1) * 0.4 + battlerEvolution * 0.2;
var scaleMultiplier = 1 + (enemyLevel - 1) * 0.15;
return {
health: Math.floor(baseHealth * healthMultiplier),
damage: Math.floor(baseDamage * damageMultiplier),
scale: baseScale * scaleMultiplier,
color: this.generateEnemyColor(enemyLevel, battlerEvolution),
abilities: this.generateEnemyAbilities(enemyLevel)
};
},
generateEnemyColor: function generateEnemyColor(enemyLevel, battlerEvolution) {
var colorOptions = [0xe74c3c, 0x9b59b6, 0x3498db, 0xe67e22, 0x1abc9c, 0xf39c12];
var colorIndex = enemyLevel * battlerEvolution % colorOptions.length;
return colorOptions[colorIndex];
},
generateEnemyAbilities: function generateEnemyAbilities(enemyLevel) {
var abilities = [];
if (enemyLevel >= 3) abilities.push('regeneration');
if (enemyLevel >= 5) abilities.push('counter-attack');
if (enemyLevel >= 7) abilities.push('area-damage');
return abilities;
}
};
var gameState = 'homescreen'; // homescreen, tutorial, exploration, transformation, evolution, combat
var battler;
var enemy;
var items = [];
var consumedCount = 0;
var textInputs = [];
var currentInput = null;
var keyboard = [];
var tutorialStep = 0;
var previousBattlerData = null; // Store battler data from previous victory
var isBoss = false;
// UI elements
var stateText;
var healthBar;
var healthBarBg;
var enemyHealthBar;
var enemyHealthBarBg;
var homeScreenUI = [];
var tutorialUI = [];
// Initialize homescreen
function createHomeScreen() {
var title = new Text2('MORPH BATTLE ARENA', {
size: 80,
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 600;
game.addChild(title);
homeScreenUI.push(title);
var subtitle = new Text2('Transform. Evolve. Conquer.', {
size: 40,
fill: 0xBDC3C7
});
subtitle.anchor.set(0.5, 0.5);
subtitle.x = 1024;
subtitle.y = 700;
game.addChild(subtitle);
homeScreenUI.push(subtitle);
var startButton = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
startButton.tint = 0x27ae60;
startButton.x = 1024;
startButton.y = 1200;
game.addChild(startButton);
homeScreenUI.push(startButton);
var startText = new Text2('START TUTORIAL', {
size: 50,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = 1024;
startText.y = 1200;
game.addChild(startText);
homeScreenUI.push(startText);
startButton.down = function () {
clearHomeScreen();
startTutorial();
};
}
function clearHomeScreen() {
for (var i = 0; i < homeScreenUI.length; i++) {
homeScreenUI[i].destroy();
}
homeScreenUI = [];
}
function startTutorial() {
gameState = 'tutorial';
tutorialStep = 0;
showTutorialStep();
}
function showTutorialStep() {
// Clear previous tutorial UI
for (var i = 0; i < tutorialUI.length; i++) {
tutorialUI[i].destroy();
}
tutorialUI = [];
var tutorialTexts = ['Welcome! You control a morphing battler that evolves based on what it eats and your descriptions.', 'Drag your battler around to collect 5 different food items. Each type affects your evolution!', 'After eating 5 items, you will describe your battler with 2 prompts to trigger evolution.', 'Your evolved battler will automatically fight enemies. Win to face stronger foes with your evolved form!', 'Food types: Red=Strength, Blue=Defense, Green=Speed, Yellow=Magic, Purple=Special abilities', 'Ready to begin your morphing journey?'];
if (tutorialStep < tutorialTexts.length) {
var tutText = new Text2(tutorialTexts[tutorialStep], {
size: 45,
fill: 0xFFFFFF
});
tutText.anchor.set(0.5, 0.5);
tutText.x = 1024;
tutText.y = 800;
game.addChild(tutText);
tutorialUI.push(tutText);
var nextButton = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
nextButton.tint = 0x3498db;
nextButton.x = 1024;
nextButton.y = 1200;
game.addChild(nextButton);
tutorialUI.push(nextButton);
var nextText = new Text2(tutorialStep < tutorialTexts.length - 1 ? 'NEXT' : 'START GAME', {
size: 40,
fill: 0xFFFFFF
});
nextText.anchor.set(0.5, 0.5);
nextText.x = 1024;
nextText.y = 1200;
game.addChild(nextText);
tutorialUI.push(nextText);
nextButton.down = function () {
tutorialStep++;
if (tutorialStep >= tutorialTexts.length) {
clearTutorialUI();
startGame();
} else {
showTutorialStep();
}
};
}
}
function clearTutorialUI() {
for (var i = 0; i < tutorialUI.length; i++) {
tutorialUI[i].destroy();
}
tutorialUI = [];
}
function startGame() {
gameState = 'exploration';
// Initialize UI
stateText = new Text2('Find and consume 5 items to evolve!', {
size: 50,
fill: 0xECF0F1
});
stateText.anchor.set(0.5, 0);
LK.gui.top.addChild(stateText);
// Create battler - use previous evolution if available
if (previousBattlerData) {
battler = game.addChild(new Battler());
// Restore previous battler characteristics
battler.evolutionCount = previousBattlerData.evolutionCount;
battler.maxHealth = previousBattlerData.maxHealth;
battler.health = Math.floor(battler.maxHealth * 0.8); // Start with 80% health
// Recreate body parts from previous evolution
for (var p = 0; p < previousBattlerData.bodyParts.length; p++) {
var partData = previousBattlerData.bodyParts[p];
var newPart = new BodyPart(partData.partType, partData.offsetX, partData.offsetY);
newPart.evolutionLevel = partData.evolutionLevel;
newPart.attributes = JSON.parse(JSON.stringify(partData.attributes));
newPart.x = partData.offsetX;
newPart.y = partData.offsetY;
battler.addChild(newPart);
battler.bodyParts.push(newPart);
}
} else {
battler = game.addChild(new Battler());
}
battler.x = 1024;
battler.y = 1366;
spawnItems();
}
// Create items scattered around the arena with different food types
function spawnItems() {
var foodTypes = [{
color: 0xff6b6b,
name: 'Strength Berry'
}, {
color: 0x4ecdc4,
name: 'Defense Fruit'
}, {
color: 0x45b7d1,
name: 'Speed Seed'
}, {
color: 0x96ceb4,
name: 'Magic Mushroom'
}, {
color: 0xfeca57,
name: 'Special Spice'
}];
for (var i = 0; i < 8; i++) {
var foodType = i % 5;
var item = game.addChild(new Item(foodType));
item.x = 300 + Math.random() * 1400;
item.y = 400 + Math.random() * 1800;
item.foodType = foodTypes[foodType];
items.push(item);
}
}
// Check if current enemy should be a boss (every 5th enemy)
function shouldBeBoss(enemyLevel) {
return enemyLevel % 5 === 0;
}
// Store battler data for next round
function storeBattlerData() {
if (battler) {
previousBattlerData = {
evolutionCount: battler.evolutionCount,
maxHealth: battler.maxHealth,
bodyParts: []
};
for (var i = 0; i < battler.bodyParts.length; i++) {
var part = battler.bodyParts[i];
previousBattlerData.bodyParts.push({
partType: part.partType,
offsetX: part.offsetX,
offsetY: part.offsetY,
evolutionLevel: part.evolutionLevel,
attributes: JSON.parse(JSON.stringify(part.attributes))
});
}
}
}
// Start the game with homescreen
createHomeScreen();
function createKeyboard() {
var keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.split('');
var rows = ['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM'];
var startY = 2000;
var keySize = 80;
var spacing = 10;
for (var row = 0; row < rows.length; row++) {
var rowKeys = rows[row];
var startX = (2048 - rowKeys.length * (keySize + spacing)) / 2;
for (var i = 0; i < rowKeys.length; i++) {
var key = game.addChild(new KeyboardKey(rowKeys[i]));
key.x = startX + i * (keySize + spacing);
key.y = startY + row * (keySize + spacing);
keyboard.push(key);
}
}
// Add space and backspace
var spaceKey = game.addChild(new KeyboardKey(' '));
spaceKey.x = 1024;
spaceKey.y = startY + 3 * (keySize + spacing);
spaceKey.scaleX = 3;
keyboard.push(spaceKey);
// Backspace key
var backspaceKey = game.addChild(new KeyboardKey('⌫'));
backspaceKey.x = 1600;
backspaceKey.y = startY + 3 * (keySize + spacing);
backspaceKey["char"] = 'BACKSPACE';
backspaceKey.down = function (x, y, obj) {
if (currentInput && currentInput.backspace) {
currentInput.backspace();
}
};
keyboard.push(backspaceKey);
}
function hideKeyboard() {
for (var i = 0; i < keyboard.length; i++) {
keyboard[i].visible = false;
}
}
function showKeyboard() {
for (var i = 0; i < keyboard.length; i++) {
keyboard[i].visible = true;
}
}
function onPromptDone(prompt1, prompt2) {
// Handle prompt completion
battler.evolve(prompt1, prompt2);
// Visual feedback for completion
stateText.setText('Evolution in progress...');
LK.effects.flashScreen(0x27ae60, 1000);
// Clean up transformation UI
for (var i = 0; i < textInputs.length; i++) {
textInputs[i].destroy();
}
// Clean up other UI elements
var confirmButton = null;
var confirmText = null;
var _iterator = _createForOfIteratorHelper(game.children),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var child = _step.value;
if (child.tint === 0x27ae60) confirmButton = child;
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (confirmButton) confirmButton.destroy();
// Find and destroy confirm text
var _iterator2 = _createForOfIteratorHelper(game.children),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var child = _step2.value;
if (child.text && child.text === 'EVOLVE!') {
child.destroy();
break;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
hideKeyboard();
textInputs = [];
currentInput = null;
LK.setTimeout(function () {
startCombat();
}, 1500);
}
function startTransformation() {
gameState = 'transformation';
stateText.setText('Select or type your transformation prompts:');
// Show predefined prompt suggestions
var promptSuggestions1 = ['fire warrior', 'ice guardian', 'nature beast', 'lightning striker', 'shadow hunter', 'crystal defender'];
var promptSuggestions2 = ['razor claws', 'healing aura', 'speed boost', 'armor plating', 'energy blast', 'poison spikes'];
// Create suggestion title for first prompt
var title1 = new Text2('Body Type Suggestions (or type your own):', {
size: 35,
fill: 0xBDC3C7
});
title1.anchor.set(0.5, 0.5);
title1.x = 1024;
title1.y = 800;
game.addChild(title1);
textInputs.push(title1);
// Create suggestion buttons for first prompt
for (var i = 0; i < promptSuggestions1.length; i++) {
var suggestionButton = LK.getAsset('item1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.5
});
suggestionButton.tint = 0x3498db;
suggestionButton.x = 200 + i % 3 * 600;
suggestionButton.y = 900 + Math.floor(i / 3) * 80;
suggestionButton.promptText = promptSuggestions1[i];
suggestionButton.inputIndex = 0;
game.addChild(suggestionButton);
textInputs.push(suggestionButton);
var suggestionText = new Text2(promptSuggestions1[i], {
size: 25,
fill: 0xFFFFFF
});
suggestionText.anchor.set(0.5, 0.5);
suggestionText.x = suggestionButton.x;
suggestionText.y = suggestionButton.y;
game.addChild(suggestionText);
textInputs.push(suggestionText);
suggestionButton.down = function () {
if (this.inputIndex === 0) {
input1.text = this.promptText;
input1.updateDisplay();
} else if (this.inputIndex === 1) {
input2.text = this.promptText;
input2.updateDisplay();
}
};
}
// Create text inputs
var input1 = game.addChild(new TextInput('Describe your battler...'));
input1.x = 1024;
input1.y = 1100;
textInputs.push(input1);
// Create suggestion title for second prompt
var title2 = new Text2('Ability Suggestions (or type your own):', {
size: 35,
fill: 0xBDC3C7
});
title2.anchor.set(0.5, 0.5);
title2.x = 1024;
title2.y = 1300;
game.addChild(title2);
textInputs.push(title2);
// Create suggestion buttons for second prompt
for (var j = 0; j < promptSuggestions2.length; j++) {
var suggestionButton2 = LK.getAsset('item2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.5
});
suggestionButton2.tint = 0xe67e22;
suggestionButton2.x = 200 + j % 3 * 600;
suggestionButton2.y = 1400 + Math.floor(j / 3) * 80;
suggestionButton2.promptText = promptSuggestions2[j];
suggestionButton2.inputIndex = 1;
game.addChild(suggestionButton2);
textInputs.push(suggestionButton2);
var suggestionText2 = new Text2(promptSuggestions2[j], {
size: 25,
fill: 0xFFFFFF
});
suggestionText2.anchor.set(0.5, 0.5);
suggestionText2.x = suggestionButton2.x;
suggestionText2.y = suggestionButton2.y;
game.addChild(suggestionText2);
textInputs.push(suggestionText2);
suggestionButton2.down = function () {
if (this.inputIndex === 0) {
input1.text = this.promptText;
input1.updateDisplay();
} else if (this.inputIndex === 1) {
input2.text = this.promptText;
input2.updateDisplay();
}
};
}
var input2 = game.addChild(new TextInput('Add special abilities...'));
input2.x = 1024;
input2.y = 1600;
textInputs.push(input2);
currentInput = input1;
createKeyboard();
// Add input switching
input1.down = function () {
currentInput = input1;
};
input2.down = function () {
currentInput = input2;
};
// Add confirm button
var confirmButton = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
confirmButton.tint = 0x27ae60;
game.addChild(confirmButton);
confirmButton.x = 1024;
confirmButton.y = 1800;
var confirmText = new Text2('EVOLVE!', {
size: 40,
fill: 0xFFFFFF
});
confirmText.anchor.set(0.5, 0.5);
confirmText.x = 1024;
confirmText.y = 1800;
game.addChild(confirmText);
confirmButton.down = function () {
if (textInputs[0].text && textInputs[0].text.length > 0 && textInputs[1].text && textInputs[1].text.length > 0) {
onPromptDone(textInputs[0].text, textInputs[1].text);
}
};
}
function startCombat() {
gameState = 'combat';
isBoss = shouldBeBoss(enemyLevel);
if (isBoss) {
stateText.setText('BOSS BATTLE! Level: ' + enemyLevel + ' | Evolution: ' + battler.evolutionCount);
} else {
stateText.setText('Battle begins! Enemy Level: ' + enemyLevel + ' | Evolution: ' + battler.evolutionCount);
}
// Generate AI-powered enemy with boss scaling
var aiEnemyData = AIEnemyGenerator.generateEnemy(battler.evolutionCount, enemyLevel);
enemy = game.addChild(new Enemy());
enemy.x = 1024;
enemy.y = 600;
// Apply boss multipliers if it's a boss
if (isBoss) {
aiEnemyData.health *= 2.5;
aiEnemyData.damage *= 1.8;
aiEnemyData.scale *= 1.4;
aiEnemyData.abilities.push('boss-rage');
aiEnemyData.abilities.push('multi-attack');
}
// Apply AI-generated enemy characteristics
enemy.maxHealth = aiEnemyData.health;
enemy.health = enemy.maxHealth;
enemy.damage = aiEnemyData.damage;
enemy.enemyType = aiEnemyData.type;
enemy.abilities = aiEnemyData.abilities;
enemy.isBoss = isBoss;
// Apply AI visual characteristics
enemy.tint = aiEnemyData.color;
enemy.scaleX = aiEnemyData.scale;
enemy.scaleY = aiEnemyData.scale;
// Boss visual effects
if (isBoss) {
LK.effects.flashScreen(0x8e44ad, 1000);
tween(enemy, {
scaleX: aiEnemyData.scale * 1.1,
scaleY: aiEnemyData.scale * 1.1,
rotation: Math.sin(LK.ticks * 0.05) * 0.2
}, {
duration: 800,
easing: tween.easeInOut,
loop: true
});
} else {
// Enhanced visual scaling animation
tween(enemy, {
scaleX: aiEnemyData.scale,
scaleY: aiEnemyData.scale,
rotation: Math.sin(LK.ticks * 0.02) * 0.1
}, {
duration: 500,
easing: tween.easeInOut
});
}
// Create health bars
healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0.5
});
healthBarBg.x = 50;
healthBarBg.y = 150;
LK.gui.addChild(healthBarBg);
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5
});
healthBar.x = 50;
healthBar.y = 150;
LK.gui.addChild(healthBar);
enemyHealthBarBg = LK.getAsset('healthBarBg', {
anchorX: 1,
anchorY: 0.5
});
enemyHealthBarBg.x = 1998;
enemyHealthBarBg.y = 150;
LK.gui.addChild(enemyHealthBarBg);
enemyHealthBar = LK.getAsset('healthBar', {
anchorX: 1,
anchorY: 0.5
});
enemyHealthBar.tint = isBoss ? 0x8e44ad : 0xe74c3c;
enemyHealthBar.x = 1998;
enemyHealthBar.y = 150;
LK.gui.addChild(enemyHealthBar);
LK.getSound('battle').play();
}
function updateHealthBars() {
if (healthBar && battler) {
var healthPercent = battler.health / battler.maxHealth;
healthBar.scaleX = healthPercent;
}
if (enemyHealthBar && enemy) {
var enemyHealthPercent = enemy.health / enemy.maxHealth;
enemyHealthBar.scaleX = enemyHealthPercent;
}
}
var enemyLevel = 1;
function checkCombatEnd() {
if (battler.health <= 0) {
stateText.setText('Defeated! Your evolution ends here...');
LK.setTimeout(function () {
previousBattlerData = null; // Reset progress on game over
LK.showGameOver();
}, 2000);
} else if (enemy.health <= 0) {
// Store current battler data for next round
storeBattlerData();
enemyLevel++;
if (isBoss) {
stateText.setText('BOSS DEFEATED! Epic victory! Evolution continues...');
LK.effects.flashScreen(0xf1c40f, 2000);
} else {
stateText.setText('Enemy defeated! Your evolution grows stronger...');
}
LK.setTimeout(function () {
startNewCombatCycle();
}, 3000);
}
}
function startNewCombatCycle() {
// Clean up current enemy
if (enemy) {
enemy.destroy();
}
// Clean up health bars
if (enemyHealthBar) enemyHealthBar.destroy();
if (enemyHealthBarBg) enemyHealthBarBg.destroy();
if (healthBar) healthBar.destroy();
if (healthBarBg) healthBarBg.destroy();
// Reset battler for new evolution cycle but keep some body parts
var partsToKeep = Math.floor(battler.bodyParts.length * 0.6); // Keep 60% of parts
for (var p = partsToKeep; p < battler.bodyParts.length; p++) {
if (battler.bodyParts[p]) {
battler.bodyParts[p].destroy();
}
}
battler.bodyParts = battler.bodyParts.slice(0, partsToKeep);
battler.consumedItems = [];
consumedCount = 0;
gameState = 'exploration';
combatTimer = 0;
currentInput = null;
textInputs = [];
// Heal battler partially but not fully to increase difficulty
battler.health = Math.min(battler.maxHealth, battler.health + 30);
// Clear old items and spawn new ones
for (var i = 0; i < items.length; i++) {
if (items[i] && !items[i].collected) {
items[i].destroy();
}
}
items = [];
spawnItems();
stateText.setText('Evolution ' + battler.evolutionCount + ' | Battle ' + enemyLevel + ' | Body Parts: ' + battler.bodyParts.length);
}
// Initialize game
spawnItems();
// Movement controls
var dragTarget = null;
game.down = function (x, y, obj) {
if (gameState === 'exploration') {
dragTarget = battler;
}
};
game.move = function (x, y, obj) {
if (dragTarget) {
dragTarget.x = x;
dragTarget.y = y;
}
};
game.up = function (x, y, obj) {
dragTarget = null;
};
// Combat timer
var combatTimer = 0;
game.update = function () {
if (gameState === 'homescreen' || gameState === 'tutorial') {
// No update logic needed for these states
return;
} else if (gameState === 'exploration') {
// Check for item collection
for (var i = items.length - 1; i >= 0; i--) {
var item = items[i];
if (!item.collected && battler.intersects(item)) {
battler.consumeItem(item);
items.splice(i, 1);
consumedCount++;
if (consumedCount >= 5) {
startTransformation();
}
var foodTypeName = item.foodType ? item.foodType.name : 'Mystery Food';
stateText.setText('Consumed ' + foodTypeName + ' (' + consumedCount + '/5)');
}
}
} else if (gameState === 'combat') {
combatTimer++;
// Enhanced AI combat system
if (combatTimer % 120 === 0) {
// Player attack - calculate damage based on body parts
var playerDamage = 25 + battler.bodyParts.length * 5;
// Check for special abilities
var criticalHit = false;
for (var bp = 0; bp < battler.bodyParts.length; bp++) {
if (battler.bodyParts[bp].attributes.specialAbility === 'attack') {
playerDamage += 15;
criticalHit = true;
}
}
if (criticalHit) {
LK.effects.flashObject(enemy, 0xffff00, 300);
}
enemy.takeDamage(playerDamage);
}
if (combatTimer % 180 === 60) {
// AI Enemy attacks with special abilities
var enemyDamage = enemy.damage;
// Boss rage mode - gets stronger as health gets lower
if (enemy.isBoss && enemy.abilities.includes('boss-rage')) {
var healthPercent = enemy.health / enemy.maxHealth;
if (healthPercent < 0.5) {
enemyDamage *= 1.5;
enemy.tint = 0xff0000;
}
if (healthPercent < 0.25) {
enemyDamage *= 2;
LK.effects.flashScreen(0xff0000, 100);
}
}
// Boss multi-attack
if (enemy.isBoss && enemy.abilities.includes('multi-attack') && combatTimer % 300 === 60) {
// Attack 3 times with reduced damage
for (var attackCount = 0; attackCount < 3; attackCount++) {
LK.setTimeout(function () {
battler.takeDamage(Math.floor(enemyDamage * 0.7));
LK.effects.flashObject(battler, 0xff0000, 200);
}, attackCount * 400);
}
return; // Skip normal attack this turn
}
// Apply other AI enemy abilities
if (enemy.abilities.includes('counter-attack') && combatTimer % 240 === 60) {
enemyDamage *= 1.5;
LK.effects.flashObject(enemy, 0xff6b6b, 500);
}
if (enemy.abilities.includes('area-damage') && combatTimer % 360 === 60) {
enemyDamage *= 2;
LK.effects.flashScreen(0xff0000, 200);
}
battler.takeDamage(enemyDamage);
// Check for battler defensive abilities
var damageReduction = 0;
for (var dp = 0; dp < battler.bodyParts.length; dp++) {
if (battler.bodyParts[dp].attributes.specialAbility === 'defense') {
damageReduction += 5;
}
}
if (damageReduction > 0) {
battler.health += Math.min(damageReduction, enemyDamage * 0.3);
battler.health = Math.min(battler.health, battler.maxHealth);
}
}
// AI enemy regeneration ability
if (enemy.abilities.includes('regeneration') && combatTimer % 300 === 0) {
enemy.health = Math.min(enemy.maxHealth, enemy.health + enemy.maxHealth * 0.1);
tween(enemy, {
tint: 0x2ecc71
}, {
duration: 300,
onFinish: function onFinish() {
tween(enemy, {
tint: enemy.tint || 0xffffff
}, {
duration: 300
});
}
});
}
updateHealthBars();
checkCombatEnd();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Battler = Container.expand(function () {
var self = Container.call(this);
var battlerGraphics = self.attachAsset('battler', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.consumedItems = [];
self.bodyParts = [];
self.evolutionCount = 0;
self.speed = 3;
// Initialize with random starting body parts
self.initializeBodyParts = function () {
var initialParts = 2 + Math.floor(Math.random() * 3); // 2-4 starting parts
for (var i = 0; i < initialParts; i++) {
var offsetX = (Math.random() - 0.5) * 80;
var offsetY = (Math.random() - 0.5) * 80;
var partType = Math.floor(Math.random() * 6);
var bodyPart = new BodyPart(partType, offsetX, offsetY);
bodyPart.x = offsetX;
bodyPart.y = offsetY;
self.addChild(bodyPart);
self.bodyParts.push(bodyPart);
}
};
self.consumeItem = function (item) {
self.consumedItems.push(item.itemType);
item.collect();
// Visual feedback
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
};
self.evolve = function (prompt1, prompt2) {
self.evolutionCount++;
LK.getSound('evolve').play();
// Evolve existing body parts
for (var i = 0; i < self.bodyParts.length; i++) {
var part = self.bodyParts[i];
part.evolve({
prompt1: prompt1,
prompt2: prompt2,
consumedItems: self.consumedItems
});
}
// Add new AI-generated body parts based on evolution level
var evolutionComplexity = Math.min(5, Math.floor(self.evolutionCount / 2) + 1);
var newPartsCount = evolutionComplexity + Math.floor(Math.random() * evolutionComplexity);
for (var j = 0; j < newPartsCount; j++) {
var offsetX = (Math.random() - 0.5) * (120 + self.evolutionCount * 20);
var offsetY = (Math.random() - 0.5) * (120 + self.evolutionCount * 20);
// Generate AI body part type
var aiPartData = AIBodyPartGenerator.generateUniqueBodyPart(self.evolutionCount, prompt1, prompt2, self.consumedItems);
var partType = (aiPartData.id - 1) % 6;
var newBodyPart = new BodyPart(partType, offsetX, offsetY);
newBodyPart.x = offsetX;
newBodyPart.y = offsetY;
newBodyPart.alpha = 0;
// Apply AI characteristics immediately
newBodyPart.attributes.specialAbility = aiPartData.specialAbility;
newBodyPart.scaleX = aiPartData.size;
newBodyPart.scaleY = aiPartData.size;
newBodyPart.tint = aiPartData.color;
self.addChild(newBodyPart);
self.bodyParts.push(newBodyPart);
// Fade in new part with AI-enhanced animation
tween(newBodyPart, {
alpha: 1
}, {
duration: 1000 + j * 200
});
}
// Boost stats based on evolution count and body parts
self.maxHealth = 100 + self.evolutionCount * 30 + self.bodyParts.length * 10;
self.health = self.maxHealth;
};
self.takeDamage = function (damage) {
self.health = Math.max(0, self.health - damage);
// Visual damage feedback on all body parts
for (var i = 0; i < self.bodyParts.length; i++) {
var part = self.bodyParts[i];
tween(part, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(part, {
tint: 0xffffff
}, {
duration: 200
});
}
});
}
tween(battlerGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(battlerGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
};
// Initialize body parts when created
self.initializeBodyParts();
return self;
});
var BodyPart = Container.expand(function (partType, offsetX, offsetY) {
var self = Container.call(this);
self.partType = partType;
self.offsetX = offsetX || 0;
self.offsetY = offsetY || 0;
self.evolutionLevel = 0;
self.attributes = {
size: 1,
color: 0xffffff,
rotation: 0,
shape: 'ellipse'
};
var partGraphics = self.attachAsset('bodyPart' + (partType + 1), {
anchorX: 0.5,
anchorY: 0.5
});
self.evolve = function (evolutionData) {
self.evolutionLevel++;
// Use AI generation system for evolution
var aiCharacteristics = AIBodyPartGenerator.generateUniqueBodyPart(self.evolutionLevel, evolutionData.prompt1, evolutionData.prompt2, evolutionData.consumedItems);
// Apply AI-generated characteristics
self.attributes.size = aiCharacteristics.size;
self.attributes.color = aiCharacteristics.color;
self.attributes.rotation = (Math.random() - 0.5) * Math.PI;
self.attributes.specialAbility = aiCharacteristics.specialAbility;
// Create new AI-generated body part asset if this is a major evolution
if (self.evolutionLevel % 2 === 0) {
// Replace with AI-generated part
partGraphics.destroy();
partGraphics = self.attachAsset('aiBodyPart' + aiCharacteristics.id, {
anchorX: 0.5,
anchorY: 0.5
});
}
tween(partGraphics, {
scaleX: aiCharacteristics.size,
scaleY: aiCharacteristics.size,
tint: aiCharacteristics.color,
rotation: self.attributes.rotation
}, {
duration: 800,
easing: tween.easeInOut
});
// Organic growth positioning
var growthFactor = 1 + self.evolutionLevel * 0.1;
var newOffsetX = self.offsetX + (Math.random() - 0.5) * 40 * growthFactor;
var newOffsetY = self.offsetY + (Math.random() - 0.5) * 40 * growthFactor;
tween(self, {
x: newOffsetX,
y: newOffsetY
}, {
duration: 800
});
self.offsetX = newOffsetX;
self.offsetY = newOffsetY;
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 80;
self.maxHealth = 80;
self.damage = 15;
self.takeDamage = function (damage) {
self.health = Math.max(0, self.health - damage);
// Visual damage feedback
tween(enemyGraphics, {
tint: 0xff0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemyGraphics, {
tint: 0xffffff
}, {
duration: 200
});
}
});
};
return self;
});
var Item = Container.expand(function (itemType) {
var self = Container.call(this);
self.itemType = itemType;
var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57];
var itemGraphics = self.attachAsset('item' + (itemType + 1), {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.collect = function () {
if (!self.collected) {
self.collected = true;
LK.getSound('pickup').play();
tween(self, {
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
}
};
return self;
});
var KeyboardKey = Container.expand(function (_char) {
var self = Container.call(this);
self["char"] = _char;
var keyBg = LK.getAsset('item1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
keyBg.tint = 0xecf0f1;
self.addChild(keyBg);
var keyText = new Text2(_char, {
size: 30,
fill: 0x2C3E50
});
keyText.anchor.set(0.5, 0.5);
self.addChild(keyText);
self.down = function (x, y, obj) {
tween(self, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
if (currentInput && currentInput.addChar) {
currentInput.addChar(self["char"]);
}
};
return self;
});
var TextInput = Container.expand(function (placeholder) {
var self = Container.call(this);
self.text = '';
self.maxLength = 20;
var inputBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.5
});
self.addChild(inputBg);
self.displayText = new Text2(placeholder || 'Enter text...', {
size: 40,
fill: 0x333333
});
self.displayText.anchor.set(0.5, 0.5);
self.addChild(self.displayText);
self.updateDisplay = function () {
if (self.text.length > 0) {
self.displayText.setText(self.text);
} else {
self.displayText.setText(placeholder || 'Enter text...');
}
};
self.addChar = function (_char2) {
if (self.text.length < self.maxLength) {
self.text += _char2;
self.updateDisplay();
}
};
self.backspace = function () {
if (self.text.length > 0) {
self.text = self.text.slice(0, -1);
self.updateDisplay();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
// AI-generated body part assets with infinite variations
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) throw o;
}
}
};
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) return _arrayLikeToArray(r, a);
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
return n;
}
var AIBodyPartGenerator = {
generateUniqueBodyPart: function generateUniqueBodyPart(evolutionLevel, prompt1, prompt2, consumedItems) {
// Generate AI-influenced body part based on prompts and evolution
var partId = this.generatePartId(prompt1, prompt2, evolutionLevel);
var characteristics = this.analyzePrompts(prompt1, prompt2, consumedItems);
return {
id: partId,
size: characteristics.size,
color: characteristics.color,
shape: characteristics.shape,
specialAbility: characteristics.ability,
evolutionTier: evolutionLevel
};
},
generatePartId: function generatePartId(prompt1, prompt2, evolutionLevel) {
// Generate unique ID based on prompts and evolution level
var hash = 0;
var combined = (prompt1 + prompt2 + evolutionLevel).toLowerCase();
for (var i = 0; i < combined.length; i++) {
hash = (hash << 5) - hash + combined.charCodeAt(i) & 0xffffffff;
}
return Math.abs(hash) % 8 + 1; // Return 1-8 for aiBodyPart assets
},
analyzePrompts: function analyzePrompts(prompt1, prompt2, consumedItems) {
var characteristics = {
size: 1.0,
color: 0xffffff,
shape: 'ellipse',
ability: 'none'
};
var allText = (prompt1 + ' ' + prompt2).toLowerCase();
// Size analysis
if (allText.includes('big') || allText.includes('large') || allText.includes('huge')) {
characteristics.size = 1.5 + Math.random() * 0.8;
} else if (allText.includes('small') || allText.includes('tiny') || allText.includes('mini')) {
characteristics.size = 0.4 + Math.random() * 0.4;
} else {
characteristics.size = 0.8 + Math.random() * 0.6;
}
// Color analysis based on prompt keywords
if (allText.includes('fire') || allText.includes('red') || allText.includes('flame')) {
characteristics.color = 0xff4757;
} else if (allText.includes('ice') || allText.includes('blue') || allText.includes('cold')) {
characteristics.color = 0x3742fa;
} else if (allText.includes('nature') || allText.includes('green') || allText.includes('plant')) {
characteristics.color = 0x2ed573;
} else if (allText.includes('electric') || allText.includes('yellow') || allText.includes('lightning')) {
characteristics.color = 0xffa502;
} else {
// Generate color based on consumed items
var colorBase = 0x000000;
for (var i = 0; i < consumedItems.length; i++) {
colorBase += consumedItems[i] * 123456;
}
characteristics.color = Math.abs(colorBase) % 0xffffff;
}
// Shape analysis
if (allText.includes('sharp') || allText.includes('spike') || allText.includes('blade')) {
characteristics.shape = 'box';
} else if (allText.includes('round') || allText.includes('smooth') || allText.includes('soft')) {
characteristics.shape = 'ellipse';
}
// Special ability analysis
if (allText.includes('weapon') || allText.includes('attack') || allText.includes('damage')) {
characteristics.ability = 'attack';
} else if (allText.includes('shield') || allText.includes('defense') || allText.includes('armor')) {
characteristics.ability = 'defense';
} else if (allText.includes('speed') || allText.includes('fast') || allText.includes('quick')) {
characteristics.ability = 'speed';
} else if (allText.includes('heal') || allText.includes('regenerate') || allText.includes('recover')) {
characteristics.ability = 'healing';
}
return characteristics;
}
};
var AIEnemyGenerator = {
generateEnemy: function generateEnemy(battlerEvolutionLevel, enemyLevel) {
var enemyType = this.determineEnemyType(battlerEvolutionLevel, enemyLevel);
var stats = this.generateEnemyStats(enemyLevel, battlerEvolutionLevel);
return {
type: enemyType,
health: stats.health,
damage: stats.damage,
scale: stats.scale,
color: stats.color,
abilities: stats.abilities
};
},
determineEnemyType: function determineEnemyType(battlerEvolution, enemyLevel) {
var types = ['basic', 'armored', 'swift', 'giant', 'elemental', 'shapeshifter'];
var typeIndex = (battlerEvolution + enemyLevel) % types.length;
return types[typeIndex];
},
generateEnemyStats: function generateEnemyStats(enemyLevel, battlerEvolution) {
var baseHealth = 80;
var baseDamage = 15;
var baseScale = 1.0;
// Scale based on both enemy level and battler evolution
var healthMultiplier = 1 + (enemyLevel - 1) * 0.5 + battlerEvolution * 0.3;
var damageMultiplier = 1 + (enemyLevel - 1) * 0.4 + battlerEvolution * 0.2;
var scaleMultiplier = 1 + (enemyLevel - 1) * 0.15;
return {
health: Math.floor(baseHealth * healthMultiplier),
damage: Math.floor(baseDamage * damageMultiplier),
scale: baseScale * scaleMultiplier,
color: this.generateEnemyColor(enemyLevel, battlerEvolution),
abilities: this.generateEnemyAbilities(enemyLevel)
};
},
generateEnemyColor: function generateEnemyColor(enemyLevel, battlerEvolution) {
var colorOptions = [0xe74c3c, 0x9b59b6, 0x3498db, 0xe67e22, 0x1abc9c, 0xf39c12];
var colorIndex = enemyLevel * battlerEvolution % colorOptions.length;
return colorOptions[colorIndex];
},
generateEnemyAbilities: function generateEnemyAbilities(enemyLevel) {
var abilities = [];
if (enemyLevel >= 3) abilities.push('regeneration');
if (enemyLevel >= 5) abilities.push('counter-attack');
if (enemyLevel >= 7) abilities.push('area-damage');
return abilities;
}
};
var gameState = 'homescreen'; // homescreen, tutorial, exploration, transformation, evolution, combat
var battler;
var enemy;
var items = [];
var consumedCount = 0;
var textInputs = [];
var currentInput = null;
var keyboard = [];
var tutorialStep = 0;
var previousBattlerData = null; // Store battler data from previous victory
var isBoss = false;
// UI elements
var stateText;
var healthBar;
var healthBarBg;
var enemyHealthBar;
var enemyHealthBarBg;
var homeScreenUI = [];
var tutorialUI = [];
// Initialize homescreen
function createHomeScreen() {
var title = new Text2('MORPH BATTLE ARENA', {
size: 80,
fill: 0xFFFFFF
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 600;
game.addChild(title);
homeScreenUI.push(title);
var subtitle = new Text2('Transform. Evolve. Conquer.', {
size: 40,
fill: 0xBDC3C7
});
subtitle.anchor.set(0.5, 0.5);
subtitle.x = 1024;
subtitle.y = 700;
game.addChild(subtitle);
homeScreenUI.push(subtitle);
var startButton = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
startButton.tint = 0x27ae60;
startButton.x = 1024;
startButton.y = 1200;
game.addChild(startButton);
homeScreenUI.push(startButton);
var startText = new Text2('START TUTORIAL', {
size: 50,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = 1024;
startText.y = 1200;
game.addChild(startText);
homeScreenUI.push(startText);
startButton.down = function () {
clearHomeScreen();
startTutorial();
};
}
function clearHomeScreen() {
for (var i = 0; i < homeScreenUI.length; i++) {
homeScreenUI[i].destroy();
}
homeScreenUI = [];
}
function startTutorial() {
gameState = 'tutorial';
tutorialStep = 0;
showTutorialStep();
}
function showTutorialStep() {
// Clear previous tutorial UI
for (var i = 0; i < tutorialUI.length; i++) {
tutorialUI[i].destroy();
}
tutorialUI = [];
var tutorialTexts = ['Welcome! You control a morphing battler that evolves based on what it eats and your descriptions.', 'Drag your battler around to collect 5 different food items. Each type affects your evolution!', 'After eating 5 items, you will describe your battler with 2 prompts to trigger evolution.', 'Your evolved battler will automatically fight enemies. Win to face stronger foes with your evolved form!', 'Food types: Red=Strength, Blue=Defense, Green=Speed, Yellow=Magic, Purple=Special abilities', 'Ready to begin your morphing journey?'];
if (tutorialStep < tutorialTexts.length) {
var tutText = new Text2(tutorialTexts[tutorialStep], {
size: 45,
fill: 0xFFFFFF
});
tutText.anchor.set(0.5, 0.5);
tutText.x = 1024;
tutText.y = 800;
game.addChild(tutText);
tutorialUI.push(tutText);
var nextButton = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
nextButton.tint = 0x3498db;
nextButton.x = 1024;
nextButton.y = 1200;
game.addChild(nextButton);
tutorialUI.push(nextButton);
var nextText = new Text2(tutorialStep < tutorialTexts.length - 1 ? 'NEXT' : 'START GAME', {
size: 40,
fill: 0xFFFFFF
});
nextText.anchor.set(0.5, 0.5);
nextText.x = 1024;
nextText.y = 1200;
game.addChild(nextText);
tutorialUI.push(nextText);
nextButton.down = function () {
tutorialStep++;
if (tutorialStep >= tutorialTexts.length) {
clearTutorialUI();
startGame();
} else {
showTutorialStep();
}
};
}
}
function clearTutorialUI() {
for (var i = 0; i < tutorialUI.length; i++) {
tutorialUI[i].destroy();
}
tutorialUI = [];
}
function startGame() {
gameState = 'exploration';
// Initialize UI
stateText = new Text2('Find and consume 5 items to evolve!', {
size: 50,
fill: 0xECF0F1
});
stateText.anchor.set(0.5, 0);
LK.gui.top.addChild(stateText);
// Create battler - use previous evolution if available
if (previousBattlerData) {
battler = game.addChild(new Battler());
// Restore previous battler characteristics
battler.evolutionCount = previousBattlerData.evolutionCount;
battler.maxHealth = previousBattlerData.maxHealth;
battler.health = Math.floor(battler.maxHealth * 0.8); // Start with 80% health
// Recreate body parts from previous evolution
for (var p = 0; p < previousBattlerData.bodyParts.length; p++) {
var partData = previousBattlerData.bodyParts[p];
var newPart = new BodyPart(partData.partType, partData.offsetX, partData.offsetY);
newPart.evolutionLevel = partData.evolutionLevel;
newPart.attributes = JSON.parse(JSON.stringify(partData.attributes));
newPart.x = partData.offsetX;
newPart.y = partData.offsetY;
battler.addChild(newPart);
battler.bodyParts.push(newPart);
}
} else {
battler = game.addChild(new Battler());
}
battler.x = 1024;
battler.y = 1366;
spawnItems();
}
// Create items scattered around the arena with different food types
function spawnItems() {
var foodTypes = [{
color: 0xff6b6b,
name: 'Strength Berry'
}, {
color: 0x4ecdc4,
name: 'Defense Fruit'
}, {
color: 0x45b7d1,
name: 'Speed Seed'
}, {
color: 0x96ceb4,
name: 'Magic Mushroom'
}, {
color: 0xfeca57,
name: 'Special Spice'
}];
for (var i = 0; i < 8; i++) {
var foodType = i % 5;
var item = game.addChild(new Item(foodType));
item.x = 300 + Math.random() * 1400;
item.y = 400 + Math.random() * 1800;
item.foodType = foodTypes[foodType];
items.push(item);
}
}
// Check if current enemy should be a boss (every 5th enemy)
function shouldBeBoss(enemyLevel) {
return enemyLevel % 5 === 0;
}
// Store battler data for next round
function storeBattlerData() {
if (battler) {
previousBattlerData = {
evolutionCount: battler.evolutionCount,
maxHealth: battler.maxHealth,
bodyParts: []
};
for (var i = 0; i < battler.bodyParts.length; i++) {
var part = battler.bodyParts[i];
previousBattlerData.bodyParts.push({
partType: part.partType,
offsetX: part.offsetX,
offsetY: part.offsetY,
evolutionLevel: part.evolutionLevel,
attributes: JSON.parse(JSON.stringify(part.attributes))
});
}
}
}
// Start the game with homescreen
createHomeScreen();
function createKeyboard() {
var keys = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.split('');
var rows = ['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM'];
var startY = 2000;
var keySize = 80;
var spacing = 10;
for (var row = 0; row < rows.length; row++) {
var rowKeys = rows[row];
var startX = (2048 - rowKeys.length * (keySize + spacing)) / 2;
for (var i = 0; i < rowKeys.length; i++) {
var key = game.addChild(new KeyboardKey(rowKeys[i]));
key.x = startX + i * (keySize + spacing);
key.y = startY + row * (keySize + spacing);
keyboard.push(key);
}
}
// Add space and backspace
var spaceKey = game.addChild(new KeyboardKey(' '));
spaceKey.x = 1024;
spaceKey.y = startY + 3 * (keySize + spacing);
spaceKey.scaleX = 3;
keyboard.push(spaceKey);
// Backspace key
var backspaceKey = game.addChild(new KeyboardKey('⌫'));
backspaceKey.x = 1600;
backspaceKey.y = startY + 3 * (keySize + spacing);
backspaceKey["char"] = 'BACKSPACE';
backspaceKey.down = function (x, y, obj) {
if (currentInput && currentInput.backspace) {
currentInput.backspace();
}
};
keyboard.push(backspaceKey);
}
function hideKeyboard() {
for (var i = 0; i < keyboard.length; i++) {
keyboard[i].visible = false;
}
}
function showKeyboard() {
for (var i = 0; i < keyboard.length; i++) {
keyboard[i].visible = true;
}
}
function onPromptDone(prompt1, prompt2) {
// Handle prompt completion
battler.evolve(prompt1, prompt2);
// Visual feedback for completion
stateText.setText('Evolution in progress...');
LK.effects.flashScreen(0x27ae60, 1000);
// Clean up transformation UI
for (var i = 0; i < textInputs.length; i++) {
textInputs[i].destroy();
}
// Clean up other UI elements
var confirmButton = null;
var confirmText = null;
var _iterator = _createForOfIteratorHelper(game.children),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var child = _step.value;
if (child.tint === 0x27ae60) confirmButton = child;
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (confirmButton) confirmButton.destroy();
// Find and destroy confirm text
var _iterator2 = _createForOfIteratorHelper(game.children),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var child = _step2.value;
if (child.text && child.text === 'EVOLVE!') {
child.destroy();
break;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
hideKeyboard();
textInputs = [];
currentInput = null;
LK.setTimeout(function () {
startCombat();
}, 1500);
}
function startTransformation() {
gameState = 'transformation';
stateText.setText('Select or type your transformation prompts:');
// Show predefined prompt suggestions
var promptSuggestions1 = ['fire warrior', 'ice guardian', 'nature beast', 'lightning striker', 'shadow hunter', 'crystal defender'];
var promptSuggestions2 = ['razor claws', 'healing aura', 'speed boost', 'armor plating', 'energy blast', 'poison spikes'];
// Create suggestion title for first prompt
var title1 = new Text2('Body Type Suggestions (or type your own):', {
size: 35,
fill: 0xBDC3C7
});
title1.anchor.set(0.5, 0.5);
title1.x = 1024;
title1.y = 800;
game.addChild(title1);
textInputs.push(title1);
// Create suggestion buttons for first prompt
for (var i = 0; i < promptSuggestions1.length; i++) {
var suggestionButton = LK.getAsset('item1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.5
});
suggestionButton.tint = 0x3498db;
suggestionButton.x = 200 + i % 3 * 600;
suggestionButton.y = 900 + Math.floor(i / 3) * 80;
suggestionButton.promptText = promptSuggestions1[i];
suggestionButton.inputIndex = 0;
game.addChild(suggestionButton);
textInputs.push(suggestionButton);
var suggestionText = new Text2(promptSuggestions1[i], {
size: 25,
fill: 0xFFFFFF
});
suggestionText.anchor.set(0.5, 0.5);
suggestionText.x = suggestionButton.x;
suggestionText.y = suggestionButton.y;
game.addChild(suggestionText);
textInputs.push(suggestionText);
suggestionButton.down = function () {
if (this.inputIndex === 0) {
input1.text = this.promptText;
input1.updateDisplay();
} else if (this.inputIndex === 1) {
input2.text = this.promptText;
input2.updateDisplay();
}
};
}
// Create text inputs
var input1 = game.addChild(new TextInput('Describe your battler...'));
input1.x = 1024;
input1.y = 1100;
textInputs.push(input1);
// Create suggestion title for second prompt
var title2 = new Text2('Ability Suggestions (or type your own):', {
size: 35,
fill: 0xBDC3C7
});
title2.anchor.set(0.5, 0.5);
title2.x = 1024;
title2.y = 1300;
game.addChild(title2);
textInputs.push(title2);
// Create suggestion buttons for second prompt
for (var j = 0; j < promptSuggestions2.length; j++) {
var suggestionButton2 = LK.getAsset('item2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 1.5
});
suggestionButton2.tint = 0xe67e22;
suggestionButton2.x = 200 + j % 3 * 600;
suggestionButton2.y = 1400 + Math.floor(j / 3) * 80;
suggestionButton2.promptText = promptSuggestions2[j];
suggestionButton2.inputIndex = 1;
game.addChild(suggestionButton2);
textInputs.push(suggestionButton2);
var suggestionText2 = new Text2(promptSuggestions2[j], {
size: 25,
fill: 0xFFFFFF
});
suggestionText2.anchor.set(0.5, 0.5);
suggestionText2.x = suggestionButton2.x;
suggestionText2.y = suggestionButton2.y;
game.addChild(suggestionText2);
textInputs.push(suggestionText2);
suggestionButton2.down = function () {
if (this.inputIndex === 0) {
input1.text = this.promptText;
input1.updateDisplay();
} else if (this.inputIndex === 1) {
input2.text = this.promptText;
input2.updateDisplay();
}
};
}
var input2 = game.addChild(new TextInput('Add special abilities...'));
input2.x = 1024;
input2.y = 1600;
textInputs.push(input2);
currentInput = input1;
createKeyboard();
// Add input switching
input1.down = function () {
currentInput = input1;
};
input2.down = function () {
currentInput = input2;
};
// Add confirm button
var confirmButton = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
confirmButton.tint = 0x27ae60;
game.addChild(confirmButton);
confirmButton.x = 1024;
confirmButton.y = 1800;
var confirmText = new Text2('EVOLVE!', {
size: 40,
fill: 0xFFFFFF
});
confirmText.anchor.set(0.5, 0.5);
confirmText.x = 1024;
confirmText.y = 1800;
game.addChild(confirmText);
confirmButton.down = function () {
if (textInputs[0].text && textInputs[0].text.length > 0 && textInputs[1].text && textInputs[1].text.length > 0) {
onPromptDone(textInputs[0].text, textInputs[1].text);
}
};
}
function startCombat() {
gameState = 'combat';
isBoss = shouldBeBoss(enemyLevel);
if (isBoss) {
stateText.setText('BOSS BATTLE! Level: ' + enemyLevel + ' | Evolution: ' + battler.evolutionCount);
} else {
stateText.setText('Battle begins! Enemy Level: ' + enemyLevel + ' | Evolution: ' + battler.evolutionCount);
}
// Generate AI-powered enemy with boss scaling
var aiEnemyData = AIEnemyGenerator.generateEnemy(battler.evolutionCount, enemyLevel);
enemy = game.addChild(new Enemy());
enemy.x = 1024;
enemy.y = 600;
// Apply boss multipliers if it's a boss
if (isBoss) {
aiEnemyData.health *= 2.5;
aiEnemyData.damage *= 1.8;
aiEnemyData.scale *= 1.4;
aiEnemyData.abilities.push('boss-rage');
aiEnemyData.abilities.push('multi-attack');
}
// Apply AI-generated enemy characteristics
enemy.maxHealth = aiEnemyData.health;
enemy.health = enemy.maxHealth;
enemy.damage = aiEnemyData.damage;
enemy.enemyType = aiEnemyData.type;
enemy.abilities = aiEnemyData.abilities;
enemy.isBoss = isBoss;
// Apply AI visual characteristics
enemy.tint = aiEnemyData.color;
enemy.scaleX = aiEnemyData.scale;
enemy.scaleY = aiEnemyData.scale;
// Boss visual effects
if (isBoss) {
LK.effects.flashScreen(0x8e44ad, 1000);
tween(enemy, {
scaleX: aiEnemyData.scale * 1.1,
scaleY: aiEnemyData.scale * 1.1,
rotation: Math.sin(LK.ticks * 0.05) * 0.2
}, {
duration: 800,
easing: tween.easeInOut,
loop: true
});
} else {
// Enhanced visual scaling animation
tween(enemy, {
scaleX: aiEnemyData.scale,
scaleY: aiEnemyData.scale,
rotation: Math.sin(LK.ticks * 0.02) * 0.1
}, {
duration: 500,
easing: tween.easeInOut
});
}
// Create health bars
healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0.5
});
healthBarBg.x = 50;
healthBarBg.y = 150;
LK.gui.addChild(healthBarBg);
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0.5
});
healthBar.x = 50;
healthBar.y = 150;
LK.gui.addChild(healthBar);
enemyHealthBarBg = LK.getAsset('healthBarBg', {
anchorX: 1,
anchorY: 0.5
});
enemyHealthBarBg.x = 1998;
enemyHealthBarBg.y = 150;
LK.gui.addChild(enemyHealthBarBg);
enemyHealthBar = LK.getAsset('healthBar', {
anchorX: 1,
anchorY: 0.5
});
enemyHealthBar.tint = isBoss ? 0x8e44ad : 0xe74c3c;
enemyHealthBar.x = 1998;
enemyHealthBar.y = 150;
LK.gui.addChild(enemyHealthBar);
LK.getSound('battle').play();
}
function updateHealthBars() {
if (healthBar && battler) {
var healthPercent = battler.health / battler.maxHealth;
healthBar.scaleX = healthPercent;
}
if (enemyHealthBar && enemy) {
var enemyHealthPercent = enemy.health / enemy.maxHealth;
enemyHealthBar.scaleX = enemyHealthPercent;
}
}
var enemyLevel = 1;
function checkCombatEnd() {
if (battler.health <= 0) {
stateText.setText('Defeated! Your evolution ends here...');
LK.setTimeout(function () {
previousBattlerData = null; // Reset progress on game over
LK.showGameOver();
}, 2000);
} else if (enemy.health <= 0) {
// Store current battler data for next round
storeBattlerData();
enemyLevel++;
if (isBoss) {
stateText.setText('BOSS DEFEATED! Epic victory! Evolution continues...');
LK.effects.flashScreen(0xf1c40f, 2000);
} else {
stateText.setText('Enemy defeated! Your evolution grows stronger...');
}
LK.setTimeout(function () {
startNewCombatCycle();
}, 3000);
}
}
function startNewCombatCycle() {
// Clean up current enemy
if (enemy) {
enemy.destroy();
}
// Clean up health bars
if (enemyHealthBar) enemyHealthBar.destroy();
if (enemyHealthBarBg) enemyHealthBarBg.destroy();
if (healthBar) healthBar.destroy();
if (healthBarBg) healthBarBg.destroy();
// Reset battler for new evolution cycle but keep some body parts
var partsToKeep = Math.floor(battler.bodyParts.length * 0.6); // Keep 60% of parts
for (var p = partsToKeep; p < battler.bodyParts.length; p++) {
if (battler.bodyParts[p]) {
battler.bodyParts[p].destroy();
}
}
battler.bodyParts = battler.bodyParts.slice(0, partsToKeep);
battler.consumedItems = [];
consumedCount = 0;
gameState = 'exploration';
combatTimer = 0;
currentInput = null;
textInputs = [];
// Heal battler partially but not fully to increase difficulty
battler.health = Math.min(battler.maxHealth, battler.health + 30);
// Clear old items and spawn new ones
for (var i = 0; i < items.length; i++) {
if (items[i] && !items[i].collected) {
items[i].destroy();
}
}
items = [];
spawnItems();
stateText.setText('Evolution ' + battler.evolutionCount + ' | Battle ' + enemyLevel + ' | Body Parts: ' + battler.bodyParts.length);
}
// Initialize game
spawnItems();
// Movement controls
var dragTarget = null;
game.down = function (x, y, obj) {
if (gameState === 'exploration') {
dragTarget = battler;
}
};
game.move = function (x, y, obj) {
if (dragTarget) {
dragTarget.x = x;
dragTarget.y = y;
}
};
game.up = function (x, y, obj) {
dragTarget = null;
};
// Combat timer
var combatTimer = 0;
game.update = function () {
if (gameState === 'homescreen' || gameState === 'tutorial') {
// No update logic needed for these states
return;
} else if (gameState === 'exploration') {
// Check for item collection
for (var i = items.length - 1; i >= 0; i--) {
var item = items[i];
if (!item.collected && battler.intersects(item)) {
battler.consumeItem(item);
items.splice(i, 1);
consumedCount++;
if (consumedCount >= 5) {
startTransformation();
}
var foodTypeName = item.foodType ? item.foodType.name : 'Mystery Food';
stateText.setText('Consumed ' + foodTypeName + ' (' + consumedCount + '/5)');
}
}
} else if (gameState === 'combat') {
combatTimer++;
// Enhanced AI combat system
if (combatTimer % 120 === 0) {
// Player attack - calculate damage based on body parts
var playerDamage = 25 + battler.bodyParts.length * 5;
// Check for special abilities
var criticalHit = false;
for (var bp = 0; bp < battler.bodyParts.length; bp++) {
if (battler.bodyParts[bp].attributes.specialAbility === 'attack') {
playerDamage += 15;
criticalHit = true;
}
}
if (criticalHit) {
LK.effects.flashObject(enemy, 0xffff00, 300);
}
enemy.takeDamage(playerDamage);
}
if (combatTimer % 180 === 60) {
// AI Enemy attacks with special abilities
var enemyDamage = enemy.damage;
// Boss rage mode - gets stronger as health gets lower
if (enemy.isBoss && enemy.abilities.includes('boss-rage')) {
var healthPercent = enemy.health / enemy.maxHealth;
if (healthPercent < 0.5) {
enemyDamage *= 1.5;
enemy.tint = 0xff0000;
}
if (healthPercent < 0.25) {
enemyDamage *= 2;
LK.effects.flashScreen(0xff0000, 100);
}
}
// Boss multi-attack
if (enemy.isBoss && enemy.abilities.includes('multi-attack') && combatTimer % 300 === 60) {
// Attack 3 times with reduced damage
for (var attackCount = 0; attackCount < 3; attackCount++) {
LK.setTimeout(function () {
battler.takeDamage(Math.floor(enemyDamage * 0.7));
LK.effects.flashObject(battler, 0xff0000, 200);
}, attackCount * 400);
}
return; // Skip normal attack this turn
}
// Apply other AI enemy abilities
if (enemy.abilities.includes('counter-attack') && combatTimer % 240 === 60) {
enemyDamage *= 1.5;
LK.effects.flashObject(enemy, 0xff6b6b, 500);
}
if (enemy.abilities.includes('area-damage') && combatTimer % 360 === 60) {
enemyDamage *= 2;
LK.effects.flashScreen(0xff0000, 200);
}
battler.takeDamage(enemyDamage);
// Check for battler defensive abilities
var damageReduction = 0;
for (var dp = 0; dp < battler.bodyParts.length; dp++) {
if (battler.bodyParts[dp].attributes.specialAbility === 'defense') {
damageReduction += 5;
}
}
if (damageReduction > 0) {
battler.health += Math.min(damageReduction, enemyDamage * 0.3);
battler.health = Math.min(battler.health, battler.maxHealth);
}
}
// AI enemy regeneration ability
if (enemy.abilities.includes('regeneration') && combatTimer % 300 === 0) {
enemy.health = Math.min(enemy.maxHealth, enemy.health + enemy.maxHealth * 0.1);
tween(enemy, {
tint: 0x2ecc71
}, {
duration: 300,
onFinish: function onFinish() {
tween(enemy, {
tint: enemy.tint || 0xffffff
}, {
duration: 300
});
}
});
}
updateHealthBars();
checkCombatEnd();
}
};