/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AnswerButton = Container.expand(function (answer, isCorrect) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.answer = answer;
self.isCorrect = isCorrect;
var answerText = new Text2(answer.toString(), {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 4
});
answerText.anchor.set(0.5, 0.5);
self.addChild(answerText);
self.down = function (x, y, obj) {
if (currentQuestion && !questionAnswered) {
handleAnswer(self.isCorrect);
}
};
return self;
});
var BuildingWindow = Container.expand(function (x, y) {
var self = Container.call(this);
var windowGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
windowGraphics.tint = 0xFFFF88;
windowGraphics.width = 40;
windowGraphics.height = 60;
windowGraphics.alpha = 0.3;
self.x = x;
self.y = y;
self.flickerTimer = Math.random() * 120;
self.update = function () {
self.flickerTimer++;
if (self.flickerTimer % 60 === 0) {
windowGraphics.alpha = Math.random() * 0.5 + 0.3;
}
};
return self;
});
var Cat = Container.expand(function () {
var self = Container.call(this);
var catGraphics = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.saved = false;
self.fallen = false;
self.update = function () {
if (!self.saved && !self.fallen) {
self.y += self.speed;
// Add cute wiggling motion to falling cats
catGraphics.rotation = Math.sin(self.y * 0.02) * 0.2;
catGraphics.scaleX = 1 + Math.sin(self.y * 0.03) * 0.1;
if (self.y > 2400) {
self.fallen = true;
}
}
};
return self;
});
var Fire = Container.expand(function () {
var self = Container.call(this);
var fireGraphics = self.attachAsset('fire', {
anchorX: 0.5,
anchorY: 0.5
});
self.animationTimer = 0;
self.update = function () {
self.animationTimer += 1;
fireGraphics.scaleX = 1 + Math.sin(self.animationTimer * 0.1) * 0.3;
fireGraphics.scaleY = 1 + Math.cos(self.animationTimer * 0.15) * 0.2;
};
return self;
});
var FloatingScore = Container.expand(function (points, x, y) {
var self = Container.call(this);
var scoreText = new Text2('+' + points, {
size: 80,
fill: 0x00FF00,
stroke: 0x000000,
strokeThickness: 4
});
scoreText.anchor.set(0.5, 0.5);
self.addChild(scoreText);
self.x = x;
self.y = y;
self.life = 120;
self.update = function () {
self.y -= 2;
self.life--;
scoreText.alpha = self.life / 120;
scoreText.scaleX = scoreText.scaleY = 1 + (120 - self.life) * 0.01;
if (self.life <= 0) {
self.destroy();
}
};
return self;
});
var Particle = Container.expand(function (color, size) {
var self = Container.call(this);
var particleGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
particleGraphics.tint = color;
particleGraphics.width = size;
particleGraphics.height = size;
self.velocityX = (Math.random() - 0.5) * 10;
self.velocityY = Math.random() * -8 - 2;
self.gravity = 0.3;
self.life = 60;
self.maxLife = 60;
self.colorTimer = 0;
self.rainbowColors = [0xFF69B4, 0x87CEEB, 0x98FB98, 0xFFB6C1, 0xDDA0DD, 0xF0E68C];
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.life--;
particleGraphics.alpha = self.life / self.maxLife;
particleGraphics.rotation += 0.1;
// Add cute rainbow color cycling
if (color === 0x00FF00) {
// Only for green celebration particles
self.colorTimer++;
if (self.colorTimer % 10 === 0) {
var colorIndex = Math.floor(self.colorTimer / 10) % self.rainbowColors.length;
particleGraphics.tint = self.rainbowColors[colorIndex];
}
}
if (self.life <= 0) {
self.destroy();
}
};
return self;
});
var RainDrop = Container.expand(function () {
var self = Container.call(this);
var dropGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
dropGraphics.tint = 0x87CEEB;
dropGraphics.width = 3;
dropGraphics.height = 15;
dropGraphics.alpha = 0.6;
self.speed = 8 + Math.random() * 4;
self.update = function () {
self.y += self.speed;
if (self.y > 2800) {
self.destroy();
}
};
return self;
});
var Smoke = Container.expand(function () {
var self = Container.call(this);
var smokeGraphics = self.attachAsset('smoke', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -1;
self.drift = Math.random() * 2 - 1;
self.update = function () {
self.y += self.speed;
self.x += self.drift;
smokeGraphics.alpha -= 0.01;
if (smokeGraphics.alpha <= 0 || self.y < -100) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0d191e
});
/****
* Game Code
****/
// Game variables
var lives = 3;
var catsRescued = 0;
var currentCat = null;
var currentQuestion = null;
var questionAnswered = false;
var gameRunning = true;
var difficulty = 1;
var questionTimer = 0;
var maxQuestionTime = 300; // 5 seconds at 60fps
// UI elements
var heartIcons = [];
// Function to update heart display
function updateHeartDisplay() {
// Clear existing hearts
for (var i = 0; i < heartIcons.length; i++) {
if (heartIcons[i].parent) {
heartIcons[i].parent.removeChild(heartIcons[i]);
}
}
heartIcons = [];
// Create hearts for remaining lives
for (var i = 0; i < lives; i++) {
var heart = new Text2('❤️', {
size: 50,
fill: 0xFF0000
});
heart.anchor.set(0, 0);
heart.x = 130 + i * 60;
heart.y = 150;
heartIcons.push(heart);
LK.gui.top.addChild(heart);
}
}
// Initialize heart display
updateHeartDisplay();
// Create cat counter display
var catIcon = new Text2('🐱', {
size: 50,
fill: 0xFFFFFF
});
catIcon.anchor.set(0, 0);
catIcon.x = 130;
catIcon.y = 220;
LK.gui.top.addChild(catIcon);
var catCounterText = new Text2('x 0', {
size: 40,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
catCounterText.anchor.set(0, 0);
catCounterText.x = 180;
catCounterText.y = 225;
LK.gui.top.addChild(catCounterText);
// Create score bar background
var scoreBar = LK.getAsset('answerButton', {
width: 300,
height: 80,
anchorX: 1,
anchorY: 0,
x: 2048 - 50,
y: 30
});
scoreBar.tint = 0x4CAF50;
var scoreText = new Text2('Skor: 0', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = scoreBar.x - scoreBar.width / 2;
scoreText.y = scoreBar.y + scoreBar.height / 2;
LK.gui.topRight.addChild(scoreBar);
LK.gui.topRight.addChild(scoreText);
// Create question background panel
var questionPanel = game.addChild(LK.getAsset('answerButton', {
width: 1600,
height: 200,
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 500
}));
questionPanel.tint = 0x2c3e50; // Dark blue-gray background
questionPanel.alpha = 0.9;
var questionText = new Text2('', {
size: 100,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 8
});
questionText.anchor.set(0.5, 0.5);
questionText.x = 1024;
questionText.y = 500;
game.addChild(questionText);
// Game objects
var building = game.addChild(LK.getAsset('building', {
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 2400
}));
var firefighter = game.addChild(LK.getAsset('firefighter', {
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 2600
}));
var net = game.addChild(LK.getAsset('net', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2500
}));
// Arrays for game objects
var fires = [];
var smokes = [];
var answerButtons = [];
var particles = [];
var rainDrops = [];
var buildingWindows = [];
var floatingScores = [];
var screenShake = 0;
var weatherTimer = 0;
var isRaining = false;
// Create fires on building
for (var i = 0; i < 8; i++) {
var fire = new Fire();
fire.x = 300 + i * 200;
fire.y = 1400 + Math.random() * 400;
fires.push(fire);
game.addChild(fire);
}
// Create building windows for atmosphere
for (var i = 0; i < 20; i++) {
var window = new BuildingWindow(400 + i % 10 * 120, 1200 + Math.floor(i / 10) * 100);
buildingWindows.push(window);
game.addChild(window);
}
// Math question generation
function generateQuestion() {
var num1, num2, operation, answer, wrongAnswers;
if (difficulty <= 1) {
// Addition and subtraction only for beginner
num1 = Math.floor(Math.random() * 20) + 1;
num2 = Math.floor(Math.random() * 20) + 1;
operation = Math.random() > 0.5 ? '+' : '-';
if (operation === '+') {
answer = num1 + num2;
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
answer = num1 - num2;
}
} else {
// All four operations for higher difficulty
var operationType = Math.floor(Math.random() * 4);
if (operationType === 0) {
// Addition
num1 = Math.floor(Math.random() * 30) + 1;
num2 = Math.floor(Math.random() * 30) + 1;
operation = '+';
answer = num1 + num2;
} else if (operationType === 1) {
// Subtraction
num1 = Math.floor(Math.random() * 50) + 10;
num2 = Math.floor(Math.random() * num1);
operation = '-';
answer = num1 - num2;
} else if (operationType === 2) {
// Multiplication
num1 = Math.floor(Math.random() * 12) + 1;
num2 = Math.floor(Math.random() * 12) + 1;
operation = '×';
answer = num1 * num2;
} else {
// Division
num2 = Math.floor(Math.random() * 12) + 1;
answer = Math.floor(Math.random() * 12) + 1;
num1 = num2 * answer;
operation = '÷';
}
}
var questionStr = num1 + ' ' + operation + ' ' + num2 + ' = ?';
// Generate wrong answers
wrongAnswers = [];
while (wrongAnswers.length < 3) {
var wrongAnswer = answer + Math.floor(Math.random() * 20) - 10;
if (wrongAnswer !== answer && wrongAnswer > 0 && wrongAnswers.indexOf(wrongAnswer) === -1) {
wrongAnswers.push(wrongAnswer);
}
}
return {
question: questionStr,
answer: answer,
wrongAnswers: wrongAnswers
};
}
function createAnswerButtons(questionData) {
// Clear existing buttons
for (var i = answerButtons.length - 1; i >= 0; i--) {
answerButtons[i].destroy();
answerButtons.splice(i, 1);
}
var allAnswers = [questionData.answer].concat(questionData.wrongAnswers);
// Shuffle answers
for (var i = allAnswers.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = allAnswers[i];
allAnswers[i] = allAnswers[j];
allAnswers[j] = temp;
}
// Create buttons
for (var i = 0; i < 4; i++) {
var isCorrect = allAnswers[i] === questionData.answer;
var button = new AnswerButton(allAnswers[i], isCorrect);
button.x = 400 + i * 300;
button.y = 700;
answerButtons.push(button);
game.addChild(button);
}
}
function startNewQuestion() {
if (!gameRunning) {
return;
}
currentQuestion = generateQuestion();
questionText.setText(currentQuestion.question);
createAnswerButtons(currentQuestion);
questionAnswered = false;
questionTimer = 0;
// Create new cat
currentCat = new Cat();
currentCat.x = 500 + Math.random() * 1000;
currentCat.y = 800;
currentCat.speed = 1 + difficulty * 0.5;
game.addChild(currentCat);
}
function handleAnswer(isCorrect) {
if (questionAnswered || !gameRunning) {
return;
}
questionAnswered = true;
if (isCorrect) {
// Correct answer
LK.getSound('correct').play();
currentCat.saved = true;
catsRescued++;
LK.setScore(catsRescued);
scoreText.setText('Skor: ' + catsRescued);
catCounterText.setText('x ' + catsRescued);
// Flash cat green
LK.effects.flashObject(currentCat, 0x00FF00, 500);
// Create cute celebration particles with stars and hearts
for (var p = 0; p < 15; p++) {
var particle = new Particle(0x00FF00, 8 + Math.random() * 8);
particle.x = currentCat.x + (Math.random() - 0.5) * 100;
particle.y = currentCat.y + (Math.random() - 0.5) * 100;
particles.push(particle);
game.addChild(particle);
}
// Add cute star particles
for (var s = 0; s < 8; s++) {
var starParticle = new Particle(0xFFD700, 12);
starParticle.x = currentCat.x + (Math.random() - 0.5) * 120;
starParticle.y = currentCat.y + (Math.random() - 0.5) * 120;
starParticle.velocityY = Math.random() * -6 - 3;
particles.push(starParticle);
game.addChild(starParticle);
}
// Create floating score
var floatingScore = new FloatingScore(1, currentCat.x, currentCat.y - 50);
floatingScores.push(floatingScore);
game.addChild(floatingScore);
// Add cute floating hearts
for (var h = 0; h < 3; h++) {
var heart = new Text2('💖', {
size: 30 + Math.random() * 20,
fill: 0xFF69B4
});
heart.anchor.set(0.5, 0.5);
heart.x = currentCat.x + (Math.random() - 0.5) * 80;
heart.y = currentCat.y - 30;
tween(heart, {
y: heart.y - 100,
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
if (heart.parent) {
heart.parent.removeChild(heart);
}
}
});
game.addChild(heart);
}
// Screen shake for excitement
screenShake = 15;
// Move firefighter and net to cat's x position
tween(firefighter, {
x: currentCat.x
}, {
duration: 800
});
tween(net, {
x: currentCat.x
}, {
duration: 800
});
// Add cute bouncing animation to cat
tween(currentCat, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(currentCat, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
// Move cat to safety
tween(currentCat, {
x: currentCat.x,
y: net.y
}, {
duration: 1000,
onFinish: function onFinish() {
if (currentCat) {
currentCat.destroy();
currentCat = null;
}
}
});
// Increase difficulty every 5 cats
if (catsRescued % 5 === 0) {
difficulty++;
maxQuestionTime = Math.max(120, maxQuestionTime - 30);
}
// Start next question after delay
LK.setTimeout(function () {
startNewQuestion();
}, 1500);
} else {
// Wrong answer
LK.getSound('wrong').play();
lives--;
updateHeartDisplay();
// Flash screen red
LK.effects.flashScreen(0xFF0000, 500);
// Create falling cat particles
if (currentCat) {
for (var p = 0; p < 12; p++) {
var particle = new Particle(0xFFFF00, 5 + Math.random() * 8);
particle.x = currentCat.x + (Math.random() - 0.5) * 100;
particle.y = currentCat.y + (Math.random() - 0.5) * 100;
particles.push(particle);
game.addChild(particle);
}
}
// Screen shake for cat falling
screenShake = 20;
// Create danger particles
for (var p = 0; p < 20; p++) {
var particle = new Particle(0xFF0000, 6 + Math.random() * 10);
particle.x = currentCat ? currentCat.x + (Math.random() - 0.5) * 150 : 1024;
particle.y = currentCat ? currentCat.y + (Math.random() - 0.5) * 150 : 1000;
particles.push(particle);
game.addChild(particle);
}
// Strong screen shake for wrong answer
screenShake = 25;
if (lives <= 0) {
gameRunning = false;
LK.showGameOver();
} else {
// Start next question after delay
LK.setTimeout(function () {
if (currentCat) {
currentCat.destroy();
currentCat = null;
}
startNewQuestion();
}, 1500);
}
}
// Clear answer buttons
for (var i = answerButtons.length - 1; i >= 0; i--) {
answerButtons[i].destroy();
answerButtons.splice(i, 1);
}
questionText.setText('');
}
// Generate smoke effects
var smokeTimer = 0;
game.update = function () {
if (!gameRunning) {
return;
}
// Check if cat fell without being saved
if (currentCat && !currentCat.saved && currentCat.fallen) {
LK.getSound('fall').play();
lives--;
updateHeartDisplay();
// Flash screen red
LK.effects.flashScreen(0xFF0000, 500);
if (lives <= 0) {
gameRunning = false;
LK.showGameOver();
} else {
currentCat.destroy();
currentCat = null;
startNewQuestion();
}
}
// Question timeout
if (currentQuestion && !questionAnswered) {
questionTimer++;
if (questionTimer >= maxQuestionTime) {
handleAnswer(false);
}
}
// Generate smoke
smokeTimer++;
if (smokeTimer % 20 === 0) {
var smoke = new Smoke();
smoke.x = 300 + Math.random() * 1400;
smoke.y = 1800 + Math.random() * 400;
smokes.push(smoke);
game.addChild(smoke);
}
// Clean up destroyed smoke
for (var i = smokes.length - 1; i >= 0; i--) {
if (smokes[i].destroyed) {
smokes.splice(i, 1);
}
}
// Clean up destroyed particles
for (var i = particles.length - 1; i >= 0; i--) {
if (particles[i].destroyed) {
particles.splice(i, 1);
}
}
// Clean up destroyed floating scores
for (var i = floatingScores.length - 1; i >= 0; i--) {
if (floatingScores[i].destroyed) {
floatingScores.splice(i, 1);
}
}
// Weather system
weatherTimer++;
if (weatherTimer % 300 === 0) {
isRaining = !isRaining;
}
// Generate rain
if (isRaining && weatherTimer % 3 === 0) {
var rain = new RainDrop();
rain.x = Math.random() * 2048;
rain.y = -20;
rainDrops.push(rain);
game.addChild(rain);
}
// Clean up rain drops
for (var i = rainDrops.length - 1; i >= 0; i--) {
if (rainDrops[i].destroyed) {
rainDrops.splice(i, 1);
}
}
// Screen shake effect
if (screenShake > 0) {
game.x = (Math.random() - 0.5) * screenShake;
game.y = (Math.random() - 0.5) * screenShake;
screenShake--;
} else {
game.x = 0;
game.y = 0;
}
};
// Start first question
startNewQuestion(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AnswerButton = Container.expand(function (answer, isCorrect) {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.answer = answer;
self.isCorrect = isCorrect;
var answerText = new Text2(answer.toString(), {
size: 60,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 4
});
answerText.anchor.set(0.5, 0.5);
self.addChild(answerText);
self.down = function (x, y, obj) {
if (currentQuestion && !questionAnswered) {
handleAnswer(self.isCorrect);
}
};
return self;
});
var BuildingWindow = Container.expand(function (x, y) {
var self = Container.call(this);
var windowGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
windowGraphics.tint = 0xFFFF88;
windowGraphics.width = 40;
windowGraphics.height = 60;
windowGraphics.alpha = 0.3;
self.x = x;
self.y = y;
self.flickerTimer = Math.random() * 120;
self.update = function () {
self.flickerTimer++;
if (self.flickerTimer % 60 === 0) {
windowGraphics.alpha = Math.random() * 0.5 + 0.3;
}
};
return self;
});
var Cat = Container.expand(function () {
var self = Container.call(this);
var catGraphics = self.attachAsset('cat', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.saved = false;
self.fallen = false;
self.update = function () {
if (!self.saved && !self.fallen) {
self.y += self.speed;
// Add cute wiggling motion to falling cats
catGraphics.rotation = Math.sin(self.y * 0.02) * 0.2;
catGraphics.scaleX = 1 + Math.sin(self.y * 0.03) * 0.1;
if (self.y > 2400) {
self.fallen = true;
}
}
};
return self;
});
var Fire = Container.expand(function () {
var self = Container.call(this);
var fireGraphics = self.attachAsset('fire', {
anchorX: 0.5,
anchorY: 0.5
});
self.animationTimer = 0;
self.update = function () {
self.animationTimer += 1;
fireGraphics.scaleX = 1 + Math.sin(self.animationTimer * 0.1) * 0.3;
fireGraphics.scaleY = 1 + Math.cos(self.animationTimer * 0.15) * 0.2;
};
return self;
});
var FloatingScore = Container.expand(function (points, x, y) {
var self = Container.call(this);
var scoreText = new Text2('+' + points, {
size: 80,
fill: 0x00FF00,
stroke: 0x000000,
strokeThickness: 4
});
scoreText.anchor.set(0.5, 0.5);
self.addChild(scoreText);
self.x = x;
self.y = y;
self.life = 120;
self.update = function () {
self.y -= 2;
self.life--;
scoreText.alpha = self.life / 120;
scoreText.scaleX = scoreText.scaleY = 1 + (120 - self.life) * 0.01;
if (self.life <= 0) {
self.destroy();
}
};
return self;
});
var Particle = Container.expand(function (color, size) {
var self = Container.call(this);
var particleGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
particleGraphics.tint = color;
particleGraphics.width = size;
particleGraphics.height = size;
self.velocityX = (Math.random() - 0.5) * 10;
self.velocityY = Math.random() * -8 - 2;
self.gravity = 0.3;
self.life = 60;
self.maxLife = 60;
self.colorTimer = 0;
self.rainbowColors = [0xFF69B4, 0x87CEEB, 0x98FB98, 0xFFB6C1, 0xDDA0DD, 0xF0E68C];
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
self.life--;
particleGraphics.alpha = self.life / self.maxLife;
particleGraphics.rotation += 0.1;
// Add cute rainbow color cycling
if (color === 0x00FF00) {
// Only for green celebration particles
self.colorTimer++;
if (self.colorTimer % 10 === 0) {
var colorIndex = Math.floor(self.colorTimer / 10) % self.rainbowColors.length;
particleGraphics.tint = self.rainbowColors[colorIndex];
}
}
if (self.life <= 0) {
self.destroy();
}
};
return self;
});
var RainDrop = Container.expand(function () {
var self = Container.call(this);
var dropGraphics = self.attachAsset('answerButton', {
anchorX: 0.5,
anchorY: 0.5
});
dropGraphics.tint = 0x87CEEB;
dropGraphics.width = 3;
dropGraphics.height = 15;
dropGraphics.alpha = 0.6;
self.speed = 8 + Math.random() * 4;
self.update = function () {
self.y += self.speed;
if (self.y > 2800) {
self.destroy();
}
};
return self;
});
var Smoke = Container.expand(function () {
var self = Container.call(this);
var smokeGraphics = self.attachAsset('smoke', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -1;
self.drift = Math.random() * 2 - 1;
self.update = function () {
self.y += self.speed;
self.x += self.drift;
smokeGraphics.alpha -= 0.01;
if (smokeGraphics.alpha <= 0 || self.y < -100) {
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0d191e
});
/****
* Game Code
****/
// Game variables
var lives = 3;
var catsRescued = 0;
var currentCat = null;
var currentQuestion = null;
var questionAnswered = false;
var gameRunning = true;
var difficulty = 1;
var questionTimer = 0;
var maxQuestionTime = 300; // 5 seconds at 60fps
// UI elements
var heartIcons = [];
// Function to update heart display
function updateHeartDisplay() {
// Clear existing hearts
for (var i = 0; i < heartIcons.length; i++) {
if (heartIcons[i].parent) {
heartIcons[i].parent.removeChild(heartIcons[i]);
}
}
heartIcons = [];
// Create hearts for remaining lives
for (var i = 0; i < lives; i++) {
var heart = new Text2('❤️', {
size: 50,
fill: 0xFF0000
});
heart.anchor.set(0, 0);
heart.x = 130 + i * 60;
heart.y = 150;
heartIcons.push(heart);
LK.gui.top.addChild(heart);
}
}
// Initialize heart display
updateHeartDisplay();
// Create cat counter display
var catIcon = new Text2('🐱', {
size: 50,
fill: 0xFFFFFF
});
catIcon.anchor.set(0, 0);
catIcon.x = 130;
catIcon.y = 220;
LK.gui.top.addChild(catIcon);
var catCounterText = new Text2('x 0', {
size: 40,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
catCounterText.anchor.set(0, 0);
catCounterText.x = 180;
catCounterText.y = 225;
LK.gui.top.addChild(catCounterText);
// Create score bar background
var scoreBar = LK.getAsset('answerButton', {
width: 300,
height: 80,
anchorX: 1,
anchorY: 0,
x: 2048 - 50,
y: 30
});
scoreBar.tint = 0x4CAF50;
var scoreText = new Text2('Skor: 0', {
size: 45,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 3
});
scoreText.anchor.set(0.5, 0.5);
scoreText.x = scoreBar.x - scoreBar.width / 2;
scoreText.y = scoreBar.y + scoreBar.height / 2;
LK.gui.topRight.addChild(scoreBar);
LK.gui.topRight.addChild(scoreText);
// Create question background panel
var questionPanel = game.addChild(LK.getAsset('answerButton', {
width: 1600,
height: 200,
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 500
}));
questionPanel.tint = 0x2c3e50; // Dark blue-gray background
questionPanel.alpha = 0.9;
var questionText = new Text2('', {
size: 100,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 8
});
questionText.anchor.set(0.5, 0.5);
questionText.x = 1024;
questionText.y = 500;
game.addChild(questionText);
// Game objects
var building = game.addChild(LK.getAsset('building', {
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 2400
}));
var firefighter = game.addChild(LK.getAsset('firefighter', {
anchorX: 0.5,
anchorY: 1,
x: 1024,
y: 2600
}));
var net = game.addChild(LK.getAsset('net', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 2500
}));
// Arrays for game objects
var fires = [];
var smokes = [];
var answerButtons = [];
var particles = [];
var rainDrops = [];
var buildingWindows = [];
var floatingScores = [];
var screenShake = 0;
var weatherTimer = 0;
var isRaining = false;
// Create fires on building
for (var i = 0; i < 8; i++) {
var fire = new Fire();
fire.x = 300 + i * 200;
fire.y = 1400 + Math.random() * 400;
fires.push(fire);
game.addChild(fire);
}
// Create building windows for atmosphere
for (var i = 0; i < 20; i++) {
var window = new BuildingWindow(400 + i % 10 * 120, 1200 + Math.floor(i / 10) * 100);
buildingWindows.push(window);
game.addChild(window);
}
// Math question generation
function generateQuestion() {
var num1, num2, operation, answer, wrongAnswers;
if (difficulty <= 1) {
// Addition and subtraction only for beginner
num1 = Math.floor(Math.random() * 20) + 1;
num2 = Math.floor(Math.random() * 20) + 1;
operation = Math.random() > 0.5 ? '+' : '-';
if (operation === '+') {
answer = num1 + num2;
} else {
if (num1 < num2) {
var temp = num1;
num1 = num2;
num2 = temp;
}
answer = num1 - num2;
}
} else {
// All four operations for higher difficulty
var operationType = Math.floor(Math.random() * 4);
if (operationType === 0) {
// Addition
num1 = Math.floor(Math.random() * 30) + 1;
num2 = Math.floor(Math.random() * 30) + 1;
operation = '+';
answer = num1 + num2;
} else if (operationType === 1) {
// Subtraction
num1 = Math.floor(Math.random() * 50) + 10;
num2 = Math.floor(Math.random() * num1);
operation = '-';
answer = num1 - num2;
} else if (operationType === 2) {
// Multiplication
num1 = Math.floor(Math.random() * 12) + 1;
num2 = Math.floor(Math.random() * 12) + 1;
operation = '×';
answer = num1 * num2;
} else {
// Division
num2 = Math.floor(Math.random() * 12) + 1;
answer = Math.floor(Math.random() * 12) + 1;
num1 = num2 * answer;
operation = '÷';
}
}
var questionStr = num1 + ' ' + operation + ' ' + num2 + ' = ?';
// Generate wrong answers
wrongAnswers = [];
while (wrongAnswers.length < 3) {
var wrongAnswer = answer + Math.floor(Math.random() * 20) - 10;
if (wrongAnswer !== answer && wrongAnswer > 0 && wrongAnswers.indexOf(wrongAnswer) === -1) {
wrongAnswers.push(wrongAnswer);
}
}
return {
question: questionStr,
answer: answer,
wrongAnswers: wrongAnswers
};
}
function createAnswerButtons(questionData) {
// Clear existing buttons
for (var i = answerButtons.length - 1; i >= 0; i--) {
answerButtons[i].destroy();
answerButtons.splice(i, 1);
}
var allAnswers = [questionData.answer].concat(questionData.wrongAnswers);
// Shuffle answers
for (var i = allAnswers.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = allAnswers[i];
allAnswers[i] = allAnswers[j];
allAnswers[j] = temp;
}
// Create buttons
for (var i = 0; i < 4; i++) {
var isCorrect = allAnswers[i] === questionData.answer;
var button = new AnswerButton(allAnswers[i], isCorrect);
button.x = 400 + i * 300;
button.y = 700;
answerButtons.push(button);
game.addChild(button);
}
}
function startNewQuestion() {
if (!gameRunning) {
return;
}
currentQuestion = generateQuestion();
questionText.setText(currentQuestion.question);
createAnswerButtons(currentQuestion);
questionAnswered = false;
questionTimer = 0;
// Create new cat
currentCat = new Cat();
currentCat.x = 500 + Math.random() * 1000;
currentCat.y = 800;
currentCat.speed = 1 + difficulty * 0.5;
game.addChild(currentCat);
}
function handleAnswer(isCorrect) {
if (questionAnswered || !gameRunning) {
return;
}
questionAnswered = true;
if (isCorrect) {
// Correct answer
LK.getSound('correct').play();
currentCat.saved = true;
catsRescued++;
LK.setScore(catsRescued);
scoreText.setText('Skor: ' + catsRescued);
catCounterText.setText('x ' + catsRescued);
// Flash cat green
LK.effects.flashObject(currentCat, 0x00FF00, 500);
// Create cute celebration particles with stars and hearts
for (var p = 0; p < 15; p++) {
var particle = new Particle(0x00FF00, 8 + Math.random() * 8);
particle.x = currentCat.x + (Math.random() - 0.5) * 100;
particle.y = currentCat.y + (Math.random() - 0.5) * 100;
particles.push(particle);
game.addChild(particle);
}
// Add cute star particles
for (var s = 0; s < 8; s++) {
var starParticle = new Particle(0xFFD700, 12);
starParticle.x = currentCat.x + (Math.random() - 0.5) * 120;
starParticle.y = currentCat.y + (Math.random() - 0.5) * 120;
starParticle.velocityY = Math.random() * -6 - 3;
particles.push(starParticle);
game.addChild(starParticle);
}
// Create floating score
var floatingScore = new FloatingScore(1, currentCat.x, currentCat.y - 50);
floatingScores.push(floatingScore);
game.addChild(floatingScore);
// Add cute floating hearts
for (var h = 0; h < 3; h++) {
var heart = new Text2('💖', {
size: 30 + Math.random() * 20,
fill: 0xFF69B4
});
heart.anchor.set(0.5, 0.5);
heart.x = currentCat.x + (Math.random() - 0.5) * 80;
heart.y = currentCat.y - 30;
tween(heart, {
y: heart.y - 100,
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
if (heart.parent) {
heart.parent.removeChild(heart);
}
}
});
game.addChild(heart);
}
// Screen shake for excitement
screenShake = 15;
// Move firefighter and net to cat's x position
tween(firefighter, {
x: currentCat.x
}, {
duration: 800
});
tween(net, {
x: currentCat.x
}, {
duration: 800
});
// Add cute bouncing animation to cat
tween(currentCat, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(currentCat, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
// Move cat to safety
tween(currentCat, {
x: currentCat.x,
y: net.y
}, {
duration: 1000,
onFinish: function onFinish() {
if (currentCat) {
currentCat.destroy();
currentCat = null;
}
}
});
// Increase difficulty every 5 cats
if (catsRescued % 5 === 0) {
difficulty++;
maxQuestionTime = Math.max(120, maxQuestionTime - 30);
}
// Start next question after delay
LK.setTimeout(function () {
startNewQuestion();
}, 1500);
} else {
// Wrong answer
LK.getSound('wrong').play();
lives--;
updateHeartDisplay();
// Flash screen red
LK.effects.flashScreen(0xFF0000, 500);
// Create falling cat particles
if (currentCat) {
for (var p = 0; p < 12; p++) {
var particle = new Particle(0xFFFF00, 5 + Math.random() * 8);
particle.x = currentCat.x + (Math.random() - 0.5) * 100;
particle.y = currentCat.y + (Math.random() - 0.5) * 100;
particles.push(particle);
game.addChild(particle);
}
}
// Screen shake for cat falling
screenShake = 20;
// Create danger particles
for (var p = 0; p < 20; p++) {
var particle = new Particle(0xFF0000, 6 + Math.random() * 10);
particle.x = currentCat ? currentCat.x + (Math.random() - 0.5) * 150 : 1024;
particle.y = currentCat ? currentCat.y + (Math.random() - 0.5) * 150 : 1000;
particles.push(particle);
game.addChild(particle);
}
// Strong screen shake for wrong answer
screenShake = 25;
if (lives <= 0) {
gameRunning = false;
LK.showGameOver();
} else {
// Start next question after delay
LK.setTimeout(function () {
if (currentCat) {
currentCat.destroy();
currentCat = null;
}
startNewQuestion();
}, 1500);
}
}
// Clear answer buttons
for (var i = answerButtons.length - 1; i >= 0; i--) {
answerButtons[i].destroy();
answerButtons.splice(i, 1);
}
questionText.setText('');
}
// Generate smoke effects
var smokeTimer = 0;
game.update = function () {
if (!gameRunning) {
return;
}
// Check if cat fell without being saved
if (currentCat && !currentCat.saved && currentCat.fallen) {
LK.getSound('fall').play();
lives--;
updateHeartDisplay();
// Flash screen red
LK.effects.flashScreen(0xFF0000, 500);
if (lives <= 0) {
gameRunning = false;
LK.showGameOver();
} else {
currentCat.destroy();
currentCat = null;
startNewQuestion();
}
}
// Question timeout
if (currentQuestion && !questionAnswered) {
questionTimer++;
if (questionTimer >= maxQuestionTime) {
handleAnswer(false);
}
}
// Generate smoke
smokeTimer++;
if (smokeTimer % 20 === 0) {
var smoke = new Smoke();
smoke.x = 300 + Math.random() * 1400;
smoke.y = 1800 + Math.random() * 400;
smokes.push(smoke);
game.addChild(smoke);
}
// Clean up destroyed smoke
for (var i = smokes.length - 1; i >= 0; i--) {
if (smokes[i].destroyed) {
smokes.splice(i, 1);
}
}
// Clean up destroyed particles
for (var i = particles.length - 1; i >= 0; i--) {
if (particles[i].destroyed) {
particles.splice(i, 1);
}
}
// Clean up destroyed floating scores
for (var i = floatingScores.length - 1; i >= 0; i--) {
if (floatingScores[i].destroyed) {
floatingScores.splice(i, 1);
}
}
// Weather system
weatherTimer++;
if (weatherTimer % 300 === 0) {
isRaining = !isRaining;
}
// Generate rain
if (isRaining && weatherTimer % 3 === 0) {
var rain = new RainDrop();
rain.x = Math.random() * 2048;
rain.y = -20;
rainDrops.push(rain);
game.addChild(rain);
}
// Clean up rain drops
for (var i = rainDrops.length - 1; i >= 0; i--) {
if (rainDrops[i].destroyed) {
rainDrops.splice(i, 1);
}
}
// Screen shake effect
if (screenShake > 0) {
game.x = (Math.random() - 0.5) * screenShake;
game.y = (Math.random() - 0.5) * screenShake;
screenShake--;
} else {
game.x = 0;
game.y = 0;
}
};
// Start first question
startNewQuestion();
bunu yıpranmış orta çağ şatosuyla değiştir. In-Game asset. 2d. High contrast. No shadows
havada atlayan tatlı bir kedi çiz. In-Game asset. 2d. High contrast. No shadows
daha tatlı alevler çiz. In-Game asset. 2d. High contrast. No shadows
havadan düşen kediyi yakalamaya çalışan tatlı itfaiye adamı çiz. In-Game asset. 2d. High contrast. No shadows
tatlı duman çiz. In-Game asset. 2d. High contrast. No shadows
içi boş masal kitabı. In-Game asset. 2d. High contrast. No shadows