/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BloodDrop = Container.expand(function (x, y, isPersistent) {
var self = Container.call(this);
var bloodGraphics = self.attachAsset('bloodDrop', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.alpha = 1.0;
self.isPersistent = isPersistent || false;
self.pulsing = false;
if (self.isPersistent) {
// Persistent blood that requires hemostat - much larger and more prominent
bloodGraphics.tint = 0xcc0000; // Brighter red for visibility
tween(self, {
scaleX: 4.5,
scaleY: 4.5
}, {
duration: 800
});
// Start more dramatic pulsing animation to draw attention
self.startPulsing = function () {
if (!self.pulsing) {
self.pulsing = true;
tween(self, {
scaleX: 5.5,
scaleY: 5.5,
alpha: 0.9
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.pulsing) {
tween(self, {
scaleX: 4.0,
scaleY: 4.0,
alpha: 1.0
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.pulsing) {
self.startPulsing();
}
}
});
}
}
});
}
};
self.startPulsing();
} else {
// Regular blood drop - animate and fade but more visible
tween(self, {
scaleX: 2.0,
scaleY: 2.0,
alpha: 0.4
}, {
duration: 3000,
onFinish: function onFinish() {
self.destroy();
}
});
}
return self;
});
var Debris = Container.expand(function (x, y) {
var self = Container.call(this);
self.removed = false;
self.pickedUp = false;
self.originalX = x;
self.originalY = y;
var debrisGraphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'cleaning' || selectedTool !== 'tweezers' || self.removed) {
return;
}
if (!self.pickedUp) {
LK.getSound('click').play();
self.pickedUp = true;
draggedPiece = self;
// Visual feedback for pickup
tween(debrisGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
debrisGraphics.tint = 0x27ae60;
}
};
return self;
});
var InfectedMaterial = Container.expand(function (x, y) {
var self = Container.call(this);
self.removed = false;
self.pickedUp = false;
self.originalX = x;
self.originalY = y;
var materialGraphics = self.attachAsset('infectedMaterial', {
anchorX: 0.5,
anchorY: 0.5
});
// Infected material is already very dark brown and larger
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'infected_removal' || selectedTool !== 'infectedScalpel' || self.removed) {
return;
}
if (!self.pickedUp) {
LK.getSound('click').play();
self.pickedUp = true;
draggedPiece = self;
// Visual feedback for pickup
tween(materialGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
materialGraphics.tint = 0x27ae60;
}
};
return self;
});
var Infection = Container.expand(function (x, y) {
var self = Container.call(this);
self.treated = false;
var infectionGraphics = self.attachAsset('infection', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'treatment' || selectedTool !== 'antiseptic' || self.treated) {
return;
}
LK.getSound('healing').play();
// Treat infection
self.treated = true;
infectionGraphics.alpha = 0.2;
infectionGraphics.tint = 0x90ee90;
infectionsHealed++;
patientComfort = Math.min(100, patientComfort + 10);
updateComfortBar();
// Check if all infections treated
if (infectionsHealed >= totalInfections) {
currentPhase = 'bandaging';
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
updateInstructions();
}
LK.setScore(LK.getScore() + 15);
scoreText.setText('Score: ' + LK.getScore());
};
return self;
});
var IngrownPart = Container.expand(function (x, y) {
var self = Container.call(this);
self.removed = false;
var partGraphics = self.attachAsset('ingrownPart', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'surgery' || selectedTool !== 'scalpel' || self.removed) {
return;
}
// Check if tool is sterile
var selectedToolObj = null;
for (var t = 0; t < tools.length; t++) {
if (tools[t].toolType === 'scalpel' && tools[t].selected) {
selectedToolObj = tools[t];
break;
}
}
if (selectedToolObj && !selectedToolObj.sterile) {
// Non-sterile tool increases infection risk
patientComfort = Math.max(0, patientComfort - 15);
updateComfortBar();
LK.effects.flashObject(self, 0xff4444, 500);
return;
}
LK.getSound('cut').play();
LK.getSound('bleed').play();
// Create bleeding effect
var bloodDropsToCreate = 4;
for (var b = 0; b < bloodDropsToCreate; b++) {
var bloodDrop = new BloodDrop(self.x + (Math.random() - 0.5) * 80, self.y + (Math.random() - 0.5) * 80, false);
game.addChild(bloodDrop);
}
// Remove ingrown part
self.removed = true;
partGraphics.alpha = 0;
ingrownPartsRemoved++;
// More realistic comfort loss
var comfortLoss = selectedToolObj && selectedToolObj.sterile ? 3 : 8;
patientComfort = Math.max(0, patientComfort - comfortLoss);
updateComfortBar();
// Mark tool as used
if (selectedToolObj) {
selectedToolObj.markUsed();
}
// Update vital signs
if (vitalSigns) {
vitalSigns.updateVitals(patientComfort);
}
// Check if all ingrown parts removed
if (ingrownPartsRemoved >= totalIngrownParts) {
checkPhaseProgression();
}
LK.setScore(LK.getScore() + 10);
scoreText.setText('Score: ' + LK.getScore());
};
return self;
});
var Tool = Container.expand(function (toolType, x, y) {
var self = Container.call(this);
self.toolType = toolType;
self.selected = false;
self.toolBackground = null; // Will be set when tool is created
self.sterile = true; // All tools start sterile
self.usageCount = 0;
var toolGraphics = self.attachAsset(toolType, {
anchorX: 0.5,
anchorY: 0.5
});
// Add sterilization indicator
self.sterilIndicator = self.attachAsset('sterilizedIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: 25,
y: -25,
scaleX: 0.5,
scaleY: 0.5
});
self.x = x;
self.y = y;
self.markUsed = function () {
self.usageCount++;
if (self.usageCount > 2) {
self.sterile = false;
self.sterilIndicator.tint = 0xff4444;
toolGraphics.tint = 0xdddddd;
}
};
self.sterilizeTool = function () {
if (!self.sterile) {
LK.getSound('sterilize').play();
self.sterile = true;
self.usageCount = 0;
self.sterilIndicator.tint = 0x00ff00;
toolGraphics.tint = 0xffffff;
// Visual sterilization effect
tween(self.sterilIndicator, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1.0
}, {
duration: 500,
onFinish: function onFinish() {
tween(self.sterilIndicator, {
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.7
}, {
duration: 300
});
}
});
}
};
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase === 'complete') {
return;
}
LK.getSound('click').play();
// Deselect all tools
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
// Reset background color
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
// Select this tool
self.selected = true;
toolGraphics.alpha = 1.0;
selectedTool = self.toolType;
// Highlight background
if (self.toolBackground) {
self.toolBackground.tint = 0x27ae60;
self.toolBackground.alpha = 0.9;
}
// Update selected tool name display
var toolIndex = toolTypes.indexOf(self.toolType);
if (toolIndex !== -1 && selectedToolText) {
selectedToolText.setText('Selected: ' + toolNames[toolIndex]);
selectedToolText.alpha = 1;
}
updateInstructions();
};
return self;
});
var TrashTray = Container.expand(function (x, y) {
var self = Container.call(this);
var trayGraphics = self.attachAsset('trashTray', {
anchorX: 0.5,
anchorY: 0.5
});
var canGraphics = self.attachAsset('trashCan', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -50
});
self.x = x;
self.y = y;
// Visual feedback when pieces are dragged over
self.highlightTray = function () {
trayGraphics.tint = 0x27ae60;
tween(trayGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200
});
};
self.unhighlightTray = function () {
trayGraphics.tint = 0xffffff;
tween(trayGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
};
self.disposePiece = function (piece) {
// Animate piece falling into trash can
tween(piece, {
x: self.x,
y: self.y - 50,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
piece.destroy();
}
});
};
return self;
});
var VitalSigns = Container.expand(function (x, y) {
var self = Container.call(this);
self.heartRate = 70 + Math.random() * 20; // 70-90 BPM normal
self.bloodPressure = 120;
self.isStressed = false;
var heartRateBar = self.attachAsset('vitalSign', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
var bpBar = self.attachAsset('vitalSign', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 40
});
self.x = x;
self.y = y;
self.updateVitals = function (comfort) {
// Heart rate increases when patient is uncomfortable
var targetHeartRate = 70 + (100 - comfort) * 0.5;
self.heartRate = self.heartRate * 0.9 + targetHeartRate * 0.1;
// Update visual indicators
if (self.heartRate > 100) {
heartRateBar.tint = 0xff4444;
self.isStressed = true;
} else if (self.heartRate > 85) {
heartRateBar.tint = 0xffaa44;
self.isStressed = false;
} else {
heartRateBar.tint = 0x44ff44;
self.isStressed = false;
}
// Scale bars based on values
heartRateBar.scaleX = Math.min(1.5, self.heartRate / 100);
bpBar.scaleX = Math.min(1.2, self.bloodPressure / 140);
};
return self;
});
var Wound = Container.expand(function (x, y) {
var self = Container.call(this);
self.healed = false;
self.persistentBlood = [];
var woundGraphics = self.attachAsset('bloodDrop', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.x = x;
self.y = y;
// Create persistent blood drops around the wound
for (var i = 0; i < 3; i++) {
var bloodX = x + (Math.random() - 0.5) * 80;
var bloodY = y + (Math.random() - 0.5) * 80;
var persistentBlood = new BloodDrop(bloodX, bloodY, true);
self.persistentBlood.push(persistentBlood);
game.addChild(persistentBlood);
}
// Pulsing animation to show active bleeding
tween(woundGraphics, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0.8
}, {
duration: 1000,
loop: true,
yoyo: true
});
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'wound_patching' || selectedTool !== 'hemostat' || self.healed) {
return;
}
LK.getSound('patch').play();
// Heal the wound
self.healed = true;
woundGraphics.tint = 0x90ee90;
woundGraphics.alpha = 0.3;
woundsToHeal--;
// Remove persistent blood drops
for (var i = 0; i < self.persistentBlood.length; i++) {
var blood = self.persistentBlood[i];
blood.pulsing = false;
tween(blood, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 1000,
onFinish: function onFinish() {
blood.destroy();
}
});
}
// Restore some patient comfort
patientComfort = Math.min(100, patientComfort + 8);
updateComfortBar();
// Visual healing effect
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 2000,
onFinish: function onFinish() {
self.destroy();
}
});
// Check if all wounds are healed
if (woundsToHeal <= 0) {
excessiveStabbing = false;
// Continue with normal phase progression
checkPhaseProgression();
}
LK.setScore(LK.getScore() + 12);
scoreText.setText('Score: ' + LK.getScore());
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xe8f4f8
});
/****
* Game Code
****/
// Game state variables
var gameState = 'title'; // title, tutorial, playing
var gameStarted = false;
var currentPhase = 'assessment'; // assessment, anesthesia, surgery, cleaning, infected_removal, treatment, bandaging, complete
var currentLevel = 1;
var patientComfort = 100;
var selectedTool = null;
var tutorialStep = 0;
var maxTutorialSteps = 7;
// Medical realism variables
var vitalSigns = null;
var sterilizationStation = null;
var bloodDropsActive = [];
var lastHeartbeatTime = 0;
var woundCount = 0;
var excessiveStabbing = false;
var woundsToHeal = 0;
// 10-Level progression system
var levelConfigs = [{
level: 1,
name: "Level 1 - Basic",
color: 0x27ae60,
comfortDecayRate: 0.2,
baseComfort: 100,
toolTolerance: 1.0,
ingrownParts: 1,
debris: 0,
infectedMaterial: 0,
infections: 0,
timeBonus: 2.0,
requiredTools: ['scalpel', 'bandage']
}, {
level: 2,
name: "Level 2 - Anesthesia",
color: 0x2ecc71,
comfortDecayRate: 0.3,
baseComfort: 95,
toolTolerance: 0.9,
ingrownParts: 1,
debris: 0,
infectedMaterial: 0,
infections: 0,
timeBonus: 1.9,
requiredTools: ['syringe', 'scalpel', 'bandage']
}, {
level: 3,
name: "Level 3 - Debris Cleaning",
color: 0x3498db,
comfortDecayRate: 0.4,
baseComfort: 90,
toolTolerance: 0.8,
ingrownParts: 1,
debris: 2,
infectedMaterial: 0,
infections: 0,
timeBonus: 1.8,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'bandage']
}, {
level: 4,
name: "Level 4 - Infected Material",
color: 0x9b59b6,
comfortDecayRate: 0.5,
baseComfort: 85,
toolTolerance: 0.7,
ingrownParts: 1,
debris: 1,
infectedMaterial: 1,
infections: 0,
timeBonus: 1.7,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'bandage']
}, {
level: 5,
name: "Level 5 - Infection Treatment",
color: 0xf39c12,
comfortDecayRate: 0.6,
baseComfort: 80,
toolTolerance: 0.6,
ingrownParts: 1,
debris: 1,
infectedMaterial: 1,
infections: 1,
timeBonus: 1.6,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 6,
name: "Level 6 - Multiple Issues",
color: 0xe67e22,
comfortDecayRate: 0.8,
baseComfort: 75,
toolTolerance: 0.5,
ingrownParts: 2,
debris: 2,
infectedMaterial: 1,
infections: 1,
timeBonus: 1.5,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 7,
name: "Level 7 - Complex Case",
color: 0xe74c3c,
comfortDecayRate: 1.0,
baseComfort: 70,
toolTolerance: 0.5,
ingrownParts: 2,
debris: 3,
infectedMaterial: 2,
infections: 1,
timeBonus: 1.4,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 8,
name: "Level 8 - Advanced",
color: 0xc0392b,
comfortDecayRate: 1.2,
baseComfort: 65,
toolTolerance: 0.4,
ingrownParts: 3,
debris: 3,
infectedMaterial: 2,
infections: 2,
timeBonus: 1.3,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 9,
name: "Level 9 - Challenging",
color: 0x8e44ad,
comfortDecayRate: 1.4,
baseComfort: 60,
toolTolerance: 0.4,
ingrownParts: 3,
debris: 4,
infectedMaterial: 3,
infections: 2,
timeBonus: 1.2,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 10,
name: "Level 10 - Master Surgeon",
color: 0x2c3e50,
comfortDecayRate: 1.6,
baseComfort: 55,
toolTolerance: 0.3,
ingrownParts: 4,
debris: 4,
infectedMaterial: 3,
infections: 3,
timeBonus: 1.1,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}];
var currentPatient = levelConfigs[0];
// Game objects
var tools = [];
var ingrownParts = [];
var debrisPieces = [];
var infectedMaterialPieces = [];
var infections = [];
// Counters
var ingrownPartsRemoved = 0;
var totalIngrownParts = 3;
var debrisRemoved = 0;
var totalDebris = 5;
var infectedMaterialRemoved = 0;
var totalInfectedMaterial = 3;
var infectionsHealed = 0;
var totalInfections = 2;
var anesthesiaApplied = false;
var bandageApplied = false;
// Trash tray system
var trashTray = null;
var draggedPiece = null;
// Create patient's toe
var toe = game.addChild(LK.getAsset('toeBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
toe.alpha = 0; // Hidden initially
var toenail = game.addChild(LK.getAsset('toenail', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1150
}));
toenail.alpha = 0; // Hidden initially
// Create title screen elements
var titleText = new Text2('NAIL DOCTOR', {
size: 120,
fill: 0x2C3E50
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
game.addChild(titleText);
var subtitleText = new Text2('Ingrown Toenail Surgery Simulator', {
size: 60,
fill: 0x7F8C8D
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 900;
game.addChild(subtitleText);
var playButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
scaleX: 1.2,
scaleY: 0.8
}));
playButton.tint = 0x27ae60;
var playButtonText = new Text2('START GAME', {
size: 60,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.x = 1024;
playButtonText.y = 1200;
game.addChild(playButtonText);
var tutorialButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400,
scaleX: 1.2,
scaleY: 0.8
}));
tutorialButton.tint = 0x3498db;
var tutorialButtonText = new Text2('HOW TO PLAY', {
size: 60,
fill: 0xFFFFFF
});
tutorialButtonText.anchor.set(0.5, 0.5);
tutorialButtonText.x = 1024;
tutorialButtonText.y = 1400;
game.addChild(tutorialButtonText);
// Create UI elements
var instructionText = new Text2('Examine the patient and assess the ingrown toenail severity', {
size: 60,
fill: 0x2C3E50
});
instructionText.anchor.set(0.5, 0);
instructionText.x = 1024;
instructionText.y = 100;
instructionText.alpha = 0; // Hidden initially
game.addChild(instructionText);
var scoreText = new Text2('Score: 0', {
size: 50,
fill: 0x27AE60
});
scoreText.anchor.set(0, 0);
scoreText.x = 100;
scoreText.y = 200;
scoreText.alpha = 0; // Hidden initially
game.addChild(scoreText);
var levelText = new Text2('Level: 1', {
size: 50,
fill: 0x2980B9
});
levelText.anchor.set(1, 0);
levelText.x = 1948;
levelText.y = 200;
levelText.alpha = 0; // Hidden initially
game.addChild(levelText);
// Patient type indicator
var patientTypeText = new Text2('Easy Patient', {
size: 45,
fill: 0x27ae60
});
patientTypeText.anchor.set(0.5, 0);
patientTypeText.x = 1024;
patientTypeText.y = 250;
patientTypeText.alpha = 0; // Hidden initially
game.addChild(patientTypeText);
// Patient comfort bar
var comfortBarBg = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 300,
scaleX: 1.3,
scaleY: 0.3
}));
comfortBarBg.tint = 0x34495e;
comfortBarBg.alpha = 0; // Hidden initially
var comfortBar = game.addChild(LK.getAsset('patientComfortBar', {
anchorX: 0,
anchorY: 0,
x: 824,
y: 300
}));
comfortBar.alpha = 0; // Hidden initially
var comfortText = new Text2('Patient Comfort: 100%', {
size: 40,
fill: 0xFFFFFF
});
comfortText.anchor.set(0.5, 0.5);
comfortText.x = 1024;
comfortText.y = 320;
comfortText.alpha = 0; // Hidden initially
game.addChild(comfortText);
// Create tool selection area
var toolY = 2200;
var toolSpacing = 320;
var startX = 200;
// Tool names for UI labels
var toolNames = ['Anesthesia Syringe', 'Surgical Scalpel', 'Cleaning Tweezers', 'Infected Material Scalpel', 'Antiseptic Spray', 'Medical Bandage'];
var toolDescriptions = ['Apply anesthesia', 'Remove ingrown parts', 'Clean debris', 'Remove infected material', 'Treat infections', 'Apply bandage'];
// Selected tool name display
var selectedToolText = new Text2('', {
size: 70,
fill: 0x27AE60
});
selectedToolText.anchor.set(0.5, 0);
selectedToolText.x = 1024;
selectedToolText.y = 2000;
selectedToolText.alpha = 0; // Hidden initially
game.addChild(selectedToolText);
// Create tools with UI elements
var toolTypes = ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage'];
for (var i = 0; i < toolTypes.length; i++) {
var toolX = startX + i * toolSpacing;
var toolYPos = toolY;
// Create tool background button
var toolBg = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: toolX,
y: toolYPos,
scaleX: 0.8,
scaleY: 1.2
}));
toolBg.tint = 0x3498db;
toolBg.alpha = 0; // Hidden initially
// Create the actual tool
var tool = new Tool(toolTypes[i], toolX, toolYPos - 30);
tool.getChildAt(0).alpha = 0; // Hidden initially
tool.toolBackground = toolBg; // Store reference to background
tools.push(tool);
game.addChild(tool);
// Create tool name label
var toolLabel = new Text2(toolNames[i], {
size: 40,
fill: 0xFFFFFF
});
toolLabel.anchor.set(0.5, 0.5);
toolLabel.x = toolX;
toolLabel.y = toolYPos + 50;
toolLabel.alpha = 0; // Hidden initially
game.addChild(toolLabel);
// Create tool description
var toolDesc = new Text2(toolDescriptions[i], {
size: 30,
fill: 0xBDC3C7
});
toolDesc.anchor.set(0.5, 0.5);
toolDesc.x = toolX;
toolDesc.y = toolYPos + 90;
toolDesc.alpha = 0; // Hidden initially
game.addChild(toolDesc);
}
// Title screen button handlers
playButton.down = function (x, y, obj) {
if (gameState === 'title') {
showGameUI();
gameState = 'playing';
}
};
tutorialButton.down = function (x, y, obj) {
if (gameState === 'title') {
showTutorial();
gameState = 'tutorial';
}
};
// Tutorial elements
var tutorialText = new Text2('', {
size: 50,
fill: 0x2C3E50
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 1024;
tutorialText.y = 400;
tutorialText.alpha = 0; // Hidden initially
game.addChild(tutorialText);
var tutorialNextButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1800,
scaleX: 1.0,
scaleY: 0.6
}));
tutorialNextButton.tint = 0x3498db;
tutorialNextButton.alpha = 0; // Hidden initially
var tutorialNextText = new Text2('NEXT', {
size: 50,
fill: 0xFFFFFF
});
tutorialNextText.anchor.set(0.5, 0.5);
tutorialNextText.x = 1024;
tutorialNextText.y = 1800;
tutorialNextText.alpha = 0; // Hidden initially
game.addChild(tutorialNextText);
var tutorialBackButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 824,
y: 1800,
scaleX: 1.0,
scaleY: 0.6
}));
tutorialBackButton.tint = 0x95a5a6;
tutorialBackButton.alpha = 0; // Hidden initially
var tutorialBackText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
tutorialBackText.anchor.set(0.5, 0.5);
tutorialBackText.x = 824;
tutorialBackText.y = 1800;
tutorialBackText.alpha = 0; // Hidden initially
game.addChild(tutorialBackText);
var tutorialSkipButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1224,
y: 1800,
scaleX: 1.0,
scaleY: 0.6
}));
tutorialSkipButton.tint = 0xe74c3c;
tutorialSkipButton.alpha = 0; // Hidden initially
var tutorialSkipText = new Text2('SKIP', {
size: 50,
fill: 0xFFFFFF
});
tutorialSkipText.anchor.set(0.5, 0.5);
tutorialSkipText.x = 1224;
tutorialSkipText.y = 1800;
tutorialSkipText.alpha = 0; // Hidden initially
game.addChild(tutorialSkipText);
// Tutorial button handlers
tutorialNextButton.down = function (x, y, obj) {
if (gameState === 'tutorial') {
tutorialStep++;
if (tutorialStep >= maxTutorialSteps) {
hideTutorial();
showGameUI();
gameState = 'playing';
} else {
updateTutorialContent();
}
}
};
tutorialBackButton.down = function (x, y, obj) {
if (gameState === 'tutorial' && tutorialStep > 0) {
tutorialStep--;
updateTutorialContent();
}
};
tutorialSkipButton.down = function (x, y, obj) {
if (gameState === 'tutorial') {
hideTutorial();
showGameUI();
gameState = 'playing';
}
};
// Start button
var startButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1600,
scaleX: 1.5,
scaleY: 0.8
}));
startButton.tint = 0x27ae60;
startButton.alpha = 0; // Hidden initially
var startText = new Text2('Start Treatment', {
size: 60,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = 1024;
startText.y = 1600;
startText.alpha = 0; // Hidden initially
game.addChild(startText);
startButton.down = function (x, y, obj) {
if (!gameStarted && gameState === 'playing') {
startGame();
}
};
function hideTitleScreen() {
titleText.alpha = 0;
subtitleText.alpha = 0;
playButton.alpha = 0;
playButtonText.alpha = 0;
tutorialButton.alpha = 0;
tutorialButtonText.alpha = 0;
}
function showGameUI() {
hideTitleScreen();
hideTutorial();
// Show game UI elements
instructionText.alpha = 1;
scoreText.alpha = 1;
levelText.alpha = 1;
patientTypeText.alpha = 1;
comfortBarBg.alpha = 1;
comfortBar.alpha = 1;
comfortText.alpha = 1;
toe.alpha = 1;
toenail.alpha = 1;
startButton.alpha = 1;
startText.alpha = 1;
selectedToolText.alpha = 0; // Initially hidden until tool selected
// Show tools
for (var i = 0; i < tools.length; i++) {
tools[i].getChildAt(0).alpha = 0.7;
tools[i].toolBackground.alpha = 0.6;
}
// Show tool labels and descriptions
for (var i = 0; i < game.children.length; i++) {
var child = game.children[i];
if (child.getText) {
var text = child.getText();
if (text.indexOf('Anesthesia') === 0 || text.indexOf('Surgical') === 0 || text.indexOf('Cleaning') === 0 || text.indexOf('Infected') === 0 || text.indexOf('Antiseptic') === 0 || text.indexOf('Medical') === 0 || text.indexOf('Apply') === 0 || text.indexOf('Remove') === 0 || text.indexOf('Clean') === 0 || text.indexOf('Treat') === 0) {
child.alpha = 1;
}
}
}
// Create trash tray
if (!trashTray) {
trashTray = new TrashTray(1700, 1800);
game.addChild(trashTray);
}
// Create vital signs monitor
if (!vitalSigns) {
vitalSigns = new VitalSigns(100, 400);
game.addChild(vitalSigns);
}
// Create sterilization station
if (!sterilizationStation) {
sterilizationStation = game.addChild(LK.getAsset('antiseptic', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 1600,
scaleX: 1.5,
scaleY: 1.5
}));
sterilizationStation.tint = 0x00ff88;
// Add sterilization label
var sterilLabel = new Text2('STERILIZE', {
size: 30,
fill: 0x00ff88
});
sterilLabel.anchor.set(0.5, 0.5);
sterilLabel.x = 200;
sterilLabel.y = 1700;
game.addChild(sterilLabel);
// Sterilization station click handler
sterilizationStation.down = function (x, y, obj) {
if (selectedTool) {
for (var t = 0; t < tools.length; t++) {
if (tools[t].selected) {
tools[t].sterilizeTool();
break;
}
}
}
};
}
}
function showTutorial() {
hideTitleScreen();
tutorialStep = 0;
tutorialText.alpha = 1;
tutorialNextButton.alpha = 1;
tutorialNextText.alpha = 1;
tutorialBackButton.alpha = 1;
tutorialBackText.alpha = 1;
tutorialSkipButton.alpha = 1;
tutorialSkipText.alpha = 1;
updateTutorialContent();
}
function hideTutorial() {
tutorialText.alpha = 0;
tutorialNextButton.alpha = 0;
tutorialNextText.alpha = 0;
tutorialBackButton.alpha = 0;
tutorialBackText.alpha = 0;
tutorialSkipButton.alpha = 0;
tutorialSkipText.alpha = 0;
selectedToolText.alpha = 0;
}
function updateTutorialContent() {
var content = '';
switch (tutorialStep) {
case 0:
content = 'Welcome to Nail Doctor!\nYou are a podiatrist treating ingrown toenails.';
break;
case 1:
content = 'Step 1: ANESTHESIA\nSelect the syringe and click the toe to numb the area\nbefore starting surgery.';
break;
case 2:
content = 'Step 2: SURGERY\nUse the scalpel to carefully remove the ingrown\nnail parts that are causing pain.';
break;
case 3:
content = 'Step 3: CLEANING\nUse tweezers to remove all debris pieces\nfrom the wound area.';
break;
case 4:
content = 'Step 4: INFECTED REMOVAL\nUse the infected material scalpel to remove\nred infected tissue pieces.';
break;
case 5:
content = 'Step 5: TREATMENT\nApply antiseptic to treat any remaining infections\nand prevent further complications.';
break;
case 6:
content = 'Step 6: BANDAGING\nFinally, apply a bandage to protect the treated area\nand complete the procedure. Good luck!';
break;
}
tutorialText.setText(content);
// Update button states
if (tutorialStep === 0) {
tutorialBackButton.alpha = 0.3;
tutorialBackText.alpha = 0.3;
} else {
tutorialBackButton.alpha = 1;
tutorialBackText.alpha = 1;
}
if (tutorialStep >= maxTutorialSteps - 1) {
tutorialNextText.setText('START');
} else {
tutorialNextText.setText('NEXT');
}
}
function startGame() {
gameStarted = true;
startButton.alpha = 0;
startText.alpha = 0;
// Determine starting phase based on what exists in this level
if (currentPatient.requiredTools.indexOf('syringe') !== -1) {
currentPhase = 'anesthesia';
} else if (currentPatient.ingrownParts > 0) {
currentPhase = 'surgery';
} else if (currentPatient.debris > 0) {
currentPhase = 'cleaning';
} else if (currentPatient.infectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (currentPatient.infections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
// Set patient-specific values
totalIngrownParts = currentPatient.ingrownParts;
totalDebris = currentPatient.debris;
totalInfectedMaterial = currentPatient.infectedMaterial;
totalInfections = currentPatient.infections;
patientComfort = currentPatient.baseComfort;
updateComfortBar();
// Only create ingrown nail parts if level has them
if (totalIngrownParts > 0) {
var ingrownPositions = [];
for (var ing = 0; ing < totalIngrownParts; ing++) {
ingrownPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < ingrownPositions.length; i++) {
var ingrownPart = new IngrownPart(ingrownPositions[i].x, ingrownPositions[i].y);
ingrownParts.push(ingrownPart);
game.addChild(ingrownPart);
}
}
// Only create debris pieces if level has them
if (totalDebris > 0) {
var debrisPositions = [];
for (var d = 0; d < totalDebris; d++) {
debrisPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < debrisPositions.length; i++) {
var debris = new Debris(debrisPositions[i].x, debrisPositions[i].y);
debrisPieces.push(debris);
game.addChild(debris);
}
}
// Only create infected material pieces if level has them
if (totalInfectedMaterial > 0) {
var infectedMaterialPositions = [];
for (var m = 0; m < totalInfectedMaterial; m++) {
infectedMaterialPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < infectedMaterialPositions.length; i++) {
var infectedMaterial = new InfectedMaterial(infectedMaterialPositions[i].x, infectedMaterialPositions[i].y);
infectedMaterialPieces.push(infectedMaterial);
game.addChild(infectedMaterial);
}
}
// Only create infections if level has them
if (totalInfections > 0) {
var infectionPositions = [];
for (var inf = 0; inf < totalInfections; inf++) {
infectionPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < infectionPositions.length; i++) {
var infection = new Infection(infectionPositions[i].x, infectionPositions[i].y);
infections.push(infection);
game.addChild(infection);
}
}
updateInstructions();
}
function updateInstructions() {
var instruction = '';
switch (currentPhase) {
case 'anesthesia':
instruction = 'Select the syringe and apply anesthesia to numb the area';
break;
case 'surgery':
instruction = 'Use the scalpel to carefully remove ingrown nail parts';
break;
case 'cleaning':
instruction = 'Use tweezers to remove all debris pieces';
break;
case 'infected_removal':
instruction = 'Use infected material scalpel to remove red infected material';
break;
case 'treatment':
instruction = 'Apply antiseptic to treat infections';
break;
case 'bandaging':
instruction = 'Apply bandage to complete the treatment';
break;
case 'complete':
instruction = 'Treatment complete! Patient is healed.';
break;
}
instructionText.setText(instruction);
}
function checkPhaseProgression() {
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
// Move to next available phase based on what exists
if (totalDebris > 0) {
currentPhase = 'cleaning';
} else if (totalInfectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (totalInfections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
updateInstructions();
return;
}
function updateComfortBar() {
var comfortWidth = patientComfort / 100 * 400;
comfortBar.width = comfortWidth;
if (patientComfort > 70) {
comfortBar.tint = 0x27ae60;
} else if (patientComfort > 40) {
comfortBar.tint = 0xf39c12;
} else {
comfortBar.tint = 0xe74c3c;
}
comfortText.setText('Patient Comfort: ' + Math.round(patientComfort) + '%');
}
// Handle toe click for anesthesia and bandaging
toe.down = function (x, y, obj) {
if (!gameStarted) {
return;
}
if (currentPhase === 'anesthesia' && selectedTool === 'syringe' && !anesthesiaApplied) {
LK.getSound('injection').play();
LK.getSound('bleed').play();
// Create bleeding effect from syringe injection
var bloodDropsToCreate = 4;
for (var b = 0; b < bloodDropsToCreate; b++) {
var bloodDrop = new BloodDrop(x + (Math.random() - 0.5) * 100, y + (Math.random() - 0.5) * 100, false);
game.addChild(bloodDrop);
tween(bloodDrop, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0.9
}, {
duration: 1000
});
}
// Create injection site visual effect
var injectionSite = game.addChild(LK.getAsset('sterilizedIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 0.3,
scaleY: 0.3
}));
injectionSite.tint = 0x87ceeb;
// Fade out injection site
tween(injectionSite, {
alpha: 0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 3000,
onFinish: function onFinish() {
injectionSite.destroy();
}
});
anesthesiaApplied = true;
currentPhase = 'surgery';
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
patientComfort = Math.min(100, patientComfort + 20);
updateComfortBar();
updateInstructions();
LK.setScore(LK.getScore() + 20);
scoreText.setText('Score: ' + LK.getScore());
// Visual feedback for anesthesia
LK.effects.flashObject(toe, 0x87ceeb, 1000);
}
if (currentPhase === 'bandaging' && selectedTool === 'bandage' && !bandageApplied) {
LK.getSound('bandageApply').play();
// Multi-stage bandaging process
bandageApplied = true;
// First, apply antiseptic pad
var antisepticPad = game.addChild(LK.getAsset('antiseptic', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1150,
scaleX: 0.8,
scaleY: 0.8
}));
antisepticPad.alpha = 0.6;
// Then wrap with bandage
LK.setTimeout(function () {
var bandageVisual = game.addChild(LK.getAsset('bandage', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1150
}));
bandageVisual.alpha = 0.9;
// Bandage wrapping animation
bandageVisual.scaleX = 0.1;
tween(bandageVisual, {
scaleX: 1.0
}, {
duration: 1000
});
}, 500);
// Add pressure and healing bonus
patientComfort = Math.min(100, patientComfort + 15);
updateComfortBar();
currentPhase = 'complete';
updateInstructions();
completeLevel();
}
};
function completeLevel() {
// Calculate final score based on patient comfort, efficiency, and level difficulty
var comfortBonus = Math.round(patientComfort * 2 * currentPatient.timeBonus);
var levelBonus = Math.round(100 * currentLevel * currentPatient.timeBonus);
LK.setScore(LK.getScore() + comfortBonus + levelBonus);
scoreText.setText('Score: ' + LK.getScore());
// Flash screen green for success
LK.effects.flashScreen(0x27ae60, 1500);
// Check if this was the final level
if (currentLevel >= 10) {
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
} else {
// Show level complete and prepare next level
LK.setTimeout(function () {
nextLevel();
}, 3000);
}
}
function nextLevel() {
currentLevel++;
levelText.setText('Level: ' + currentLevel);
// Check if we've completed all 10 levels
if (currentLevel > 10) {
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
return;
}
// Get the configuration for the current level
currentPatient = levelConfigs[currentLevel - 1];
// Update patient type display
patientTypeText.setText(currentPatient.name);
patientTypeText.tint = currentPatient.color;
// Visual feedback for patient change
LK.effects.flashObject(patientTypeText, currentPatient.color, 1000);
// Reset game state
resetGame();
startGame();
}
function resetGame() {
// Reset counters
ingrownPartsRemoved = 0;
debrisRemoved = 0;
infectedMaterialRemoved = 0;
infectionsHealed = 0;
anesthesiaApplied = false;
bandageApplied = false;
// Reset patient comfort to level-specific base comfort
patientComfort = currentPatient.baseComfort;
updateComfortBar();
// Set starting phase based on what exists in this level
if (currentPatient.requiredTools.indexOf('syringe') !== -1) {
currentPhase = 'anesthesia';
} else if (currentPatient.ingrownParts > 0) {
currentPhase = 'surgery';
} else if (currentPatient.debris > 0) {
currentPhase = 'cleaning';
} else if (currentPatient.infectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (currentPatient.infections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
selectedTool = null;
// Clear old game objects
for (var i = 0; i < ingrownParts.length; i++) {
ingrownParts[i].destroy();
}
for (var i = 0; i < debrisPieces.length; i++) {
debrisPieces[i].destroy();
}
for (var i = 0; i < infectedMaterialPieces.length; i++) {
infectedMaterialPieces[i].destroy();
}
for (var i = 0; i < infections.length; i++) {
infections[i].destroy();
}
// Remove bandage from previous level if it exists
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
// Check if child has bandage asset properties
if (child.width === 120 && child.height === 80 && child.x === 1024 && child.y === 1150) {
child.destroy();
}
}
ingrownParts = [];
debrisPieces = [];
infectedMaterialPieces = [];
infections = [];
// Reset tool selection and show/hide tools based on level requirements
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
// Show only required tools for current level
if (currentPatient.requiredTools.indexOf(tools[i].toolType) !== -1) {
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.alpha = 0.6;
tools[i].toolBackground.tint = 0x3498db;
}
} else {
tools[i].getChildAt(0).alpha = 0.2;
if (tools[i].toolBackground) {
tools[i].toolBackground.alpha = 0.2;
tools[i].toolBackground.tint = 0x7f8c8d;
}
}
}
}
// Global drag handlers
game.move = function (x, y, obj) {
if (draggedPiece) {
draggedPiece.x = x;
draggedPiece.y = y;
// Check if over trash tray
if (trashTray && Math.abs(draggedPiece.x - trashTray.x) < 150 && Math.abs(draggedPiece.y - trashTray.y) < 100) {
trashTray.highlightTray();
} else if (trashTray) {
trashTray.unhighlightTray();
}
}
};
game.up = function (x, y, obj) {
if (draggedPiece && trashTray) {
// Check if piece is dropped on trash tray
if (Math.abs(draggedPiece.x - trashTray.x) < 150 && Math.abs(draggedPiece.y - trashTray.y) < 100) {
// Successfully disposed
trashTray.disposePiece(draggedPiece);
trashTray.unhighlightTray();
// Check which type of piece was disposed
var isDebris = false;
var isInfectedMaterial = false;
// Check if draggedPiece is in debris array
for (var d = 0; d < debrisPieces.length; d++) {
if (debrisPieces[d] === draggedPiece) {
isDebris = true;
break;
}
}
// Check if draggedPiece is in infected material array
for (var m = 0; m < infectedMaterialPieces.length; m++) {
if (infectedMaterialPieces[m] === draggedPiece) {
isInfectedMaterial = true;
break;
}
}
if (isDebris) {
debrisRemoved++;
// Check if all debris removed
if (debrisRemoved >= totalDebris) {
// Move to next available phase based on what exists
if (totalInfectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (totalInfections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
updateInstructions();
}
LK.setScore(LK.getScore() + 5);
} else if (isInfectedMaterial) {
infectedMaterialRemoved++;
patientComfort = Math.min(100, patientComfort + 5);
updateComfortBar();
// Check if all infected material removed
if (infectedMaterialRemoved >= totalInfectedMaterial) {
// Move to next available phase based on what exists
if (totalInfections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
updateInstructions();
}
LK.setScore(LK.getScore() + 8);
}
scoreText.setText('Score: ' + LK.getScore());
} else {
// Return piece to original position
tween(draggedPiece, {
x: draggedPiece.originalX,
y: draggedPiece.originalY,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300
});
draggedPiece.getChildAt(0).tint = 0xffffff;
draggedPiece.pickedUp = false;
}
draggedPiece = null;
}
};
game.update = function () {
// Gradually decrease patient comfort over time if surgery is taking too long
if (gameStarted && currentPhase !== 'complete' && LK.ticks % 300 === 0) {
patientComfort = Math.max(0, patientComfort - currentPatient.comfortDecayRate);
updateComfortBar();
// Game over if patient comfort drops too low
if (patientComfort <= 0) {
LK.effects.flashScreen(0xe74c3c, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
// Update vital signs monitoring
if (gameStarted && vitalSigns) {
vitalSigns.updateVitals(patientComfort);
// Play heartbeat sound based on heart rate
var heartbeatInterval = Math.max(30, 90 - vitalSigns.heartRate);
if (LK.ticks - lastHeartbeatTime > heartbeatInterval) {
if (vitalSigns.isStressed) {
LK.getSound('heartbeat').play();
}
lastHeartbeatTime = LK.ticks;
}
}
// Clean up expired blood drops
for (var i = bloodDropsActive.length - 1; i >= 0; i--) {
if (bloodDropsActive[i].alpha <= 0.1) {
bloodDropsActive.splice(i, 1);
}
}
// Add realistic tool contamination over time
if (gameStarted && LK.ticks % 1800 === 0) {
// Every 30 seconds
for (var t = 0; t < tools.length; t++) {
if (tools[t].usageCount > 0 && Math.random() < 0.3) {
tools[t].markUsed(); // Gradual contamination
}
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BloodDrop = Container.expand(function (x, y, isPersistent) {
var self = Container.call(this);
var bloodGraphics = self.attachAsset('bloodDrop', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.alpha = 1.0;
self.isPersistent = isPersistent || false;
self.pulsing = false;
if (self.isPersistent) {
// Persistent blood that requires hemostat - much larger and more prominent
bloodGraphics.tint = 0xcc0000; // Brighter red for visibility
tween(self, {
scaleX: 4.5,
scaleY: 4.5
}, {
duration: 800
});
// Start more dramatic pulsing animation to draw attention
self.startPulsing = function () {
if (!self.pulsing) {
self.pulsing = true;
tween(self, {
scaleX: 5.5,
scaleY: 5.5,
alpha: 0.9
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.pulsing) {
tween(self, {
scaleX: 4.0,
scaleY: 4.0,
alpha: 1.0
}, {
duration: 600,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (self.pulsing) {
self.startPulsing();
}
}
});
}
}
});
}
};
self.startPulsing();
} else {
// Regular blood drop - animate and fade but more visible
tween(self, {
scaleX: 2.0,
scaleY: 2.0,
alpha: 0.4
}, {
duration: 3000,
onFinish: function onFinish() {
self.destroy();
}
});
}
return self;
});
var Debris = Container.expand(function (x, y) {
var self = Container.call(this);
self.removed = false;
self.pickedUp = false;
self.originalX = x;
self.originalY = y;
var debrisGraphics = self.attachAsset('debris', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'cleaning' || selectedTool !== 'tweezers' || self.removed) {
return;
}
if (!self.pickedUp) {
LK.getSound('click').play();
self.pickedUp = true;
draggedPiece = self;
// Visual feedback for pickup
tween(debrisGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
debrisGraphics.tint = 0x27ae60;
}
};
return self;
});
var InfectedMaterial = Container.expand(function (x, y) {
var self = Container.call(this);
self.removed = false;
self.pickedUp = false;
self.originalX = x;
self.originalY = y;
var materialGraphics = self.attachAsset('infectedMaterial', {
anchorX: 0.5,
anchorY: 0.5
});
// Infected material is already very dark brown and larger
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'infected_removal' || selectedTool !== 'infectedScalpel' || self.removed) {
return;
}
if (!self.pickedUp) {
LK.getSound('click').play();
self.pickedUp = true;
draggedPiece = self;
// Visual feedback for pickup
tween(materialGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200
});
materialGraphics.tint = 0x27ae60;
}
};
return self;
});
var Infection = Container.expand(function (x, y) {
var self = Container.call(this);
self.treated = false;
var infectionGraphics = self.attachAsset('infection', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'treatment' || selectedTool !== 'antiseptic' || self.treated) {
return;
}
LK.getSound('healing').play();
// Treat infection
self.treated = true;
infectionGraphics.alpha = 0.2;
infectionGraphics.tint = 0x90ee90;
infectionsHealed++;
patientComfort = Math.min(100, patientComfort + 10);
updateComfortBar();
// Check if all infections treated
if (infectionsHealed >= totalInfections) {
currentPhase = 'bandaging';
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
updateInstructions();
}
LK.setScore(LK.getScore() + 15);
scoreText.setText('Score: ' + LK.getScore());
};
return self;
});
var IngrownPart = Container.expand(function (x, y) {
var self = Container.call(this);
self.removed = false;
var partGraphics = self.attachAsset('ingrownPart', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'surgery' || selectedTool !== 'scalpel' || self.removed) {
return;
}
// Check if tool is sterile
var selectedToolObj = null;
for (var t = 0; t < tools.length; t++) {
if (tools[t].toolType === 'scalpel' && tools[t].selected) {
selectedToolObj = tools[t];
break;
}
}
if (selectedToolObj && !selectedToolObj.sterile) {
// Non-sterile tool increases infection risk
patientComfort = Math.max(0, patientComfort - 15);
updateComfortBar();
LK.effects.flashObject(self, 0xff4444, 500);
return;
}
LK.getSound('cut').play();
LK.getSound('bleed').play();
// Create bleeding effect
var bloodDropsToCreate = 4;
for (var b = 0; b < bloodDropsToCreate; b++) {
var bloodDrop = new BloodDrop(self.x + (Math.random() - 0.5) * 80, self.y + (Math.random() - 0.5) * 80, false);
game.addChild(bloodDrop);
}
// Remove ingrown part
self.removed = true;
partGraphics.alpha = 0;
ingrownPartsRemoved++;
// More realistic comfort loss
var comfortLoss = selectedToolObj && selectedToolObj.sterile ? 3 : 8;
patientComfort = Math.max(0, patientComfort - comfortLoss);
updateComfortBar();
// Mark tool as used
if (selectedToolObj) {
selectedToolObj.markUsed();
}
// Update vital signs
if (vitalSigns) {
vitalSigns.updateVitals(patientComfort);
}
// Check if all ingrown parts removed
if (ingrownPartsRemoved >= totalIngrownParts) {
checkPhaseProgression();
}
LK.setScore(LK.getScore() + 10);
scoreText.setText('Score: ' + LK.getScore());
};
return self;
});
var Tool = Container.expand(function (toolType, x, y) {
var self = Container.call(this);
self.toolType = toolType;
self.selected = false;
self.toolBackground = null; // Will be set when tool is created
self.sterile = true; // All tools start sterile
self.usageCount = 0;
var toolGraphics = self.attachAsset(toolType, {
anchorX: 0.5,
anchorY: 0.5
});
// Add sterilization indicator
self.sterilIndicator = self.attachAsset('sterilizedIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: 25,
y: -25,
scaleX: 0.5,
scaleY: 0.5
});
self.x = x;
self.y = y;
self.markUsed = function () {
self.usageCount++;
if (self.usageCount > 2) {
self.sterile = false;
self.sterilIndicator.tint = 0xff4444;
toolGraphics.tint = 0xdddddd;
}
};
self.sterilizeTool = function () {
if (!self.sterile) {
LK.getSound('sterilize').play();
self.sterile = true;
self.usageCount = 0;
self.sterilIndicator.tint = 0x00ff00;
toolGraphics.tint = 0xffffff;
// Visual sterilization effect
tween(self.sterilIndicator, {
scaleX: 1.0,
scaleY: 1.0,
alpha: 1.0
}, {
duration: 500,
onFinish: function onFinish() {
tween(self.sterilIndicator, {
scaleX: 0.5,
scaleY: 0.5,
alpha: 0.7
}, {
duration: 300
});
}
});
}
};
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase === 'complete') {
return;
}
LK.getSound('click').play();
// Deselect all tools
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
// Reset background color
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
// Select this tool
self.selected = true;
toolGraphics.alpha = 1.0;
selectedTool = self.toolType;
// Highlight background
if (self.toolBackground) {
self.toolBackground.tint = 0x27ae60;
self.toolBackground.alpha = 0.9;
}
// Update selected tool name display
var toolIndex = toolTypes.indexOf(self.toolType);
if (toolIndex !== -1 && selectedToolText) {
selectedToolText.setText('Selected: ' + toolNames[toolIndex]);
selectedToolText.alpha = 1;
}
updateInstructions();
};
return self;
});
var TrashTray = Container.expand(function (x, y) {
var self = Container.call(this);
var trayGraphics = self.attachAsset('trashTray', {
anchorX: 0.5,
anchorY: 0.5
});
var canGraphics = self.attachAsset('trashCan', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: -50
});
self.x = x;
self.y = y;
// Visual feedback when pieces are dragged over
self.highlightTray = function () {
trayGraphics.tint = 0x27ae60;
tween(trayGraphics, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200
});
};
self.unhighlightTray = function () {
trayGraphics.tint = 0xffffff;
tween(trayGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200
});
};
self.disposePiece = function (piece) {
// Animate piece falling into trash can
tween(piece, {
x: self.x,
y: self.y - 50,
scaleX: 0.3,
scaleY: 0.3,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
piece.destroy();
}
});
};
return self;
});
var VitalSigns = Container.expand(function (x, y) {
var self = Container.call(this);
self.heartRate = 70 + Math.random() * 20; // 70-90 BPM normal
self.bloodPressure = 120;
self.isStressed = false;
var heartRateBar = self.attachAsset('vitalSign', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
var bpBar = self.attachAsset('vitalSign', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 40
});
self.x = x;
self.y = y;
self.updateVitals = function (comfort) {
// Heart rate increases when patient is uncomfortable
var targetHeartRate = 70 + (100 - comfort) * 0.5;
self.heartRate = self.heartRate * 0.9 + targetHeartRate * 0.1;
// Update visual indicators
if (self.heartRate > 100) {
heartRateBar.tint = 0xff4444;
self.isStressed = true;
} else if (self.heartRate > 85) {
heartRateBar.tint = 0xffaa44;
self.isStressed = false;
} else {
heartRateBar.tint = 0x44ff44;
self.isStressed = false;
}
// Scale bars based on values
heartRateBar.scaleX = Math.min(1.5, self.heartRate / 100);
bpBar.scaleX = Math.min(1.2, self.bloodPressure / 140);
};
return self;
});
var Wound = Container.expand(function (x, y) {
var self = Container.call(this);
self.healed = false;
self.persistentBlood = [];
var woundGraphics = self.attachAsset('bloodDrop', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.0,
scaleY: 2.0
});
self.x = x;
self.y = y;
// Create persistent blood drops around the wound
for (var i = 0; i < 3; i++) {
var bloodX = x + (Math.random() - 0.5) * 80;
var bloodY = y + (Math.random() - 0.5) * 80;
var persistentBlood = new BloodDrop(bloodX, bloodY, true);
self.persistentBlood.push(persistentBlood);
game.addChild(persistentBlood);
}
// Pulsing animation to show active bleeding
tween(woundGraphics, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0.8
}, {
duration: 1000,
loop: true,
yoyo: true
});
self.down = function (x, y, obj) {
if (!gameStarted || currentPhase !== 'wound_patching' || selectedTool !== 'hemostat' || self.healed) {
return;
}
LK.getSound('patch').play();
// Heal the wound
self.healed = true;
woundGraphics.tint = 0x90ee90;
woundGraphics.alpha = 0.3;
woundsToHeal--;
// Remove persistent blood drops
for (var i = 0; i < self.persistentBlood.length; i++) {
var blood = self.persistentBlood[i];
blood.pulsing = false;
tween(blood, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 1000,
onFinish: function onFinish() {
blood.destroy();
}
});
}
// Restore some patient comfort
patientComfort = Math.min(100, patientComfort + 8);
updateComfortBar();
// Visual healing effect
tween(self, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 2000,
onFinish: function onFinish() {
self.destroy();
}
});
// Check if all wounds are healed
if (woundsToHeal <= 0) {
excessiveStabbing = false;
// Continue with normal phase progression
checkPhaseProgression();
}
LK.setScore(LK.getScore() + 12);
scoreText.setText('Score: ' + LK.getScore());
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xe8f4f8
});
/****
* Game Code
****/
// Game state variables
var gameState = 'title'; // title, tutorial, playing
var gameStarted = false;
var currentPhase = 'assessment'; // assessment, anesthesia, surgery, cleaning, infected_removal, treatment, bandaging, complete
var currentLevel = 1;
var patientComfort = 100;
var selectedTool = null;
var tutorialStep = 0;
var maxTutorialSteps = 7;
// Medical realism variables
var vitalSigns = null;
var sterilizationStation = null;
var bloodDropsActive = [];
var lastHeartbeatTime = 0;
var woundCount = 0;
var excessiveStabbing = false;
var woundsToHeal = 0;
// 10-Level progression system
var levelConfigs = [{
level: 1,
name: "Level 1 - Basic",
color: 0x27ae60,
comfortDecayRate: 0.2,
baseComfort: 100,
toolTolerance: 1.0,
ingrownParts: 1,
debris: 0,
infectedMaterial: 0,
infections: 0,
timeBonus: 2.0,
requiredTools: ['scalpel', 'bandage']
}, {
level: 2,
name: "Level 2 - Anesthesia",
color: 0x2ecc71,
comfortDecayRate: 0.3,
baseComfort: 95,
toolTolerance: 0.9,
ingrownParts: 1,
debris: 0,
infectedMaterial: 0,
infections: 0,
timeBonus: 1.9,
requiredTools: ['syringe', 'scalpel', 'bandage']
}, {
level: 3,
name: "Level 3 - Debris Cleaning",
color: 0x3498db,
comfortDecayRate: 0.4,
baseComfort: 90,
toolTolerance: 0.8,
ingrownParts: 1,
debris: 2,
infectedMaterial: 0,
infections: 0,
timeBonus: 1.8,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'bandage']
}, {
level: 4,
name: "Level 4 - Infected Material",
color: 0x9b59b6,
comfortDecayRate: 0.5,
baseComfort: 85,
toolTolerance: 0.7,
ingrownParts: 1,
debris: 1,
infectedMaterial: 1,
infections: 0,
timeBonus: 1.7,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'bandage']
}, {
level: 5,
name: "Level 5 - Infection Treatment",
color: 0xf39c12,
comfortDecayRate: 0.6,
baseComfort: 80,
toolTolerance: 0.6,
ingrownParts: 1,
debris: 1,
infectedMaterial: 1,
infections: 1,
timeBonus: 1.6,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 6,
name: "Level 6 - Multiple Issues",
color: 0xe67e22,
comfortDecayRate: 0.8,
baseComfort: 75,
toolTolerance: 0.5,
ingrownParts: 2,
debris: 2,
infectedMaterial: 1,
infections: 1,
timeBonus: 1.5,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 7,
name: "Level 7 - Complex Case",
color: 0xe74c3c,
comfortDecayRate: 1.0,
baseComfort: 70,
toolTolerance: 0.5,
ingrownParts: 2,
debris: 3,
infectedMaterial: 2,
infections: 1,
timeBonus: 1.4,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 8,
name: "Level 8 - Advanced",
color: 0xc0392b,
comfortDecayRate: 1.2,
baseComfort: 65,
toolTolerance: 0.4,
ingrownParts: 3,
debris: 3,
infectedMaterial: 2,
infections: 2,
timeBonus: 1.3,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 9,
name: "Level 9 - Challenging",
color: 0x8e44ad,
comfortDecayRate: 1.4,
baseComfort: 60,
toolTolerance: 0.4,
ingrownParts: 3,
debris: 4,
infectedMaterial: 3,
infections: 2,
timeBonus: 1.2,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}, {
level: 10,
name: "Level 10 - Master Surgeon",
color: 0x2c3e50,
comfortDecayRate: 1.6,
baseComfort: 55,
toolTolerance: 0.3,
ingrownParts: 4,
debris: 4,
infectedMaterial: 3,
infections: 3,
timeBonus: 1.1,
requiredTools: ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage']
}];
var currentPatient = levelConfigs[0];
// Game objects
var tools = [];
var ingrownParts = [];
var debrisPieces = [];
var infectedMaterialPieces = [];
var infections = [];
// Counters
var ingrownPartsRemoved = 0;
var totalIngrownParts = 3;
var debrisRemoved = 0;
var totalDebris = 5;
var infectedMaterialRemoved = 0;
var totalInfectedMaterial = 3;
var infectionsHealed = 0;
var totalInfections = 2;
var anesthesiaApplied = false;
var bandageApplied = false;
// Trash tray system
var trashTray = null;
var draggedPiece = null;
// Create patient's toe
var toe = game.addChild(LK.getAsset('toeBackground', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
toe.alpha = 0; // Hidden initially
var toenail = game.addChild(LK.getAsset('toenail', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1150
}));
toenail.alpha = 0; // Hidden initially
// Create title screen elements
var titleText = new Text2('NAIL DOCTOR', {
size: 120,
fill: 0x2C3E50
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
game.addChild(titleText);
var subtitleText = new Text2('Ingrown Toenail Surgery Simulator', {
size: 60,
fill: 0x7F8C8D
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 900;
game.addChild(subtitleText);
var playButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200,
scaleX: 1.2,
scaleY: 0.8
}));
playButton.tint = 0x27ae60;
var playButtonText = new Text2('START GAME', {
size: 60,
fill: 0xFFFFFF
});
playButtonText.anchor.set(0.5, 0.5);
playButtonText.x = 1024;
playButtonText.y = 1200;
game.addChild(playButtonText);
var tutorialButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400,
scaleX: 1.2,
scaleY: 0.8
}));
tutorialButton.tint = 0x3498db;
var tutorialButtonText = new Text2('HOW TO PLAY', {
size: 60,
fill: 0xFFFFFF
});
tutorialButtonText.anchor.set(0.5, 0.5);
tutorialButtonText.x = 1024;
tutorialButtonText.y = 1400;
game.addChild(tutorialButtonText);
// Create UI elements
var instructionText = new Text2('Examine the patient and assess the ingrown toenail severity', {
size: 60,
fill: 0x2C3E50
});
instructionText.anchor.set(0.5, 0);
instructionText.x = 1024;
instructionText.y = 100;
instructionText.alpha = 0; // Hidden initially
game.addChild(instructionText);
var scoreText = new Text2('Score: 0', {
size: 50,
fill: 0x27AE60
});
scoreText.anchor.set(0, 0);
scoreText.x = 100;
scoreText.y = 200;
scoreText.alpha = 0; // Hidden initially
game.addChild(scoreText);
var levelText = new Text2('Level: 1', {
size: 50,
fill: 0x2980B9
});
levelText.anchor.set(1, 0);
levelText.x = 1948;
levelText.y = 200;
levelText.alpha = 0; // Hidden initially
game.addChild(levelText);
// Patient type indicator
var patientTypeText = new Text2('Easy Patient', {
size: 45,
fill: 0x27ae60
});
patientTypeText.anchor.set(0.5, 0);
patientTypeText.x = 1024;
patientTypeText.y = 250;
patientTypeText.alpha = 0; // Hidden initially
game.addChild(patientTypeText);
// Patient comfort bar
var comfortBarBg = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0,
x: 1024,
y: 300,
scaleX: 1.3,
scaleY: 0.3
}));
comfortBarBg.tint = 0x34495e;
comfortBarBg.alpha = 0; // Hidden initially
var comfortBar = game.addChild(LK.getAsset('patientComfortBar', {
anchorX: 0,
anchorY: 0,
x: 824,
y: 300
}));
comfortBar.alpha = 0; // Hidden initially
var comfortText = new Text2('Patient Comfort: 100%', {
size: 40,
fill: 0xFFFFFF
});
comfortText.anchor.set(0.5, 0.5);
comfortText.x = 1024;
comfortText.y = 320;
comfortText.alpha = 0; // Hidden initially
game.addChild(comfortText);
// Create tool selection area
var toolY = 2200;
var toolSpacing = 320;
var startX = 200;
// Tool names for UI labels
var toolNames = ['Anesthesia Syringe', 'Surgical Scalpel', 'Cleaning Tweezers', 'Infected Material Scalpel', 'Antiseptic Spray', 'Medical Bandage'];
var toolDescriptions = ['Apply anesthesia', 'Remove ingrown parts', 'Clean debris', 'Remove infected material', 'Treat infections', 'Apply bandage'];
// Selected tool name display
var selectedToolText = new Text2('', {
size: 70,
fill: 0x27AE60
});
selectedToolText.anchor.set(0.5, 0);
selectedToolText.x = 1024;
selectedToolText.y = 2000;
selectedToolText.alpha = 0; // Hidden initially
game.addChild(selectedToolText);
// Create tools with UI elements
var toolTypes = ['syringe', 'scalpel', 'tweezers', 'infectedScalpel', 'antiseptic', 'bandage'];
for (var i = 0; i < toolTypes.length; i++) {
var toolX = startX + i * toolSpacing;
var toolYPos = toolY;
// Create tool background button
var toolBg = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: toolX,
y: toolYPos,
scaleX: 0.8,
scaleY: 1.2
}));
toolBg.tint = 0x3498db;
toolBg.alpha = 0; // Hidden initially
// Create the actual tool
var tool = new Tool(toolTypes[i], toolX, toolYPos - 30);
tool.getChildAt(0).alpha = 0; // Hidden initially
tool.toolBackground = toolBg; // Store reference to background
tools.push(tool);
game.addChild(tool);
// Create tool name label
var toolLabel = new Text2(toolNames[i], {
size: 40,
fill: 0xFFFFFF
});
toolLabel.anchor.set(0.5, 0.5);
toolLabel.x = toolX;
toolLabel.y = toolYPos + 50;
toolLabel.alpha = 0; // Hidden initially
game.addChild(toolLabel);
// Create tool description
var toolDesc = new Text2(toolDescriptions[i], {
size: 30,
fill: 0xBDC3C7
});
toolDesc.anchor.set(0.5, 0.5);
toolDesc.x = toolX;
toolDesc.y = toolYPos + 90;
toolDesc.alpha = 0; // Hidden initially
game.addChild(toolDesc);
}
// Title screen button handlers
playButton.down = function (x, y, obj) {
if (gameState === 'title') {
showGameUI();
gameState = 'playing';
}
};
tutorialButton.down = function (x, y, obj) {
if (gameState === 'title') {
showTutorial();
gameState = 'tutorial';
}
};
// Tutorial elements
var tutorialText = new Text2('', {
size: 50,
fill: 0x2C3E50
});
tutorialText.anchor.set(0.5, 0.5);
tutorialText.x = 1024;
tutorialText.y = 400;
tutorialText.alpha = 0; // Hidden initially
game.addChild(tutorialText);
var tutorialNextButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1800,
scaleX: 1.0,
scaleY: 0.6
}));
tutorialNextButton.tint = 0x3498db;
tutorialNextButton.alpha = 0; // Hidden initially
var tutorialNextText = new Text2('NEXT', {
size: 50,
fill: 0xFFFFFF
});
tutorialNextText.anchor.set(0.5, 0.5);
tutorialNextText.x = 1024;
tutorialNextText.y = 1800;
tutorialNextText.alpha = 0; // Hidden initially
game.addChild(tutorialNextText);
var tutorialBackButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 824,
y: 1800,
scaleX: 1.0,
scaleY: 0.6
}));
tutorialBackButton.tint = 0x95a5a6;
tutorialBackButton.alpha = 0; // Hidden initially
var tutorialBackText = new Text2('BACK', {
size: 50,
fill: 0xFFFFFF
});
tutorialBackText.anchor.set(0.5, 0.5);
tutorialBackText.x = 824;
tutorialBackText.y = 1800;
tutorialBackText.alpha = 0; // Hidden initially
game.addChild(tutorialBackText);
var tutorialSkipButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1224,
y: 1800,
scaleX: 1.0,
scaleY: 0.6
}));
tutorialSkipButton.tint = 0xe74c3c;
tutorialSkipButton.alpha = 0; // Hidden initially
var tutorialSkipText = new Text2('SKIP', {
size: 50,
fill: 0xFFFFFF
});
tutorialSkipText.anchor.set(0.5, 0.5);
tutorialSkipText.x = 1224;
tutorialSkipText.y = 1800;
tutorialSkipText.alpha = 0; // Hidden initially
game.addChild(tutorialSkipText);
// Tutorial button handlers
tutorialNextButton.down = function (x, y, obj) {
if (gameState === 'tutorial') {
tutorialStep++;
if (tutorialStep >= maxTutorialSteps) {
hideTutorial();
showGameUI();
gameState = 'playing';
} else {
updateTutorialContent();
}
}
};
tutorialBackButton.down = function (x, y, obj) {
if (gameState === 'tutorial' && tutorialStep > 0) {
tutorialStep--;
updateTutorialContent();
}
};
tutorialSkipButton.down = function (x, y, obj) {
if (gameState === 'tutorial') {
hideTutorial();
showGameUI();
gameState = 'playing';
}
};
// Start button
var startButton = game.addChild(LK.getAsset('toolButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1600,
scaleX: 1.5,
scaleY: 0.8
}));
startButton.tint = 0x27ae60;
startButton.alpha = 0; // Hidden initially
var startText = new Text2('Start Treatment', {
size: 60,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startText.x = 1024;
startText.y = 1600;
startText.alpha = 0; // Hidden initially
game.addChild(startText);
startButton.down = function (x, y, obj) {
if (!gameStarted && gameState === 'playing') {
startGame();
}
};
function hideTitleScreen() {
titleText.alpha = 0;
subtitleText.alpha = 0;
playButton.alpha = 0;
playButtonText.alpha = 0;
tutorialButton.alpha = 0;
tutorialButtonText.alpha = 0;
}
function showGameUI() {
hideTitleScreen();
hideTutorial();
// Show game UI elements
instructionText.alpha = 1;
scoreText.alpha = 1;
levelText.alpha = 1;
patientTypeText.alpha = 1;
comfortBarBg.alpha = 1;
comfortBar.alpha = 1;
comfortText.alpha = 1;
toe.alpha = 1;
toenail.alpha = 1;
startButton.alpha = 1;
startText.alpha = 1;
selectedToolText.alpha = 0; // Initially hidden until tool selected
// Show tools
for (var i = 0; i < tools.length; i++) {
tools[i].getChildAt(0).alpha = 0.7;
tools[i].toolBackground.alpha = 0.6;
}
// Show tool labels and descriptions
for (var i = 0; i < game.children.length; i++) {
var child = game.children[i];
if (child.getText) {
var text = child.getText();
if (text.indexOf('Anesthesia') === 0 || text.indexOf('Surgical') === 0 || text.indexOf('Cleaning') === 0 || text.indexOf('Infected') === 0 || text.indexOf('Antiseptic') === 0 || text.indexOf('Medical') === 0 || text.indexOf('Apply') === 0 || text.indexOf('Remove') === 0 || text.indexOf('Clean') === 0 || text.indexOf('Treat') === 0) {
child.alpha = 1;
}
}
}
// Create trash tray
if (!trashTray) {
trashTray = new TrashTray(1700, 1800);
game.addChild(trashTray);
}
// Create vital signs monitor
if (!vitalSigns) {
vitalSigns = new VitalSigns(100, 400);
game.addChild(vitalSigns);
}
// Create sterilization station
if (!sterilizationStation) {
sterilizationStation = game.addChild(LK.getAsset('antiseptic', {
anchorX: 0.5,
anchorY: 0.5,
x: 200,
y: 1600,
scaleX: 1.5,
scaleY: 1.5
}));
sterilizationStation.tint = 0x00ff88;
// Add sterilization label
var sterilLabel = new Text2('STERILIZE', {
size: 30,
fill: 0x00ff88
});
sterilLabel.anchor.set(0.5, 0.5);
sterilLabel.x = 200;
sterilLabel.y = 1700;
game.addChild(sterilLabel);
// Sterilization station click handler
sterilizationStation.down = function (x, y, obj) {
if (selectedTool) {
for (var t = 0; t < tools.length; t++) {
if (tools[t].selected) {
tools[t].sterilizeTool();
break;
}
}
}
};
}
}
function showTutorial() {
hideTitleScreen();
tutorialStep = 0;
tutorialText.alpha = 1;
tutorialNextButton.alpha = 1;
tutorialNextText.alpha = 1;
tutorialBackButton.alpha = 1;
tutorialBackText.alpha = 1;
tutorialSkipButton.alpha = 1;
tutorialSkipText.alpha = 1;
updateTutorialContent();
}
function hideTutorial() {
tutorialText.alpha = 0;
tutorialNextButton.alpha = 0;
tutorialNextText.alpha = 0;
tutorialBackButton.alpha = 0;
tutorialBackText.alpha = 0;
tutorialSkipButton.alpha = 0;
tutorialSkipText.alpha = 0;
selectedToolText.alpha = 0;
}
function updateTutorialContent() {
var content = '';
switch (tutorialStep) {
case 0:
content = 'Welcome to Nail Doctor!\nYou are a podiatrist treating ingrown toenails.';
break;
case 1:
content = 'Step 1: ANESTHESIA\nSelect the syringe and click the toe to numb the area\nbefore starting surgery.';
break;
case 2:
content = 'Step 2: SURGERY\nUse the scalpel to carefully remove the ingrown\nnail parts that are causing pain.';
break;
case 3:
content = 'Step 3: CLEANING\nUse tweezers to remove all debris pieces\nfrom the wound area.';
break;
case 4:
content = 'Step 4: INFECTED REMOVAL\nUse the infected material scalpel to remove\nred infected tissue pieces.';
break;
case 5:
content = 'Step 5: TREATMENT\nApply antiseptic to treat any remaining infections\nand prevent further complications.';
break;
case 6:
content = 'Step 6: BANDAGING\nFinally, apply a bandage to protect the treated area\nand complete the procedure. Good luck!';
break;
}
tutorialText.setText(content);
// Update button states
if (tutorialStep === 0) {
tutorialBackButton.alpha = 0.3;
tutorialBackText.alpha = 0.3;
} else {
tutorialBackButton.alpha = 1;
tutorialBackText.alpha = 1;
}
if (tutorialStep >= maxTutorialSteps - 1) {
tutorialNextText.setText('START');
} else {
tutorialNextText.setText('NEXT');
}
}
function startGame() {
gameStarted = true;
startButton.alpha = 0;
startText.alpha = 0;
// Determine starting phase based on what exists in this level
if (currentPatient.requiredTools.indexOf('syringe') !== -1) {
currentPhase = 'anesthesia';
} else if (currentPatient.ingrownParts > 0) {
currentPhase = 'surgery';
} else if (currentPatient.debris > 0) {
currentPhase = 'cleaning';
} else if (currentPatient.infectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (currentPatient.infections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
// Set patient-specific values
totalIngrownParts = currentPatient.ingrownParts;
totalDebris = currentPatient.debris;
totalInfectedMaterial = currentPatient.infectedMaterial;
totalInfections = currentPatient.infections;
patientComfort = currentPatient.baseComfort;
updateComfortBar();
// Only create ingrown nail parts if level has them
if (totalIngrownParts > 0) {
var ingrownPositions = [];
for (var ing = 0; ing < totalIngrownParts; ing++) {
ingrownPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < ingrownPositions.length; i++) {
var ingrownPart = new IngrownPart(ingrownPositions[i].x, ingrownPositions[i].y);
ingrownParts.push(ingrownPart);
game.addChild(ingrownPart);
}
}
// Only create debris pieces if level has them
if (totalDebris > 0) {
var debrisPositions = [];
for (var d = 0; d < totalDebris; d++) {
debrisPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < debrisPositions.length; i++) {
var debris = new Debris(debrisPositions[i].x, debrisPositions[i].y);
debrisPieces.push(debris);
game.addChild(debris);
}
}
// Only create infected material pieces if level has them
if (totalInfectedMaterial > 0) {
var infectedMaterialPositions = [];
for (var m = 0; m < totalInfectedMaterial; m++) {
infectedMaterialPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < infectedMaterialPositions.length; i++) {
var infectedMaterial = new InfectedMaterial(infectedMaterialPositions[i].x, infectedMaterialPositions[i].y);
infectedMaterialPieces.push(infectedMaterial);
game.addChild(infectedMaterial);
}
}
// Only create infections if level has them
if (totalInfections > 0) {
var infectionPositions = [];
for (var inf = 0; inf < totalInfections; inf++) {
infectionPositions.push({
x: 800 + Math.random() * 448,
// Random x within toe bounds (800-1248)
y: 1000 + Math.random() * 400 // Random y within toe bounds (1000-1400)
});
}
for (var i = 0; i < infectionPositions.length; i++) {
var infection = new Infection(infectionPositions[i].x, infectionPositions[i].y);
infections.push(infection);
game.addChild(infection);
}
}
updateInstructions();
}
function updateInstructions() {
var instruction = '';
switch (currentPhase) {
case 'anesthesia':
instruction = 'Select the syringe and apply anesthesia to numb the area';
break;
case 'surgery':
instruction = 'Use the scalpel to carefully remove ingrown nail parts';
break;
case 'cleaning':
instruction = 'Use tweezers to remove all debris pieces';
break;
case 'infected_removal':
instruction = 'Use infected material scalpel to remove red infected material';
break;
case 'treatment':
instruction = 'Apply antiseptic to treat infections';
break;
case 'bandaging':
instruction = 'Apply bandage to complete the treatment';
break;
case 'complete':
instruction = 'Treatment complete! Patient is healed.';
break;
}
instructionText.setText(instruction);
}
function checkPhaseProgression() {
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
// Move to next available phase based on what exists
if (totalDebris > 0) {
currentPhase = 'cleaning';
} else if (totalInfectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (totalInfections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
updateInstructions();
return;
}
function updateComfortBar() {
var comfortWidth = patientComfort / 100 * 400;
comfortBar.width = comfortWidth;
if (patientComfort > 70) {
comfortBar.tint = 0x27ae60;
} else if (patientComfort > 40) {
comfortBar.tint = 0xf39c12;
} else {
comfortBar.tint = 0xe74c3c;
}
comfortText.setText('Patient Comfort: ' + Math.round(patientComfort) + '%');
}
// Handle toe click for anesthesia and bandaging
toe.down = function (x, y, obj) {
if (!gameStarted) {
return;
}
if (currentPhase === 'anesthesia' && selectedTool === 'syringe' && !anesthesiaApplied) {
LK.getSound('injection').play();
LK.getSound('bleed').play();
// Create bleeding effect from syringe injection
var bloodDropsToCreate = 4;
for (var b = 0; b < bloodDropsToCreate; b++) {
var bloodDrop = new BloodDrop(x + (Math.random() - 0.5) * 100, y + (Math.random() - 0.5) * 100, false);
game.addChild(bloodDrop);
tween(bloodDrop, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0.9
}, {
duration: 1000
});
}
// Create injection site visual effect
var injectionSite = game.addChild(LK.getAsset('sterilizedIndicator', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
scaleX: 0.3,
scaleY: 0.3
}));
injectionSite.tint = 0x87ceeb;
// Fade out injection site
tween(injectionSite, {
alpha: 0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 3000,
onFinish: function onFinish() {
injectionSite.destroy();
}
});
anesthesiaApplied = true;
currentPhase = 'surgery';
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
patientComfort = Math.min(100, patientComfort + 20);
updateComfortBar();
updateInstructions();
LK.setScore(LK.getScore() + 20);
scoreText.setText('Score: ' + LK.getScore());
// Visual feedback for anesthesia
LK.effects.flashObject(toe, 0x87ceeb, 1000);
}
if (currentPhase === 'bandaging' && selectedTool === 'bandage' && !bandageApplied) {
LK.getSound('bandageApply').play();
// Multi-stage bandaging process
bandageApplied = true;
// First, apply antiseptic pad
var antisepticPad = game.addChild(LK.getAsset('antiseptic', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1150,
scaleX: 0.8,
scaleY: 0.8
}));
antisepticPad.alpha = 0.6;
// Then wrap with bandage
LK.setTimeout(function () {
var bandageVisual = game.addChild(LK.getAsset('bandage', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1150
}));
bandageVisual.alpha = 0.9;
// Bandage wrapping animation
bandageVisual.scaleX = 0.1;
tween(bandageVisual, {
scaleX: 1.0
}, {
duration: 1000
});
}, 500);
// Add pressure and healing bonus
patientComfort = Math.min(100, patientComfort + 15);
updateComfortBar();
currentPhase = 'complete';
updateInstructions();
completeLevel();
}
};
function completeLevel() {
// Calculate final score based on patient comfort, efficiency, and level difficulty
var comfortBonus = Math.round(patientComfort * 2 * currentPatient.timeBonus);
var levelBonus = Math.round(100 * currentLevel * currentPatient.timeBonus);
LK.setScore(LK.getScore() + comfortBonus + levelBonus);
scoreText.setText('Score: ' + LK.getScore());
// Flash screen green for success
LK.effects.flashScreen(0x27ae60, 1500);
// Check if this was the final level
if (currentLevel >= 10) {
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
} else {
// Show level complete and prepare next level
LK.setTimeout(function () {
nextLevel();
}, 3000);
}
}
function nextLevel() {
currentLevel++;
levelText.setText('Level: ' + currentLevel);
// Check if we've completed all 10 levels
if (currentLevel > 10) {
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
return;
}
// Get the configuration for the current level
currentPatient = levelConfigs[currentLevel - 1];
// Update patient type display
patientTypeText.setText(currentPatient.name);
patientTypeText.tint = currentPatient.color;
// Visual feedback for patient change
LK.effects.flashObject(patientTypeText, currentPatient.color, 1000);
// Reset game state
resetGame();
startGame();
}
function resetGame() {
// Reset counters
ingrownPartsRemoved = 0;
debrisRemoved = 0;
infectedMaterialRemoved = 0;
infectionsHealed = 0;
anesthesiaApplied = false;
bandageApplied = false;
// Reset patient comfort to level-specific base comfort
patientComfort = currentPatient.baseComfort;
updateComfortBar();
// Set starting phase based on what exists in this level
if (currentPatient.requiredTools.indexOf('syringe') !== -1) {
currentPhase = 'anesthesia';
} else if (currentPatient.ingrownParts > 0) {
currentPhase = 'surgery';
} else if (currentPatient.debris > 0) {
currentPhase = 'cleaning';
} else if (currentPatient.infectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (currentPatient.infections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
selectedTool = null;
// Clear old game objects
for (var i = 0; i < ingrownParts.length; i++) {
ingrownParts[i].destroy();
}
for (var i = 0; i < debrisPieces.length; i++) {
debrisPieces[i].destroy();
}
for (var i = 0; i < infectedMaterialPieces.length; i++) {
infectedMaterialPieces[i].destroy();
}
for (var i = 0; i < infections.length; i++) {
infections[i].destroy();
}
// Remove bandage from previous level if it exists
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
// Check if child has bandage asset properties
if (child.width === 120 && child.height === 80 && child.x === 1024 && child.y === 1150) {
child.destroy();
}
}
ingrownParts = [];
debrisPieces = [];
infectedMaterialPieces = [];
infections = [];
// Reset tool selection and show/hide tools based on level requirements
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
// Show only required tools for current level
if (currentPatient.requiredTools.indexOf(tools[i].toolType) !== -1) {
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.alpha = 0.6;
tools[i].toolBackground.tint = 0x3498db;
}
} else {
tools[i].getChildAt(0).alpha = 0.2;
if (tools[i].toolBackground) {
tools[i].toolBackground.alpha = 0.2;
tools[i].toolBackground.tint = 0x7f8c8d;
}
}
}
}
// Global drag handlers
game.move = function (x, y, obj) {
if (draggedPiece) {
draggedPiece.x = x;
draggedPiece.y = y;
// Check if over trash tray
if (trashTray && Math.abs(draggedPiece.x - trashTray.x) < 150 && Math.abs(draggedPiece.y - trashTray.y) < 100) {
trashTray.highlightTray();
} else if (trashTray) {
trashTray.unhighlightTray();
}
}
};
game.up = function (x, y, obj) {
if (draggedPiece && trashTray) {
// Check if piece is dropped on trash tray
if (Math.abs(draggedPiece.x - trashTray.x) < 150 && Math.abs(draggedPiece.y - trashTray.y) < 100) {
// Successfully disposed
trashTray.disposePiece(draggedPiece);
trashTray.unhighlightTray();
// Check which type of piece was disposed
var isDebris = false;
var isInfectedMaterial = false;
// Check if draggedPiece is in debris array
for (var d = 0; d < debrisPieces.length; d++) {
if (debrisPieces[d] === draggedPiece) {
isDebris = true;
break;
}
}
// Check if draggedPiece is in infected material array
for (var m = 0; m < infectedMaterialPieces.length; m++) {
if (infectedMaterialPieces[m] === draggedPiece) {
isInfectedMaterial = true;
break;
}
}
if (isDebris) {
debrisRemoved++;
// Check if all debris removed
if (debrisRemoved >= totalDebris) {
// Move to next available phase based on what exists
if (totalInfectedMaterial > 0) {
currentPhase = 'infected_removal';
} else if (totalInfections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
updateInstructions();
}
LK.setScore(LK.getScore() + 5);
} else if (isInfectedMaterial) {
infectedMaterialRemoved++;
patientComfort = Math.min(100, patientComfort + 5);
updateComfortBar();
// Check if all infected material removed
if (infectedMaterialRemoved >= totalInfectedMaterial) {
// Move to next available phase based on what exists
if (totalInfections > 0) {
currentPhase = 'treatment';
} else {
currentPhase = 'bandaging';
}
// Reset tool selection for next phase
selectedTool = null;
for (var i = 0; i < tools.length; i++) {
tools[i].selected = false;
tools[i].getChildAt(0).alpha = 0.7;
if (tools[i].toolBackground) {
tools[i].toolBackground.tint = 0x3498db;
tools[i].toolBackground.alpha = 0.6;
}
}
if (selectedToolText) {
selectedToolText.alpha = 0;
}
updateInstructions();
}
LK.setScore(LK.getScore() + 8);
}
scoreText.setText('Score: ' + LK.getScore());
} else {
// Return piece to original position
tween(draggedPiece, {
x: draggedPiece.originalX,
y: draggedPiece.originalY,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300
});
draggedPiece.getChildAt(0).tint = 0xffffff;
draggedPiece.pickedUp = false;
}
draggedPiece = null;
}
};
game.update = function () {
// Gradually decrease patient comfort over time if surgery is taking too long
if (gameStarted && currentPhase !== 'complete' && LK.ticks % 300 === 0) {
patientComfort = Math.max(0, patientComfort - currentPatient.comfortDecayRate);
updateComfortBar();
// Game over if patient comfort drops too low
if (patientComfort <= 0) {
LK.effects.flashScreen(0xe74c3c, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
// Update vital signs monitoring
if (gameStarted && vitalSigns) {
vitalSigns.updateVitals(patientComfort);
// Play heartbeat sound based on heart rate
var heartbeatInterval = Math.max(30, 90 - vitalSigns.heartRate);
if (LK.ticks - lastHeartbeatTime > heartbeatInterval) {
if (vitalSigns.isStressed) {
LK.getSound('heartbeat').play();
}
lastHeartbeatTime = LK.ticks;
}
}
// Clean up expired blood drops
for (var i = bloodDropsActive.length - 1; i >= 0; i--) {
if (bloodDropsActive[i].alpha <= 0.1) {
bloodDropsActive.splice(i, 1);
}
}
// Add realistic tool contamination over time
if (gameStarted && LK.ticks % 1800 === 0) {
// Every 30 seconds
for (var t = 0; t < tools.length; t++) {
if (tools[t].usageCount > 0 && Math.random() < 0.3) {
tools[t].markUsed(); // Gradual contamination
}
}
}
};