Code edit (1 edits merged)
Please save this source code
User prompt
Math Castle Quest
Initial prompt
create a mini game easy math question with 4 answers the one of them will be qorrect and make a man walking through a castle in 10 questions if the answer is correct make the person go step by step to castle. if the player completes the ten questions he will reach the castle and will go to next level to the second level.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AnswerButton = Container.expand(function (answerText, isCorrect, onAnswerSelected) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(answerText, {
size: 60,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.isCorrect = isCorrect;
self.onAnswerSelected = onAnswerSelected;
self.down = function (x, y, obj) {
self.onAnswerSelected(self.isCorrect);
};
self.setCorrectStyle = function () {
buttonGraphics.tint = 0x00ff00;
};
self.setIncorrectStyle = function () {
buttonGraphics.tint = 0xff0000;
};
self.resetStyle = function () {
buttonGraphics.tint = 0xffffff;
};
return self;
});
var Castle = Container.expand(function () {
var self = Container.call(this);
var castleGraphics = self.attachAsset('castle', {
anchorX: 0.5,
anchorY: 1.0
});
return self;
});
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 1.0
});
self.moveToPosition = function (targetX, questionNumber) {
var duration = 1000;
if (questionNumber === 5 || questionNumber === 10 || questionNumber === 15) {
duration = 2500;
}
tween(self, {
x: targetX
}, {
duration: duration,
easing: tween.easeInOut
});
};
return self;
});
var DifficultySelector = Container.expand(function (onDifficultySelected) {
var self = Container.call(this);
// Create semi-transparent overlay
var overlay = self.attachAsset('questionPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
overlay.tint = 0x000000;
overlay.alpha = 0.8;
overlay.x = 0;
overlay.y = 0;
// Create title text
var titleText = new Text2("SELECT DIFFICULTY", {
size: 100,
fill: 0xffffff
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -400;
self.addChild(titleText);
// Create difficulty buttons
var difficulties = [{
name: 'EASY',
level: 1,
color: 0x00ff00
}, {
name: 'MEDIUM',
level: 2,
color: 0xffff00
}, {
name: 'HARD',
level: 3,
color: 0xff0000
}, {
name: 'INFINITY',
level: 4,
color: 0x9900ff
}];
var buttonPositions = [{
x: -500,
y: 100
}, {
x: 0,
y: 100
}, {
x: 500,
y: 100
}, {
x: 0,
y: 300
}];
for (var i = 0; i < difficulties.length; i++) {
var difficulty = difficulties[i];
var buttonContainer = new Container();
buttonContainer.x = buttonPositions[i].x;
buttonContainer.y = buttonPositions[i].y;
var assetId = difficulty.name.toLowerCase() + 'Button';
var buttonGraphics = buttonContainer.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
buttonGraphics.tint = difficulty.color;
var buttonText = new Text2(difficulty.name, {
size: 60,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
buttonContainer.addChild(buttonText);
buttonContainer.difficulty = difficulty;
buttonContainer.down = function (x, y, obj) {
onDifficultySelected(this.difficulty.level);
};
self.addChild(buttonContainer);
}
return self;
});
var PrincessGuard = Container.expand(function (guardNumber) {
var self = Container.call(this);
var guardAsset = guardNumber === 1 ? 'guard1' : 'guard2';
var guardGraphics = self.attachAsset(guardAsset, {
anchorX: 0.5,
anchorY: 1.0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var currentLevel = storage.currentLevel || 1;
var completedLevels = storage.completedLevels || 0;
var currentQuestion = 0;
var totalQuestions = 15;
var correctAnswers = 0;
var gameActive = false;
var questionTimer = null;
var timeLeft = 10;
var timerText = null;
var hearts = 3;
var heartsDisplay = null;
var isInfinityMode = false;
// Math problem generation
var mathProblems = [];
var currentProblem = null;
// Game objects
var character = null;
var castle = null;
var ground = null;
var path = null;
var questionPanel = null;
var questionText = null;
var progressText = null;
var answerButtons = [];
// Positions
var startX = 200;
var endX = 1800;
var characterY = 2400;
var pathY = 2450;
var guard1 = null;
var guard2 = null;
var princess = null;
var guard1X = startX + (endX - startX) * (5 / 15);
var guard2X = startX + (endX - startX) * (10 / 15);
var princessX = endX;
// Initialize game elements
function initializeGame() {
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2470
}));
// Create path
path = game.addChild(LK.getAsset('path', {
anchorX: 0,
anchorY: 0.5,
x: 124,
y: pathY
}));
// Create character
character = game.addChild(new Character());
character.x = startX;
character.y = characterY;
// Create castle
castle = game.addChild(new Castle());
castle.x = endX;
castle.y = characterY;
// Create guard 1
guard1 = game.addChild(new PrincessGuard(1));
guard1.x = guard1X;
guard1.y = characterY;
// Create guard 2
guard2 = game.addChild(new PrincessGuard(2));
guard2.x = guard2X;
guard2.y = characterY;
// Create princess at the end
// Create question panel
questionPanel = game.addChild(LK.getAsset('questionPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1000
}));
questionPanel.alpha = 0.9;
// Create question text
questionText = new Text2('', {
size: 80,
fill: 0x000000
});
questionText.anchor.set(0.5, 0.5);
questionText.x = 1024;
questionText.y = 880;
game.addChild(questionText);
// Create progress text
progressText = new Text2('', {
size: 60,
fill: 0x2b2b2b
});
progressText.anchor.set(0.5, 0.5);
progressText.x = 1024;
progressText.y = 700;
game.addChild(progressText);
// Create timer text
timerText = new Text2('Time: 10', {
size: 70,
fill: 0xff0000
});
timerText.anchor.set(0.5, 0.5);
timerText.x = 1024;
timerText.y = 550;
game.addChild(timerText);
// Create completion counter text
var completionCounterText = new Text2('Princesses Saved: ' + completedLevels, {
size: 50,
fill: 0x000000
});
completionCounterText.anchor.set(0.5, 0.0);
completionCounterText.x = 1024;
completionCounterText.y = 50;
game.addChild(completionCounterText);
// Create hearts display
heartsDisplay = new Text2('❤️ ❤️ ❤️', {
size: 80,
fill: 0xff0000
});
heartsDisplay.anchor.set(0.5, 0.0);
heartsDisplay.x = 1024;
heartsDisplay.y = 120;
if (!isInfinityMode) {
game.addChild(heartsDisplay);
}
// Create answer buttons
var buttonPositions = [{
x: 512,
y: 1100
}, {
x: 1536,
y: 1100
}, {
x: 512,
y: 1300
}, {
x: 1536,
y: 1300
}];
for (var i = 0; i < 4; i++) {
var button = new AnswerButton('', false, onAnswerSelected);
button.x = buttonPositions[i].x;
button.y = buttonPositions[i].y;
answerButtons.push(button);
game.addChild(button);
}
// Create music toggle icon in top right corner
var musicIcon = new Text2('🎵', {
size: 80,
fill: 0x000000
});
musicIcon.anchor.set(1.0, 0.0);
musicIcon.x = 1948; // 100px from right edge (2048 - 100)
musicIcon.y = 100;
LK.gui.addChild(musicIcon);
// Add click handler to stop music
musicIcon.down = function (x, y, obj) {
LK.stopMusic();
};
generateMathProblems();
startNextQuestion();
}
function generateMathProblems() {
mathProblems = [];
for (var i = 0; i < totalQuestions; i++) {
var problem = generateMathProblem(currentLevel);
mathProblems.push(problem);
}
}
function generateMathProblem(level) {
var num1, num2, operation, correctAnswer, question;
if (level === 1) {
// Easy: Addition and subtraction only, up to 15
num1 = Math.floor(Math.random() * 15) + 1;
num2 = Math.floor(Math.random() * 15) + 1;
operation = Math.random() < 0.5 ? '+' : '-';
if (operation === '+') {
correctAnswer = num1 + num2;
question = num1 + ' + ' + num2 + ' = ?';
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
correctAnswer = num1 - num2;
question = num1 + ' - ' + num2 + ' = ?';
}
} else if (level === 2) {
// Medium: Addition and subtraction with low numbers up to 50
var ops = ['+', '-'];
operation = ops[Math.floor(Math.random() * ops.length)];
num1 = Math.floor(Math.random() * 50) + 1;
num2 = Math.floor(Math.random() * 50) + 1;
if (operation === '+') {
correctAnswer = num1 + num2;
question = num1 + ' + ' + num2 + ' = ?';
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
correctAnswer = num1 - num2;
question = num1 + ' - ' + num2 + ' = ?';
}
} else {
// Hard: All operations with larger numbers
var ops = ['+', '-', '*', '/'];
operation = ops[Math.floor(Math.random() * ops.length)];
if (operation === '/') {
correctAnswer = Math.floor(Math.random() * 20) + 1;
num2 = Math.floor(Math.random() * 12) + 1;
num1 = correctAnswer * num2;
question = num1 + ' ÷ ' + num2 + ' = ?';
} else if (operation === '*') {
num1 = Math.floor(Math.random() * 25) + 1;
num2 = Math.floor(Math.random() * 25) + 1;
correctAnswer = num1 * num2;
question = num1 + ' × ' + num2 + ' = ?';
} else {
num1 = Math.floor(Math.random() * 100) + 1;
num2 = Math.floor(Math.random() * 100) + 1;
if (operation === '+') {
correctAnswer = num1 + num2;
question = num1 + ' + ' + num2 + ' = ?';
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
correctAnswer = num1 - num2;
question = num1 + ' - ' + num2 + ' = ?';
}
}
}
// Generate wrong answers
var wrongAnswers = [];
var attempts = 0;
while (wrongAnswers.length < 3 && attempts < 20) {
var wrongAnswer;
var variation = Math.floor(Math.random() * 10) + 1;
if (Math.random() < 0.5) {
wrongAnswer = correctAnswer + variation;
} else {
wrongAnswer = correctAnswer - variation;
}
if (wrongAnswer !== correctAnswer && wrongAnswer > 0 && wrongAnswers.indexOf(wrongAnswer) === -1) {
wrongAnswers.push(wrongAnswer);
}
attempts++;
}
// Ensure we have exactly 3 wrong answers
while (wrongAnswers.length < 3) {
var fallbackWrong = correctAnswer + Math.floor(Math.random() * 20) - 10;
if (fallbackWrong !== correctAnswer && fallbackWrong > 0 && wrongAnswers.indexOf(fallbackWrong) === -1) {
wrongAnswers.push(fallbackWrong);
}
}
return {
question: question,
correctAnswer: correctAnswer,
wrongAnswers: wrongAnswers
};
}
function updateHeartsDisplay() {
var heartString = '';
for (var i = 0; i < hearts; i++) {
heartString += '❤️ ';
}
if (heartString === '') {
heartString = 'NO HEARTS LEFT';
}
heartsDisplay.setText(heartString);
}
function startTimer() {
timeLeft = 13;
timerText.setText('Time: ' + timeLeft);
timerText.tint = 0xff0000;
if (questionTimer) {
LK.clearInterval(questionTimer);
}
questionTimer = LK.setInterval(function () {
timeLeft--;
timerText.setText('Time: ' + timeLeft);
if (timeLeft <= 0) {
LK.clearInterval(questionTimer);
onTimeUp();
}
}, 1000);
}
function onTimeUp() {
if (!gameActive) {
return;
}
gameActive = false;
// Flash screen red and show game over
LK.effects.flashScreen(0xff0000, 2000);
// Create failure message text
var failureText = new Text2("Time's up! You couldn't save the princess!", {
size: 70,
fill: 0x000000
});
failureText.anchor.set(0.5, 0.5);
failureText.x = 1024;
failureText.y = 1566;
game.addChild(failureText);
// Animate the text to fade in and out
failureText.alpha = 0;
tween(failureText, {
alpha: 1
}, {
duration: 700,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(failureText, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
failureText.destroy();
}
});
}, 1500);
}
});
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
}
function startNextQuestion() {
if (currentQuestion >= totalQuestions) {
if (questionTimer) {
LK.clearInterval(questionTimer);
}
completeLevel();
return;
}
currentProblem = mathProblems[currentQuestion];
// Update question text
questionText.setText(currentProblem.question);
progressText.setText('Question ' + (currentQuestion + 1) + ' of ' + totalQuestions);
// Create answer options
var answers = [currentProblem.correctAnswer].concat(currentProblem.wrongAnswers);
// Shuffle answers
for (var i = answers.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = answers[i];
answers[i] = answers[j];
answers[j] = temp;
}
// Set button texts and correct answer
for (var i = 0; i < 4; i++) {
answerButtons[i].children[1].setText(answers[i].toString());
answerButtons[i].isCorrect = answers[i] === currentProblem.correctAnswer;
answerButtons[i].resetStyle();
}
gameActive = true;
startTimer();
}
function onAnswerSelected(isCorrect) {
if (!gameActive) {
return;
}
gameActive = false;
if (questionTimer) {
LK.clearInterval(questionTimer);
}
// Show feedback on buttons
for (var i = 0; i < answerButtons.length; i++) {
if (answerButtons[i].isCorrect) {
answerButtons[i].setCorrectStyle();
} else {
answerButtons[i].setIncorrectStyle();
}
}
if (isCorrect) {
correctAnswers++;
LK.getSound('correct').play();
} else {
LK.getSound('incorrect').play();
if (!isInfinityMode) {
hearts--;
updateHeartsDisplay();
}
}
// Move character forward for correct answers, or backward in infinity mode for incorrect answers
var progress;
if (isInfinityMode && !isCorrect) {
// Move backward one step in infinity mode on incorrect answer
var backwardQuestion = Math.max(0, currentQuestion - 1);
progress = backwardQuestion / totalQuestions;
var targetX = startX + (endX - startX) * progress;
character.moveToPosition(targetX, backwardQuestion);
} else {
// Move forward normally
progress = (currentQuestion + 1) / totalQuestions;
var targetX = startX + (endX - startX) * progress;
character.moveToPosition(targetX, currentQuestion + 1);
}
// Check milestones
if (currentQuestion + 1 === 5 && guard1) {
LK.effects.flashScreen(0xffaa00, 800);
guard1.destroy(); //{4p_new}
guard1 = null; //{4p_new2}
}
if (currentQuestion + 1 === 10 && guard2) {
LK.effects.flashScreen(0xffaa00, 800);
guard2.destroy(); //{4r_new}
guard2 = null; //{4r_new2}
}
if (currentQuestion + 1 === 15 && princess) {
LK.effects.flashScreen(0xffff00, 800);
}
// Only award points for correct answers
if (isCorrect) {
LK.setScore(LK.getScore() + 10 * currentLevel);
}
// Wait before next question
LK.setTimeout(function () {
if (isInfinityMode) {
// In infinity mode, only increment question on correct answers
if (isCorrect) {
currentQuestion++;
}
// If incorrect, keep same question (currentQuestion stays the same)
} else {
// In other modes, always increment
currentQuestion++;
}
startNextQuestion();
}, 2000);
}
function completeLevel() {
// Check if player reached the finish (reached castle at question 15)
var reachedFinish = character.x >= princessX - 50;
if (reachedFinish) {
LK.getSound('victory').play();
// Change background to light blue for victory
game.setBackgroundColor(0xadd8e6);
// Flash screen with celebration color
LK.effects.flashScreen(0xffd700, 1500);
// Create princess image
var princessImage = game.addChild(LK.getAsset('princess', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
princessImage.alpha = 0;
// Create victory text
var victoryText = new Text2("YOU SAVED THE PRINCESS!", {
size: 90,
fill: 0x000000
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 1024;
victoryText.y = 1600;
victoryText.alpha = 0;
game.addChild(victoryText);
// Animate princess image and text to fade in
tween(princessImage, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeIn
});
tween(victoryText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeIn
});
// Increment completion counter
completedLevels++;
storage.completedLevels = completedLevels;
// Update counter display
game.children.forEach(function (child) {
if (child.text && child.text.indexOf('Princesses Saved:') === 0) {
child.setText('Princesses Saved: ' + completedLevels);
}
});
// End game after 15th question
LK.setTimeout(function () {
// Fade out victory elements
tween(princessImage, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
princessImage.destroy();
}
});
tween(victoryText, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
victoryText.destroy();
}
});
// Wait a bit more before showing you win
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}, 3000);
} else {
// Player did not save the princess (either wrong answers or did not reach finish), show failure message
LK.effects.flashScreen(0xff0000, 2000);
// Create failure message text
var failureText = new Text2("You couldn't save the princess!", {
size: 80,
fill: 0x000000
});
failureText.anchor.set(0.5, 0.5);
failureText.x = 1024;
failureText.y = 1566;
game.addChild(failureText);
// Animate the text to fade in and out
failureText.alpha = 0;
tween(failureText, {
alpha: 1
}, {
duration: 700,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(failureText, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
failureText.destroy();
}
});
}, 1500);
}
});
LK.setTimeout(function () {
currentQuestion = 0;
correctAnswers = 0;
hearts = 3;
updateHeartsDisplay();
character.x = startX;
// Reset guards for retry
if (guard1) {
guard1.destroy();
}
if (guard2) {
guard2.destroy();
}
if (princess) {
princess.destroy();
}
guard1 = game.addChild(new PrincessGuard(1));
guard1.x = guard1X;
guard1.y = characterY;
guard2 = game.addChild(new PrincessGuard(2));
guard2.x = guard2X;
guard2.y = characterY;
princess = game.addChild(LK.getAsset('princess', {
anchorX: 0.5,
anchorY: 1.0,
x: princessX,
y: characterY
}));
generateMathProblems();
startNextQuestion();
}, 3000);
}
}
// Game state
var gameStarted = false;
// Start screen setup
function showStartScreen() {
// Create semi-transparent overlay
var overlay = game.addChild(LK.getAsset('questionPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 1.2,
scaleY: 1.2
}));
overlay.tint = 0x222222;
overlay.alpha = 0.8;
// Create title text
var titleText = new Text2("SAVE THE PRINCESS", {
size: 100,
fill: 0xffffff
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 600;
game.addChild(titleText);
// Create subtitle text
var subtitleText = new Text2("Answer math questions correctly to save the princess!", {
size: 60,
fill: 0xffff00
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 1000;
game.addChild(subtitleText);
// Create start button
var startButton = game.addChild(LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400
}));
// Create button text with play icon
var buttonText = new Text2("", {
size: 120,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
startButton.addChild(buttonText);
// Handle button click
startButton.down = function (x, y, obj) {
// Remove start screen elements
overlay.destroy();
titleText.destroy();
subtitleText.destroy();
startButton.destroy();
// Show difficulty selector
showDifficultyScreen();
};
}
// Show difficulty selection screen
function showDifficultyScreen() {
var difficultySelector = game.addChild(new DifficultySelector(function (selectedLevel) {
currentLevel = selectedLevel;
isInfinityMode = selectedLevel === 4;
// Remove difficulty selector
difficultySelector.destroy();
// Start game
gameStarted = true;
LK.playMusic('game-song1');
initializeGame();
}));
// Position difficulty selector in center
difficultySelector.x = 1024;
difficultySelector.y = 1366;
}
// Show start screen instead of directly initializing
showStartScreen();
game.update = function () {
// Game update logic if needed
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var AnswerButton = Container.expand(function (answerText, isCorrect, onAnswerSelected) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
var buttonText = new Text2(answerText, {
size: 60,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.isCorrect = isCorrect;
self.onAnswerSelected = onAnswerSelected;
self.down = function (x, y, obj) {
self.onAnswerSelected(self.isCorrect);
};
self.setCorrectStyle = function () {
buttonGraphics.tint = 0x00ff00;
};
self.setIncorrectStyle = function () {
buttonGraphics.tint = 0xff0000;
};
self.resetStyle = function () {
buttonGraphics.tint = 0xffffff;
};
return self;
});
var Castle = Container.expand(function () {
var self = Container.call(this);
var castleGraphics = self.attachAsset('castle', {
anchorX: 0.5,
anchorY: 1.0
});
return self;
});
var Character = Container.expand(function () {
var self = Container.call(this);
var characterGraphics = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 1.0
});
self.moveToPosition = function (targetX, questionNumber) {
var duration = 1000;
if (questionNumber === 5 || questionNumber === 10 || questionNumber === 15) {
duration = 2500;
}
tween(self, {
x: targetX
}, {
duration: duration,
easing: tween.easeInOut
});
};
return self;
});
var DifficultySelector = Container.expand(function (onDifficultySelected) {
var self = Container.call(this);
// Create semi-transparent overlay
var overlay = self.attachAsset('questionPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
overlay.tint = 0x000000;
overlay.alpha = 0.8;
overlay.x = 0;
overlay.y = 0;
// Create title text
var titleText = new Text2("SELECT DIFFICULTY", {
size: 100,
fill: 0xffffff
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 0;
titleText.y = -400;
self.addChild(titleText);
// Create difficulty buttons
var difficulties = [{
name: 'EASY',
level: 1,
color: 0x00ff00
}, {
name: 'MEDIUM',
level: 2,
color: 0xffff00
}, {
name: 'HARD',
level: 3,
color: 0xff0000
}, {
name: 'INFINITY',
level: 4,
color: 0x9900ff
}];
var buttonPositions = [{
x: -500,
y: 100
}, {
x: 0,
y: 100
}, {
x: 500,
y: 100
}, {
x: 0,
y: 300
}];
for (var i = 0; i < difficulties.length; i++) {
var difficulty = difficulties[i];
var buttonContainer = new Container();
buttonContainer.x = buttonPositions[i].x;
buttonContainer.y = buttonPositions[i].y;
var assetId = difficulty.name.toLowerCase() + 'Button';
var buttonGraphics = buttonContainer.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
buttonGraphics.tint = difficulty.color;
var buttonText = new Text2(difficulty.name, {
size: 60,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
buttonContainer.addChild(buttonText);
buttonContainer.difficulty = difficulty;
buttonContainer.down = function (x, y, obj) {
onDifficultySelected(this.difficulty.level);
};
self.addChild(buttonContainer);
}
return self;
});
var PrincessGuard = Container.expand(function (guardNumber) {
var self = Container.call(this);
var guardAsset = guardNumber === 1 ? 'guard1' : 'guard2';
var guardGraphics = self.attachAsset(guardAsset, {
anchorX: 0.5,
anchorY: 1.0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var currentLevel = storage.currentLevel || 1;
var completedLevels = storage.completedLevels || 0;
var currentQuestion = 0;
var totalQuestions = 15;
var correctAnswers = 0;
var gameActive = false;
var questionTimer = null;
var timeLeft = 10;
var timerText = null;
var hearts = 3;
var heartsDisplay = null;
var isInfinityMode = false;
// Math problem generation
var mathProblems = [];
var currentProblem = null;
// Game objects
var character = null;
var castle = null;
var ground = null;
var path = null;
var questionPanel = null;
var questionText = null;
var progressText = null;
var answerButtons = [];
// Positions
var startX = 200;
var endX = 1800;
var characterY = 2400;
var pathY = 2450;
var guard1 = null;
var guard2 = null;
var princess = null;
var guard1X = startX + (endX - startX) * (5 / 15);
var guard2X = startX + (endX - startX) * (10 / 15);
var princessX = endX;
// Initialize game elements
function initializeGame() {
// Create ground
ground = game.addChild(LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2470
}));
// Create path
path = game.addChild(LK.getAsset('path', {
anchorX: 0,
anchorY: 0.5,
x: 124,
y: pathY
}));
// Create character
character = game.addChild(new Character());
character.x = startX;
character.y = characterY;
// Create castle
castle = game.addChild(new Castle());
castle.x = endX;
castle.y = characterY;
// Create guard 1
guard1 = game.addChild(new PrincessGuard(1));
guard1.x = guard1X;
guard1.y = characterY;
// Create guard 2
guard2 = game.addChild(new PrincessGuard(2));
guard2.x = guard2X;
guard2.y = characterY;
// Create princess at the end
// Create question panel
questionPanel = game.addChild(LK.getAsset('questionPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1000
}));
questionPanel.alpha = 0.9;
// Create question text
questionText = new Text2('', {
size: 80,
fill: 0x000000
});
questionText.anchor.set(0.5, 0.5);
questionText.x = 1024;
questionText.y = 880;
game.addChild(questionText);
// Create progress text
progressText = new Text2('', {
size: 60,
fill: 0x2b2b2b
});
progressText.anchor.set(0.5, 0.5);
progressText.x = 1024;
progressText.y = 700;
game.addChild(progressText);
// Create timer text
timerText = new Text2('Time: 10', {
size: 70,
fill: 0xff0000
});
timerText.anchor.set(0.5, 0.5);
timerText.x = 1024;
timerText.y = 550;
game.addChild(timerText);
// Create completion counter text
var completionCounterText = new Text2('Princesses Saved: ' + completedLevels, {
size: 50,
fill: 0x000000
});
completionCounterText.anchor.set(0.5, 0.0);
completionCounterText.x = 1024;
completionCounterText.y = 50;
game.addChild(completionCounterText);
// Create hearts display
heartsDisplay = new Text2('❤️ ❤️ ❤️', {
size: 80,
fill: 0xff0000
});
heartsDisplay.anchor.set(0.5, 0.0);
heartsDisplay.x = 1024;
heartsDisplay.y = 120;
if (!isInfinityMode) {
game.addChild(heartsDisplay);
}
// Create answer buttons
var buttonPositions = [{
x: 512,
y: 1100
}, {
x: 1536,
y: 1100
}, {
x: 512,
y: 1300
}, {
x: 1536,
y: 1300
}];
for (var i = 0; i < 4; i++) {
var button = new AnswerButton('', false, onAnswerSelected);
button.x = buttonPositions[i].x;
button.y = buttonPositions[i].y;
answerButtons.push(button);
game.addChild(button);
}
// Create music toggle icon in top right corner
var musicIcon = new Text2('🎵', {
size: 80,
fill: 0x000000
});
musicIcon.anchor.set(1.0, 0.0);
musicIcon.x = 1948; // 100px from right edge (2048 - 100)
musicIcon.y = 100;
LK.gui.addChild(musicIcon);
// Add click handler to stop music
musicIcon.down = function (x, y, obj) {
LK.stopMusic();
};
generateMathProblems();
startNextQuestion();
}
function generateMathProblems() {
mathProblems = [];
for (var i = 0; i < totalQuestions; i++) {
var problem = generateMathProblem(currentLevel);
mathProblems.push(problem);
}
}
function generateMathProblem(level) {
var num1, num2, operation, correctAnswer, question;
if (level === 1) {
// Easy: Addition and subtraction only, up to 15
num1 = Math.floor(Math.random() * 15) + 1;
num2 = Math.floor(Math.random() * 15) + 1;
operation = Math.random() < 0.5 ? '+' : '-';
if (operation === '+') {
correctAnswer = num1 + num2;
question = num1 + ' + ' + num2 + ' = ?';
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
correctAnswer = num1 - num2;
question = num1 + ' - ' + num2 + ' = ?';
}
} else if (level === 2) {
// Medium: Addition and subtraction with low numbers up to 50
var ops = ['+', '-'];
operation = ops[Math.floor(Math.random() * ops.length)];
num1 = Math.floor(Math.random() * 50) + 1;
num2 = Math.floor(Math.random() * 50) + 1;
if (operation === '+') {
correctAnswer = num1 + num2;
question = num1 + ' + ' + num2 + ' = ?';
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
correctAnswer = num1 - num2;
question = num1 + ' - ' + num2 + ' = ?';
}
} else {
// Hard: All operations with larger numbers
var ops = ['+', '-', '*', '/'];
operation = ops[Math.floor(Math.random() * ops.length)];
if (operation === '/') {
correctAnswer = Math.floor(Math.random() * 20) + 1;
num2 = Math.floor(Math.random() * 12) + 1;
num1 = correctAnswer * num2;
question = num1 + ' ÷ ' + num2 + ' = ?';
} else if (operation === '*') {
num1 = Math.floor(Math.random() * 25) + 1;
num2 = Math.floor(Math.random() * 25) + 1;
correctAnswer = num1 * num2;
question = num1 + ' × ' + num2 + ' = ?';
} else {
num1 = Math.floor(Math.random() * 100) + 1;
num2 = Math.floor(Math.random() * 100) + 1;
if (operation === '+') {
correctAnswer = num1 + num2;
question = num1 + ' + ' + num2 + ' = ?';
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
correctAnswer = num1 - num2;
question = num1 + ' - ' + num2 + ' = ?';
}
}
}
// Generate wrong answers
var wrongAnswers = [];
var attempts = 0;
while (wrongAnswers.length < 3 && attempts < 20) {
var wrongAnswer;
var variation = Math.floor(Math.random() * 10) + 1;
if (Math.random() < 0.5) {
wrongAnswer = correctAnswer + variation;
} else {
wrongAnswer = correctAnswer - variation;
}
if (wrongAnswer !== correctAnswer && wrongAnswer > 0 && wrongAnswers.indexOf(wrongAnswer) === -1) {
wrongAnswers.push(wrongAnswer);
}
attempts++;
}
// Ensure we have exactly 3 wrong answers
while (wrongAnswers.length < 3) {
var fallbackWrong = correctAnswer + Math.floor(Math.random() * 20) - 10;
if (fallbackWrong !== correctAnswer && fallbackWrong > 0 && wrongAnswers.indexOf(fallbackWrong) === -1) {
wrongAnswers.push(fallbackWrong);
}
}
return {
question: question,
correctAnswer: correctAnswer,
wrongAnswers: wrongAnswers
};
}
function updateHeartsDisplay() {
var heartString = '';
for (var i = 0; i < hearts; i++) {
heartString += '❤️ ';
}
if (heartString === '') {
heartString = 'NO HEARTS LEFT';
}
heartsDisplay.setText(heartString);
}
function startTimer() {
timeLeft = 13;
timerText.setText('Time: ' + timeLeft);
timerText.tint = 0xff0000;
if (questionTimer) {
LK.clearInterval(questionTimer);
}
questionTimer = LK.setInterval(function () {
timeLeft--;
timerText.setText('Time: ' + timeLeft);
if (timeLeft <= 0) {
LK.clearInterval(questionTimer);
onTimeUp();
}
}, 1000);
}
function onTimeUp() {
if (!gameActive) {
return;
}
gameActive = false;
// Flash screen red and show game over
LK.effects.flashScreen(0xff0000, 2000);
// Create failure message text
var failureText = new Text2("Time's up! You couldn't save the princess!", {
size: 70,
fill: 0x000000
});
failureText.anchor.set(0.5, 0.5);
failureText.x = 1024;
failureText.y = 1566;
game.addChild(failureText);
// Animate the text to fade in and out
failureText.alpha = 0;
tween(failureText, {
alpha: 1
}, {
duration: 700,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(failureText, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
failureText.destroy();
}
});
}, 1500);
}
});
LK.setTimeout(function () {
LK.showGameOver();
}, 3000);
}
function startNextQuestion() {
if (currentQuestion >= totalQuestions) {
if (questionTimer) {
LK.clearInterval(questionTimer);
}
completeLevel();
return;
}
currentProblem = mathProblems[currentQuestion];
// Update question text
questionText.setText(currentProblem.question);
progressText.setText('Question ' + (currentQuestion + 1) + ' of ' + totalQuestions);
// Create answer options
var answers = [currentProblem.correctAnswer].concat(currentProblem.wrongAnswers);
// Shuffle answers
for (var i = answers.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = answers[i];
answers[i] = answers[j];
answers[j] = temp;
}
// Set button texts and correct answer
for (var i = 0; i < 4; i++) {
answerButtons[i].children[1].setText(answers[i].toString());
answerButtons[i].isCorrect = answers[i] === currentProblem.correctAnswer;
answerButtons[i].resetStyle();
}
gameActive = true;
startTimer();
}
function onAnswerSelected(isCorrect) {
if (!gameActive) {
return;
}
gameActive = false;
if (questionTimer) {
LK.clearInterval(questionTimer);
}
// Show feedback on buttons
for (var i = 0; i < answerButtons.length; i++) {
if (answerButtons[i].isCorrect) {
answerButtons[i].setCorrectStyle();
} else {
answerButtons[i].setIncorrectStyle();
}
}
if (isCorrect) {
correctAnswers++;
LK.getSound('correct').play();
} else {
LK.getSound('incorrect').play();
if (!isInfinityMode) {
hearts--;
updateHeartsDisplay();
}
}
// Move character forward for correct answers, or backward in infinity mode for incorrect answers
var progress;
if (isInfinityMode && !isCorrect) {
// Move backward one step in infinity mode on incorrect answer
var backwardQuestion = Math.max(0, currentQuestion - 1);
progress = backwardQuestion / totalQuestions;
var targetX = startX + (endX - startX) * progress;
character.moveToPosition(targetX, backwardQuestion);
} else {
// Move forward normally
progress = (currentQuestion + 1) / totalQuestions;
var targetX = startX + (endX - startX) * progress;
character.moveToPosition(targetX, currentQuestion + 1);
}
// Check milestones
if (currentQuestion + 1 === 5 && guard1) {
LK.effects.flashScreen(0xffaa00, 800);
guard1.destroy(); //{4p_new}
guard1 = null; //{4p_new2}
}
if (currentQuestion + 1 === 10 && guard2) {
LK.effects.flashScreen(0xffaa00, 800);
guard2.destroy(); //{4r_new}
guard2 = null; //{4r_new2}
}
if (currentQuestion + 1 === 15 && princess) {
LK.effects.flashScreen(0xffff00, 800);
}
// Only award points for correct answers
if (isCorrect) {
LK.setScore(LK.getScore() + 10 * currentLevel);
}
// Wait before next question
LK.setTimeout(function () {
if (isInfinityMode) {
// In infinity mode, only increment question on correct answers
if (isCorrect) {
currentQuestion++;
}
// If incorrect, keep same question (currentQuestion stays the same)
} else {
// In other modes, always increment
currentQuestion++;
}
startNextQuestion();
}, 2000);
}
function completeLevel() {
// Check if player reached the finish (reached castle at question 15)
var reachedFinish = character.x >= princessX - 50;
if (reachedFinish) {
LK.getSound('victory').play();
// Change background to light blue for victory
game.setBackgroundColor(0xadd8e6);
// Flash screen with celebration color
LK.effects.flashScreen(0xffd700, 1500);
// Create princess image
var princessImage = game.addChild(LK.getAsset('princess', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1200
}));
princessImage.alpha = 0;
// Create victory text
var victoryText = new Text2("YOU SAVED THE PRINCESS!", {
size: 90,
fill: 0x000000
});
victoryText.anchor.set(0.5, 0.5);
victoryText.x = 1024;
victoryText.y = 1600;
victoryText.alpha = 0;
game.addChild(victoryText);
// Animate princess image and text to fade in
tween(princessImage, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeIn
});
tween(victoryText, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeIn
});
// Increment completion counter
completedLevels++;
storage.completedLevels = completedLevels;
// Update counter display
game.children.forEach(function (child) {
if (child.text && child.text.indexOf('Princesses Saved:') === 0) {
child.setText('Princesses Saved: ' + completedLevels);
}
});
// End game after 15th question
LK.setTimeout(function () {
// Fade out victory elements
tween(princessImage, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
princessImage.destroy();
}
});
tween(victoryText, {
alpha: 0
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
victoryText.destroy();
}
});
// Wait a bit more before showing you win
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}, 3000);
} else {
// Player did not save the princess (either wrong answers or did not reach finish), show failure message
LK.effects.flashScreen(0xff0000, 2000);
// Create failure message text
var failureText = new Text2("You couldn't save the princess!", {
size: 80,
fill: 0x000000
});
failureText.anchor.set(0.5, 0.5);
failureText.x = 1024;
failureText.y = 1566;
game.addChild(failureText);
// Animate the text to fade in and out
failureText.alpha = 0;
tween(failureText, {
alpha: 1
}, {
duration: 700,
easing: tween.easeIn,
onFinish: function onFinish() {
LK.setTimeout(function () {
tween(failureText, {
alpha: 0
}, {
duration: 700,
easing: tween.easeOut,
onFinish: function onFinish() {
failureText.destroy();
}
});
}, 1500);
}
});
LK.setTimeout(function () {
currentQuestion = 0;
correctAnswers = 0;
hearts = 3;
updateHeartsDisplay();
character.x = startX;
// Reset guards for retry
if (guard1) {
guard1.destroy();
}
if (guard2) {
guard2.destroy();
}
if (princess) {
princess.destroy();
}
guard1 = game.addChild(new PrincessGuard(1));
guard1.x = guard1X;
guard1.y = characterY;
guard2 = game.addChild(new PrincessGuard(2));
guard2.x = guard2X;
guard2.y = characterY;
princess = game.addChild(LK.getAsset('princess', {
anchorX: 0.5,
anchorY: 1.0,
x: princessX,
y: characterY
}));
generateMathProblems();
startNextQuestion();
}, 3000);
}
}
// Game state
var gameStarted = false;
// Start screen setup
function showStartScreen() {
// Create semi-transparent overlay
var overlay = game.addChild(LK.getAsset('questionPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366,
scaleX: 1.2,
scaleY: 1.2
}));
overlay.tint = 0x222222;
overlay.alpha = 0.8;
// Create title text
var titleText = new Text2("SAVE THE PRINCESS", {
size: 100,
fill: 0xffffff
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 600;
game.addChild(titleText);
// Create subtitle text
var subtitleText = new Text2("Answer math questions correctly to save the princess!", {
size: 60,
fill: 0xffff00
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 1000;
game.addChild(subtitleText);
// Create start button
var startButton = game.addChild(LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1400
}));
// Create button text with play icon
var buttonText = new Text2("", {
size: 120,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
startButton.addChild(buttonText);
// Handle button click
startButton.down = function (x, y, obj) {
// Remove start screen elements
overlay.destroy();
titleText.destroy();
subtitleText.destroy();
startButton.destroy();
// Show difficulty selector
showDifficultyScreen();
};
}
// Show difficulty selection screen
function showDifficultyScreen() {
var difficultySelector = game.addChild(new DifficultySelector(function (selectedLevel) {
currentLevel = selectedLevel;
isInfinityMode = selectedLevel === 4;
// Remove difficulty selector
difficultySelector.destroy();
// Start game
gameStarted = true;
LK.playMusic('game-song1');
initializeGame();
}));
// Position difficulty selector in center
difficultySelector.x = 1024;
difficultySelector.y = 1366;
}
// Show start screen instead of directly initializing
showStartScreen();
game.update = function () {
// Game update logic if needed
};
knight warrior. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
add a princess at the middle top of the castle
stone road. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Princess . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
start button . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
rectangle red color. In-Game asset. 2d. High contrast. No shadows. rectangle red
rectangle purple color . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
rectangle orange color no background. In-Game asset. 2d. High contrast. No shadows. ractangle