User prompt
karakterimiz geçice yaklaşamıyor. çok yaklaşınca yeni haritaya geçelim. ve her kapıya yol yapmamışsın
Code edit (1 edits merged)
Please save this source code
User prompt
Path Explorer: Ancient Maps
Initial prompt
harita sistemi yapmalıyız kahverengi büyük noktalarla dağları küçük beyaz noktalarla yolları işaretle biz de sadece o yolardan geçebilelim hareket sistemimiz age of gibi tıkladığımız yere yavaş bir hızda ilerleyecek karakterimiz yolu takip ederek. yollar ekranın sınırlarına kadar gitsin, ekran sınırındaki yolların sonunda geçitler olsun geçitler ile haritaları birbirine bağla 12 farklı harita yap kaydet her haritada 1,2 ya da üç geçit olsun ve hangi geçidin hangi diğer haritaya geçeceğini mantıklı bir şekilde ayarla
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CenterMarker = Container.expand(function () {
var self = Container.call(this);
var markerGraphics = self.attachAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.isMoving = false;
self.targetX = 0;
self.targetY = 0;
self.speed = 3;
self.lastX = 0; // Track last X position for direction detection
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate speed bonus from speeditems (1% per speeditem)
var speedBonus = playerInventory.speeditem * 0.01;
var actualSpeed = self.speed * (1 + speedBonus);
if (distance < actualSpeed) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
} else {
// Store current X before updating
var currentX = self.x;
self.x += dx / distance * actualSpeed;
self.y += dy / distance * actualSpeed;
// Check direction change and flip character accordingly
if (self.x > currentX) {
// Moving right - face right (normal)
characterGraphics.scale.x = Math.abs(characterGraphics.scale.x);
} else if (self.x < currentX) {
// Moving left - face left (flipped)
characterGraphics.scale.x = -Math.abs(characterGraphics.scale.x);
}
}
}
};
return self;
});
var City = Container.expand(function () {
var self = Container.call(this);
var cityGraphics = self.attachAsset('city', {
anchorX: 0.5,
anchorY: 0.5
});
cityGraphics.y = -60; // Move graphics up by 60 pixels
return self;
});
var InventorySlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.quantity = 0;
// Create invisible slot background for click detection
var slotBg = LK.getAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
slotBg.alpha = 0; // Make invisible but still clickable
self.addChild(slotBg);
// Item icon (initially invisible)
var itemIcon = null;
// Quantity text (initially invisible)
var quantityText = new Text2('', {
size: 58,
fill: 0xFFFFFF
});
quantityText.anchor.set(1, 1);
quantityText.x = 60;
quantityText.y = 60;
self.addChild(quantityText);
// Method to set item and quantity
self.setItem = function (itemType, qty) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
self.quantity = qty || 0;
if (itemType === 'salt' && self.quantity > 0) {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'apple' && self.quantity > 0) {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'speeditem' && self.quantity > 0) {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'sword' && self.quantity > 0) {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else {
// Empty slot
self.item = null;
self.quantity = 0;
quantityText.setText('');
}
};
// Method to add quantity to existing item
self.addQuantity = function (qty) {
self.quantity += qty;
if (self.quantity > 0) {
quantityText.setText(self.quantity.toString());
} else {
self.setItem(null, 0);
}
};
return self;
});
var Mountain = Container.expand(function () {
var self = Container.call(this);
var mountainGraphics = self.attachAsset('mountain', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Passage = Container.expand(function () {
var self = Container.call(this);
var passageGraphics = self.attachAsset('passage', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetMap = 0;
self.targetX = 0;
self.targetY = 0;
return self;
});
var Road = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('road', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var SellSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item) {
// Check if player has this item in inventory
var hasItem = false;
if (self.item === 'salt' && playerInventory.salt > 0) {
hasItem = true;
} else if (self.item === 'apple' && playerInventory.apple > 0) {
hasItem = true;
} else if (self.item === 'speeditem' && playerInventory.speeditem > 0) {
hasItem = true;
} else if (self.item === 'sword' && playerInventory.sword > 0) {
hasItem = true;
}
if (hasItem) {
// Sell item
playerGold = Math.round((playerGold + self.price) * 10) / 10;
updateGoldDisplay();
// Remove item from inventory
if (self.item === 'salt') {
playerInventory.salt--;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple--;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem--;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword--;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on sale
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after sale
self.setItem(null);
} else {
// Don't have item - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
}
};
return self;
});
var TradeSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item && playerGold >= self.price) {
// Purchase item
playerGold = Math.round((playerGold - self.price) * 10) / 10;
updateGoldDisplay();
// Add item to inventory
if (self.item === 'salt') {
playerInventory.salt++;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple++;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem++;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword++;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on purchase
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after purchase
self.setItem(null);
} else if (self.item && playerGold < self.price) {
// Not enough gold - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228b22
});
/****
* Game Code
****/
var currentMap = storage.currentMap || 0;
var character = game.addChild(new Character());
var roads = [];
var mountains = [];
var passages = [];
var centerMarker = null;
var city = null;
// Gold system variables
var playerGold = Math.round((storage.playerGold || 100) * 10) / 10;
var goldIcon = null;
var goldText = null;
// Economy system variables - flattened for storage compatibility
var saltBasePrice = 2000;
var saltCurrentPrice = storage.saltCurrentPrice || 2000;
var appleBasePrice = 10;
var appleCurrentPrice = storage.appleCurrentPrice || 10;
var speeditemBasePrice = 20;
var speeditemCurrentPrice = storage.speeditemCurrentPrice || 20;
var swordBasePrice = 60;
var swordCurrentPrice = storage.swordCurrentPrice || 60;
// Movement tracking for economy
var lastPlayerX = 0;
var lastPlayerY = 0;
var totalMovementDistance = storage.totalMovementDistance || 0;
var lastSaltPriceUpdate = storage.lastSaltPriceUpdate || 0;
var lastApplePriceUpdate = storage.lastApplePriceUpdate || 0;
var lastSpeeditemPriceUpdate = storage.lastSpeeditemPriceUpdate || 0;
var lastSwordPriceUpdate = storage.lastSwordPriceUpdate || 0;
// Map data - 12 interconnected maps
var mapData = [
// Map 0
{
roads: [{
x: 200,
y: 400
}, {
x: 300,
y: 400
}, {
x: 400,
y: 400
}, {
x: 500,
y: 400
}, {
x: 600,
y: 400
}, {
x: 700,
y: 400
}, {
x: 800,
y: 500
}, {
x: 900,
y: 600
}, {
x: 1000,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1400,
y: 1100
}, {
x: 1500,
y: 1200
}, {
x: 1600,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1800,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 1800,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1800,
y: 1800
}, {
x: 1800,
y: 1900
}, {
x: 1800,
y: 2000
}, {
x: 1800,
y: 2100
}, {
x: 1800,
y: 2200
}, {
x: 1800,
y: 2300
}, {
x: 1800,
y: 2400
}, {
x: 1800,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1800,
y: 2700
}],
mountains: [{
x: 150,
y: 200
}, {
x: 250,
y: 150
}, {
x: 350,
y: 180
}, {
x: 450,
y: 220
}, {
x: 550,
y: 180
}, {
x: 650,
y: 200
}, {
x: 750,
y: 250
}, {
x: 850,
y: 300
}, {
x: 950,
y: 350
}, {
x: 1050,
y: 400
}, {
x: 1150,
y: 450
}, {
x: 1250,
y: 500
}, {
x: 1350,
y: 550
}, {
x: 1450,
y: 600
}, {
x: 1550,
y: 650
}, {
x: 1650,
y: 700
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 1,
targetX: 100,
targetY: 1500
}, {
x: 1800,
y: 2700,
targetMap: 3,
targetX: 1800,
targetY: 100
}],
startX: 200,
startY: 400
},
// Map 1
{
roads: [{
x: 100,
y: 1500
}, {
x: 200,
y: 1500
}, {
x: 300,
y: 1500
}, {
x: 400,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 600,
y: 1200
}, {
x: 700,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 900,
y: 900
}, {
x: 1000,
y: 800
}, {
x: 1100,
y: 700
}, {
x: 1200,
y: 600
}, {
x: 1300,
y: 500
}, {
x: 1400,
y: 400
}, {
x: 1500,
y: 300
}, {
x: 1600,
y: 200
}, {
x: 48,
y: 1500
}, {
x: 1600,
y: 150
}, {
x: 1600,
y: 100
}, {
x: 1600,
y: 48
}],
mountains: [{
x: 200,
y: 1700
}, {
x: 300,
y: 1800
}, {
x: 400,
y: 1700
}, {
x: 500,
y: 1600
}, {
x: 600,
y: 1500
}, {
x: 700,
y: 1400
}, {
x: 800,
y: 1300
}, {
x: 900,
y: 1200
}, {
x: 1000,
y: 1100
}, {
x: 1100,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 800
}],
passages: [{
x: 100,
y: 1500,
targetMap: 0,
targetX: 2000,
targetY: 1500
}, {
x: 1600,
y: 100,
targetMap: 2,
targetX: 1600,
targetY: 2700
}],
startX: 100,
startY: 1500
},
// Map 2
{
roads: [{
x: 1600,
y: 2700
}, {
x: 1600,
y: 2600
}, {
x: 1600,
y: 2500
}, {
x: 1600,
y: 2400
}, {
x: 1600,
y: 2300
}, {
x: 1600,
y: 2200
}, {
x: 1600,
y: 2100
}, {
x: 1600,
y: 2000
}, {
x: 1600,
y: 1900
}, {
x: 1600,
y: 1800
}, {
x: 1600,
y: 1700
}, {
x: 1600,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1600,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1600,
y: 1200
}],
mountains: [{
x: 1400,
y: 2600
}, {
x: 1500,
y: 2500
}, {
x: 1700,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1400,
y: 2400
}, {
x: 1800,
y: 2400
}, {
x: 1400,
y: 2200
}, {
x: 1800,
y: 2200
}, {
x: 1400,
y: 2000
}, {
x: 1800,
y: 2000
}, {
x: 1400,
y: 1800
}, {
x: 1800,
y: 1800
}],
passages: [{
x: 1600,
y: 2700,
targetMap: 1,
targetX: 1600,
targetY: 100
}, {
x: 1600,
y: 1200,
targetMap: 4,
targetX: 1600,
targetY: 2350
}],
startX: 1600,
startY: 2700
},
// Map 3
{
roads: [{
x: 1800,
y: 100
}, {
x: 1700,
y: 200
}, {
x: 1600,
y: 300
}, {
x: 1500,
y: 400
}, {
x: 1400,
y: 500
}, {
x: 1300,
y: 600
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 900
}, {
x: 900,
y: 1000
}, {
x: 800,
y: 1100
}, {
x: 700,
y: 1200
}, {
x: 600,
y: 1300
}, {
x: 500,
y: 1400
}, {
x: 400,
y: 1500
}, {
x: 300,
y: 1600
}, {
x: 1800,
y: 48
}, {
x: 250,
y: 1600
}, {
x: 200,
y: 1600
}],
mountains: [{
x: 1900,
y: 200
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 800,
y: 1300
}],
passages: [{
x: 1800,
y: 100,
targetMap: 0,
targetX: 1800,
targetY: 2700
}, {
x: 200,
y: 1600,
targetMap: 5,
targetX: 1900,
targetY: 1600
}],
startX: 1800,
startY: 100
},
// Map 4
{
roads: [{
x: 1600,
y: 2350
}, {
x: 1500,
y: 2250
}, {
x: 1400,
y: 2150
}, {
x: 1300,
y: 2050
}, {
x: 1200,
y: 1950
}, {
x: 1100,
y: 1850
}, {
x: 1000,
y: 1750
}, {
x: 900,
y: 1650
}, {
x: 800,
y: 1550
}, {
x: 700,
y: 1450
}, {
x: 600,
y: 1350
}, {
x: 500,
y: 1250
}],
mountains: [{
x: 1700,
y: 2700
}, {
x: 1600,
y: 2800
}, {
x: 1500,
y: 2700
}, {
x: 1400,
y: 2600
}, {
x: 1300,
y: 2500
}, {
x: 1200,
y: 2400
}, {
x: 1100,
y: 2300
}, {
x: 1000,
y: 2200
}],
passages: [{
x: 1600,
y: 2350,
targetMap: 2,
targetX: 1600,
targetY: 1200
}, {
x: 500,
y: 1250,
targetMap: 6,
targetX: 1800,
targetY: 1500
}],
startX: 1600,
startY: 2350
},
// Map 5
{
roads: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1600
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 1400,
y: 1600
}, {
x: 1300,
y: 1600
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1600
}, {
x: 1000,
y: 1600
}, {
x: 900,
y: 1600
}, {
x: 800,
y: 1600
}, {
x: 750,
y: 1600
}, {
x: 700,
y: 1600
}, {
x: 1950,
y: 1600
}, {
x: 2000,
y: 1600
}],
mountains: [{
x: 1900,
y: 1400
}, {
x: 1800,
y: 1400
}, {
x: 1900,
y: 1800
}, {
x: 1800,
y: 1800
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1400
}, {
x: 1700,
y: 1800
}, {
x: 1600,
y: 1800
}],
passages: [{
x: 2000,
y: 1600,
targetMap: 3,
targetX: 200,
targetY: 1600
}, {
x: 700,
y: 1600,
targetMap: 7,
targetX: 1400,
targetY: 1600
}],
startX: 1900,
startY: 1600
},
// Map 6
{
roads: [{
x: 1800,
y: 1500
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 700
}, {
x: 900,
y: 600
}, {
x: 800,
y: 500
}, {
x: 700,
y: 400
}, {
x: 1850,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 1950,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 650,
y: 400
}, {
x: 600,
y: 400
}],
mountains: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1500,
y: 1400
}, {
x: 1400,
y: 1300
}, {
x: 1300,
y: 1200
}, {
x: 1200,
y: 1100
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 4,
targetX: 500,
targetY: 1250
}, {
x: 600,
y: 400,
targetMap: 8,
targetX: 1500,
targetY: 2300
}],
startX: 1800,
startY: 1500
},
// Map 7
{
roads: [{
x: 1400,
y: 1600
}, {
x: 1300,
y: 1500
}, {
x: 1200,
y: 1400
}, {
x: 1100,
y: 1300
}, {
x: 1000,
y: 1200
}, {
x: 900,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 700,
y: 900
}, {
x: 600,
y: 800
}, {
x: 500,
y: 700
}, {
x: 400,
y: 600
}, {
x: 300,
y: 500
}, {
x: 1450,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 250,
y: 500
}, {
x: 200,
y: 500
}],
mountains: [{
x: 1500,
y: 1700
}, {
x: 1400,
y: 1800
}, {
x: 1300,
y: 1700
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1500
}, {
x: 1000,
y: 1400
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1200
}],
passages: [{
x: 1500,
y: 1600,
targetMap: 5,
targetX: 700,
targetY: 1600
}, {
x: 200,
y: 500,
targetMap: 9,
targetX: 1800,
targetY: 500
}],
startX: 1400,
startY: 1600
},
// Map 8
{
roads: [{
x: 1500,
y: 2300
}, {
x: 1400,
y: 2200
}, {
x: 1300,
y: 2100
}, {
x: 1200,
y: 2000
}, {
x: 1100,
y: 1900
}, {
x: 1000,
y: 1800
}, {
x: 900,
y: 1700
}, {
x: 800,
y: 1600
}, {
x: 700,
y: 1500
}, {
x: 600,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 400,
y: 1200
}, {
x: 1500,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1500,
y: 2600
}, {
x: 1500,
y: 2700
}, {
x: 1500,
y: 2732
}, {
x: 350,
y: 1200
}, {
x: 300,
y: 1200
}],
mountains: [{
x: 1600,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1400,
y: 2400
}, {
x: 1300,
y: 2300
}, {
x: 1200,
y: 2200
}, {
x: 1100,
y: 2100
}, {
x: 1000,
y: 2000
}, {
x: 900,
y: 1900
}],
passages: [{
x: 1500,
y: 2700,
targetMap: 6,
targetX: 600,
targetY: 400
}, {
x: 300,
y: 1200,
targetMap: 10,
targetX: 1700,
targetY: 1200
}],
startX: 1500,
startY: 2300
},
// Map 9
{
roads: [{
x: 1800,
y: 500
}, {
x: 1700,
y: 600
}, {
x: 1600,
y: 700
}, {
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 1850,
y: 500
}, {
x: 1900,
y: 500
}, {
x: 1950,
y: 500
}, {
x: 2000,
y: 500
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1300
}, {
x: 700,
y: 1300
}, {
x: 600,
y: 1300
}, {
x: 550,
y: 1300
}, {
x: 500,
y: 1300
}],
mountains: [{
x: 1900,
y: 400
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}],
passages: [{
x: 2000,
y: 500,
targetMap: 7,
targetX: 200,
targetY: 500
}, {
x: 500,
y: 1300,
targetMap: 11,
targetX: 1500,
targetY: 800
}],
startX: 1800,
startY: 500
},
// Map 10
{
roads: [{
x: 1700,
y: 1200
}, {
x: 1600,
y: 1100
}, {
x: 1500,
y: 1000
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 600
}, {
x: 1000,
y: 500
}, {
x: 900,
y: 400
}, {
x: 800,
y: 300
}, {
x: 700,
y: 200
}, {
x: 600,
y: 100
}, {
x: 1750,
y: 1200
}, {
x: 1800,
y: 1200
}, {
x: 600,
y: 75
}, {
x: 600,
y: 48
}],
mountains: [{
x: 1800,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}],
passages: [{
x: 1795,
y: 1260,
targetMap: 8,
targetX: 300,
targetY: 1200
}, {
x: 600,
y: 100,
targetMap: 11,
targetX: 600,
targetY: 2700
}],
startX: 1700,
startY: 1200
},
// Map 11
{
roads: [{
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 600,
y: 1700
}, {
x: 600,
y: 1800
}, {
x: 600,
y: 1900
}, {
x: 600,
y: 2000
}, {
x: 600,
y: 2100
}, {
x: 600,
y: 2200
}, {
x: 600,
y: 2300
}, {
x: 600,
y: 2400
}, {
x: 600,
y: 2500
}, {
x: 600,
y: 2600
}, {
x: 1500,
y: 750
}, {
x: 1500,
y: 700
}, {
x: 600,
y: 2650
}, {
x: 600,
y: 2700
}, {
x: 600,
y: 2732
}],
mountains: [{
x: 1600,
y: 700
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 500,
y: 1700
}, {
x: 700,
y: 1700
}, {
x: 500,
y: 1900
}, {
x: 700,
y: 1900
}],
passages: [{
x: 1500,
y: 700,
targetMap: 9,
targetX: 600,
targetY: 1600
}, {
x: 600,
y: 2700,
targetMap: 10,
targetX: 600,
targetY: 100
}],
startX: 1500,
startY: 800
}];
var arBackground = null;
function loadMap(mapIndex) {
// Clear existing elements
for (var i = 0; i < roads.length; i++) {
roads[i].destroy();
}
// Mountain cleanup removed
for (var i = 0; i < passages.length; i++) {
passages[i].destroy();
}
// Clean up existing center marker
if (centerMarker) {
centerMarker.destroy();
centerMarker = null;
}
// Clean up existing city marker
if (city) {
city.destroy();
city = null;
}
// Clean up existing AR background
if (arBackground) {
arBackground.destroy();
arBackground = null;
}
roads = [];
mountains = [];
passages = [];
var map = mapData[mapIndex];
// Add AR background only for Ancient Ruins (map 6)
if (mapIndex === 6) {
arBackground = game.addChild(LK.getAsset('AR', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
x: 1024,
y: 1366
}));
}
// Add CP background only for Central Plains (map 4)
if (mapIndex === 4) {
arBackground = game.addChild(LK.getAsset('CP', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add SR background only for Southern Ridge (map 2)
if (mapIndex === 2) {
arBackground = game.addChild(LK.getAsset('Sr', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add EV background only for Eastern Valleys (map 1)
if (mapIndex === 1) {
arBackground = game.addChild(LK.getAsset('Ev', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add NH background only for Northern Highlands (map 0)
if (mapIndex === 0) {
arBackground = game.addChild(LK.getAsset('Nh', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add WP background only for Western Peaks (map 3)
if (mapIndex === 3) {
arBackground = game.addChild(LK.getAsset('wp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 9,
x: 1024,
y: 1366
}));
}
// Add MW background only for Mystic Woods (map 5)
if (mapIndex === 5) {
arBackground = game.addChild(LK.getAsset('mw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add DS background only for Desert Sands (map 7)
if (mapIndex === 7) {
arBackground = game.addChild(LK.getAsset('ds', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add CC background only for Coastal Cliffs (map 9)
if (mapIndex === 9) {
arBackground = game.addChild(LK.getAsset('cc', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add SG background only for Sacred Grove (map 11)
if (mapIndex === 11) {
arBackground = game.addChild(LK.getAsset('sg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add MP background only for Mountain Pass (map 10)
if (mapIndex === 10) {
arBackground = game.addChild(LK.getAsset('mp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add FW background only for Frozen Wastes (map 8)
if (mapIndex === 8) {
arBackground = game.addChild(LK.getAsset('fw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Create roads
for (var i = 0; i < map.roads.length; i++) {
var road = game.addChild(new Road());
road.x = map.roads[i].x;
road.y = map.roads[i].y;
roads.push(road);
}
// Mountains removed from display
// Create passages
for (var i = 0; i < map.passages.length; i++) {
var passage = game.addChild(new Passage());
passage.x = map.passages[i].x;
passage.y = map.passages[i].y;
passage.targetMap = map.passages[i].targetMap;
passage.targetX = map.passages[i].targetX;
passage.targetY = map.passages[i].targetY;
passages.push(passage);
}
// Set character position
if (character.x === 0 && character.y === 0) {
character.x = map.startX;
character.y = map.startY;
}
// Find and mark the center road point
var centerRoad = findCenterRoad();
if (centerRoad) {
centerMarker = game.addChild(new CenterMarker());
centerMarker.x = centerRoad.x;
centerMarker.y = centerRoad.y;
}
// Add city marker at calculated position
var cityPosition = findCityPosition();
city = game.addChild(new City());
city.x = cityPosition.x;
city.y = cityPosition.y;
// Create connecting road between center marker and city
if (centerMarker && city) {
var connectionRoads = createConnectionRoad(centerMarker.x, centerMarker.y, city.x, city.y);
for (var i = 0; i < connectionRoads.length; i++) {
roads.push(connectionRoads[i]);
}
}
// Bring city to front so it appears above roads
if (city) {
game.removeChild(city);
game.addChild(city);
}
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Reset city visit tracking for new map
hasVisitedCity = false;
lastCityDistance = Infinity;
if (isMarketOpen) {
closeMarketScreen();
}
// Generate new market slots for this map
if (!marketSlots) {
marketSlots = [];
}
// Refresh market inventories when changing regions
generateMarketSlots();
generateSellSlots();
}
function findNearestRoad(x, y) {
var nearestRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = x - road.x;
var dy = y - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearestRoad = road;
}
}
return nearestRoad;
}
function findCityPosition() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var mirrorPoints = [];
var map = mapData[currentMap];
// Calculate mirror coordinates for each passage
for (var i = 0; i < map.passages.length; i++) {
var passage = map.passages[i];
var mirrorX = 2 * centerX - passage.x;
var mirrorY = 2 * centerY - passage.y;
mirrorPoints.push({
x: mirrorX,
y: mirrorY
});
}
// Find the center of all mirror points
if (mirrorPoints.length === 0) {
return {
x: centerX,
y: centerY
}; // Default to screen center if no passages
}
var totalX = 0;
var totalY = 0;
for (var i = 0; i < mirrorPoints.length; i++) {
totalX += mirrorPoints[i].x;
totalY += mirrorPoints[i].y;
}
return {
x: totalX / mirrorPoints.length,
y: totalY / mirrorPoints.length
};
}
function createConnectionRoad(startX, startY, endX, endY) {
var connectionRoads = [];
var dx = endX - startX;
var dy = endY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var steps = Math.floor(distance / 100); // Create road points every 100 pixels
for (var i = 1; i <= steps; i++) {
var progress = i / (steps + 1);
var roadX = startX + dx * progress;
var roadY = startY + dy * progress;
var road = game.addChild(new Road());
road.x = roadX;
road.y = roadY;
connectionRoads.push(road);
}
return connectionRoads;
}
function findCenterRoad() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var centerRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = centerX - road.x;
var dy = centerY - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
centerRoad = road;
}
}
return centerRoad;
}
function checkPassageCollision() {
for (var i = 0; i < passages.length; i++) {
var passage = passages[i];
var dx = character.x - passage.x;
var dy = character.y - passage.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 80) {
currentMap = passage.targetMap;
storage.currentMap = currentMap;
loadMap(currentMap);
// Find the 4th nearest road point to the target passage
var targetPassageX = passage.targetX;
var targetPassageY = passage.targetY;
var roadDistances = [];
// Calculate distances from target passage to all roads
for (var j = 0; j < roads.length; j++) {
var road = roads[j];
var rdx = targetPassageX - road.x;
var rdy = targetPassageY - road.y;
var roadDistance = Math.sqrt(rdx * rdx + rdy * rdy);
roadDistances.push({
road: road,
distance: roadDistance
});
}
// Sort roads by distance
roadDistances.sort(function (a, b) {
return a.distance - b.distance;
});
// Get the 4th nearest road (index 3), or closest available if less than 4 roads
var targetRoadIndex = Math.min(3, roadDistances.length - 1);
// Special case for Western Peaks left passage teleportation - use 5th nearest road for better positioning
if (currentMap === 5 && passage.targetX === 1900 && passage.targetY === 1600) {
targetRoadIndex = Math.min(4, roadDistances.length - 1);
}
// Special case for Sacred Grove to Coastal Cliffs teleportation - use 3rd nearest road
if (currentMap === 9 && passage.targetX === 600 && passage.targetY === 1600) {
targetRoadIndex = Math.min(2, roadDistances.length - 1);
}
var targetRoad = roadDistances[targetRoadIndex].road;
character.x = targetRoad.x;
character.y = targetRoad.y;
character.isMoving = false;
break;
}
}
}
// Initialize first map
loadMap(currentMap);
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Initialize economy system tracking
lastPlayerX = character.x;
lastPlayerY = character.y;
// Initialize market slots array to prevent undefined errors
var marketSlots = [];
var sellSlots = [];
// Slot probability pools for each city - initialized as global variable
var slotProbabilityPools = [
// Map 0 - Northern Highlands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// 35% empty, 25% apple, 15% salt, 15% speeditem, 10% sword
// Map 1 - Eastern Valleys
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 2 - Southern Ridge
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 3 - Western Peaks
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 4 - Central Plains
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 5 - Mystic Woods
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 6 - Ancient Ruins
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 7 - Desert Sands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 8 - Frozen Wastes
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 9 - Coastal Cliffs
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 10 - Mountain Pass
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 11 - Sacred Grove
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword']];
// Region names for each map
var regionNames = ['Northern Highlands', 'Eastern Valleys', 'Southern Ridge', 'Western Peaks', 'Central Plains', 'Mystic Woods', 'Ancient Ruins', 'Desert Sands', 'Frozen Wastes', 'Coastal Cliffs', 'Mountain Pass', 'Sacred Grove'];
// Map info display
var mapText = new Text2(regionNames[currentMap], {
size: 60,
fill: 0xFFFFFF
});
mapText.anchor.set(1, 1);
LK.gui.bottomRight.addChild(mapText);
// Gold display setup
goldIcon = LK.getAsset('gold', {
anchorX: 0,
anchorY: 0,
scaleX: 1.6,
scaleY: 1.6
});
goldIcon.x = 120;
goldIcon.y = 20;
LK.gui.topLeft.addChild(goldIcon);
goldText = new Text2(playerGold.toString(), {
size: 96,
fill: 0xFFD700
});
goldText.anchor.set(0, 0);
goldText.x = 280;
goldText.y = 50;
LK.gui.topLeft.addChild(goldText);
// Inventory button setup
var inventoryButton = LK.getAsset('bag', {
anchorX: 1,
anchorY: 0,
scaleX: 1.2,
scaleY: 1.2
});
inventoryButton.x = -20;
inventoryButton.y = 20;
LK.gui.topRight.addChild(inventoryButton);
// City market UI variables
var marketScreen = null;
var marketTitle = null;
var closeButton = null;
var isMarketOpen = false;
var lastCityDistance = Infinity;
var hasVisitedCity = false;
// Inventory UI variables
var inventoryScreen = null;
var isInventoryOpen = false;
var inventorySlots = [];
// Market mode variables
var marketMode = 'selection'; // 'selection', 'buy', 'sell'
var buyButton = null;
var sellButton = null;
// Player inventory system
var playerInventory = {
salt: storage.playerSaltCount || 0,
apple: storage.playerAppleCount || 0,
speeditem: storage.playerSpeeditemCount || 0,
sword: storage.playerSwordCount || 0
};
// Market slot system variables
// Slot refresh now happens on map change
function generateMarketSlots() {
// Clear existing slots
for (var i = 0; i < marketSlots.length; i++) {
if (marketSlots[i] && marketSlots[i].parent) {
marketSlots[i].parent.removeChild(marketSlots[i]);
}
}
marketSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 slots
for (var i = 0; i < 6; i++) {
var slot = new TradeSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
marketSlots.push(slot);
}
}
function generateSellSlots() {
// Clear existing sell slots
// Safety check for sellSlots array existence
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (sellSlots[i] && sellSlots[i].parent) {
sellSlots[i].parent.removeChild(sellSlots[i]);
}
}
}
sellSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 sell slots
for (var i = 0; i < 6; i++) {
var slot = new SellSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
sellSlots.push(slot);
}
}
function refreshMarketSlots() {
// Safety check for marketSlots array
if (!marketSlots) {
marketSlots = [];
generateMarketSlots();
return;
}
// Additional safety check for marketSlots length
if (marketSlots.length === 0) {
generateMarketSlots();
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// 10% chance to refresh each slot
var probabilityPool = slotProbabilityPools[currentMap];
for (var i = 0; i < marketSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
marketSlots[i].setItem(itemType);
}
}
// Also refresh sell slots if they exist
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
sellSlots[i].setItem(itemType);
}
}
}
}
function createMarketScreen() {
// Create market background container
marketScreen = new Container();
marketScreen.x = 0;
marketScreen.y = 0;
// Create market background using citytrade texture
var marketBg = LK.getAsset('citytrade', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
marketBg.x = 24;
marketBg.y = -34;
marketScreen.addChild(marketBg);
// Show mode selection buttons
if (marketMode === 'selection') {
// Create buy button
buyButton = LK.getAsset('buybuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
buyButton.x = -150;
buyButton.y = 0;
marketScreen.addChild(buyButton);
// Create sell button
sellButton = LK.getAsset('sellbuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
sellButton.x = 150;
sellButton.y = 0;
marketScreen.addChild(sellButton);
// Add button functionality
buyButton.down = function () {
marketMode = 'buy';
showBuyMode();
};
sellButton.down = function () {
marketMode = 'sell';
showSellMode();
};
} else if (marketMode === 'buy') {
showBuyMode();
} else if (marketMode === 'sell') {
showSellMode();
}
// Create market title
marketTitle = new Text2(regionNames[currentMap] + ' Market', {
size: 77,
fill: 0xFFFFFF
});
marketTitle.anchor.set(0.5, 0);
marketTitle.x = 24;
marketTitle.y = -490;
marketScreen.addChild(marketTitle);
// Create close button using xbutton texture
closeButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
closeButton.x = 556;
closeButton.y = -680;
marketScreen.addChild(closeButton);
// Add close button functionality
closeButton.down = function () {
closeMarketScreen();
};
LK.gui.center.addChild(marketScreen);
isMarketOpen = true;
}
function showBuyMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate market slots if they don't exist
if (marketSlots.length === 0) {
generateMarketSlots();
}
// Position and add buy slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < marketSlots.length; i++) {
var slot = marketSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function showSellMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate sell slots if they don't exist
if (sellSlots.length === 0) {
generateSellSlots();
}
// Position and add sell slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < sellSlots.length; i++) {
var slot = sellSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function closeMarketScreen() {
if (marketScreen) {
LK.gui.center.removeChild(marketScreen);
marketScreen = null;
marketTitle = null;
closeButton = null;
buyButton = null;
sellButton = null;
isMarketOpen = false;
marketMode = 'selection'; // Reset to selection mode
}
}
function checkCityProximity() {
if (!city) {
return;
}
var dx = character.x - city.x;
var dy = character.y - city.y;
var currentDistance = Math.sqrt(dx * dx + dy * dy);
// Check if entering city range (distance < 100)
if (lastCityDistance >= 100 && currentDistance < 100) {
// Just entered city - show market if not already visited
if (!hasVisitedCity && !isMarketOpen) {
createMarketScreen();
hasVisitedCity = true;
}
}
// Check if leaving city range (distance > 150)
if (lastCityDistance <= 150 && currentDistance > 150) {
// Left city area - reset visit flag for next entry
hasVisitedCity = false;
if (isMarketOpen) {
closeMarketScreen();
}
}
lastCityDistance = currentDistance;
}
game.down = function (x, y, obj) {
// Prevent movement when market or inventory is open
if (isMarketOpen || isInventoryOpen) {
return;
}
var nearestRoad = findNearestRoad(x, y);
if (nearestRoad) {
character.moveTo(nearestRoad.x, nearestRoad.y);
}
};
function updateGoldDisplay() {
if (goldText) {
goldText.setText(playerGold.toString());
storage.playerGold = Math.round(playerGold * 10) / 10;
}
}
function updateEconomySystem() {
// Track movement distance
var dx = character.x - lastPlayerX;
var dy = character.y - lastPlayerY;
var movementThisFrame = Math.sqrt(dx * dx + dy * dy);
if (movementThisFrame > 0) {
totalMovementDistance += movementThisFrame;
// Salt price update every 5000 pixels
var saltDistanceThreshold = lastSaltPriceUpdate + 5000;
if (totalMovementDistance >= saltDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (7%) or decrease (6%)
if (Math.random() < 0.5) {
saltCurrentPrice = Math.round(saltCurrentPrice * 1.07 * 10) / 10; // 7% increase
} else {
saltCurrentPrice = Math.round(saltCurrentPrice * 0.94 * 10) / 10; // 6% decrease
}
}
lastSaltPriceUpdate = totalMovementDistance;
}
// Apple price update every 500 pixels
var appleDistanceThreshold = lastApplePriceUpdate + 500;
if (totalMovementDistance >= appleDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (+1) or decrease (-1)
if (Math.random() < 0.5) {
appleCurrentPrice = Math.round((appleCurrentPrice + 1) * 10) / 10;
} else {
appleCurrentPrice = Math.round((appleCurrentPrice - 1) * 10) / 10;
}
// Apply price limits for apple (5-25)
if (appleCurrentPrice < 5) {
appleCurrentPrice = 5;
}
if (appleCurrentPrice > 25) {
appleCurrentPrice = 25;
}
}
lastApplePriceUpdate = totalMovementDistance;
}
// Speeditem price update every 2000 pixels
var speeditemDistanceThreshold = lastSpeeditemPriceUpdate + 2000;
if (totalMovementDistance >= speeditemDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSpeeditemPriceUpdate = totalMovementDistance;
}
// Sword price update every 2000 pixels
var swordDistanceThreshold = lastSwordPriceUpdate + 2000;
if (totalMovementDistance >= swordDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
swordCurrentPrice = Math.round(swordCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
swordCurrentPrice = Math.round(swordCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSwordPriceUpdate = totalMovementDistance;
}
// Slot refresh now happens on map change instead of movement distance
// Save economy data to storage
storage.saltCurrentPrice = saltCurrentPrice;
storage.appleCurrentPrice = appleCurrentPrice;
storage.speeditemCurrentPrice = speeditemCurrentPrice;
storage.swordCurrentPrice = swordCurrentPrice;
storage.totalMovementDistance = totalMovementDistance;
storage.lastSaltPriceUpdate = lastSaltPriceUpdate;
storage.lastApplePriceUpdate = lastApplePriceUpdate;
storage.lastSpeeditemPriceUpdate = lastSpeeditemPriceUpdate;
storage.lastSwordPriceUpdate = lastSwordPriceUpdate;
}
// Update last position
lastPlayerX = character.x;
lastPlayerY = character.y;
}
// Add inventory button functionality
inventoryButton.down = function () {
if (!isInventoryOpen) {
createInventoryScreen();
} else {
closeInventoryScreen();
}
};
function createInventoryScreen() {
// Create inventory background container
inventoryScreen = new Container();
inventoryScreen.x = 0;
inventoryScreen.y = 0;
// Create inventory background using playerinventory texture
var inventoryBg = LK.getAsset('playerinventory', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
inventoryBg.x = 0;
inventoryBg.y = 0;
inventoryScreen.addChild(inventoryBg);
// Create 4x4 grid of inventory slots
inventorySlots = [];
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++) {
var slot = new InventorySlot();
// Position with 8px down offset and increased spacing: 30px margin, 120px slot size, 15px spacing
slot.x = -300 + 30 + col * 135 + 60; // -300 to center, +30 margin, +60 for slot center, 135px spacing (120+15)
slot.y = -300 + 30 + row * 135 + 60 + 8; // -300 to center, +30 margin, +60 for slot center, +8px down, 135px spacing
inventoryScreen.addChild(slot);
inventorySlots.push(slot);
}
}
// Create close button
var inventoryCloseButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
inventoryCloseButton.x = 330;
inventoryCloseButton.y = -330;
inventoryScreen.addChild(inventoryCloseButton);
// Add close button functionality
inventoryCloseButton.down = function () {
closeInventoryScreen();
};
LK.gui.center.addChild(inventoryScreen);
isInventoryOpen = true;
// Update inventory display
updateInventoryDisplay();
}
function closeInventoryScreen() {
if (inventoryScreen) {
LK.gui.center.removeChild(inventoryScreen);
inventoryScreen = null;
inventorySlots = [];
isInventoryOpen = false;
}
}
function updateInventoryDisplay() {
if (!inventorySlots || inventorySlots.length === 0) return;
// Clear all slots first
for (var i = 0; i < inventorySlots.length; i++) {
inventorySlots[i].setItem(null, 0);
}
// Fill slots with player inventory
var slotIndex = 0;
// Add salt items
if (playerInventory.salt > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('salt', playerInventory.salt);
slotIndex++;
}
// Add apple items
if (playerInventory.apple > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('apple', playerInventory.apple);
slotIndex++;
}
// Add speeditem items
if (playerInventory.speeditem > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('speeditem', playerInventory.speeditem);
slotIndex++;
}
// Add sword items
if (playerInventory.sword > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('sword', playerInventory.sword);
slotIndex++;
}
}
function addItemToInventory(itemType) {
// Find existing slot with same item type
for (var i = 0; i < inventorySlots.length; i++) {
if (inventorySlots[i].item === itemType) {
inventorySlots[i].addQuantity(1);
return;
}
}
// Find first empty slot
for (var i = 0; i < inventorySlots.length; i++) {
if (!inventorySlots[i].item) {
inventorySlots[i].setItem(itemType, 1);
return;
}
}
}
// Generate initial market slots after everything is initialized
generateMarketSlots();
generateSellSlots();
game.update = function () {
checkPassageCollision();
mapText.setText(regionNames[currentMap]);
checkCityProximity();
updateGoldDisplay();
updateEconomySystem();
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CenterMarker = Container.expand(function () {
var self = Container.call(this);
var markerGraphics = self.attachAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5
});
self.isMoving = false;
self.targetX = 0;
self.targetY = 0;
self.speed = 3;
self.lastX = 0; // Track last X position for direction detection
self.moveTo = function (x, y) {
self.targetX = x;
self.targetY = y;
self.isMoving = true;
};
self.update = function () {
if (self.isMoving) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate speed bonus from speeditems (1% per speeditem)
var speedBonus = playerInventory.speeditem * 0.01;
var actualSpeed = self.speed * (1 + speedBonus);
if (distance < actualSpeed) {
self.x = self.targetX;
self.y = self.targetY;
self.isMoving = false;
} else {
// Store current X before updating
var currentX = self.x;
self.x += dx / distance * actualSpeed;
self.y += dy / distance * actualSpeed;
// Check direction change and flip character accordingly
if (self.x > currentX) {
// Moving right - face right (normal)
characterGraphics.scale.x = Math.abs(characterGraphics.scale.x);
} else if (self.x < currentX) {
// Moving left - face left (flipped)
characterGraphics.scale.x = -Math.abs(characterGraphics.scale.x);
}
}
}
};
return self;
});
var City = Container.expand(function () {
var self = Container.call(this);
var cityGraphics = self.attachAsset('city', {
anchorX: 0.5,
anchorY: 0.5
});
cityGraphics.y = -60; // Move graphics up by 60 pixels
return self;
});
var InventorySlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.quantity = 0;
// Create invisible slot background for click detection
var slotBg = LK.getAsset('centerMarker', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
slotBg.alpha = 0; // Make invisible but still clickable
self.addChild(slotBg);
// Item icon (initially invisible)
var itemIcon = null;
// Quantity text (initially invisible)
var quantityText = new Text2('', {
size: 58,
fill: 0xFFFFFF
});
quantityText.anchor.set(1, 1);
quantityText.x = 60;
quantityText.y = 60;
self.addChild(quantityText);
// Method to set item and quantity
self.setItem = function (itemType, qty) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
self.quantity = qty || 0;
if (itemType === 'salt' && self.quantity > 0) {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'apple' && self.quantity > 0) {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'speeditem' && self.quantity > 0) {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else if (itemType === 'sword' && self.quantity > 0) {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = 0;
self.addChild(itemIcon);
self.removeChild(quantityText);
self.addChild(quantityText);
quantityText.setText(self.quantity.toString());
} else {
// Empty slot
self.item = null;
self.quantity = 0;
quantityText.setText('');
}
};
// Method to add quantity to existing item
self.addQuantity = function (qty) {
self.quantity += qty;
if (self.quantity > 0) {
quantityText.setText(self.quantity.toString());
} else {
self.setItem(null, 0);
}
};
return self;
});
var Mountain = Container.expand(function () {
var self = Container.call(this);
var mountainGraphics = self.attachAsset('mountain', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Passage = Container.expand(function () {
var self = Container.call(this);
var passageGraphics = self.attachAsset('passage', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetMap = 0;
self.targetX = 0;
self.targetY = 0;
return self;
});
var Road = Container.expand(function () {
var self = Container.call(this);
var roadGraphics = self.attachAsset('road', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var SellSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 0.8 * 10) / 10; // 80% of current price
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item) {
// Check if player has this item in inventory
var hasItem = false;
if (self.item === 'salt' && playerInventory.salt > 0) {
hasItem = true;
} else if (self.item === 'apple' && playerInventory.apple > 0) {
hasItem = true;
} else if (self.item === 'speeditem' && playerInventory.speeditem > 0) {
hasItem = true;
} else if (self.item === 'sword' && playerInventory.sword > 0) {
hasItem = true;
}
if (hasItem) {
// Sell item
playerGold = Math.round((playerGold + self.price) * 10) / 10;
updateGoldDisplay();
// Remove item from inventory
if (self.item === 'salt') {
playerInventory.salt--;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple--;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem--;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword--;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on sale
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after sale
self.setItem(null);
} else {
// Don't have item - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
}
};
return self;
});
var TradeSlot = Container.expand(function () {
var self = Container.call(this);
// Slot properties
self.item = null; // 'salt', 'apple', or null for empty
self.price = 0;
// Create slot background (tradearea)
var slotBg = self.attachAsset('tradearea', {
anchorX: 0.5,
anchorY: 0.5
});
// Item icon (initially invisible)
var itemIcon = null;
// Item name text
var itemNameText = new Text2('', {
size: 38,
fill: 0xFFFFFF
});
itemNameText.anchor.set(0.5, 0.5);
itemNameText.x = 0;
itemNameText.y = 50;
self.addChild(itemNameText);
// Item price text
var itemPriceText = new Text2('', {
size: 40,
fill: 0xFFD700
});
itemPriceText.anchor.set(0.5, 0.5);
itemPriceText.x = 0;
itemPriceText.y = 80;
self.addChild(itemPriceText);
// Method to set item
self.setItem = function (itemType) {
// Clear existing item icon
if (itemIcon) {
self.removeChild(itemIcon);
itemIcon = null;
}
self.item = itemType;
if (itemType === 'salt') {
itemIcon = LK.getAsset('salt', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Salt');
self.price = Math.round(saltCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'apple') {
itemIcon = LK.getAsset('elma', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Apple');
self.price = Math.round(appleCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'speeditem') {
itemIcon = LK.getAsset('speeditem', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Speed Item');
self.price = Math.round(speeditemCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else if (itemType === 'sword') {
itemIcon = LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
itemIcon.x = 0;
itemIcon.y = -20;
self.addChild(itemIcon);
itemNameText.setText('Sword');
self.price = Math.round(swordCurrentPrice * 10) / 10;
// Create coin icon and price display
var coinIcon = LK.getAsset('coin', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
coinIcon.x = -60;
coinIcon.y = 80;
self.addChild(coinIcon);
itemPriceText.setText(self.price.toString());
itemPriceText.fill = 0xB8860B; // Darker gold color
} else {
// Empty slot
itemNameText.setText('');
itemPriceText.setText('');
self.price = 0;
}
};
// Handle slot click
self.down = function (x, y, obj) {
if (self.item && playerGold >= self.price) {
// Purchase item
playerGold = Math.round((playerGold - self.price) * 10) / 10;
updateGoldDisplay();
// Add item to inventory
if (self.item === 'salt') {
playerInventory.salt++;
storage.playerSaltCount = playerInventory.salt;
} else if (self.item === 'apple') {
playerInventory.apple++;
storage.playerAppleCount = playerInventory.apple;
} else if (self.item === 'speeditem') {
playerInventory.speeditem++;
storage.playerSpeeditemCount = playerInventory.speeditem;
} else if (self.item === 'sword') {
playerInventory.sword++;
storage.playerSwordCount = playerInventory.sword;
}
// Update inventory display if open
if (isInventoryOpen) {
updateInventoryDisplay();
}
// Flash effect on purchase
LK.effects.flashObject(self, 0x00FF00, 500);
// Clear the slot after purchase
self.setItem(null);
} else if (self.item && playerGold < self.price) {
// Not enough gold - flash red
LK.effects.flashObject(self, 0xFF0000, 500);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228b22
});
/****
* Game Code
****/
var currentMap = storage.currentMap || 0;
var character = game.addChild(new Character());
var roads = [];
var mountains = [];
var passages = [];
var centerMarker = null;
var city = null;
// Gold system variables
var playerGold = Math.round((storage.playerGold || 100) * 10) / 10;
var goldIcon = null;
var goldText = null;
// Economy system variables - flattened for storage compatibility
var saltBasePrice = 2000;
var saltCurrentPrice = storage.saltCurrentPrice || 2000;
var appleBasePrice = 10;
var appleCurrentPrice = storage.appleCurrentPrice || 10;
var speeditemBasePrice = 20;
var speeditemCurrentPrice = storage.speeditemCurrentPrice || 20;
var swordBasePrice = 60;
var swordCurrentPrice = storage.swordCurrentPrice || 60;
// Movement tracking for economy
var lastPlayerX = 0;
var lastPlayerY = 0;
var totalMovementDistance = storage.totalMovementDistance || 0;
var lastSaltPriceUpdate = storage.lastSaltPriceUpdate || 0;
var lastApplePriceUpdate = storage.lastApplePriceUpdate || 0;
var lastSpeeditemPriceUpdate = storage.lastSpeeditemPriceUpdate || 0;
var lastSwordPriceUpdate = storage.lastSwordPriceUpdate || 0;
// Map data - 12 interconnected maps
var mapData = [
// Map 0
{
roads: [{
x: 200,
y: 400
}, {
x: 300,
y: 400
}, {
x: 400,
y: 400
}, {
x: 500,
y: 400
}, {
x: 600,
y: 400
}, {
x: 700,
y: 400
}, {
x: 800,
y: 500
}, {
x: 900,
y: 600
}, {
x: 1000,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1400,
y: 1100
}, {
x: 1500,
y: 1200
}, {
x: 1600,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1800,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 1800,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1800,
y: 1800
}, {
x: 1800,
y: 1900
}, {
x: 1800,
y: 2000
}, {
x: 1800,
y: 2100
}, {
x: 1800,
y: 2200
}, {
x: 1800,
y: 2300
}, {
x: 1800,
y: 2400
}, {
x: 1800,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1800,
y: 2700
}],
mountains: [{
x: 150,
y: 200
}, {
x: 250,
y: 150
}, {
x: 350,
y: 180
}, {
x: 450,
y: 220
}, {
x: 550,
y: 180
}, {
x: 650,
y: 200
}, {
x: 750,
y: 250
}, {
x: 850,
y: 300
}, {
x: 950,
y: 350
}, {
x: 1050,
y: 400
}, {
x: 1150,
y: 450
}, {
x: 1250,
y: 500
}, {
x: 1350,
y: 550
}, {
x: 1450,
y: 600
}, {
x: 1550,
y: 650
}, {
x: 1650,
y: 700
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 1,
targetX: 100,
targetY: 1500
}, {
x: 1800,
y: 2700,
targetMap: 3,
targetX: 1800,
targetY: 100
}],
startX: 200,
startY: 400
},
// Map 1
{
roads: [{
x: 100,
y: 1500
}, {
x: 200,
y: 1500
}, {
x: 300,
y: 1500
}, {
x: 400,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 600,
y: 1200
}, {
x: 700,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 900,
y: 900
}, {
x: 1000,
y: 800
}, {
x: 1100,
y: 700
}, {
x: 1200,
y: 600
}, {
x: 1300,
y: 500
}, {
x: 1400,
y: 400
}, {
x: 1500,
y: 300
}, {
x: 1600,
y: 200
}, {
x: 48,
y: 1500
}, {
x: 1600,
y: 150
}, {
x: 1600,
y: 100
}, {
x: 1600,
y: 48
}],
mountains: [{
x: 200,
y: 1700
}, {
x: 300,
y: 1800
}, {
x: 400,
y: 1700
}, {
x: 500,
y: 1600
}, {
x: 600,
y: 1500
}, {
x: 700,
y: 1400
}, {
x: 800,
y: 1300
}, {
x: 900,
y: 1200
}, {
x: 1000,
y: 1100
}, {
x: 1100,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1300,
y: 800
}],
passages: [{
x: 100,
y: 1500,
targetMap: 0,
targetX: 2000,
targetY: 1500
}, {
x: 1600,
y: 100,
targetMap: 2,
targetX: 1600,
targetY: 2700
}],
startX: 100,
startY: 1500
},
// Map 2
{
roads: [{
x: 1600,
y: 2700
}, {
x: 1600,
y: 2600
}, {
x: 1600,
y: 2500
}, {
x: 1600,
y: 2400
}, {
x: 1600,
y: 2300
}, {
x: 1600,
y: 2200
}, {
x: 1600,
y: 2100
}, {
x: 1600,
y: 2000
}, {
x: 1600,
y: 1900
}, {
x: 1600,
y: 1800
}, {
x: 1600,
y: 1700
}, {
x: 1600,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1600,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1600,
y: 1200
}],
mountains: [{
x: 1400,
y: 2600
}, {
x: 1500,
y: 2500
}, {
x: 1700,
y: 2500
}, {
x: 1800,
y: 2600
}, {
x: 1400,
y: 2400
}, {
x: 1800,
y: 2400
}, {
x: 1400,
y: 2200
}, {
x: 1800,
y: 2200
}, {
x: 1400,
y: 2000
}, {
x: 1800,
y: 2000
}, {
x: 1400,
y: 1800
}, {
x: 1800,
y: 1800
}],
passages: [{
x: 1600,
y: 2700,
targetMap: 1,
targetX: 1600,
targetY: 100
}, {
x: 1600,
y: 1200,
targetMap: 4,
targetX: 1600,
targetY: 2350
}],
startX: 1600,
startY: 2700
},
// Map 3
{
roads: [{
x: 1800,
y: 100
}, {
x: 1700,
y: 200
}, {
x: 1600,
y: 300
}, {
x: 1500,
y: 400
}, {
x: 1400,
y: 500
}, {
x: 1300,
y: 600
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 900
}, {
x: 900,
y: 1000
}, {
x: 800,
y: 1100
}, {
x: 700,
y: 1200
}, {
x: 600,
y: 1300
}, {
x: 500,
y: 1400
}, {
x: 400,
y: 1500
}, {
x: 300,
y: 1600
}, {
x: 1800,
y: 48
}, {
x: 250,
y: 1600
}, {
x: 200,
y: 1600
}],
mountains: [{
x: 1900,
y: 200
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 800,
y: 1300
}],
passages: [{
x: 1800,
y: 100,
targetMap: 0,
targetX: 1800,
targetY: 2700
}, {
x: 200,
y: 1600,
targetMap: 5,
targetX: 1900,
targetY: 1600
}],
startX: 1800,
startY: 100
},
// Map 4
{
roads: [{
x: 1600,
y: 2350
}, {
x: 1500,
y: 2250
}, {
x: 1400,
y: 2150
}, {
x: 1300,
y: 2050
}, {
x: 1200,
y: 1950
}, {
x: 1100,
y: 1850
}, {
x: 1000,
y: 1750
}, {
x: 900,
y: 1650
}, {
x: 800,
y: 1550
}, {
x: 700,
y: 1450
}, {
x: 600,
y: 1350
}, {
x: 500,
y: 1250
}],
mountains: [{
x: 1700,
y: 2700
}, {
x: 1600,
y: 2800
}, {
x: 1500,
y: 2700
}, {
x: 1400,
y: 2600
}, {
x: 1300,
y: 2500
}, {
x: 1200,
y: 2400
}, {
x: 1100,
y: 2300
}, {
x: 1000,
y: 2200
}],
passages: [{
x: 1600,
y: 2350,
targetMap: 2,
targetX: 1600,
targetY: 1200
}, {
x: 500,
y: 1250,
targetMap: 6,
targetX: 1800,
targetY: 1500
}],
startX: 1600,
startY: 2350
},
// Map 5
{
roads: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1600
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 1400,
y: 1600
}, {
x: 1300,
y: 1600
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1600
}, {
x: 1000,
y: 1600
}, {
x: 900,
y: 1600
}, {
x: 800,
y: 1600
}, {
x: 750,
y: 1600
}, {
x: 700,
y: 1600
}, {
x: 1950,
y: 1600
}, {
x: 2000,
y: 1600
}],
mountains: [{
x: 1900,
y: 1400
}, {
x: 1800,
y: 1400
}, {
x: 1900,
y: 1800
}, {
x: 1800,
y: 1800
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1400
}, {
x: 1700,
y: 1800
}, {
x: 1600,
y: 1800
}],
passages: [{
x: 2000,
y: 1600,
targetMap: 3,
targetX: 200,
targetY: 1600
}, {
x: 700,
y: 1600,
targetMap: 7,
targetX: 1400,
targetY: 1600
}],
startX: 1900,
startY: 1600
},
// Map 6
{
roads: [{
x: 1800,
y: 1500
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}, {
x: 1000,
y: 700
}, {
x: 900,
y: 600
}, {
x: 800,
y: 500
}, {
x: 700,
y: 400
}, {
x: 1850,
y: 1500
}, {
x: 1900,
y: 1500
}, {
x: 1950,
y: 1500
}, {
x: 2000,
y: 1500
}, {
x: 650,
y: 400
}, {
x: 600,
y: 400
}],
mountains: [{
x: 1900,
y: 1600
}, {
x: 1800,
y: 1700
}, {
x: 1700,
y: 1600
}, {
x: 1600,
y: 1500
}, {
x: 1500,
y: 1400
}, {
x: 1400,
y: 1300
}, {
x: 1300,
y: 1200
}, {
x: 1200,
y: 1100
}],
passages: [{
x: 2000,
y: 1500,
targetMap: 4,
targetX: 500,
targetY: 1250
}, {
x: 600,
y: 400,
targetMap: 8,
targetX: 1500,
targetY: 2300
}],
startX: 1800,
startY: 1500
},
// Map 7
{
roads: [{
x: 1400,
y: 1600
}, {
x: 1300,
y: 1500
}, {
x: 1200,
y: 1400
}, {
x: 1100,
y: 1300
}, {
x: 1000,
y: 1200
}, {
x: 900,
y: 1100
}, {
x: 800,
y: 1000
}, {
x: 700,
y: 900
}, {
x: 600,
y: 800
}, {
x: 500,
y: 700
}, {
x: 400,
y: 600
}, {
x: 300,
y: 500
}, {
x: 1450,
y: 1600
}, {
x: 1500,
y: 1600
}, {
x: 250,
y: 500
}, {
x: 200,
y: 500
}],
mountains: [{
x: 1500,
y: 1700
}, {
x: 1400,
y: 1800
}, {
x: 1300,
y: 1700
}, {
x: 1200,
y: 1600
}, {
x: 1100,
y: 1500
}, {
x: 1000,
y: 1400
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1200
}],
passages: [{
x: 1500,
y: 1600,
targetMap: 5,
targetX: 700,
targetY: 1600
}, {
x: 200,
y: 500,
targetMap: 9,
targetX: 1800,
targetY: 500
}],
startX: 1400,
startY: 1600
},
// Map 8
{
roads: [{
x: 1500,
y: 2300
}, {
x: 1400,
y: 2200
}, {
x: 1300,
y: 2100
}, {
x: 1200,
y: 2000
}, {
x: 1100,
y: 1900
}, {
x: 1000,
y: 1800
}, {
x: 900,
y: 1700
}, {
x: 800,
y: 1600
}, {
x: 700,
y: 1500
}, {
x: 600,
y: 1400
}, {
x: 500,
y: 1300
}, {
x: 400,
y: 1200
}, {
x: 1500,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1500,
y: 2600
}, {
x: 1500,
y: 2700
}, {
x: 1500,
y: 2732
}, {
x: 350,
y: 1200
}, {
x: 300,
y: 1200
}],
mountains: [{
x: 1600,
y: 2400
}, {
x: 1500,
y: 2500
}, {
x: 1400,
y: 2400
}, {
x: 1300,
y: 2300
}, {
x: 1200,
y: 2200
}, {
x: 1100,
y: 2100
}, {
x: 1000,
y: 2000
}, {
x: 900,
y: 1900
}],
passages: [{
x: 1500,
y: 2700,
targetMap: 6,
targetX: 600,
targetY: 400
}, {
x: 300,
y: 1200,
targetMap: 10,
targetX: 1700,
targetY: 1200
}],
startX: 1500,
startY: 2300
},
// Map 9
{
roads: [{
x: 1800,
y: 500
}, {
x: 1700,
y: 600
}, {
x: 1600,
y: 700
}, {
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 1850,
y: 500
}, {
x: 1900,
y: 500
}, {
x: 1950,
y: 500
}, {
x: 2000,
y: 500
}, {
x: 900,
y: 1300
}, {
x: 800,
y: 1300
}, {
x: 700,
y: 1300
}, {
x: 600,
y: 1300
}, {
x: 550,
y: 1300
}, {
x: 500,
y: 1300
}],
mountains: [{
x: 1900,
y: 400
}, {
x: 1800,
y: 300
}, {
x: 1700,
y: 400
}, {
x: 1600,
y: 500
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}],
passages: [{
x: 2000,
y: 500,
targetMap: 7,
targetX: 200,
targetY: 500
}, {
x: 500,
y: 1300,
targetMap: 11,
targetX: 1500,
targetY: 800
}],
startX: 1800,
startY: 500
},
// Map 10
{
roads: [{
x: 1700,
y: 1200
}, {
x: 1600,
y: 1100
}, {
x: 1500,
y: 1000
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 700
}, {
x: 1100,
y: 600
}, {
x: 1000,
y: 500
}, {
x: 900,
y: 400
}, {
x: 800,
y: 300
}, {
x: 700,
y: 200
}, {
x: 600,
y: 100
}, {
x: 1750,
y: 1200
}, {
x: 1800,
y: 1200
}, {
x: 600,
y: 75
}, {
x: 600,
y: 48
}],
mountains: [{
x: 1800,
y: 1300
}, {
x: 1700,
y: 1400
}, {
x: 1600,
y: 1300
}, {
x: 1500,
y: 1200
}, {
x: 1400,
y: 1100
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 800
}],
passages: [{
x: 1795,
y: 1260,
targetMap: 8,
targetX: 300,
targetY: 1200
}, {
x: 600,
y: 100,
targetMap: 11,
targetX: 600,
targetY: 2700
}],
startX: 1700,
startY: 1200
},
// Map 11
{
roads: [{
x: 1500,
y: 800
}, {
x: 1400,
y: 900
}, {
x: 1300,
y: 1000
}, {
x: 1200,
y: 1100
}, {
x: 1100,
y: 1200
}, {
x: 1000,
y: 1300
}, {
x: 900,
y: 1400
}, {
x: 800,
y: 1500
}, {
x: 700,
y: 1600
}, {
x: 600,
y: 1700
}, {
x: 600,
y: 1800
}, {
x: 600,
y: 1900
}, {
x: 600,
y: 2000
}, {
x: 600,
y: 2100
}, {
x: 600,
y: 2200
}, {
x: 600,
y: 2300
}, {
x: 600,
y: 2400
}, {
x: 600,
y: 2500
}, {
x: 600,
y: 2600
}, {
x: 1500,
y: 750
}, {
x: 1500,
y: 700
}, {
x: 600,
y: 2650
}, {
x: 600,
y: 2700
}, {
x: 600,
y: 2732
}],
mountains: [{
x: 1600,
y: 700
}, {
x: 1500,
y: 600
}, {
x: 1400,
y: 700
}, {
x: 1300,
y: 800
}, {
x: 1200,
y: 900
}, {
x: 1100,
y: 1000
}, {
x: 1000,
y: 1100
}, {
x: 900,
y: 1200
}, {
x: 500,
y: 1700
}, {
x: 700,
y: 1700
}, {
x: 500,
y: 1900
}, {
x: 700,
y: 1900
}],
passages: [{
x: 1500,
y: 700,
targetMap: 9,
targetX: 600,
targetY: 1600
}, {
x: 600,
y: 2700,
targetMap: 10,
targetX: 600,
targetY: 100
}],
startX: 1500,
startY: 800
}];
var arBackground = null;
function loadMap(mapIndex) {
// Clear existing elements
for (var i = 0; i < roads.length; i++) {
roads[i].destroy();
}
// Mountain cleanup removed
for (var i = 0; i < passages.length; i++) {
passages[i].destroy();
}
// Clean up existing center marker
if (centerMarker) {
centerMarker.destroy();
centerMarker = null;
}
// Clean up existing city marker
if (city) {
city.destroy();
city = null;
}
// Clean up existing AR background
if (arBackground) {
arBackground.destroy();
arBackground = null;
}
roads = [];
mountains = [];
passages = [];
var map = mapData[mapIndex];
// Add AR background only for Ancient Ruins (map 6)
if (mapIndex === 6) {
arBackground = game.addChild(LK.getAsset('AR', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
x: 1024,
y: 1366
}));
}
// Add CP background only for Central Plains (map 4)
if (mapIndex === 4) {
arBackground = game.addChild(LK.getAsset('CP', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add SR background only for Southern Ridge (map 2)
if (mapIndex === 2) {
arBackground = game.addChild(LK.getAsset('Sr', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
x: 1024,
y: 1366
}));
}
// Add EV background only for Eastern Valleys (map 1)
if (mapIndex === 1) {
arBackground = game.addChild(LK.getAsset('Ev', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add NH background only for Northern Highlands (map 0)
if (mapIndex === 0) {
arBackground = game.addChild(LK.getAsset('Nh', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add WP background only for Western Peaks (map 3)
if (mapIndex === 3) {
arBackground = game.addChild(LK.getAsset('wp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 9,
x: 1024,
y: 1366
}));
}
// Add MW background only for Mystic Woods (map 5)
if (mapIndex === 5) {
arBackground = game.addChild(LK.getAsset('mw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add DS background only for Desert Sands (map 7)
if (mapIndex === 7) {
arBackground = game.addChild(LK.getAsset('ds', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add CC background only for Coastal Cliffs (map 9)
if (mapIndex === 9) {
arBackground = game.addChild(LK.getAsset('cc', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add SG background only for Sacred Grove (map 11)
if (mapIndex === 11) {
arBackground = game.addChild(LK.getAsset('sg', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 7,
x: 1024,
y: 1366
}));
}
// Add MP background only for Mountain Pass (map 10)
if (mapIndex === 10) {
arBackground = game.addChild(LK.getAsset('mp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Add FW background only for Frozen Wastes (map 8)
if (mapIndex === 8) {
arBackground = game.addChild(LK.getAsset('fw', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
x: 1024,
y: 1366
}));
}
// Create roads
for (var i = 0; i < map.roads.length; i++) {
var road = game.addChild(new Road());
road.x = map.roads[i].x;
road.y = map.roads[i].y;
roads.push(road);
}
// Mountains removed from display
// Create passages
for (var i = 0; i < map.passages.length; i++) {
var passage = game.addChild(new Passage());
passage.x = map.passages[i].x;
passage.y = map.passages[i].y;
passage.targetMap = map.passages[i].targetMap;
passage.targetX = map.passages[i].targetX;
passage.targetY = map.passages[i].targetY;
passages.push(passage);
}
// Set character position
if (character.x === 0 && character.y === 0) {
character.x = map.startX;
character.y = map.startY;
}
// Find and mark the center road point
var centerRoad = findCenterRoad();
if (centerRoad) {
centerMarker = game.addChild(new CenterMarker());
centerMarker.x = centerRoad.x;
centerMarker.y = centerRoad.y;
}
// Add city marker at calculated position
var cityPosition = findCityPosition();
city = game.addChild(new City());
city.x = cityPosition.x;
city.y = cityPosition.y;
// Create connecting road between center marker and city
if (centerMarker && city) {
var connectionRoads = createConnectionRoad(centerMarker.x, centerMarker.y, city.x, city.y);
for (var i = 0; i < connectionRoads.length; i++) {
roads.push(connectionRoads[i]);
}
}
// Bring city to front so it appears above roads
if (city) {
game.removeChild(city);
game.addChild(city);
}
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Reset city visit tracking for new map
hasVisitedCity = false;
lastCityDistance = Infinity;
if (isMarketOpen) {
closeMarketScreen();
}
// Generate new market slots for this map
if (!marketSlots) {
marketSlots = [];
}
// Refresh market inventories when changing regions
generateMarketSlots();
generateSellSlots();
}
function findNearestRoad(x, y) {
var nearestRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = x - road.x;
var dy = y - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearestRoad = road;
}
}
return nearestRoad;
}
function findCityPosition() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var mirrorPoints = [];
var map = mapData[currentMap];
// Calculate mirror coordinates for each passage
for (var i = 0; i < map.passages.length; i++) {
var passage = map.passages[i];
var mirrorX = 2 * centerX - passage.x;
var mirrorY = 2 * centerY - passage.y;
mirrorPoints.push({
x: mirrorX,
y: mirrorY
});
}
// Find the center of all mirror points
if (mirrorPoints.length === 0) {
return {
x: centerX,
y: centerY
}; // Default to screen center if no passages
}
var totalX = 0;
var totalY = 0;
for (var i = 0; i < mirrorPoints.length; i++) {
totalX += mirrorPoints[i].x;
totalY += mirrorPoints[i].y;
}
return {
x: totalX / mirrorPoints.length,
y: totalY / mirrorPoints.length
};
}
function createConnectionRoad(startX, startY, endX, endY) {
var connectionRoads = [];
var dx = endX - startX;
var dy = endY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
var steps = Math.floor(distance / 100); // Create road points every 100 pixels
for (var i = 1; i <= steps; i++) {
var progress = i / (steps + 1);
var roadX = startX + dx * progress;
var roadY = startY + dy * progress;
var road = game.addChild(new Road());
road.x = roadX;
road.y = roadY;
connectionRoads.push(road);
}
return connectionRoads;
}
function findCenterRoad() {
var centerX = 1024; // Screen center X
var centerY = 1366; // Screen center Y
var centerRoad = null;
var minDistance = Infinity;
for (var i = 0; i < roads.length; i++) {
var road = roads[i];
var dx = centerX - road.x;
var dy = centerY - road.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
centerRoad = road;
}
}
return centerRoad;
}
function checkPassageCollision() {
for (var i = 0; i < passages.length; i++) {
var passage = passages[i];
var dx = character.x - passage.x;
var dy = character.y - passage.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 80) {
currentMap = passage.targetMap;
storage.currentMap = currentMap;
loadMap(currentMap);
// Find the 4th nearest road point to the target passage
var targetPassageX = passage.targetX;
var targetPassageY = passage.targetY;
var roadDistances = [];
// Calculate distances from target passage to all roads
for (var j = 0; j < roads.length; j++) {
var road = roads[j];
var rdx = targetPassageX - road.x;
var rdy = targetPassageY - road.y;
var roadDistance = Math.sqrt(rdx * rdx + rdy * rdy);
roadDistances.push({
road: road,
distance: roadDistance
});
}
// Sort roads by distance
roadDistances.sort(function (a, b) {
return a.distance - b.distance;
});
// Get the 4th nearest road (index 3), or closest available if less than 4 roads
var targetRoadIndex = Math.min(3, roadDistances.length - 1);
// Special case for Western Peaks left passage teleportation - use 5th nearest road for better positioning
if (currentMap === 5 && passage.targetX === 1900 && passage.targetY === 1600) {
targetRoadIndex = Math.min(4, roadDistances.length - 1);
}
// Special case for Sacred Grove to Coastal Cliffs teleportation - use 3rd nearest road
if (currentMap === 9 && passage.targetX === 600 && passage.targetY === 1600) {
targetRoadIndex = Math.min(2, roadDistances.length - 1);
}
var targetRoad = roadDistances[targetRoadIndex].road;
character.x = targetRoad.x;
character.y = targetRoad.y;
character.isMoving = false;
break;
}
}
}
// Initialize first map
loadMap(currentMap);
// Bring character to front so it appears above roads
game.removeChild(character);
game.addChild(character);
// Initialize economy system tracking
lastPlayerX = character.x;
lastPlayerY = character.y;
// Initialize market slots array to prevent undefined errors
var marketSlots = [];
var sellSlots = [];
// Slot probability pools for each city - initialized as global variable
var slotProbabilityPools = [
// Map 0 - Northern Highlands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// 35% empty, 25% apple, 15% salt, 15% speeditem, 10% sword
// Map 1 - Eastern Valleys
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 2 - Southern Ridge
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 3 - Western Peaks
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 4 - Central Plains
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 5 - Mystic Woods
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 6 - Ancient Ruins
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 7 - Desert Sands
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 8 - Frozen Wastes
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 9 - Coastal Cliffs
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 10 - Mountain Pass
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword'],
// Map 11 - Sacred Grove
[null, null, null, null, null, null, null, 'apple', 'apple', 'apple', 'apple', 'apple', 'salt', 'salt', 'salt', 'speeditem', 'speeditem', 'speeditem', 'sword', 'sword']];
// Region names for each map
var regionNames = ['Northern Highlands', 'Eastern Valleys', 'Southern Ridge', 'Western Peaks', 'Central Plains', 'Mystic Woods', 'Ancient Ruins', 'Desert Sands', 'Frozen Wastes', 'Coastal Cliffs', 'Mountain Pass', 'Sacred Grove'];
// Map info display
var mapText = new Text2(regionNames[currentMap], {
size: 60,
fill: 0xFFFFFF
});
mapText.anchor.set(1, 1);
LK.gui.bottomRight.addChild(mapText);
// Gold display setup
goldIcon = LK.getAsset('gold', {
anchorX: 0,
anchorY: 0,
scaleX: 1.6,
scaleY: 1.6
});
goldIcon.x = 120;
goldIcon.y = 20;
LK.gui.topLeft.addChild(goldIcon);
goldText = new Text2(playerGold.toString(), {
size: 96,
fill: 0xFFD700
});
goldText.anchor.set(0, 0);
goldText.x = 280;
goldText.y = 50;
LK.gui.topLeft.addChild(goldText);
// Inventory button setup
var inventoryButton = LK.getAsset('bag', {
anchorX: 1,
anchorY: 0,
scaleX: 1.2,
scaleY: 1.2
});
inventoryButton.x = -20;
inventoryButton.y = 20;
LK.gui.topRight.addChild(inventoryButton);
// City market UI variables
var marketScreen = null;
var marketTitle = null;
var closeButton = null;
var isMarketOpen = false;
var lastCityDistance = Infinity;
var hasVisitedCity = false;
// Inventory UI variables
var inventoryScreen = null;
var isInventoryOpen = false;
var inventorySlots = [];
// Market mode variables
var marketMode = 'selection'; // 'selection', 'buy', 'sell'
var buyButton = null;
var sellButton = null;
// Player inventory system
var playerInventory = {
salt: storage.playerSaltCount || 0,
apple: storage.playerAppleCount || 0,
speeditem: storage.playerSpeeditemCount || 0,
sword: storage.playerSwordCount || 0
};
// Market slot system variables
// Slot refresh now happens on map change
function generateMarketSlots() {
// Clear existing slots
for (var i = 0; i < marketSlots.length; i++) {
if (marketSlots[i] && marketSlots[i].parent) {
marketSlots[i].parent.removeChild(marketSlots[i]);
}
}
marketSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 slots
for (var i = 0; i < 6; i++) {
var slot = new TradeSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
marketSlots.push(slot);
}
}
function generateSellSlots() {
// Clear existing sell slots
// Safety check for sellSlots array existence
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (sellSlots[i] && sellSlots[i].parent) {
sellSlots[i].parent.removeChild(sellSlots[i]);
}
}
}
sellSlots = [];
// Safety check for slotProbabilityPools existence
if (!slotProbabilityPools || !Array.isArray(slotProbabilityPools)) {
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// Get probability pool for current map
var probabilityPool = slotProbabilityPools[currentMap];
// Generate 6 sell slots
for (var i = 0; i < 6; i++) {
var slot = new SellSlot();
// Random item from probability pool
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
slot.setItem(itemType);
sellSlots.push(slot);
}
}
function refreshMarketSlots() {
// Safety check for marketSlots array
if (!marketSlots) {
marketSlots = [];
generateMarketSlots();
return;
}
// Additional safety check for marketSlots length
if (marketSlots.length === 0) {
generateMarketSlots();
return;
}
// Safety check for currentMap and slotProbabilityPools
if (currentMap < 0 || currentMap >= slotProbabilityPools.length || !slotProbabilityPools[currentMap]) {
return;
}
// 10% chance to refresh each slot
var probabilityPool = slotProbabilityPools[currentMap];
for (var i = 0; i < marketSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
marketSlots[i].setItem(itemType);
}
}
// Also refresh sell slots if they exist
if (sellSlots && sellSlots.length > 0) {
for (var i = 0; i < sellSlots.length; i++) {
if (Math.random() < 0.1) {
var randomIndex = Math.floor(Math.random() * probabilityPool.length);
var itemType = probabilityPool[randomIndex];
sellSlots[i].setItem(itemType);
}
}
}
}
function createMarketScreen() {
// Create market background container
marketScreen = new Container();
marketScreen.x = 0;
marketScreen.y = 0;
// Create market background using citytrade texture
var marketBg = LK.getAsset('citytrade', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
marketBg.x = 24;
marketBg.y = -34;
marketScreen.addChild(marketBg);
// Show mode selection buttons
if (marketMode === 'selection') {
// Create buy button
buyButton = LK.getAsset('buybuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
buyButton.x = -150;
buyButton.y = 0;
marketScreen.addChild(buyButton);
// Create sell button
sellButton = LK.getAsset('sellbuton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
sellButton.x = 150;
sellButton.y = 0;
marketScreen.addChild(sellButton);
// Add button functionality
buyButton.down = function () {
marketMode = 'buy';
showBuyMode();
};
sellButton.down = function () {
marketMode = 'sell';
showSellMode();
};
} else if (marketMode === 'buy') {
showBuyMode();
} else if (marketMode === 'sell') {
showSellMode();
}
// Create market title
marketTitle = new Text2(regionNames[currentMap] + ' Market', {
size: 77,
fill: 0xFFFFFF
});
marketTitle.anchor.set(0.5, 0);
marketTitle.x = 24;
marketTitle.y = -490;
marketScreen.addChild(marketTitle);
// Create close button using xbutton texture
closeButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
closeButton.x = 556;
closeButton.y = -680;
marketScreen.addChild(closeButton);
// Add close button functionality
closeButton.down = function () {
closeMarketScreen();
};
LK.gui.center.addChild(marketScreen);
isMarketOpen = true;
}
function showBuyMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate market slots if they don't exist
if (marketSlots.length === 0) {
generateMarketSlots();
}
// Position and add buy slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < marketSlots.length; i++) {
var slot = marketSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function showSellMode() {
// Clear mode selection buttons
if (buyButton) {
marketScreen.removeChild(buyButton);
buyButton = null;
}
if (sellButton) {
marketScreen.removeChild(sellButton);
sellButton = null;
}
// Generate sell slots if they don't exist
if (sellSlots.length === 0) {
generateSellSlots();
}
// Position and add sell slots to market screen (2 rows, 3 columns)
var slotStartX = -190;
var slotStartY = -180;
var slotSpacingX = 220;
var slotSpacingY = 210;
for (var i = 0; i < sellSlots.length; i++) {
var slot = sellSlots[i];
var row = Math.floor(i / 3);
var col = i % 3;
slot.x = slotStartX + col * slotSpacingX;
slot.y = slotStartY + row * slotSpacingY;
// Move top 3 slots (first row) 70 pixels up
if (row === 0) {
slot.y -= 70;
}
marketScreen.addChild(slot);
}
}
function closeMarketScreen() {
if (marketScreen) {
LK.gui.center.removeChild(marketScreen);
marketScreen = null;
marketTitle = null;
closeButton = null;
buyButton = null;
sellButton = null;
isMarketOpen = false;
marketMode = 'selection'; // Reset to selection mode
}
}
function checkCityProximity() {
if (!city) {
return;
}
var dx = character.x - city.x;
var dy = character.y - city.y;
var currentDistance = Math.sqrt(dx * dx + dy * dy);
// Check if entering city range (distance < 100)
if (lastCityDistance >= 100 && currentDistance < 100) {
// Just entered city - show market if not already visited
if (!hasVisitedCity && !isMarketOpen) {
createMarketScreen();
hasVisitedCity = true;
}
}
// Check if leaving city range (distance > 150)
if (lastCityDistance <= 150 && currentDistance > 150) {
// Left city area - reset visit flag for next entry
hasVisitedCity = false;
if (isMarketOpen) {
closeMarketScreen();
}
}
lastCityDistance = currentDistance;
}
game.down = function (x, y, obj) {
// Prevent movement when market or inventory is open
if (isMarketOpen || isInventoryOpen) {
return;
}
var nearestRoad = findNearestRoad(x, y);
if (nearestRoad) {
character.moveTo(nearestRoad.x, nearestRoad.y);
}
};
function updateGoldDisplay() {
if (goldText) {
goldText.setText(playerGold.toString());
storage.playerGold = Math.round(playerGold * 10) / 10;
}
}
function updateEconomySystem() {
// Track movement distance
var dx = character.x - lastPlayerX;
var dy = character.y - lastPlayerY;
var movementThisFrame = Math.sqrt(dx * dx + dy * dy);
if (movementThisFrame > 0) {
totalMovementDistance += movementThisFrame;
// Salt price update every 5000 pixels
var saltDistanceThreshold = lastSaltPriceUpdate + 5000;
if (totalMovementDistance >= saltDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (7%) or decrease (6%)
if (Math.random() < 0.5) {
saltCurrentPrice = Math.round(saltCurrentPrice * 1.07 * 10) / 10; // 7% increase
} else {
saltCurrentPrice = Math.round(saltCurrentPrice * 0.94 * 10) / 10; // 6% decrease
}
}
lastSaltPriceUpdate = totalMovementDistance;
}
// Apple price update every 500 pixels
var appleDistanceThreshold = lastApplePriceUpdate + 500;
if (totalMovementDistance >= appleDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (+1) or decrease (-1)
if (Math.random() < 0.5) {
appleCurrentPrice = Math.round((appleCurrentPrice + 1) * 10) / 10;
} else {
appleCurrentPrice = Math.round((appleCurrentPrice - 1) * 10) / 10;
}
// Apply price limits for apple (5-25)
if (appleCurrentPrice < 5) {
appleCurrentPrice = 5;
}
if (appleCurrentPrice > 25) {
appleCurrentPrice = 25;
}
}
lastApplePriceUpdate = totalMovementDistance;
}
// Speeditem price update every 2000 pixels
var speeditemDistanceThreshold = lastSpeeditemPriceUpdate + 2000;
if (totalMovementDistance >= speeditemDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
speeditemCurrentPrice = Math.round(speeditemCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSpeeditemPriceUpdate = totalMovementDistance;
}
// Sword price update every 2000 pixels
var swordDistanceThreshold = lastSwordPriceUpdate + 2000;
if (totalMovementDistance >= swordDistanceThreshold) {
// 50% chance for price change
if (Math.random() < 0.5) {
// 50% chance for increase (5%) or decrease (5%)
if (Math.random() < 0.5) {
swordCurrentPrice = Math.round(swordCurrentPrice * 1.05 * 10) / 10; // 5% increase
} else {
swordCurrentPrice = Math.round(swordCurrentPrice * 0.95 * 10) / 10; // 5% decrease
}
}
lastSwordPriceUpdate = totalMovementDistance;
}
// Slot refresh now happens on map change instead of movement distance
// Save economy data to storage
storage.saltCurrentPrice = saltCurrentPrice;
storage.appleCurrentPrice = appleCurrentPrice;
storage.speeditemCurrentPrice = speeditemCurrentPrice;
storage.swordCurrentPrice = swordCurrentPrice;
storage.totalMovementDistance = totalMovementDistance;
storage.lastSaltPriceUpdate = lastSaltPriceUpdate;
storage.lastApplePriceUpdate = lastApplePriceUpdate;
storage.lastSpeeditemPriceUpdate = lastSpeeditemPriceUpdate;
storage.lastSwordPriceUpdate = lastSwordPriceUpdate;
}
// Update last position
lastPlayerX = character.x;
lastPlayerY = character.y;
}
// Add inventory button functionality
inventoryButton.down = function () {
if (!isInventoryOpen) {
createInventoryScreen();
} else {
closeInventoryScreen();
}
};
function createInventoryScreen() {
// Create inventory background container
inventoryScreen = new Container();
inventoryScreen.x = 0;
inventoryScreen.y = 0;
// Create inventory background using playerinventory texture
var inventoryBg = LK.getAsset('playerinventory', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
inventoryBg.x = 0;
inventoryBg.y = 0;
inventoryScreen.addChild(inventoryBg);
// Create 4x4 grid of inventory slots
inventorySlots = [];
for (var row = 0; row < 4; row++) {
for (var col = 0; col < 4; col++) {
var slot = new InventorySlot();
// Position with 8px down offset and increased spacing: 30px margin, 120px slot size, 15px spacing
slot.x = -300 + 30 + col * 135 + 60; // -300 to center, +30 margin, +60 for slot center, 135px spacing (120+15)
slot.y = -300 + 30 + row * 135 + 60 + 8; // -300 to center, +30 margin, +60 for slot center, +8px down, 135px spacing
inventoryScreen.addChild(slot);
inventorySlots.push(slot);
}
}
// Create close button
var inventoryCloseButton = LK.getAsset('xbutton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
inventoryCloseButton.x = 330;
inventoryCloseButton.y = -330;
inventoryScreen.addChild(inventoryCloseButton);
// Add close button functionality
inventoryCloseButton.down = function () {
closeInventoryScreen();
};
LK.gui.center.addChild(inventoryScreen);
isInventoryOpen = true;
// Update inventory display
updateInventoryDisplay();
}
function closeInventoryScreen() {
if (inventoryScreen) {
LK.gui.center.removeChild(inventoryScreen);
inventoryScreen = null;
inventorySlots = [];
isInventoryOpen = false;
}
}
function updateInventoryDisplay() {
if (!inventorySlots || inventorySlots.length === 0) return;
// Clear all slots first
for (var i = 0; i < inventorySlots.length; i++) {
inventorySlots[i].setItem(null, 0);
}
// Fill slots with player inventory
var slotIndex = 0;
// Add salt items
if (playerInventory.salt > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('salt', playerInventory.salt);
slotIndex++;
}
// Add apple items
if (playerInventory.apple > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('apple', playerInventory.apple);
slotIndex++;
}
// Add speeditem items
if (playerInventory.speeditem > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('speeditem', playerInventory.speeditem);
slotIndex++;
}
// Add sword items
if (playerInventory.sword > 0 && slotIndex < inventorySlots.length) {
inventorySlots[slotIndex].setItem('sword', playerInventory.sword);
slotIndex++;
}
}
function addItemToInventory(itemType) {
// Find existing slot with same item type
for (var i = 0; i < inventorySlots.length; i++) {
if (inventorySlots[i].item === itemType) {
inventorySlots[i].addQuantity(1);
return;
}
}
// Find first empty slot
for (var i = 0; i < inventorySlots.length; i++) {
if (!inventorySlots[i].item) {
inventorySlots[i].setItem(itemType, 1);
return;
}
}
}
// Generate initial market slots after everything is initialized
generateMarketSlots();
generateSellSlots();
game.update = function () {
checkPassageCollision();
mapText.setText(regionNames[currentMap]);
checkCityProximity();
updateGoldDisplay();
updateEconomySystem();
};
mağara girişi. In-Game asset. 2d. High contrast. No shadows
ortaçağ atlı araba ve tüccar . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
aynısı arkaplansız
medieval X close button. In-Game asset. 2d. High contrast. No shadows
altın kesesi. In-Game asset. 2d. High contrast. No shadows
elma. In-Game asset. 2d. High contrast. No shadows
ortaçağ ticari tuz. In-Game asset. 2d. High contrast. No shadows
çivi ile duvara asılı hafif yıpranmış parşomen. In-Game asset. 2d. High contrast. No shadows
medieval envanter bag. In-Game asset. 2d. High contrast. No shadows
minecraft envaneri gibi kutucuklar sadece kutucuklar başka uı elementi yok. ortaçağ temasında bir çanta içi hissi vermeli dokusu . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bir ortaçağ eşyası bize hız veriyor ne olur bilmiyorum. In-Game asset. 2d. High contrast. No shadows
medieval sword. In-Game asset. 2d. High contrast. No shadows