/****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function (enemyType) {
var self = Container.call(this);
self.enemyType = enemyType || 'goblin';
var enemyStats = {
goblin: {
health: 40,
attack: 8,
defense: 3,
exp: 15,
gold: 10
},
orc: {
health: 80,
attack: 12,
defense: 6,
exp: 25,
gold: 20
},
dragon: {
health: 150,
attack: 20,
defense: 10,
exp: 50,
gold: 50
}
};
var stats = enemyStats[self.enemyType];
self.maxHealth = stats.health;
self.currentHealth = self.maxHealth;
self.attack = stats.attack;
self.defense = stats.defense;
self.expReward = stats.exp;
self.goldReward = stats.gold;
var enemyGraphics = self.attachAsset(self.enemyType, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
var actualDamage = Math.max(1, damage - self.defense);
self.currentHealth = Math.max(0, self.currentHealth - actualDamage);
return actualDamage;
};
self.isDead = function () {
return self.currentHealth <= 0;
};
return self;
});
var InventorySlot = Container.expand(function () {
var self = Container.call(this);
self.item = null;
var slotGraphics = self.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
self.itemText = new Text2('', {
size: 20,
fill: '#ffffff'
});
self.itemText.anchor.set(0.5, 0.5);
self.addChild(self.itemText);
self.setItem = function (item) {
self.item = item;
if (item) {
self.itemText.setText(item.name.substring(0, 3));
} else {
self.itemText.setText('');
}
};
self.down = function (x, y, obj) {
if (self.item && self.item.type === 'potion') {
player.heal(self.item.healAmount || 30);
self.setItem(null);
var index = player.inventory.indexOf(self.item);
if (index > -1) {
player.inventory.splice(index, 1);
}
}
};
return self;
});
var Player = Container.expand(function (characterClass) {
var self = Container.call(this);
self.characterClass = characterClass || 'warrior';
self.level = 1;
self.experience = 0;
self.experienceToNext = 100;
self.gold = 50;
// Base stats by class
var baseStats = {
warrior: {
health: 120,
mana: 30,
attack: 15,
defense: 12,
speed: 8
},
mage: {
health: 80,
mana: 100,
attack: 20,
defense: 6,
speed: 10
},
archer: {
health: 100,
mana: 60,
attack: 18,
defense: 8,
speed: 14
}
};
var stats = baseStats[self.characterClass];
self.maxHealth = stats.health;
self.currentHealth = self.maxHealth;
self.maxMana = stats.mana;
self.currentMana = self.maxMana;
self.attack = stats.attack;
self.defense = stats.defense;
self.speed = stats.speed;
self.inventory = [];
self.equipment = {
weapon: null,
armor: null,
accessory: null
};
var playerGraphics = self.attachAsset(self.characterClass, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
var actualDamage = Math.max(1, damage - self.defense);
self.currentHealth = Math.max(0, self.currentHealth - actualDamage);
return actualDamage;
};
self.heal = function (amount) {
self.currentHealth = Math.min(self.maxHealth, self.currentHealth + amount);
};
self.useMana = function (amount) {
if (self.currentMana >= amount) {
self.currentMana -= amount;
return true;
}
return false;
};
self.gainExperience = function (exp) {
self.experience += exp;
if (self.experience >= self.experienceToNext) {
self.levelUp();
}
};
self.levelUp = function () {
self.level++;
self.experience -= self.experienceToNext;
self.experienceToNext = Math.floor(self.experienceToNext * 1.5);
// Increase stats on level up
self.maxHealth += 10;
self.currentHealth = self.maxHealth;
self.maxMana += 5;
self.currentMana = self.maxMana;
self.attack += 2;
self.defense += 1;
LK.getSound('levelUp').play();
};
self.addItem = function (item) {
if (self.inventory.length < 20) {
self.inventory.push(item);
return true;
}
return false;
};
self.equipItem = function (item) {
if (item.type === 'weapon' || item.type === 'armor' || item.type === 'accessory') {
if (self.equipment[item.type]) {
self.addItem(self.equipment[item.type]);
}
self.equipment[item.type] = item;
// Apply item bonuses
if (item.stats) {
self.attack += item.stats.attack || 0;
self.defense += item.stats.defense || 0;
if (item.stats.health) {
self.maxHealth += item.stats.health;
self.currentHealth += item.stats.health;
}
}
}
};
return self;
});
var Quest = Container.expand(function (questData) {
var self = Container.call(this);
self.title = questData.title;
self.description = questData.description;
self.target = questData.target;
self.targetCount = questData.targetCount;
self.currentCount = 0;
self.reward = questData.reward;
self.isComplete = false;
self.updateProgress = function (enemyType) {
if (enemyType === self.target && self.currentCount < self.targetCount) {
self.currentCount++;
if (self.currentCount >= self.targetCount) {
self.isComplete = true;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
// Game state variables
var gameState = 'characterSelect'; // characterSelect, exploration, combat, inventory, quest
var player = null;
var currentEnemy = null;
var currentQuest = null;
var inventorySlots = [];
var combatTurn = 'player';
// UI Elements
var healthBar = null;
var manaBar = null;
var expBar = null;
var goldText = null;
var levelText = null;
// Character selection buttons
var warriorButton = null;
var mageButton = null;
var archerButton = null;
// Combat UI
var attackButton = null;
var defendButton = null;
var fleeButton = null;
// Exploration UI
var exploreButton = null;
var inventoryButton = null;
var questButton = null;
// Quest data
var availableQuests = [{
title: "Goblin Slayer",
description: "Defeat 3 goblins",
target: "goblin",
targetCount: 3,
reward: {
exp: 50,
gold: 30
}
}, {
title: "Orc Hunter",
description: "Defeat 2 orcs",
target: "orc",
targetCount: 2,
reward: {
exp: 80,
gold: 60
}
}];
function initCharacterSelect() {
game.removeChildren();
var title = new Text2('Choose Your Class', {
size: 60,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 400;
game.addChild(title);
// Warrior button
warriorButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
scaleX: 1.5,
scaleY: 1.5
});
warriorButton.interactive = true;
game.addChild(warriorButton);
var warriorText = new Text2('Warrior', {
size: 40,
fill: '#ffffff'
});
warriorText.anchor.set(0.5, 0.5);
warriorButton.addChild(warriorText);
// Add character sprite preview for warrior
var warriorPreview = LK.getAsset('warrior', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -60,
scaleX: 1.2,
scaleY: 1.2
});
warriorButton.addChild(warriorPreview);
// Add down event handler for warrior button
warriorButton.down = function () {
player = new Player('warrior');
initExploration();
};
// Mage button
mageButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1000,
scaleX: 1.5,
scaleY: 1.5
});
mageButton.interactive = true;
game.addChild(mageButton);
var mageText = new Text2('Mage', {
size: 40,
fill: '#ffffff'
});
mageText.anchor.set(0.5, 0.5);
mageButton.addChild(mageText);
// Add character sprite preview for mage
var magePreview = LK.getAsset('mage', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -60,
scaleX: 1.2,
scaleY: 1.2
});
mageButton.addChild(magePreview);
// Add down event handler for mage button
mageButton.down = function () {
player = new Player('mage');
initExploration();
};
// Archer button
archerButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
scaleX: 1.5,
scaleY: 1.5
});
archerButton.interactive = true;
game.addChild(archerButton);
var archerText = new Text2('Archer', {
size: 40,
fill: '#ffffff'
});
archerText.anchor.set(0.5, 0.5);
archerButton.addChild(archerText);
// Add character sprite preview for archer
var archerPreview = LK.getAsset('archer', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -60,
scaleX: 1.2,
scaleY: 1.2
});
archerButton.addChild(archerPreview);
// Add down event handler for archer button
archerButton.down = function () {
player = new Player('archer');
initExploration();
};
// Add pulsing animation to all buttons
tween(warriorButton, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1000
});
tween(mageButton, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1200
});
tween(archerButton, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1400
});
}
function initExploration() {
game.removeChildren();
gameState = 'exploration';
// Create UI bars
createUIBars();
// Create player sprite with larger scale
player.scaleX = 2.0;
player.scaleY = 2.0;
player.x = 1024;
player.y = 1366;
game.addChild(player);
// Add breathing animation to player
tween(player, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 2000
});
// Create exploration buttons with larger sizes
exploreButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000,
scaleX: 1.3,
scaleY: 1.3
});
exploreButton.interactive = true;
game.addChild(exploreButton);
var exploreText = new Text2('Explore', {
size: 40,
fill: '#ffffff'
});
exploreText.anchor.set(0.5, 0.5);
exploreButton.addChild(exploreText);
inventoryButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 724,
y: 2000,
scaleX: 1.3,
scaleY: 1.3
});
inventoryButton.interactive = true;
game.addChild(inventoryButton);
var inventoryText = new Text2('Inventory', {
size: 32,
fill: '#ffffff'
});
inventoryText.anchor.set(0.5, 0.5);
inventoryButton.addChild(inventoryText);
questButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1324,
y: 2000,
scaleX: 1.3,
scaleY: 1.3
});
questButton.interactive = true;
game.addChild(questButton);
var questText = new Text2('Quests', {
size: 40,
fill: '#ffffff'
});
questText.anchor.set(0.5, 0.5);
questButton.addChild(questText);
// Add growing hover effects to buttons
exploreButton.down = function () {
tween(exploreButton, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
var enemyTypes = ['goblin', 'orc', 'dragon'];
var randomEnemy = enemyTypes[Math.floor(Math.random() * enemyTypes.length)];
startCombat(randomEnemy);
};
inventoryButton.down = function () {
tween(inventoryButton, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
showInventory();
};
questButton.down = function () {
tween(questButton, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
showQuests();
};
// Add some starting items
player.addItem({
name: 'Health Potion',
type: 'potion',
healAmount: 30
});
player.addItem({
name: 'Iron Sword',
type: 'weapon',
stats: {
attack: 5
}
});
}
function createUIBars() {
// Health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0,
x: 200,
y: 150
});
game.addChild(healthBar);
// Mana bar
manaBar = LK.getAsset('manaBar', {
anchorX: 0,
anchorY: 0,
x: 200,
y: 180
});
game.addChild(manaBar);
// Experience bar
expBar = LK.getAsset('expBar', {
anchorX: 0,
anchorY: 0,
x: 200,
y: 210
});
game.addChild(expBar);
// Gold text
goldText = new Text2('Gold: ' + (player ? player.gold : 0), {
size: 30,
fill: '#ffd700'
});
goldText.x = 200;
goldText.y = 250;
game.addChild(goldText);
// Level text
levelText = new Text2('Level: ' + (player ? player.level : 1), {
size: 30,
fill: '#ffffff'
});
levelText.x = 200;
levelText.y = 280;
game.addChild(levelText);
}
function updateUIBars() {
if (player && healthBar && manaBar && expBar) {
healthBar.width = player.currentHealth / player.maxHealth * 200;
manaBar.width = player.currentMana / player.maxMana * 200;
expBar.width = player.experience / player.experienceToNext * 200;
if (goldText) goldText.setText('Gold: ' + player.gold);
if (levelText) levelText.setText('Level: ' + player.level);
}
}
function startCombat(enemyType) {
game.removeChildren();
gameState = 'combat';
combatTurn = 'player';
currentEnemy = new Enemy(enemyType);
currentEnemy.scaleX = 2.5;
currentEnemy.scaleY = 2.5;
currentEnemy.x = 1324;
currentEnemy.y = 800;
game.addChild(currentEnemy);
player.scaleX = 2.5;
player.scaleY = 2.5;
player.x = 724;
player.y = 800;
game.addChild(player);
createUIBars();
// Add intimidating animations
tween(currentEnemy, {
scaleX: 2.8,
scaleY: 2.8
}, {
duration: 1500
});
tween(player, {
scaleX: 2.8,
scaleY: 2.8
}, {
duration: 1200
});
// Combat buttons with larger sizes
attackButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 724,
y: 2000,
scaleX: 1.4,
scaleY: 1.4
});
attackButton.interactive = true;
game.addChild(attackButton);
var attackText = new Text2('Attack', {
size: 40,
fill: '#ffffff'
});
attackText.anchor.set(0.5, 0.5);
attackButton.addChild(attackText);
defendButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000,
scaleX: 1.4,
scaleY: 1.4
});
defendButton.interactive = true;
game.addChild(defendButton);
var defendText = new Text2('Defend', {
size: 40,
fill: '#ffffff'
});
defendText.anchor.set(0.5, 0.5);
defendButton.addChild(defendText);
fleeButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1324,
y: 2000,
scaleX: 1.4,
scaleY: 1.4
});
fleeButton.interactive = true;
game.addChild(fleeButton);
var fleeText = new Text2('Flee', {
size: 40,
fill: '#ffffff'
});
fleeText.anchor.set(0.5, 0.5);
fleeButton.addChild(fleeText);
// Add press growing effects to combat buttons
attackButton.down = function () {
tween(attackButton, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 150
});
playerAttack();
};
defendButton.down = function () {
tween(defendButton, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 150
});
// Add defend animation - player grows briefly
tween(player, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 300
});
player.defense += 5;
combatTurn = 'enemy';
LK.setTimeout(function () {
player.defense -= 5;
enemyAttack();
}, 1000);
};
fleeButton.down = function () {
tween(fleeButton, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 150
});
// Add flee animation - player shrinks then disappears
tween(player, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
initExploration();
}
});
};
}
function playerAttack() {
if (combatTurn === 'player' && currentEnemy) {
// Add attack animation - player grows then shrinks
tween(player, {
scaleX: 3.2,
scaleY: 3.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(player, {
scaleX: 2.5,
scaleY: 2.5
}, {
duration: 200
});
}
});
var damage = currentEnemy.takeDamage(player.attack);
LK.getSound('attack').play();
LK.effects.flashObject(currentEnemy, 0xff0000, 300);
// Enemy shrinks when hit then returns to normal
tween(currentEnemy, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(currentEnemy, {
scaleX: 2.5,
scaleY: 2.5
}, {
duration: 200
});
}
});
if (currentEnemy.isDead()) {
// Enemy defeated
player.gainExperience(currentEnemy.expReward);
player.gold += currentEnemy.goldReward;
// Update quest progress
if (currentQuest) {
currentQuest.updateProgress(currentEnemy.enemyType);
}
// Random loot
if (Math.random() < 0.3) {
var loot = generateLoot();
player.addItem(loot);
}
initExploration();
} else {
combatTurn = 'enemy';
LK.setTimeout(enemyAttack, 1000);
}
}
}
function enemyAttack() {
if (combatTurn === 'enemy' && currentEnemy && player) {
var damage = player.takeDamage(currentEnemy.attack);
LK.effects.flashObject(player, 0xff0000, 300);
if (player.currentHealth <= 0) {
LK.showGameOver();
} else {
combatTurn = 'player';
}
}
}
function generateLoot() {
var lootTable = [{
name: 'Health Potion',
type: 'potion',
healAmount: 30
}, {
name: 'Mana Potion',
type: 'potion',
manaAmount: 25
}, {
name: 'Steel Sword',
type: 'weapon',
stats: {
attack: 8
}
}, {
name: 'Leather Armor',
type: 'armor',
stats: {
defense: 5
}
}, {
name: 'Ring of Power',
type: 'accessory',
stats: {
attack: 3
}
}];
return lootTable[Math.floor(Math.random() * lootTable.length)];
}
function showInventory() {
game.removeChildren();
gameState = 'inventory';
var title = new Text2('Inventory', {
size: 50,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 300;
game.addChild(title);
// Create inventory grid
inventorySlots = [];
for (var i = 0; i < 20; i++) {
var slot = new InventorySlot();
slot.x = 300 + i % 5 * 100;
slot.y = 500 + Math.floor(i / 5) * 100;
if (i < player.inventory.length) {
slot.setItem(player.inventory[i]);
}
inventorySlots.push(slot);
game.addChild(slot);
}
// Back button
var backButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000
});
game.addChild(backButton);
var backText = new Text2('Back', {
size: 30,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backButton.addChild(backText);
backButton.down = function () {
initExploration();
};
}
function showQuests() {
game.removeChildren();
gameState = 'quest';
var title = new Text2('Quests', {
size: 50,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 300;
game.addChild(title);
// Show available quest
if (!currentQuest && availableQuests.length > 0) {
var quest = availableQuests[0];
var questTitle = new Text2(quest.title, {
size: 40,
fill: '#ffd700'
});
questTitle.anchor.set(0.5, 0.5);
questTitle.x = 1024;
questTitle.y = 600;
game.addChild(questTitle);
var questDesc = new Text2(quest.description, {
size: 30,
fill: '#ffffff'
});
questDesc.anchor.set(0.5, 0.5);
questDesc.x = 1024;
questDesc.y = 700;
game.addChild(questDesc);
var acceptButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 900
});
game.addChild(acceptButton);
var acceptText = new Text2('Accept', {
size: 30,
fill: '#ffffff'
});
acceptText.anchor.set(0.5, 0.5);
acceptButton.addChild(acceptText);
acceptButton.down = function () {
currentQuest = new Quest(quest);
availableQuests.shift();
initExploration();
};
} else if (currentQuest) {
var questTitle = new Text2(currentQuest.title, {
size: 40,
fill: '#ffd700'
});
questTitle.anchor.set(0.5, 0.5);
questTitle.x = 1024;
questTitle.y = 600;
game.addChild(questTitle);
var progress = new Text2('Progress: ' + currentQuest.currentCount + '/' + currentQuest.targetCount, {
size: 30,
fill: '#ffffff'
});
progress.anchor.set(0.5, 0.5);
progress.x = 1024;
progress.y = 700;
game.addChild(progress);
if (currentQuest.isComplete) {
var completeButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 900
});
game.addChild(completeButton);
var completeText = new Text2('Complete', {
size: 30,
fill: '#ffffff'
});
completeText.anchor.set(0.5, 0.5);
completeButton.addChild(completeText);
completeButton.down = function () {
player.gainExperience(currentQuest.reward.exp);
player.gold += currentQuest.reward.gold;
LK.getSound('questComplete').play();
currentQuest = null;
initExploration();
};
}
}
// Back button
var backButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000
});
game.addChild(backButton);
var backText = new Text2('Back', {
size: 30,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backButton.addChild(backText);
backButton.down = function () {
initExploration();
};
}
// Load saved game data
var savedData = storage.playerData;
if (savedData) {
player = new Player(savedData.characterClass);
player.level = savedData.level || 1;
player.experience = savedData.experience || 0;
player.gold = savedData.gold || 50;
player.currentHealth = savedData.currentHealth || player.maxHealth;
player.currentMana = savedData.currentMana || player.maxMana;
initExploration();
} else {
initCharacterSelect();
}
game.down = function (x, y, obj) {
if (gameState === 'characterSelect') {
if (obj === warriorButton) {
player = new Player('warrior');
initExploration();
} else if (obj === mageButton) {
player = new Player('mage');
initExploration();
} else if (obj === archerButton) {
player = new Player('archer');
initExploration();
}
} else if (gameState === 'exploration') {
if (obj === exploreButton) {
var enemyTypes = ['goblin', 'orc', 'dragon'];
var randomEnemy = enemyTypes[Math.floor(Math.random() * enemyTypes.length)];
startCombat(randomEnemy);
} else if (obj === inventoryButton) {
showInventory();
} else if (obj === questButton) {
showQuests();
}
} else if (gameState === 'combat') {
if (obj === attackButton) {
playerAttack();
} else if (obj === defendButton) {
// Add defend animation - player grows briefly
tween(player, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 300
});
player.defense += 5;
combatTurn = 'enemy';
LK.setTimeout(function () {
player.defense -= 5;
enemyAttack();
}, 1000);
} else if (obj === fleeButton) {
// Add flee animation - player shrinks then disappears
tween(player, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
initExploration();
}
});
}
}
};
game.update = function () {
updateUIBars();
// Save game data periodically
if (LK.ticks % 300 === 0 && player) {
storage.playerData = {
characterClass: player.characterClass,
level: player.level,
experience: player.experience,
gold: player.gold,
currentHealth: player.currentHealth,
currentMana: player.currentMana
};
}
}; /****
* Plugins
****/
var storage = LK.import("@upit/storage.v1");
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Enemy = Container.expand(function (enemyType) {
var self = Container.call(this);
self.enemyType = enemyType || 'goblin';
var enemyStats = {
goblin: {
health: 40,
attack: 8,
defense: 3,
exp: 15,
gold: 10
},
orc: {
health: 80,
attack: 12,
defense: 6,
exp: 25,
gold: 20
},
dragon: {
health: 150,
attack: 20,
defense: 10,
exp: 50,
gold: 50
}
};
var stats = enemyStats[self.enemyType];
self.maxHealth = stats.health;
self.currentHealth = self.maxHealth;
self.attack = stats.attack;
self.defense = stats.defense;
self.expReward = stats.exp;
self.goldReward = stats.gold;
var enemyGraphics = self.attachAsset(self.enemyType, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
var actualDamage = Math.max(1, damage - self.defense);
self.currentHealth = Math.max(0, self.currentHealth - actualDamage);
return actualDamage;
};
self.isDead = function () {
return self.currentHealth <= 0;
};
return self;
});
var InventorySlot = Container.expand(function () {
var self = Container.call(this);
self.item = null;
var slotGraphics = self.attachAsset('inventorySlot', {
anchorX: 0.5,
anchorY: 0.5
});
self.itemText = new Text2('', {
size: 20,
fill: '#ffffff'
});
self.itemText.anchor.set(0.5, 0.5);
self.addChild(self.itemText);
self.setItem = function (item) {
self.item = item;
if (item) {
self.itemText.setText(item.name.substring(0, 3));
} else {
self.itemText.setText('');
}
};
self.down = function (x, y, obj) {
if (self.item && self.item.type === 'potion') {
player.heal(self.item.healAmount || 30);
self.setItem(null);
var index = player.inventory.indexOf(self.item);
if (index > -1) {
player.inventory.splice(index, 1);
}
}
};
return self;
});
var Player = Container.expand(function (characterClass) {
var self = Container.call(this);
self.characterClass = characterClass || 'warrior';
self.level = 1;
self.experience = 0;
self.experienceToNext = 100;
self.gold = 50;
// Base stats by class
var baseStats = {
warrior: {
health: 120,
mana: 30,
attack: 15,
defense: 12,
speed: 8
},
mage: {
health: 80,
mana: 100,
attack: 20,
defense: 6,
speed: 10
},
archer: {
health: 100,
mana: 60,
attack: 18,
defense: 8,
speed: 14
}
};
var stats = baseStats[self.characterClass];
self.maxHealth = stats.health;
self.currentHealth = self.maxHealth;
self.maxMana = stats.mana;
self.currentMana = self.maxMana;
self.attack = stats.attack;
self.defense = stats.defense;
self.speed = stats.speed;
self.inventory = [];
self.equipment = {
weapon: null,
armor: null,
accessory: null
};
var playerGraphics = self.attachAsset(self.characterClass, {
anchorX: 0.5,
anchorY: 0.5
});
self.takeDamage = function (damage) {
var actualDamage = Math.max(1, damage - self.defense);
self.currentHealth = Math.max(0, self.currentHealth - actualDamage);
return actualDamage;
};
self.heal = function (amount) {
self.currentHealth = Math.min(self.maxHealth, self.currentHealth + amount);
};
self.useMana = function (amount) {
if (self.currentMana >= amount) {
self.currentMana -= amount;
return true;
}
return false;
};
self.gainExperience = function (exp) {
self.experience += exp;
if (self.experience >= self.experienceToNext) {
self.levelUp();
}
};
self.levelUp = function () {
self.level++;
self.experience -= self.experienceToNext;
self.experienceToNext = Math.floor(self.experienceToNext * 1.5);
// Increase stats on level up
self.maxHealth += 10;
self.currentHealth = self.maxHealth;
self.maxMana += 5;
self.currentMana = self.maxMana;
self.attack += 2;
self.defense += 1;
LK.getSound('levelUp').play();
};
self.addItem = function (item) {
if (self.inventory.length < 20) {
self.inventory.push(item);
return true;
}
return false;
};
self.equipItem = function (item) {
if (item.type === 'weapon' || item.type === 'armor' || item.type === 'accessory') {
if (self.equipment[item.type]) {
self.addItem(self.equipment[item.type]);
}
self.equipment[item.type] = item;
// Apply item bonuses
if (item.stats) {
self.attack += item.stats.attack || 0;
self.defense += item.stats.defense || 0;
if (item.stats.health) {
self.maxHealth += item.stats.health;
self.currentHealth += item.stats.health;
}
}
}
};
return self;
});
var Quest = Container.expand(function (questData) {
var self = Container.call(this);
self.title = questData.title;
self.description = questData.description;
self.target = questData.target;
self.targetCount = questData.targetCount;
self.currentCount = 0;
self.reward = questData.reward;
self.isComplete = false;
self.updateProgress = function (enemyType) {
if (enemyType === self.target && self.currentCount < self.targetCount) {
self.currentCount++;
if (self.currentCount >= self.targetCount) {
self.isComplete = true;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2d5016
});
/****
* Game Code
****/
// Game state variables
var gameState = 'characterSelect'; // characterSelect, exploration, combat, inventory, quest
var player = null;
var currentEnemy = null;
var currentQuest = null;
var inventorySlots = [];
var combatTurn = 'player';
// UI Elements
var healthBar = null;
var manaBar = null;
var expBar = null;
var goldText = null;
var levelText = null;
// Character selection buttons
var warriorButton = null;
var mageButton = null;
var archerButton = null;
// Combat UI
var attackButton = null;
var defendButton = null;
var fleeButton = null;
// Exploration UI
var exploreButton = null;
var inventoryButton = null;
var questButton = null;
// Quest data
var availableQuests = [{
title: "Goblin Slayer",
description: "Defeat 3 goblins",
target: "goblin",
targetCount: 3,
reward: {
exp: 50,
gold: 30
}
}, {
title: "Orc Hunter",
description: "Defeat 2 orcs",
target: "orc",
targetCount: 2,
reward: {
exp: 80,
gold: 60
}
}];
function initCharacterSelect() {
game.removeChildren();
var title = new Text2('Choose Your Class', {
size: 60,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 400;
game.addChild(title);
// Warrior button
warriorButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 800,
scaleX: 1.5,
scaleY: 1.5
});
warriorButton.interactive = true;
game.addChild(warriorButton);
var warriorText = new Text2('Warrior', {
size: 40,
fill: '#ffffff'
});
warriorText.anchor.set(0.5, 0.5);
warriorButton.addChild(warriorText);
// Add character sprite preview for warrior
var warriorPreview = LK.getAsset('warrior', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -60,
scaleX: 1.2,
scaleY: 1.2
});
warriorButton.addChild(warriorPreview);
// Add down event handler for warrior button
warriorButton.down = function () {
player = new Player('warrior');
initExploration();
};
// Mage button
mageButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1000,
scaleX: 1.5,
scaleY: 1.5
});
mageButton.interactive = true;
game.addChild(mageButton);
var mageText = new Text2('Mage', {
size: 40,
fill: '#ffffff'
});
mageText.anchor.set(0.5, 0.5);
mageButton.addChild(mageText);
// Add character sprite preview for mage
var magePreview = LK.getAsset('mage', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -60,
scaleX: 1.2,
scaleY: 1.2
});
mageButton.addChild(magePreview);
// Add down event handler for mage button
mageButton.down = function () {
player = new Player('mage');
initExploration();
};
// Archer button
archerButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
scaleX: 1.5,
scaleY: 1.5
});
archerButton.interactive = true;
game.addChild(archerButton);
var archerText = new Text2('Archer', {
size: 40,
fill: '#ffffff'
});
archerText.anchor.set(0.5, 0.5);
archerButton.addChild(archerText);
// Add character sprite preview for archer
var archerPreview = LK.getAsset('archer', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -60,
scaleX: 1.2,
scaleY: 1.2
});
archerButton.addChild(archerPreview);
// Add down event handler for archer button
archerButton.down = function () {
player = new Player('archer');
initExploration();
};
// Add pulsing animation to all buttons
tween(warriorButton, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1000
});
tween(mageButton, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1200
});
tween(archerButton, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1400
});
}
function initExploration() {
game.removeChildren();
gameState = 'exploration';
// Create UI bars
createUIBars();
// Create player sprite with larger scale
player.scaleX = 2.0;
player.scaleY = 2.0;
player.x = 1024;
player.y = 1366;
game.addChild(player);
// Add breathing animation to player
tween(player, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 2000
});
// Create exploration buttons with larger sizes
exploreButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000,
scaleX: 1.3,
scaleY: 1.3
});
exploreButton.interactive = true;
game.addChild(exploreButton);
var exploreText = new Text2('Explore', {
size: 40,
fill: '#ffffff'
});
exploreText.anchor.set(0.5, 0.5);
exploreButton.addChild(exploreText);
inventoryButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 724,
y: 2000,
scaleX: 1.3,
scaleY: 1.3
});
inventoryButton.interactive = true;
game.addChild(inventoryButton);
var inventoryText = new Text2('Inventory', {
size: 32,
fill: '#ffffff'
});
inventoryText.anchor.set(0.5, 0.5);
inventoryButton.addChild(inventoryText);
questButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1324,
y: 2000,
scaleX: 1.3,
scaleY: 1.3
});
questButton.interactive = true;
game.addChild(questButton);
var questText = new Text2('Quests', {
size: 40,
fill: '#ffffff'
});
questText.anchor.set(0.5, 0.5);
questButton.addChild(questText);
// Add growing hover effects to buttons
exploreButton.down = function () {
tween(exploreButton, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
var enemyTypes = ['goblin', 'orc', 'dragon'];
var randomEnemy = enemyTypes[Math.floor(Math.random() * enemyTypes.length)];
startCombat(randomEnemy);
};
inventoryButton.down = function () {
tween(inventoryButton, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
showInventory();
};
questButton.down = function () {
tween(questButton, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200
});
showQuests();
};
// Add some starting items
player.addItem({
name: 'Health Potion',
type: 'potion',
healAmount: 30
});
player.addItem({
name: 'Iron Sword',
type: 'weapon',
stats: {
attack: 5
}
});
}
function createUIBars() {
// Health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0,
x: 200,
y: 150
});
game.addChild(healthBar);
// Mana bar
manaBar = LK.getAsset('manaBar', {
anchorX: 0,
anchorY: 0,
x: 200,
y: 180
});
game.addChild(manaBar);
// Experience bar
expBar = LK.getAsset('expBar', {
anchorX: 0,
anchorY: 0,
x: 200,
y: 210
});
game.addChild(expBar);
// Gold text
goldText = new Text2('Gold: ' + (player ? player.gold : 0), {
size: 30,
fill: '#ffd700'
});
goldText.x = 200;
goldText.y = 250;
game.addChild(goldText);
// Level text
levelText = new Text2('Level: ' + (player ? player.level : 1), {
size: 30,
fill: '#ffffff'
});
levelText.x = 200;
levelText.y = 280;
game.addChild(levelText);
}
function updateUIBars() {
if (player && healthBar && manaBar && expBar) {
healthBar.width = player.currentHealth / player.maxHealth * 200;
manaBar.width = player.currentMana / player.maxMana * 200;
expBar.width = player.experience / player.experienceToNext * 200;
if (goldText) goldText.setText('Gold: ' + player.gold);
if (levelText) levelText.setText('Level: ' + player.level);
}
}
function startCombat(enemyType) {
game.removeChildren();
gameState = 'combat';
combatTurn = 'player';
currentEnemy = new Enemy(enemyType);
currentEnemy.scaleX = 2.5;
currentEnemy.scaleY = 2.5;
currentEnemy.x = 1324;
currentEnemy.y = 800;
game.addChild(currentEnemy);
player.scaleX = 2.5;
player.scaleY = 2.5;
player.x = 724;
player.y = 800;
game.addChild(player);
createUIBars();
// Add intimidating animations
tween(currentEnemy, {
scaleX: 2.8,
scaleY: 2.8
}, {
duration: 1500
});
tween(player, {
scaleX: 2.8,
scaleY: 2.8
}, {
duration: 1200
});
// Combat buttons with larger sizes
attackButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 724,
y: 2000,
scaleX: 1.4,
scaleY: 1.4
});
attackButton.interactive = true;
game.addChild(attackButton);
var attackText = new Text2('Attack', {
size: 40,
fill: '#ffffff'
});
attackText.anchor.set(0.5, 0.5);
attackButton.addChild(attackText);
defendButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000,
scaleX: 1.4,
scaleY: 1.4
});
defendButton.interactive = true;
game.addChild(defendButton);
var defendText = new Text2('Defend', {
size: 40,
fill: '#ffffff'
});
defendText.anchor.set(0.5, 0.5);
defendButton.addChild(defendText);
fleeButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1324,
y: 2000,
scaleX: 1.4,
scaleY: 1.4
});
fleeButton.interactive = true;
game.addChild(fleeButton);
var fleeText = new Text2('Flee', {
size: 40,
fill: '#ffffff'
});
fleeText.anchor.set(0.5, 0.5);
fleeButton.addChild(fleeText);
// Add press growing effects to combat buttons
attackButton.down = function () {
tween(attackButton, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 150
});
playerAttack();
};
defendButton.down = function () {
tween(defendButton, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 150
});
// Add defend animation - player grows briefly
tween(player, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 300
});
player.defense += 5;
combatTurn = 'enemy';
LK.setTimeout(function () {
player.defense -= 5;
enemyAttack();
}, 1000);
};
fleeButton.down = function () {
tween(fleeButton, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 150
});
// Add flee animation - player shrinks then disappears
tween(player, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
initExploration();
}
});
};
}
function playerAttack() {
if (combatTurn === 'player' && currentEnemy) {
// Add attack animation - player grows then shrinks
tween(player, {
scaleX: 3.2,
scaleY: 3.2
}, {
duration: 200,
onFinish: function onFinish() {
tween(player, {
scaleX: 2.5,
scaleY: 2.5
}, {
duration: 200
});
}
});
var damage = currentEnemy.takeDamage(player.attack);
LK.getSound('attack').play();
LK.effects.flashObject(currentEnemy, 0xff0000, 300);
// Enemy shrinks when hit then returns to normal
tween(currentEnemy, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 100,
onFinish: function onFinish() {
tween(currentEnemy, {
scaleX: 2.5,
scaleY: 2.5
}, {
duration: 200
});
}
});
if (currentEnemy.isDead()) {
// Enemy defeated
player.gainExperience(currentEnemy.expReward);
player.gold += currentEnemy.goldReward;
// Update quest progress
if (currentQuest) {
currentQuest.updateProgress(currentEnemy.enemyType);
}
// Random loot
if (Math.random() < 0.3) {
var loot = generateLoot();
player.addItem(loot);
}
initExploration();
} else {
combatTurn = 'enemy';
LK.setTimeout(enemyAttack, 1000);
}
}
}
function enemyAttack() {
if (combatTurn === 'enemy' && currentEnemy && player) {
var damage = player.takeDamage(currentEnemy.attack);
LK.effects.flashObject(player, 0xff0000, 300);
if (player.currentHealth <= 0) {
LK.showGameOver();
} else {
combatTurn = 'player';
}
}
}
function generateLoot() {
var lootTable = [{
name: 'Health Potion',
type: 'potion',
healAmount: 30
}, {
name: 'Mana Potion',
type: 'potion',
manaAmount: 25
}, {
name: 'Steel Sword',
type: 'weapon',
stats: {
attack: 8
}
}, {
name: 'Leather Armor',
type: 'armor',
stats: {
defense: 5
}
}, {
name: 'Ring of Power',
type: 'accessory',
stats: {
attack: 3
}
}];
return lootTable[Math.floor(Math.random() * lootTable.length)];
}
function showInventory() {
game.removeChildren();
gameState = 'inventory';
var title = new Text2('Inventory', {
size: 50,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 300;
game.addChild(title);
// Create inventory grid
inventorySlots = [];
for (var i = 0; i < 20; i++) {
var slot = new InventorySlot();
slot.x = 300 + i % 5 * 100;
slot.y = 500 + Math.floor(i / 5) * 100;
if (i < player.inventory.length) {
slot.setItem(player.inventory[i]);
}
inventorySlots.push(slot);
game.addChild(slot);
}
// Back button
var backButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000
});
game.addChild(backButton);
var backText = new Text2('Back', {
size: 30,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backButton.addChild(backText);
backButton.down = function () {
initExploration();
};
}
function showQuests() {
game.removeChildren();
gameState = 'quest';
var title = new Text2('Quests', {
size: 50,
fill: '#ffffff'
});
title.anchor.set(0.5, 0.5);
title.x = 1024;
title.y = 300;
game.addChild(title);
// Show available quest
if (!currentQuest && availableQuests.length > 0) {
var quest = availableQuests[0];
var questTitle = new Text2(quest.title, {
size: 40,
fill: '#ffd700'
});
questTitle.anchor.set(0.5, 0.5);
questTitle.x = 1024;
questTitle.y = 600;
game.addChild(questTitle);
var questDesc = new Text2(quest.description, {
size: 30,
fill: '#ffffff'
});
questDesc.anchor.set(0.5, 0.5);
questDesc.x = 1024;
questDesc.y = 700;
game.addChild(questDesc);
var acceptButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 900
});
game.addChild(acceptButton);
var acceptText = new Text2('Accept', {
size: 30,
fill: '#ffffff'
});
acceptText.anchor.set(0.5, 0.5);
acceptButton.addChild(acceptText);
acceptButton.down = function () {
currentQuest = new Quest(quest);
availableQuests.shift();
initExploration();
};
} else if (currentQuest) {
var questTitle = new Text2(currentQuest.title, {
size: 40,
fill: '#ffd700'
});
questTitle.anchor.set(0.5, 0.5);
questTitle.x = 1024;
questTitle.y = 600;
game.addChild(questTitle);
var progress = new Text2('Progress: ' + currentQuest.currentCount + '/' + currentQuest.targetCount, {
size: 30,
fill: '#ffffff'
});
progress.anchor.set(0.5, 0.5);
progress.x = 1024;
progress.y = 700;
game.addChild(progress);
if (currentQuest.isComplete) {
var completeButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 900
});
game.addChild(completeButton);
var completeText = new Text2('Complete', {
size: 30,
fill: '#ffffff'
});
completeText.anchor.set(0.5, 0.5);
completeButton.addChild(completeText);
completeButton.down = function () {
player.gainExperience(currentQuest.reward.exp);
player.gold += currentQuest.reward.gold;
LK.getSound('questComplete').play();
currentQuest = null;
initExploration();
};
}
}
// Back button
var backButton = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2000
});
game.addChild(backButton);
var backText = new Text2('Back', {
size: 30,
fill: '#ffffff'
});
backText.anchor.set(0.5, 0.5);
backButton.addChild(backText);
backButton.down = function () {
initExploration();
};
}
// Load saved game data
var savedData = storage.playerData;
if (savedData) {
player = new Player(savedData.characterClass);
player.level = savedData.level || 1;
player.experience = savedData.experience || 0;
player.gold = savedData.gold || 50;
player.currentHealth = savedData.currentHealth || player.maxHealth;
player.currentMana = savedData.currentMana || player.maxMana;
initExploration();
} else {
initCharacterSelect();
}
game.down = function (x, y, obj) {
if (gameState === 'characterSelect') {
if (obj === warriorButton) {
player = new Player('warrior');
initExploration();
} else if (obj === mageButton) {
player = new Player('mage');
initExploration();
} else if (obj === archerButton) {
player = new Player('archer');
initExploration();
}
} else if (gameState === 'exploration') {
if (obj === exploreButton) {
var enemyTypes = ['goblin', 'orc', 'dragon'];
var randomEnemy = enemyTypes[Math.floor(Math.random() * enemyTypes.length)];
startCombat(randomEnemy);
} else if (obj === inventoryButton) {
showInventory();
} else if (obj === questButton) {
showQuests();
}
} else if (gameState === 'combat') {
if (obj === attackButton) {
playerAttack();
} else if (obj === defendButton) {
// Add defend animation - player grows briefly
tween(player, {
scaleX: 3.0,
scaleY: 3.0
}, {
duration: 300
});
player.defense += 5;
combatTurn = 'enemy';
LK.setTimeout(function () {
player.defense -= 5;
enemyAttack();
}, 1000);
} else if (obj === fleeButton) {
// Add flee animation - player shrinks then disappears
tween(player, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
initExploration();
}
});
}
}
};
game.update = function () {
updateUIBars();
// Save game data periodically
if (LK.ticks % 300 === 0 && player) {
storage.playerData = {
characterClass: player.characterClass,
level: player.level,
experience: player.experience,
gold: player.gold,
currentHealth: player.currentHealth,
currentMana: player.currentMana
};
}
};