/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CaseManager = Container.expand(function () {
var self = Container.call(this);
self.cases = [{
id: 1,
title: "The Missing Necklace",
description: "A valuable necklace was stolen from Mrs. Henderson's jewelry box.",
suspects: [{
name: "SARAH (MAID)",
guilty: false,
responses: [{
text: "I cleaned the room yesterday morning as usual.",
emotion: "calm",
intensity: 0.2,
truthLevel: 1.0
}, {
text: "I never touched the jewelry box, I swear!",
emotion: "nervousness",
intensity: 0.6,
truthLevel: 1.0
}, {
text: "Maybe someone else had access to the room?",
emotion: "calm",
intensity: 0.1,
truthLevel: 0.8
}]
}, {
name: "DAVID (SON)",
guilty: true,
responses: [{
text: "I was at school all day, you can check.",
emotion: "nervousness",
intensity: 0.8,
truthLevel: 0.3
}, {
text: "Why would I steal from my own mother?",
emotion: "anger",
intensity: 0.7,
truthLevel: 0.5
}, {
text: "I... I needed money for something important.",
emotion: "fear",
intensity: 0.9,
truthLevel: 1.0
}]
}],
questions: ["Where were you yesterday morning?", "Did you see anything suspicious?", "Is there anything you're not telling me?"]
}, {
id: 2,
title: "Office Break-In",
description: "Someone broke into the law office and stole confidential files.",
suspects: [{
name: "MIKE (JANITOR)",
guilty: true,
responses: [{
text: "I work late shifts, but I didn't see anything.",
emotion: "nervousness",
intensity: 0.7,
truthLevel: 0.4
}, {
text: "Those lawyers have many enemies, could be anyone.",
emotion: "calm",
intensity: 0.2,
truthLevel: 0.8
}, {
text: "Okay, okay! Someone paid me to get those files!",
emotion: "fear",
intensity: 1.0,
truthLevel: 1.0
}]
}, {
name: "LISA (SECRETARY)",
guilty: false,
responses: [{
text: "I left at 6 PM sharp, like always.",
emotion: "calm",
intensity: 0.1,
truthLevel: 1.0
}, {
text: "The security system was working when I left.",
emotion: "calm",
intensity: 0.2,
truthLevel: 1.0
}, {
text: "Check the cameras, they'll prove I'm innocent.",
emotion: "nervousness",
intensity: 0.4,
truthLevel: 1.0
}]
}],
questions: ["What time did you leave the office?", "Did you notice anything unusual?", "Tell me the truth about what happened."]
}];
self.currentCase = null;
self.currentSuspectIndex = 0;
self.evidence = [];
self.completedCases = storage.completedCases || 0;
self.startCase = function (caseId) {
self.currentCase = self.cases.find(function (c) {
return c.id === caseId;
});
self.currentSuspectIndex = 0;
self.evidence = [];
};
self.getCurrentSuspect = function () {
if (self.currentCase && self.currentSuspectIndex < self.currentCase.suspects.length) {
return self.currentCase.suspects[self.currentSuspectIndex];
}
return null;
};
self.nextSuspect = function () {
self.currentSuspectIndex++;
return self.currentSuspectIndex < self.currentCase.suspects.length;
};
self.addEvidence = function (evidence) {
self.evidence.push(evidence);
};
self.completeCase = function () {
self.completedCases++;
storage.completedCases = self.completedCases;
LK.getSound('caseComplete').play();
};
return self;
});
var EmotionIndicator = Container.expand(function (emotion, intensity) {
var self = Container.call(this);
var indicator = self.attachAsset('emotionIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
var emotionColors = {
fear: 0xFF6B6B,
anger: 0xFF0000,
nervousness: 0xFFD93D,
calm: 0x6BCF7F
};
indicator.tint = emotionColors[emotion] || 0xFF6B6B;
indicator.alpha = intensity;
var emotionText = new Text2(emotion.toUpperCase(), {
size: 24,
fill: 0xFFFFFF
});
emotionText.anchor.set(0.5, 0.5);
emotionText.y = 60;
self.addChild(emotionText);
self.pulse = function () {
tween(indicator, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(indicator, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeIn
});
}
});
};
return self;
});
var QuestionButton = Container.expand(function (text, callback) {
var self = Container.call(this);
var buttonBg = self.attachAsset('questionButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(text, {
size: 36,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.callback = callback;
self.isActive = true;
self.down = function (x, y, obj) {
if (self.isActive && self.callback) {
LK.getSound('questionSound').play();
self.callback();
}
};
self.setActive = function (active) {
self.isActive = active;
buttonBg.alpha = active ? 1.0 : 0.5;
buttonText.alpha = active ? 1.0 : 0.5;
};
return self;
});
var Suspect = Container.expand(function (suspectData) {
var self = Container.call(this);
var suspectGraphics = self.attachAsset('suspect', {
anchorX: 0.5,
anchorY: 1.0
});
var nameText = new Text2(suspectData.name, {
size: 32,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -320;
self.addChild(nameText);
self.data = suspectData;
self.nervousness = 0;
self.lastQuestionIndex = -1;
self.respondToQuestion = function (questionIndex) {
self.lastQuestionIndex = questionIndex;
var response = self.data.responses[questionIndex];
self.nervousness = response.emotion === 'calm' ? 0 : response.intensity;
if (response.emotion !== 'calm') {
LK.getSound('emotionDetected').play();
}
return response;
};
self.getTruthLevel = function () {
if (self.lastQuestionIndex >= 0) {
return self.data.responses[self.lastQuestionIndex].truthLevel;
}
return 1.0;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C3E50
});
/****
* Game Code
****/
var gameState = 'menu'; // 'menu', 'interrogation', 'caseComplete'
var caseManager = new CaseManager();
var currentSuspect = null;
var currentEmotionIndicator = null;
var questionButtons = [];
var caseButtons = [];
var currentQuestionIndex = -1;
var playerPoints = storage.playerPoints || 100; // Start with 100 points
var catchButton = null;
// UI Elements
var titleText = new Text2('MIND READER DETECTIVE', {
size: 64,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
var instructionText = new Text2('Select a case to begin your investigation', {
size: 36,
fill: 0xBDC3C7
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 400;
var responseText = new Text2('', {
size: 32,
fill: 0xFFFFFF
});
responseText.anchor.set(0.5, 0.5);
responseText.x = 1024;
responseText.y = 1800;
var evidenceText = new Text2('EVIDENCE COLLECTED:', {
size: 28,
fill: 0xF39C12
});
evidenceText.anchor.set(0, 0.5);
evidenceText.x = 200;
evidenceText.y = 2400;
var scoreText = new Text2('Cases Solved: 0', {
size: 32,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Game scene elements
var detectiveDesk = game.addChild(LK.getAsset('detectiveDesk', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
var detective = game.addChild(LK.getAsset('detective', {
anchorX: 0.5,
anchorY: 1.0,
x: 800,
y: 1200
}));
var suspectChair = game.addChild(LK.getAsset('suspectChair', {
anchorX: 0.5,
anchorY: 0.5,
x: 1300,
y: 1200
}));
var evidenceBox = game.addChild(LK.getAsset('evidenceBox', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2400
}));
// Initialize menu
function initializeMenu() {
gameState = 'menu';
game.addChild(titleText);
game.addChild(instructionText);
// Create case selection buttons
for (var i = 0; i < caseManager.cases.length; i++) {
var caseData = caseManager.cases[i];
var button = new QuestionButton(caseData.title, function (caseId) {
return function () {
startCase(caseId);
};
}(caseData.id));
button.x = 1024;
button.y = 600 + i * 200;
caseButtons.push(button);
game.addChild(button);
}
scoreText.setText('Points: ' + playerPoints + ' | Cases Solved: ' + caseManager.completedCases);
}
function startCase(caseId) {
gameState = 'interrogation';
// Clear menu
game.removeChild(titleText);
game.removeChild(instructionText);
for (var i = 0; i < caseButtons.length; i++) {
game.removeChild(caseButtons[i]);
}
caseButtons = [];
caseManager.startCase(caseId);
startInterrogation();
}
function startInterrogation() {
var suspectData = caseManager.getCurrentSuspect();
if (!suspectData) {
completeCase();
return;
}
// Create suspect
if (currentSuspect) {
game.removeChild(currentSuspect);
}
currentSuspect = new Suspect(suspectData);
currentSuspect.x = 1300;
currentSuspect.y = 1200;
game.addChild(currentSuspect);
// Create question buttons
clearQuestionButtons();
for (var i = 0; i < caseManager.currentCase.questions.length; i++) {
var questionText = caseManager.currentCase.questions[i];
var button = new QuestionButton(questionText, function (index) {
return function () {
askQuestion(index);
};
}(i));
button.x = 1024;
button.y = 2000 + i * 120;
questionButtons.push(button);
game.addChild(button);
}
// Add "Catch Suspect" button
catchButton = new QuestionButton("ARREST " + suspectData.name.split(' ')[0], function () {
catchSuspect();
});
catchButton.x = 800;
catchButton.y = 2000 + caseManager.currentCase.questions.length * 120;
questionButtons.push(catchButton);
game.addChild(catchButton);
// Add "Next Suspect" button
var nextButton = new QuestionButton("NEXT SUSPECT", function () {
nextSuspect();
});
nextButton.x = 1200;
nextButton.y = 2000 + caseManager.currentCase.questions.length * 120;
questionButtons.push(nextButton);
game.addChild(nextButton);
responseText.setText('');
game.addChild(responseText);
game.addChild(evidenceText);
}
function askQuestion(questionIndex) {
currentQuestionIndex = questionIndex;
var response = currentSuspect.respondToQuestion(questionIndex);
responseText.setText('"' + response.text + '"');
// Show emotion indicator
if (currentEmotionIndicator) {
game.removeChild(currentEmotionIndicator);
}
if (response.emotion !== 'calm') {
currentEmotionIndicator = new EmotionIndicator(response.emotion, response.intensity);
currentEmotionIndicator.x = 1500;
currentEmotionIndicator.y = 900;
game.addChild(currentEmotionIndicator);
currentEmotionIndicator.pulse();
// Add evidence
var evidence = {
suspect: currentSuspect.data.name,
question: caseManager.currentCase.questions[questionIndex],
emotion: response.emotion,
intensity: response.intensity,
truthLevel: response.truthLevel
};
caseManager.addEvidence(evidence);
// Update score based on detection
if (response.intensity > 0.5) {
LK.setScore(LK.getScore() + 10);
}
}
// Disable the used question button
questionButtons[questionIndex].setActive(false);
}
function nextSuspect() {
if (caseManager.nextSuspect()) {
startInterrogation();
} else {
completeCase();
}
}
function catchSuspect() {
if (!currentSuspect) return;
// Check if any questions have been asked
var questionsAsked = false;
for (var i = 0; i < questionButtons.length - 2; i++) {
// -2 to exclude catch and next buttons
if (!questionButtons[i].isActive) {
questionsAsked = true;
break;
}
}
// If no questions asked, deduct points and show warning
if (!questionsAsked) {
playerPoints -= 20;
storage.playerPoints = playerPoints;
// Flash screen orange for warning
LK.effects.flashScreen(0xFF8C00, 1000);
// Show warning message
var warningText = new Text2('NO INVESTIGATION! -20 POINTS', {
size: 54,
fill: 0xFF8C00
});
warningText.anchor.set(0.5, 0.5);
warningText.x = 1024;
warningText.y = 800;
game.addChild(warningText);
// Check for game over
if (playerPoints <= 0) {
LK.setTimeout(function () {
game.removeChild(warningText);
gameOver();
}, 2000);
} else {
// Continue with warning message and return to menu
LK.setTimeout(function () {
game.removeChild(warningText);
returnToMenu();
}, 2000);
}
// Disable all buttons during result display
for (var i = 0; i < questionButtons.length; i++) {
questionButtons[i].setActive(false);
}
return;
}
var isGuilty = currentSuspect.data.guilty;
if (isGuilty) {
// Correct arrest - gain points and solve case
playerPoints += 50;
LK.setScore(LK.getScore() + 100);
storage.playerPoints = playerPoints;
// Flash screen green
LK.effects.flashScreen(0x27AE60, 1000);
// Show success message
var successText = new Text2('CORRECT ARREST!', {
size: 54,
fill: 0x27AE60
});
successText.anchor.set(0.5, 0.5);
successText.x = 1024;
successText.y = 800;
game.addChild(successText);
// Auto-remove message and complete case
LK.setTimeout(function () {
game.removeChild(successText);
completeCase();
}, 2000);
} else {
// Wrong arrest - lose points
playerPoints -= 30;
storage.playerPoints = playerPoints;
// Flash screen red
LK.effects.flashScreen(0xFF0000, 1000);
// Show failure message
var failureText = new Text2('WRONG ARREST! -30 POINTS', {
size: 54,
fill: 0xFF0000
});
failureText.anchor.set(0.5, 0.5);
failureText.x = 1024;
failureText.y = 800;
game.addChild(failureText);
// Check for game over
if (playerPoints <= 0) {
LK.setTimeout(function () {
game.removeChild(failureText);
gameOver();
}, 2000);
} else {
// Continue with next suspect
LK.setTimeout(function () {
game.removeChild(failureText);
nextSuspect();
}, 2000);
}
}
// Disable all buttons during result display
for (var i = 0; i < questionButtons.length; i++) {
questionButtons[i].setActive(false);
}
}
function gameOver() {
gameState = 'gameOver';
// Clear interrogation UI
clearQuestionButtons();
if (currentSuspect) {
game.removeChild(currentSuspect);
currentSuspect = null;
}
if (currentEmotionIndicator) {
game.removeChild(currentEmotionIndicator);
currentEmotionIndicator = null;
}
game.removeChild(responseText);
game.removeChild(evidenceText);
// Show game over screen
var gameOverText = new Text2('YOU\'VE BEEN FIRED!', {
size: 72,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 1024;
gameOverText.y = 1000;
game.addChild(gameOverText);
var reasonText = new Text2('Too many wrong arrests destroyed your reputation', {
size: 36,
fill: 0xFFFFFF
});
reasonText.anchor.set(0.5, 0.5);
reasonText.x = 1024;
reasonText.y = 1150;
game.addChild(reasonText);
// Reset and restart button
var restartButton = new QuestionButton("START OVER", function () {
resetGame();
});
restartButton.x = 1024;
restartButton.y = 1400;
game.addChild(restartButton);
// Show final stats
var statsText = new Text2('Cases Solved: ' + caseManager.completedCases + ' | Final Score: ' + LK.getScore(), {
size: 32,
fill: 0xBDC3C7
});
statsText.anchor.set(0.5, 0.5);
statsText.x = 1024;
statsText.y = 1300;
game.addChild(statsText);
}
function resetGame() {
// Reset all game state
playerPoints = 100;
storage.playerPoints = playerPoints;
caseManager.completedCases = 0;
storage.completedCases = 0;
LK.setScore(0);
returnToMenu();
}
function completeCase() {
gameState = 'caseComplete';
// Clear interrogation UI
clearQuestionButtons();
if (currentSuspect) {
game.removeChild(currentSuspect);
currentSuspect = null;
}
if (currentEmotionIndicator) {
game.removeChild(currentEmotionIndicator);
currentEmotionIndicator = null;
}
game.removeChild(responseText);
game.removeChild(evidenceText);
caseManager.completeCase();
// Show case complete screen
var completeText = new Text2('CASE SOLVED!', {
size: 72,
fill: 0x27AE60
});
completeText.anchor.set(0.5, 0.5);
completeText.x = 1024;
completeText.y = 1000;
game.addChild(completeText);
var finalScore = LK.getScore();
var scoreDisplayText = new Text2('Points: ' + playerPoints + ' | Investigation Score: ' + finalScore, {
size: 48,
fill: 0xFFFFFF
});
scoreDisplayText.anchor.set(0.5, 0.5);
scoreDisplayText.x = 1024;
scoreDisplayText.y = 1200;
game.addChild(scoreDisplayText);
// Return to menu button
var menuButton = new QuestionButton("RETURN TO MENU", function () {
returnToMenu();
});
menuButton.x = 1024;
menuButton.y = 1500;
game.addChild(menuButton);
scoreText.setText('Cases Solved: ' + caseManager.completedCases);
// Flash screen green for case completion
LK.effects.flashScreen(0x27AE60, 1000);
}
function returnToMenu() {
// Clear all game elements
game.removeChildren();
// Re-add persistent elements
game.addChild(detectiveDesk);
game.addChild(detective);
game.addChild(suspectChair);
game.addChild(evidenceBox);
// Reset game state
currentSuspect = null;
currentEmotionIndicator = null;
questionButtons = [];
caseButtons = [];
currentQuestionIndex = -1;
initializeMenu();
}
function clearQuestionButtons() {
for (var i = 0; i < questionButtons.length; i++) {
game.removeChild(questionButtons[i]);
}
questionButtons = [];
}
// Start the game
initializeMenu();
game.update = function () {
// Update score display
if (gameState === 'interrogation') {
scoreText.setText('Points: ' + playerPoints + ' | Score: ' + LK.getScore() + ' | Cases: ' + caseManager.completedCases);
} else if (gameState === 'menu') {
scoreText.setText('Points: ' + playerPoints + ' | Cases Solved: ' + caseManager.completedCases);
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CaseManager = Container.expand(function () {
var self = Container.call(this);
self.cases = [{
id: 1,
title: "The Missing Necklace",
description: "A valuable necklace was stolen from Mrs. Henderson's jewelry box.",
suspects: [{
name: "SARAH (MAID)",
guilty: false,
responses: [{
text: "I cleaned the room yesterday morning as usual.",
emotion: "calm",
intensity: 0.2,
truthLevel: 1.0
}, {
text: "I never touched the jewelry box, I swear!",
emotion: "nervousness",
intensity: 0.6,
truthLevel: 1.0
}, {
text: "Maybe someone else had access to the room?",
emotion: "calm",
intensity: 0.1,
truthLevel: 0.8
}]
}, {
name: "DAVID (SON)",
guilty: true,
responses: [{
text: "I was at school all day, you can check.",
emotion: "nervousness",
intensity: 0.8,
truthLevel: 0.3
}, {
text: "Why would I steal from my own mother?",
emotion: "anger",
intensity: 0.7,
truthLevel: 0.5
}, {
text: "I... I needed money for something important.",
emotion: "fear",
intensity: 0.9,
truthLevel: 1.0
}]
}],
questions: ["Where were you yesterday morning?", "Did you see anything suspicious?", "Is there anything you're not telling me?"]
}, {
id: 2,
title: "Office Break-In",
description: "Someone broke into the law office and stole confidential files.",
suspects: [{
name: "MIKE (JANITOR)",
guilty: true,
responses: [{
text: "I work late shifts, but I didn't see anything.",
emotion: "nervousness",
intensity: 0.7,
truthLevel: 0.4
}, {
text: "Those lawyers have many enemies, could be anyone.",
emotion: "calm",
intensity: 0.2,
truthLevel: 0.8
}, {
text: "Okay, okay! Someone paid me to get those files!",
emotion: "fear",
intensity: 1.0,
truthLevel: 1.0
}]
}, {
name: "LISA (SECRETARY)",
guilty: false,
responses: [{
text: "I left at 6 PM sharp, like always.",
emotion: "calm",
intensity: 0.1,
truthLevel: 1.0
}, {
text: "The security system was working when I left.",
emotion: "calm",
intensity: 0.2,
truthLevel: 1.0
}, {
text: "Check the cameras, they'll prove I'm innocent.",
emotion: "nervousness",
intensity: 0.4,
truthLevel: 1.0
}]
}],
questions: ["What time did you leave the office?", "Did you notice anything unusual?", "Tell me the truth about what happened."]
}];
self.currentCase = null;
self.currentSuspectIndex = 0;
self.evidence = [];
self.completedCases = storage.completedCases || 0;
self.startCase = function (caseId) {
self.currentCase = self.cases.find(function (c) {
return c.id === caseId;
});
self.currentSuspectIndex = 0;
self.evidence = [];
};
self.getCurrentSuspect = function () {
if (self.currentCase && self.currentSuspectIndex < self.currentCase.suspects.length) {
return self.currentCase.suspects[self.currentSuspectIndex];
}
return null;
};
self.nextSuspect = function () {
self.currentSuspectIndex++;
return self.currentSuspectIndex < self.currentCase.suspects.length;
};
self.addEvidence = function (evidence) {
self.evidence.push(evidence);
};
self.completeCase = function () {
self.completedCases++;
storage.completedCases = self.completedCases;
LK.getSound('caseComplete').play();
};
return self;
});
var EmotionIndicator = Container.expand(function (emotion, intensity) {
var self = Container.call(this);
var indicator = self.attachAsset('emotionIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
var emotionColors = {
fear: 0xFF6B6B,
anger: 0xFF0000,
nervousness: 0xFFD93D,
calm: 0x6BCF7F
};
indicator.tint = emotionColors[emotion] || 0xFF6B6B;
indicator.alpha = intensity;
var emotionText = new Text2(emotion.toUpperCase(), {
size: 24,
fill: 0xFFFFFF
});
emotionText.anchor.set(0.5, 0.5);
emotionText.y = 60;
self.addChild(emotionText);
self.pulse = function () {
tween(indicator, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(indicator, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 300,
easing: tween.easeIn
});
}
});
};
return self;
});
var QuestionButton = Container.expand(function (text, callback) {
var self = Container.call(this);
var buttonBg = self.attachAsset('questionButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(text, {
size: 36,
fill: 0xFFFFFF
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.callback = callback;
self.isActive = true;
self.down = function (x, y, obj) {
if (self.isActive && self.callback) {
LK.getSound('questionSound').play();
self.callback();
}
};
self.setActive = function (active) {
self.isActive = active;
buttonBg.alpha = active ? 1.0 : 0.5;
buttonText.alpha = active ? 1.0 : 0.5;
};
return self;
});
var Suspect = Container.expand(function (suspectData) {
var self = Container.call(this);
var suspectGraphics = self.attachAsset('suspect', {
anchorX: 0.5,
anchorY: 1.0
});
var nameText = new Text2(suspectData.name, {
size: 32,
fill: 0xFFFFFF
});
nameText.anchor.set(0.5, 0.5);
nameText.y = -320;
self.addChild(nameText);
self.data = suspectData;
self.nervousness = 0;
self.lastQuestionIndex = -1;
self.respondToQuestion = function (questionIndex) {
self.lastQuestionIndex = questionIndex;
var response = self.data.responses[questionIndex];
self.nervousness = response.emotion === 'calm' ? 0 : response.intensity;
if (response.emotion !== 'calm') {
LK.getSound('emotionDetected').play();
}
return response;
};
self.getTruthLevel = function () {
if (self.lastQuestionIndex >= 0) {
return self.data.responses[self.lastQuestionIndex].truthLevel;
}
return 1.0;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C3E50
});
/****
* Game Code
****/
var gameState = 'menu'; // 'menu', 'interrogation', 'caseComplete'
var caseManager = new CaseManager();
var currentSuspect = null;
var currentEmotionIndicator = null;
var questionButtons = [];
var caseButtons = [];
var currentQuestionIndex = -1;
var playerPoints = storage.playerPoints || 100; // Start with 100 points
var catchButton = null;
// UI Elements
var titleText = new Text2('MIND READER DETECTIVE', {
size: 64,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
var instructionText = new Text2('Select a case to begin your investigation', {
size: 36,
fill: 0xBDC3C7
});
instructionText.anchor.set(0.5, 0.5);
instructionText.x = 1024;
instructionText.y = 400;
var responseText = new Text2('', {
size: 32,
fill: 0xFFFFFF
});
responseText.anchor.set(0.5, 0.5);
responseText.x = 1024;
responseText.y = 1800;
var evidenceText = new Text2('EVIDENCE COLLECTED:', {
size: 28,
fill: 0xF39C12
});
evidenceText.anchor.set(0, 0.5);
evidenceText.x = 200;
evidenceText.y = 2400;
var scoreText = new Text2('Cases Solved: 0', {
size: 32,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
// Game scene elements
var detectiveDesk = game.addChild(LK.getAsset('detectiveDesk', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
var detective = game.addChild(LK.getAsset('detective', {
anchorX: 0.5,
anchorY: 1.0,
x: 800,
y: 1200
}));
var suspectChair = game.addChild(LK.getAsset('suspectChair', {
anchorX: 0.5,
anchorY: 0.5,
x: 1300,
y: 1200
}));
var evidenceBox = game.addChild(LK.getAsset('evidenceBox', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2400
}));
// Initialize menu
function initializeMenu() {
gameState = 'menu';
game.addChild(titleText);
game.addChild(instructionText);
// Create case selection buttons
for (var i = 0; i < caseManager.cases.length; i++) {
var caseData = caseManager.cases[i];
var button = new QuestionButton(caseData.title, function (caseId) {
return function () {
startCase(caseId);
};
}(caseData.id));
button.x = 1024;
button.y = 600 + i * 200;
caseButtons.push(button);
game.addChild(button);
}
scoreText.setText('Points: ' + playerPoints + ' | Cases Solved: ' + caseManager.completedCases);
}
function startCase(caseId) {
gameState = 'interrogation';
// Clear menu
game.removeChild(titleText);
game.removeChild(instructionText);
for (var i = 0; i < caseButtons.length; i++) {
game.removeChild(caseButtons[i]);
}
caseButtons = [];
caseManager.startCase(caseId);
startInterrogation();
}
function startInterrogation() {
var suspectData = caseManager.getCurrentSuspect();
if (!suspectData) {
completeCase();
return;
}
// Create suspect
if (currentSuspect) {
game.removeChild(currentSuspect);
}
currentSuspect = new Suspect(suspectData);
currentSuspect.x = 1300;
currentSuspect.y = 1200;
game.addChild(currentSuspect);
// Create question buttons
clearQuestionButtons();
for (var i = 0; i < caseManager.currentCase.questions.length; i++) {
var questionText = caseManager.currentCase.questions[i];
var button = new QuestionButton(questionText, function (index) {
return function () {
askQuestion(index);
};
}(i));
button.x = 1024;
button.y = 2000 + i * 120;
questionButtons.push(button);
game.addChild(button);
}
// Add "Catch Suspect" button
catchButton = new QuestionButton("ARREST " + suspectData.name.split(' ')[0], function () {
catchSuspect();
});
catchButton.x = 800;
catchButton.y = 2000 + caseManager.currentCase.questions.length * 120;
questionButtons.push(catchButton);
game.addChild(catchButton);
// Add "Next Suspect" button
var nextButton = new QuestionButton("NEXT SUSPECT", function () {
nextSuspect();
});
nextButton.x = 1200;
nextButton.y = 2000 + caseManager.currentCase.questions.length * 120;
questionButtons.push(nextButton);
game.addChild(nextButton);
responseText.setText('');
game.addChild(responseText);
game.addChild(evidenceText);
}
function askQuestion(questionIndex) {
currentQuestionIndex = questionIndex;
var response = currentSuspect.respondToQuestion(questionIndex);
responseText.setText('"' + response.text + '"');
// Show emotion indicator
if (currentEmotionIndicator) {
game.removeChild(currentEmotionIndicator);
}
if (response.emotion !== 'calm') {
currentEmotionIndicator = new EmotionIndicator(response.emotion, response.intensity);
currentEmotionIndicator.x = 1500;
currentEmotionIndicator.y = 900;
game.addChild(currentEmotionIndicator);
currentEmotionIndicator.pulse();
// Add evidence
var evidence = {
suspect: currentSuspect.data.name,
question: caseManager.currentCase.questions[questionIndex],
emotion: response.emotion,
intensity: response.intensity,
truthLevel: response.truthLevel
};
caseManager.addEvidence(evidence);
// Update score based on detection
if (response.intensity > 0.5) {
LK.setScore(LK.getScore() + 10);
}
}
// Disable the used question button
questionButtons[questionIndex].setActive(false);
}
function nextSuspect() {
if (caseManager.nextSuspect()) {
startInterrogation();
} else {
completeCase();
}
}
function catchSuspect() {
if (!currentSuspect) return;
// Check if any questions have been asked
var questionsAsked = false;
for (var i = 0; i < questionButtons.length - 2; i++) {
// -2 to exclude catch and next buttons
if (!questionButtons[i].isActive) {
questionsAsked = true;
break;
}
}
// If no questions asked, deduct points and show warning
if (!questionsAsked) {
playerPoints -= 20;
storage.playerPoints = playerPoints;
// Flash screen orange for warning
LK.effects.flashScreen(0xFF8C00, 1000);
// Show warning message
var warningText = new Text2('NO INVESTIGATION! -20 POINTS', {
size: 54,
fill: 0xFF8C00
});
warningText.anchor.set(0.5, 0.5);
warningText.x = 1024;
warningText.y = 800;
game.addChild(warningText);
// Check for game over
if (playerPoints <= 0) {
LK.setTimeout(function () {
game.removeChild(warningText);
gameOver();
}, 2000);
} else {
// Continue with warning message and return to menu
LK.setTimeout(function () {
game.removeChild(warningText);
returnToMenu();
}, 2000);
}
// Disable all buttons during result display
for (var i = 0; i < questionButtons.length; i++) {
questionButtons[i].setActive(false);
}
return;
}
var isGuilty = currentSuspect.data.guilty;
if (isGuilty) {
// Correct arrest - gain points and solve case
playerPoints += 50;
LK.setScore(LK.getScore() + 100);
storage.playerPoints = playerPoints;
// Flash screen green
LK.effects.flashScreen(0x27AE60, 1000);
// Show success message
var successText = new Text2('CORRECT ARREST!', {
size: 54,
fill: 0x27AE60
});
successText.anchor.set(0.5, 0.5);
successText.x = 1024;
successText.y = 800;
game.addChild(successText);
// Auto-remove message and complete case
LK.setTimeout(function () {
game.removeChild(successText);
completeCase();
}, 2000);
} else {
// Wrong arrest - lose points
playerPoints -= 30;
storage.playerPoints = playerPoints;
// Flash screen red
LK.effects.flashScreen(0xFF0000, 1000);
// Show failure message
var failureText = new Text2('WRONG ARREST! -30 POINTS', {
size: 54,
fill: 0xFF0000
});
failureText.anchor.set(0.5, 0.5);
failureText.x = 1024;
failureText.y = 800;
game.addChild(failureText);
// Check for game over
if (playerPoints <= 0) {
LK.setTimeout(function () {
game.removeChild(failureText);
gameOver();
}, 2000);
} else {
// Continue with next suspect
LK.setTimeout(function () {
game.removeChild(failureText);
nextSuspect();
}, 2000);
}
}
// Disable all buttons during result display
for (var i = 0; i < questionButtons.length; i++) {
questionButtons[i].setActive(false);
}
}
function gameOver() {
gameState = 'gameOver';
// Clear interrogation UI
clearQuestionButtons();
if (currentSuspect) {
game.removeChild(currentSuspect);
currentSuspect = null;
}
if (currentEmotionIndicator) {
game.removeChild(currentEmotionIndicator);
currentEmotionIndicator = null;
}
game.removeChild(responseText);
game.removeChild(evidenceText);
// Show game over screen
var gameOverText = new Text2('YOU\'VE BEEN FIRED!', {
size: 72,
fill: 0xFF0000
});
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 1024;
gameOverText.y = 1000;
game.addChild(gameOverText);
var reasonText = new Text2('Too many wrong arrests destroyed your reputation', {
size: 36,
fill: 0xFFFFFF
});
reasonText.anchor.set(0.5, 0.5);
reasonText.x = 1024;
reasonText.y = 1150;
game.addChild(reasonText);
// Reset and restart button
var restartButton = new QuestionButton("START OVER", function () {
resetGame();
});
restartButton.x = 1024;
restartButton.y = 1400;
game.addChild(restartButton);
// Show final stats
var statsText = new Text2('Cases Solved: ' + caseManager.completedCases + ' | Final Score: ' + LK.getScore(), {
size: 32,
fill: 0xBDC3C7
});
statsText.anchor.set(0.5, 0.5);
statsText.x = 1024;
statsText.y = 1300;
game.addChild(statsText);
}
function resetGame() {
// Reset all game state
playerPoints = 100;
storage.playerPoints = playerPoints;
caseManager.completedCases = 0;
storage.completedCases = 0;
LK.setScore(0);
returnToMenu();
}
function completeCase() {
gameState = 'caseComplete';
// Clear interrogation UI
clearQuestionButtons();
if (currentSuspect) {
game.removeChild(currentSuspect);
currentSuspect = null;
}
if (currentEmotionIndicator) {
game.removeChild(currentEmotionIndicator);
currentEmotionIndicator = null;
}
game.removeChild(responseText);
game.removeChild(evidenceText);
caseManager.completeCase();
// Show case complete screen
var completeText = new Text2('CASE SOLVED!', {
size: 72,
fill: 0x27AE60
});
completeText.anchor.set(0.5, 0.5);
completeText.x = 1024;
completeText.y = 1000;
game.addChild(completeText);
var finalScore = LK.getScore();
var scoreDisplayText = new Text2('Points: ' + playerPoints + ' | Investigation Score: ' + finalScore, {
size: 48,
fill: 0xFFFFFF
});
scoreDisplayText.anchor.set(0.5, 0.5);
scoreDisplayText.x = 1024;
scoreDisplayText.y = 1200;
game.addChild(scoreDisplayText);
// Return to menu button
var menuButton = new QuestionButton("RETURN TO MENU", function () {
returnToMenu();
});
menuButton.x = 1024;
menuButton.y = 1500;
game.addChild(menuButton);
scoreText.setText('Cases Solved: ' + caseManager.completedCases);
// Flash screen green for case completion
LK.effects.flashScreen(0x27AE60, 1000);
}
function returnToMenu() {
// Clear all game elements
game.removeChildren();
// Re-add persistent elements
game.addChild(detectiveDesk);
game.addChild(detective);
game.addChild(suspectChair);
game.addChild(evidenceBox);
// Reset game state
currentSuspect = null;
currentEmotionIndicator = null;
questionButtons = [];
caseButtons = [];
currentQuestionIndex = -1;
initializeMenu();
}
function clearQuestionButtons() {
for (var i = 0; i < questionButtons.length; i++) {
game.removeChild(questionButtons[i]);
}
questionButtons = [];
}
// Start the game
initializeMenu();
game.update = function () {
// Update score display
if (gameState === 'interrogation') {
scoreText.setText('Points: ' + playerPoints + ' | Score: ' + LK.getScore() + ' | Cases: ' + caseManager.completedCases);
} else if (gameState === 'menu') {
scoreText.setText('Points: ' + playerPoints + ' | Cases Solved: ' + caseManager.completedCases);
}
};