/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AnvilSlot = Container.expand(function () {
var self = Container.call(this);
var slotGraphics = self.attachAsset('anvil_slot', {
anchorX: 0.5,
anchorY: 0.5
});
self.currentItem = null;
self.placeItem = function (item) {
if (self.currentItem) {
self.currentItem.returnToOriginalPosition();
}
// Return any item in preview slot to inventory
if (previewSlot && previewSlot.previewItem) {
previewSlot.previewItem.returnToOriginalPosition();
inventoryItems.push(previewSlot.previewItem);
previewSlot.previewItem = null;
}
self.currentItem = item;
item.x = self.x;
item.y = self.y;
};
self.removeItem = function () {
if (self.currentItem) {
self.currentItem = null;
}
};
self.hasItem = function () {
return self.currentItem !== null;
};
return self;
});
var Button = Container.expand(function (text, color) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset(color === 0x4CAF50 ? 'confirm_button' : 'cancel_button', {
anchorX: 0.5,
anchorY: 0.5
});
self.callback = null;
self.setCallback = function (cb) {
self.callback = cb;
};
self.down = function (x, y, obj) {
if (self.callback) {
self.callback();
}
};
return self;
});
var Item = Container.expand(function (itemType, enhanceLevel) {
var self = Container.call(this);
self.itemType = itemType || 'Mirage_Dagger';
self.enhanceLevel = enhanceLevel || 1;
self.originalX = 0;
self.originalY = 0;
self.originalSlotIndex = -1; // Store the original inventory slot index
self.isDragging = false;
// Create item graphics based on type
var itemGraphics = self.attachAsset(self.itemType, {
anchorX: 0.5,
anchorY: 0.5
});
// Enhancement level text
self.levelText = new Text2('+' + self.enhanceLevel, {
size: 80,
fill: 0xFFD700
});
self.levelText.anchor.set(0.5, 0.5);
self.levelText.x = -150;
self.levelText.y = -itemGraphics.height / 2 + 20;
self.addChild(self.levelText);
if (self.enhanceLevel < 1) {
self.levelText.visible = false;
}
self.updateEnhanceLevel = function (newLevel) {
self.enhanceLevel = newLevel;
if (self.enhanceLevel < 1) {
self.levelText.visible = false;
} else {
self.levelText.visible = true;
self.levelText.setText('+' + self.enhanceLevel);
}
};
self.setOriginalPosition = function (x, y, slotIndex) {
self.originalX = x;
self.originalY = y;
if (slotIndex !== undefined) {
self.originalSlotIndex = slotIndex;
}
};
self.returnToOriginalPosition = function () {
tween(self, {
x: self.originalX,
y: self.originalY
}, {
duration: 300
});
};
self.down = function (x, y, obj) {
// Check for right click (button 2) first
if (obj && obj.event && obj.event.button === 2) {
// Move item to first inventory slot (index 0)
var itemIndex = inventoryItems.indexOf(self);
if (itemIndex > -1) {
// Calculate first slot position
var row = Math.floor(0 / itemsPerRow);
var col = 0 % itemsPerRow;
var slotX = startX + col * itemSpacing;
var slotY = startY + row * rowSpacing;
// Move item to first slot position
tween(self, {
x: slotX,
y: slotY
}, {
duration: 300
});
// Update original position to first slot
self.setOriginalPosition(slotX, slotY, 0);
return; // Exit early for right-click
}
}
self.isDragging = true;
// Special handling for bus items - create a copy for dragging
if (self.itemType === 'bus') {
var busCopy = new Item('bus', -1);
busCopy.scaleX = 0.6;
busCopy.scaleY = 0.6;
busCopy.x = self.x;
busCopy.y = self.y;
busCopy.setOriginalPosition(self.x, self.y, self.originalSlotIndex);
game.addChild(busCopy);
draggedItem = busCopy;
} else {
draggedItem = self;
}
};
self.up = function (x, y, obj) {
self.isDragging = false;
draggedItem = null;
};
return self;
});
var PreviewSlot = Container.expand(function () {
var self = Container.call(this);
var slotGraphics = self.attachAsset('preview_slot', {
anchorX: 0.5,
anchorY: 0.5
});
self.previewItem = null;
self.showPreview = function (item) {
if (self.previewItem) {
self.previewItem.destroy();
}
// Preview will only be shown after successful upgrade
};
self.showSuccessPreview = function (item) {
if (self.previewItem) {
self.previewItem.destroy();
}
self.previewItem = new Item(item.itemType, item.enhanceLevel);
self.previewItem.x = self.x;
self.previewItem.y = self.y;
self.previewItem.alpha = 0.8;
self.parent.addChild(self.previewItem);
};
self.hidePreview = function () {
if (self.previewItem) {
self.previewItem.destroy();
self.previewItem = null;
}
};
return self;
});
var UpgradeEffect = Container.expand(function () {
var self = Container.call(this);
var glowEffect = self.attachAsset('upgrade_glow', {
anchorX: 0.5,
anchorY: 0.5
});
glowEffect.alpha = 0;
glowEffect.scaleX = 0.5;
glowEffect.scaleY = 0.5;
self.playSuccessEffect = function () {
// Create upgrade light with 12px width and 2px height
glowEffect.alpha = 0.8;
glowEffect.scaleX = 0.75; // 300px width (400 * 0.75 = 300)
glowEffect.scaleY = 0.015; // 6px height (400 * 0.015 = 6)
glowEffect.x = -300; // Start from left
glowEffect.y = 0; // Centered horizontally
glowEffect.tint = 0xFFD700; // Golden color
// First animation: light point moves at constant speed from left to right
tween(glowEffect, {
x: 300
}, {
duration: 800,
// Faster constant speed
easing: tween.linear,
onFinish: function onFinish() {
// Second animation: light point returns to left at same speed
tween(glowEffect, {
x: -300
}, {
duration: 800,
easing: tween.linear,
onFinish: function onFinish() {
// Third animation: light point moves right again at same speed and disappears instantly
tween(glowEffect, {
x: 300
}, {
duration: 800,
easing: tween.linear,
onFinish: function onFinish() {
// Instantly disappear
glowEffect.alpha = 0;
}
});
}
});
}
});
};
self.playFailEffect = function () {
// Create upgrade light with 12px width and 2px height
glowEffect.alpha = 0.7;
glowEffect.scaleX = 0.75; // 300px width (400 * 0.75 = 300)
glowEffect.scaleY = 0.015; // 6px height (400 * 0.015 = 6)
glowEffect.x = -300; // Start from left
glowEffect.y = 0; // Centered horizontally
glowEffect.tint = 0xFF0000; // Red color for failure
// Animate red light point moving from left to right
tween(glowEffect, {
x: 300
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
// Instantly disappear
glowEffect.alpha = 0;
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F4F
});
/****
* Game Code
****/
var anvilArea = game.addChild(LK.getAsset('anvil_area', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 600
}));
var inventoryPanel = game.addChild(LK.getAsset('inventory_panel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1800
}));
// Create anvil slot (left side)
var anvilSlot = game.addChild(new AnvilSlot());
anvilSlot.x = 1024 - 300; // Left side of anvil
anvilSlot.y = 600;
// Create preview slot (right side)
var previewSlot = game.addChild(new PreviewSlot());
previewSlot.x = 1024 + 300; // Right side of anvil
previewSlot.y = 600;
// Create busbox in center of the two slots
var busBox = game.addChild(LK.getAsset('busbox', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
// Center between anvil slot (724) and preview slot (1324)
y: 600
}));
var upgradeEffect = game.addChild(new UpgradeEffect());
upgradeEffect.x = 1024;
upgradeEffect.y = 600;
// Create buttons at the bottom of anvil area
var confirmButton = game.addChild(new Button('Confirm', 0x4CAF50));
confirmButton.x = 1024 - 140;
confirmButton.y = 1100; // Bottom of anvil area (600 + 600/2 - 60 for button height)
var cancelButton = game.addChild(new Button('Cancel', 0xF44336));
cancelButton.x = 1024 + 140;
cancelButton.y = 1100; // Bottom of anvil area (600 + 600/2 - 60 for button height)
// Create inventory items
var inventoryItems = [];
var itemTypes = ['Mirage_Dagger', 'armor', 'helmet', 'shield', 'ring'];
var itemsPerRow = 4;
var itemRows = 4;
var padding = 60; // Equal padding from all sides
var availableWidth = inventoryPanel.width - padding * 2;
var availableHeight = inventoryPanel.height - padding * 2;
var itemSpacing = availableWidth / itemsPerRow;
var rowSpacing = availableHeight / itemRows;
var startX = inventoryPanel.x - availableWidth / 2 + itemSpacing / 2;
var startY = inventoryPanel.y - availableHeight / 2 + rowSpacing / 2;
for (var i = 0; i < 16; i++) {
if (i === 0) {
// Create 32 stacked bus items in first slot
var busItem = new Item('bus', -1); // Set enhance level to -1 to hide + symbol completely
var row = Math.floor(i / itemsPerRow);
var col = i % itemsPerRow;
// Scale down items to fit within grid boxes (from 200px to ~120px)
busItem.scaleX = 0.6;
busItem.scaleY = 0.6;
// Center items within each inventory grid box
busItem.x = startX + col * itemSpacing;
busItem.y = startY + row * rowSpacing;
busItem.setOriginalPosition(busItem.x, busItem.y, i);
// Add stack count property
busItem.stackCount = 32;
// Add stack count text next to the bus visual
var stackText = new Text2('32', {
size: 40,
fill: 0xFFFFFF
});
stackText.anchor.set(0, 0.5); // Left anchor, middle anchor
stackText.x = 70; // Position next to the right side of the bus
stackText.y = 0; // Vertically centered with the bus
busItem.addChild(stackText);
inventoryItems.push(busItem);
game.addChild(busItem);
} else {
var itemType = itemTypes[i % itemTypes.length];
var item = new Item(itemType, 1);
var row = Math.floor(i / itemsPerRow);
var col = i % itemsPerRow;
// Scale down items to fit within grid boxes (from 200px to ~120px)
item.scaleX = 0.6;
item.scaleY = 0.6;
// Center items within each inventory grid box
item.x = startX + col * itemSpacing;
item.y = startY + row * rowSpacing;
item.setOriginalPosition(item.x, item.y, i);
inventoryItems.push(item);
game.addChild(item);
}
}
// Game variables
var draggedItem = null;
var totalUpgrades = 0;
var successfulUpgrades = 0;
var maxItems = 16;
var busInBusbox = null; // Track bus item placed in busbox
// Setup button callbacks
confirmButton.setCallback(function () {
// Return any item in preview slot to inventory first
if (previewSlot.previewItem) {
previewSlot.previewItem.returnToOriginalPosition();
inventoryItems.push(previewSlot.previewItem);
previewSlot.previewItem = null;
}
if (anvilSlot.hasItem() && busInBusbox) {
var item = anvilSlot.currentItem;
var upgradeResult = attemptUpgrade(item);
// Consume the bus item in busbox regardless of upgrade success/failure
var busStackText = busInBusbox.children[1]; // Get the stack count text
if (busInBusbox.stackCount > 1) {
// Decrease stack count
busInBusbox.stackCount--;
busStackText.setText(busInBusbox.stackCount.toString());
} else {
// Remove bus item completely when stack reaches 0
busInBusbox.destroy();
busInBusbox = null;
}
// Also decrease inventory bus stack count
var inventoryBusItem = inventoryItems.find(function (item) {
return item.itemType === 'bus';
});
if (inventoryBusItem) {
var inventoryStackText = inventoryBusItem.children[1]; // Get the stack count text
if (inventoryBusItem.stackCount > 1) {
inventoryBusItem.stackCount--;
inventoryStackText.setText(inventoryBusItem.stackCount.toString());
} else {
// Remove bus item completely when stack reaches 0
var itemIndex = inventoryItems.indexOf(inventoryBusItem);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
}
inventoryBusItem.destroy();
}
}
if (upgradeResult.success) {
// Add 2 second delay before moving item to preview slot
LK.setTimeout(function () {
// Create new item with upgraded level for preview
var previewItem = new Item(item.itemType, upgradeResult.newLevel);
previewItem.scaleX = 0.6;
previewItem.scaleY = 0.6;
previewItem.x = previewSlot.x;
previewItem.y = previewSlot.y;
previewItem.alpha = 0; // Start invisible
// Smooth fade-in animation
tween(previewItem, {
alpha: 0.8
}, {
duration: 800,
easing: tween.easeInOut
});
// Set original position for preview item to return to inventory using original slot
var originalSlotIndex = item.originalSlotIndex;
if (originalSlotIndex >= 0) {
var row = Math.floor(originalSlotIndex / itemsPerRow);
var col = originalSlotIndex % itemsPerRow;
var slotX = startX + col * itemSpacing;
var slotY = startY + row * rowSpacing;
previewItem.setOriginalPosition(slotX, slotY, originalSlotIndex);
}
game.addChild(previewItem);
// Remove original item from inventory
var itemIndex = inventoryItems.indexOf(item);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
}
item.destroy();
anvilSlot.currentItem = null; // Clear anvil slot
previewSlot.previewItem = previewItem; // Set preview item
}, 2000);
} else {
// Item failed upgrade and was destroyed
anvilSlot.currentItem = null; // Clear anvil slot
}
}
});
cancelButton.setCallback(function () {
// Return any item in preview slot to inventory first
if (previewSlot.previewItem) {
previewSlot.previewItem.returnToOriginalPosition();
inventoryItems.push(previewSlot.previewItem);
previewSlot.previewItem = null;
}
if (anvilSlot.hasItem()) {
var item = anvilSlot.currentItem;
item.returnToOriginalPosition();
anvilSlot.currentItem = null; // Clear anvil slot
previewSlot.hidePreview();
}
// Return bus from busbox to inventory
if (busInBusbox) {
busInBusbox.returnToOriginalPosition();
inventoryItems.push(busInBusbox);
busInBusbox = null;
}
});
// UI Elements removed
// Upgrade success rates based on level
var upgradeRates = {
0: 0.95,
// +0 to +1
1: 0.85,
// +1 to +2
2: 0.75,
// +2 to +3
3: 0.65,
// +3 to +4
4: 0.50,
// +4 to +5
5: 0.35,
// +5 to +6
6: 0.20,
// +6 to +7
7: 0.10 // +7 to +8
};
function attemptUpgrade(item) {
if (item.enhanceLevel >= 8) {
return {
success: false
}; // Max level reached
}
var successRate = upgradeRates[item.enhanceLevel];
var success = Math.random() < successRate;
if (success) {
// Successful upgrade
var newLevel = item.enhanceLevel + 1;
upgradeEffect.playSuccessEffect();
LK.getSound('upgrade_success').play();
successfulUpgrades++;
// Update score
LK.setScore(successfulUpgrades);
// Win condition
if (successfulUpgrades >= 20) {
LK.showYouWin();
}
return {
success: true,
newLevel: newLevel
};
} else {
// Failed upgrade
upgradeEffect.playFailEffect();
LK.getSound('upgrade_fail').play();
// Destroy item on failure
var itemIndex = inventoryItems.indexOf(item);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
item.destroy();
maxItems--;
// Check if no items left
if (maxItems <= 0) {
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
return {
success: false
};
}
totalUpgrades++;
}
function isItemInAnvilArea(item) {
var anvilBounds = {
left: anvilArea.x - anvilArea.width / 2,
right: anvilArea.x + anvilArea.width / 2,
top: anvilArea.y - anvilArea.height / 2,
bottom: anvilArea.y + anvilArea.height / 2
};
return item.x >= anvilBounds.left && item.x <= anvilBounds.right && item.y >= anvilBounds.top && item.y <= anvilBounds.bottom;
}
// Game event handlers
game.move = function (x, y, obj) {
if (draggedItem) {
draggedItem.x = x;
draggedItem.y = y;
}
};
game.down = function (x, y, obj) {
// No special handling needed here, items handle their own down events
};
game.up = function (x, y, obj) {
if (draggedItem) {
// Check if dropped on anvil slot
var distanceToSlot = Math.sqrt(Math.pow(draggedItem.x - anvilSlot.x, 2) + Math.pow(draggedItem.y - anvilSlot.y, 2));
// Check if dropped on busbox
var distanceToBusbox = Math.sqrt(Math.pow(draggedItem.x - busBox.x, 2) + Math.pow(draggedItem.y - busBox.y, 2));
if (distanceToSlot < 200 && draggedItem.itemType !== 'bus') {
// Place non-bus item in anvil slot
anvilSlot.placeItem(draggedItem);
} else if (distanceToBusbox < 100 && draggedItem.itemType === 'bus') {
// Place bus item in busbox
if (busInBusbox) {
// Return previous bus item to inventory
busInBusbox.returnToOriginalPosition();
inventoryItems.push(busInBusbox);
}
busInBusbox = draggedItem;
draggedItem.x = busBox.x;
draggedItem.y = busBox.y;
// Decrease stack count of original bus item
var originalBusItem = inventoryItems.find(function (item) {
return item.itemType === 'bus';
});
if (originalBusItem) {
var stackText = originalBusItem.children[1]; // Get the stack count text
if (originalBusItem.stackCount > 1) {
originalBusItem.stackCount--;
stackText.setText(originalBusItem.stackCount.toString());
} else {
// Remove bus item completely when stack reaches 0
var itemIndex = inventoryItems.indexOf(originalBusItem);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
}
originalBusItem.destroy();
}
}
} else {
// Return to original position or destroy if it's a bus copy
if (draggedItem.itemType === 'bus') {
// Check if this is a copy by seeing if it's in inventory
var itemIndex = inventoryItems.indexOf(draggedItem);
if (itemIndex === -1) {
// This is a copy, destroy it
draggedItem.destroy();
} else {
draggedItem.returnToOriginalPosition();
}
} else {
draggedItem.returnToOriginalPosition();
}
}
draggedItem = null;
}
};
game.update = function () {
// Update game state
if (totalUpgrades > 50 && successfulUpgrades < 5) {
LK.showGameOver();
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AnvilSlot = Container.expand(function () {
var self = Container.call(this);
var slotGraphics = self.attachAsset('anvil_slot', {
anchorX: 0.5,
anchorY: 0.5
});
self.currentItem = null;
self.placeItem = function (item) {
if (self.currentItem) {
self.currentItem.returnToOriginalPosition();
}
// Return any item in preview slot to inventory
if (previewSlot && previewSlot.previewItem) {
previewSlot.previewItem.returnToOriginalPosition();
inventoryItems.push(previewSlot.previewItem);
previewSlot.previewItem = null;
}
self.currentItem = item;
item.x = self.x;
item.y = self.y;
};
self.removeItem = function () {
if (self.currentItem) {
self.currentItem = null;
}
};
self.hasItem = function () {
return self.currentItem !== null;
};
return self;
});
var Button = Container.expand(function (text, color) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset(color === 0x4CAF50 ? 'confirm_button' : 'cancel_button', {
anchorX: 0.5,
anchorY: 0.5
});
self.callback = null;
self.setCallback = function (cb) {
self.callback = cb;
};
self.down = function (x, y, obj) {
if (self.callback) {
self.callback();
}
};
return self;
});
var Item = Container.expand(function (itemType, enhanceLevel) {
var self = Container.call(this);
self.itemType = itemType || 'Mirage_Dagger';
self.enhanceLevel = enhanceLevel || 1;
self.originalX = 0;
self.originalY = 0;
self.originalSlotIndex = -1; // Store the original inventory slot index
self.isDragging = false;
// Create item graphics based on type
var itemGraphics = self.attachAsset(self.itemType, {
anchorX: 0.5,
anchorY: 0.5
});
// Enhancement level text
self.levelText = new Text2('+' + self.enhanceLevel, {
size: 80,
fill: 0xFFD700
});
self.levelText.anchor.set(0.5, 0.5);
self.levelText.x = -150;
self.levelText.y = -itemGraphics.height / 2 + 20;
self.addChild(self.levelText);
if (self.enhanceLevel < 1) {
self.levelText.visible = false;
}
self.updateEnhanceLevel = function (newLevel) {
self.enhanceLevel = newLevel;
if (self.enhanceLevel < 1) {
self.levelText.visible = false;
} else {
self.levelText.visible = true;
self.levelText.setText('+' + self.enhanceLevel);
}
};
self.setOriginalPosition = function (x, y, slotIndex) {
self.originalX = x;
self.originalY = y;
if (slotIndex !== undefined) {
self.originalSlotIndex = slotIndex;
}
};
self.returnToOriginalPosition = function () {
tween(self, {
x: self.originalX,
y: self.originalY
}, {
duration: 300
});
};
self.down = function (x, y, obj) {
// Check for right click (button 2) first
if (obj && obj.event && obj.event.button === 2) {
// Move item to first inventory slot (index 0)
var itemIndex = inventoryItems.indexOf(self);
if (itemIndex > -1) {
// Calculate first slot position
var row = Math.floor(0 / itemsPerRow);
var col = 0 % itemsPerRow;
var slotX = startX + col * itemSpacing;
var slotY = startY + row * rowSpacing;
// Move item to first slot position
tween(self, {
x: slotX,
y: slotY
}, {
duration: 300
});
// Update original position to first slot
self.setOriginalPosition(slotX, slotY, 0);
return; // Exit early for right-click
}
}
self.isDragging = true;
// Special handling for bus items - create a copy for dragging
if (self.itemType === 'bus') {
var busCopy = new Item('bus', -1);
busCopy.scaleX = 0.6;
busCopy.scaleY = 0.6;
busCopy.x = self.x;
busCopy.y = self.y;
busCopy.setOriginalPosition(self.x, self.y, self.originalSlotIndex);
game.addChild(busCopy);
draggedItem = busCopy;
} else {
draggedItem = self;
}
};
self.up = function (x, y, obj) {
self.isDragging = false;
draggedItem = null;
};
return self;
});
var PreviewSlot = Container.expand(function () {
var self = Container.call(this);
var slotGraphics = self.attachAsset('preview_slot', {
anchorX: 0.5,
anchorY: 0.5
});
self.previewItem = null;
self.showPreview = function (item) {
if (self.previewItem) {
self.previewItem.destroy();
}
// Preview will only be shown after successful upgrade
};
self.showSuccessPreview = function (item) {
if (self.previewItem) {
self.previewItem.destroy();
}
self.previewItem = new Item(item.itemType, item.enhanceLevel);
self.previewItem.x = self.x;
self.previewItem.y = self.y;
self.previewItem.alpha = 0.8;
self.parent.addChild(self.previewItem);
};
self.hidePreview = function () {
if (self.previewItem) {
self.previewItem.destroy();
self.previewItem = null;
}
};
return self;
});
var UpgradeEffect = Container.expand(function () {
var self = Container.call(this);
var glowEffect = self.attachAsset('upgrade_glow', {
anchorX: 0.5,
anchorY: 0.5
});
glowEffect.alpha = 0;
glowEffect.scaleX = 0.5;
glowEffect.scaleY = 0.5;
self.playSuccessEffect = function () {
// Create upgrade light with 12px width and 2px height
glowEffect.alpha = 0.8;
glowEffect.scaleX = 0.75; // 300px width (400 * 0.75 = 300)
glowEffect.scaleY = 0.015; // 6px height (400 * 0.015 = 6)
glowEffect.x = -300; // Start from left
glowEffect.y = 0; // Centered horizontally
glowEffect.tint = 0xFFD700; // Golden color
// First animation: light point moves at constant speed from left to right
tween(glowEffect, {
x: 300
}, {
duration: 800,
// Faster constant speed
easing: tween.linear,
onFinish: function onFinish() {
// Second animation: light point returns to left at same speed
tween(glowEffect, {
x: -300
}, {
duration: 800,
easing: tween.linear,
onFinish: function onFinish() {
// Third animation: light point moves right again at same speed and disappears instantly
tween(glowEffect, {
x: 300
}, {
duration: 800,
easing: tween.linear,
onFinish: function onFinish() {
// Instantly disappear
glowEffect.alpha = 0;
}
});
}
});
}
});
};
self.playFailEffect = function () {
// Create upgrade light with 12px width and 2px height
glowEffect.alpha = 0.7;
glowEffect.scaleX = 0.75; // 300px width (400 * 0.75 = 300)
glowEffect.scaleY = 0.015; // 6px height (400 * 0.015 = 6)
glowEffect.x = -300; // Start from left
glowEffect.y = 0; // Centered horizontally
glowEffect.tint = 0xFF0000; // Red color for failure
// Animate red light point moving from left to right
tween(glowEffect, {
x: 300
}, {
duration: 1200,
easing: tween.easeOut,
onFinish: function onFinish() {
// Instantly disappear
glowEffect.alpha = 0;
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F4F
});
/****
* Game Code
****/
var anvilArea = game.addChild(LK.getAsset('anvil_area', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 600
}));
var inventoryPanel = game.addChild(LK.getAsset('inventory_panel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1800
}));
// Create anvil slot (left side)
var anvilSlot = game.addChild(new AnvilSlot());
anvilSlot.x = 1024 - 300; // Left side of anvil
anvilSlot.y = 600;
// Create preview slot (right side)
var previewSlot = game.addChild(new PreviewSlot());
previewSlot.x = 1024 + 300; // Right side of anvil
previewSlot.y = 600;
// Create busbox in center of the two slots
var busBox = game.addChild(LK.getAsset('busbox', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
// Center between anvil slot (724) and preview slot (1324)
y: 600
}));
var upgradeEffect = game.addChild(new UpgradeEffect());
upgradeEffect.x = 1024;
upgradeEffect.y = 600;
// Create buttons at the bottom of anvil area
var confirmButton = game.addChild(new Button('Confirm', 0x4CAF50));
confirmButton.x = 1024 - 140;
confirmButton.y = 1100; // Bottom of anvil area (600 + 600/2 - 60 for button height)
var cancelButton = game.addChild(new Button('Cancel', 0xF44336));
cancelButton.x = 1024 + 140;
cancelButton.y = 1100; // Bottom of anvil area (600 + 600/2 - 60 for button height)
// Create inventory items
var inventoryItems = [];
var itemTypes = ['Mirage_Dagger', 'armor', 'helmet', 'shield', 'ring'];
var itemsPerRow = 4;
var itemRows = 4;
var padding = 60; // Equal padding from all sides
var availableWidth = inventoryPanel.width - padding * 2;
var availableHeight = inventoryPanel.height - padding * 2;
var itemSpacing = availableWidth / itemsPerRow;
var rowSpacing = availableHeight / itemRows;
var startX = inventoryPanel.x - availableWidth / 2 + itemSpacing / 2;
var startY = inventoryPanel.y - availableHeight / 2 + rowSpacing / 2;
for (var i = 0; i < 16; i++) {
if (i === 0) {
// Create 32 stacked bus items in first slot
var busItem = new Item('bus', -1); // Set enhance level to -1 to hide + symbol completely
var row = Math.floor(i / itemsPerRow);
var col = i % itemsPerRow;
// Scale down items to fit within grid boxes (from 200px to ~120px)
busItem.scaleX = 0.6;
busItem.scaleY = 0.6;
// Center items within each inventory grid box
busItem.x = startX + col * itemSpacing;
busItem.y = startY + row * rowSpacing;
busItem.setOriginalPosition(busItem.x, busItem.y, i);
// Add stack count property
busItem.stackCount = 32;
// Add stack count text next to the bus visual
var stackText = new Text2('32', {
size: 40,
fill: 0xFFFFFF
});
stackText.anchor.set(0, 0.5); // Left anchor, middle anchor
stackText.x = 70; // Position next to the right side of the bus
stackText.y = 0; // Vertically centered with the bus
busItem.addChild(stackText);
inventoryItems.push(busItem);
game.addChild(busItem);
} else {
var itemType = itemTypes[i % itemTypes.length];
var item = new Item(itemType, 1);
var row = Math.floor(i / itemsPerRow);
var col = i % itemsPerRow;
// Scale down items to fit within grid boxes (from 200px to ~120px)
item.scaleX = 0.6;
item.scaleY = 0.6;
// Center items within each inventory grid box
item.x = startX + col * itemSpacing;
item.y = startY + row * rowSpacing;
item.setOriginalPosition(item.x, item.y, i);
inventoryItems.push(item);
game.addChild(item);
}
}
// Game variables
var draggedItem = null;
var totalUpgrades = 0;
var successfulUpgrades = 0;
var maxItems = 16;
var busInBusbox = null; // Track bus item placed in busbox
// Setup button callbacks
confirmButton.setCallback(function () {
// Return any item in preview slot to inventory first
if (previewSlot.previewItem) {
previewSlot.previewItem.returnToOriginalPosition();
inventoryItems.push(previewSlot.previewItem);
previewSlot.previewItem = null;
}
if (anvilSlot.hasItem() && busInBusbox) {
var item = anvilSlot.currentItem;
var upgradeResult = attemptUpgrade(item);
// Consume the bus item in busbox regardless of upgrade success/failure
var busStackText = busInBusbox.children[1]; // Get the stack count text
if (busInBusbox.stackCount > 1) {
// Decrease stack count
busInBusbox.stackCount--;
busStackText.setText(busInBusbox.stackCount.toString());
} else {
// Remove bus item completely when stack reaches 0
busInBusbox.destroy();
busInBusbox = null;
}
// Also decrease inventory bus stack count
var inventoryBusItem = inventoryItems.find(function (item) {
return item.itemType === 'bus';
});
if (inventoryBusItem) {
var inventoryStackText = inventoryBusItem.children[1]; // Get the stack count text
if (inventoryBusItem.stackCount > 1) {
inventoryBusItem.stackCount--;
inventoryStackText.setText(inventoryBusItem.stackCount.toString());
} else {
// Remove bus item completely when stack reaches 0
var itemIndex = inventoryItems.indexOf(inventoryBusItem);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
}
inventoryBusItem.destroy();
}
}
if (upgradeResult.success) {
// Add 2 second delay before moving item to preview slot
LK.setTimeout(function () {
// Create new item with upgraded level for preview
var previewItem = new Item(item.itemType, upgradeResult.newLevel);
previewItem.scaleX = 0.6;
previewItem.scaleY = 0.6;
previewItem.x = previewSlot.x;
previewItem.y = previewSlot.y;
previewItem.alpha = 0; // Start invisible
// Smooth fade-in animation
tween(previewItem, {
alpha: 0.8
}, {
duration: 800,
easing: tween.easeInOut
});
// Set original position for preview item to return to inventory using original slot
var originalSlotIndex = item.originalSlotIndex;
if (originalSlotIndex >= 0) {
var row = Math.floor(originalSlotIndex / itemsPerRow);
var col = originalSlotIndex % itemsPerRow;
var slotX = startX + col * itemSpacing;
var slotY = startY + row * rowSpacing;
previewItem.setOriginalPosition(slotX, slotY, originalSlotIndex);
}
game.addChild(previewItem);
// Remove original item from inventory
var itemIndex = inventoryItems.indexOf(item);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
}
item.destroy();
anvilSlot.currentItem = null; // Clear anvil slot
previewSlot.previewItem = previewItem; // Set preview item
}, 2000);
} else {
// Item failed upgrade and was destroyed
anvilSlot.currentItem = null; // Clear anvil slot
}
}
});
cancelButton.setCallback(function () {
// Return any item in preview slot to inventory first
if (previewSlot.previewItem) {
previewSlot.previewItem.returnToOriginalPosition();
inventoryItems.push(previewSlot.previewItem);
previewSlot.previewItem = null;
}
if (anvilSlot.hasItem()) {
var item = anvilSlot.currentItem;
item.returnToOriginalPosition();
anvilSlot.currentItem = null; // Clear anvil slot
previewSlot.hidePreview();
}
// Return bus from busbox to inventory
if (busInBusbox) {
busInBusbox.returnToOriginalPosition();
inventoryItems.push(busInBusbox);
busInBusbox = null;
}
});
// UI Elements removed
// Upgrade success rates based on level
var upgradeRates = {
0: 0.95,
// +0 to +1
1: 0.85,
// +1 to +2
2: 0.75,
// +2 to +3
3: 0.65,
// +3 to +4
4: 0.50,
// +4 to +5
5: 0.35,
// +5 to +6
6: 0.20,
// +6 to +7
7: 0.10 // +7 to +8
};
function attemptUpgrade(item) {
if (item.enhanceLevel >= 8) {
return {
success: false
}; // Max level reached
}
var successRate = upgradeRates[item.enhanceLevel];
var success = Math.random() < successRate;
if (success) {
// Successful upgrade
var newLevel = item.enhanceLevel + 1;
upgradeEffect.playSuccessEffect();
LK.getSound('upgrade_success').play();
successfulUpgrades++;
// Update score
LK.setScore(successfulUpgrades);
// Win condition
if (successfulUpgrades >= 20) {
LK.showYouWin();
}
return {
success: true,
newLevel: newLevel
};
} else {
// Failed upgrade
upgradeEffect.playFailEffect();
LK.getSound('upgrade_fail').play();
// Destroy item on failure
var itemIndex = inventoryItems.indexOf(item);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
item.destroy();
maxItems--;
// Check if no items left
if (maxItems <= 0) {
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
return {
success: false
};
}
totalUpgrades++;
}
function isItemInAnvilArea(item) {
var anvilBounds = {
left: anvilArea.x - anvilArea.width / 2,
right: anvilArea.x + anvilArea.width / 2,
top: anvilArea.y - anvilArea.height / 2,
bottom: anvilArea.y + anvilArea.height / 2
};
return item.x >= anvilBounds.left && item.x <= anvilBounds.right && item.y >= anvilBounds.top && item.y <= anvilBounds.bottom;
}
// Game event handlers
game.move = function (x, y, obj) {
if (draggedItem) {
draggedItem.x = x;
draggedItem.y = y;
}
};
game.down = function (x, y, obj) {
// No special handling needed here, items handle their own down events
};
game.up = function (x, y, obj) {
if (draggedItem) {
// Check if dropped on anvil slot
var distanceToSlot = Math.sqrt(Math.pow(draggedItem.x - anvilSlot.x, 2) + Math.pow(draggedItem.y - anvilSlot.y, 2));
// Check if dropped on busbox
var distanceToBusbox = Math.sqrt(Math.pow(draggedItem.x - busBox.x, 2) + Math.pow(draggedItem.y - busBox.y, 2));
if (distanceToSlot < 200 && draggedItem.itemType !== 'bus') {
// Place non-bus item in anvil slot
anvilSlot.placeItem(draggedItem);
} else if (distanceToBusbox < 100 && draggedItem.itemType === 'bus') {
// Place bus item in busbox
if (busInBusbox) {
// Return previous bus item to inventory
busInBusbox.returnToOriginalPosition();
inventoryItems.push(busInBusbox);
}
busInBusbox = draggedItem;
draggedItem.x = busBox.x;
draggedItem.y = busBox.y;
// Decrease stack count of original bus item
var originalBusItem = inventoryItems.find(function (item) {
return item.itemType === 'bus';
});
if (originalBusItem) {
var stackText = originalBusItem.children[1]; // Get the stack count text
if (originalBusItem.stackCount > 1) {
originalBusItem.stackCount--;
stackText.setText(originalBusItem.stackCount.toString());
} else {
// Remove bus item completely when stack reaches 0
var itemIndex = inventoryItems.indexOf(originalBusItem);
if (itemIndex > -1) {
inventoryItems.splice(itemIndex, 1);
}
originalBusItem.destroy();
}
}
} else {
// Return to original position or destroy if it's a bus copy
if (draggedItem.itemType === 'bus') {
// Check if this is a copy by seeing if it's in inventory
var itemIndex = inventoryItems.indexOf(draggedItem);
if (itemIndex === -1) {
// This is a copy, destroy it
draggedItem.destroy();
} else {
draggedItem.returnToOriginalPosition();
}
} else {
draggedItem.returnToOriginalPosition();
}
}
draggedItem = null;
}
};
game.update = function () {
// Update game state
if (totalUpgrades > 50 && successfulUpgrades < 5) {
LK.showGameOver();
}
};
Raptor from Knight Online. In-Game asset. 2d. High contrast. No shadows
Cancel Button for medeivel concept. In-Game asset. 2d. High contrast. No shadows
Confirm Button for medeivel concept. In-Game asset. 2d. High contrast. No shadows
rectangular frame, medevil concept without text and dark color platte. In-Game asset. 2d. High contrast. No shadows
rectangular frame, without text, wooden color palette with good concept. In-Game asset. 2d. High contrast. No shadows
Chitin Shield. In-Game asset. 2d. High contrast. No shadows
Gray dagger from medevil . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
warsctyhe. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
içinde yazı olmayan, kenarlında boşluk olmayan 15 adet bölmeden oluşan bir inventory. In-Game asset. 2d. High contrast. No shadows
a wooden frame. In-Game asset. 2d. High contrast. No shadows
Smal enchancement scrool from online game with shine effected. In-Game asset. 2d. High contrast. No shadows