/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var FallingNumber = Container.expand(function (value, isBonus) { var self = Container.call(this); self.value = value; self.isBonus = isBonus || false; self.fallSpeed = 3 + Math.random() * 2; self.collected = false; var bgAsset = self.isBonus ? 'bonusBg' : 'numberBg'; var background = self.attachAsset(bgAsset, { anchorX: 0.5, anchorY: 0.5 }); var numberText = new Text2(value.toString(), { size: 60, fill: 0xFFFFFF }); numberText.anchor.set(0.5, 0.5); self.addChild(numberText); if (self.isBonus) { background.tint = 0xFFD700; tween(background, { scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(background, { scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeInOut }); } }); } self.update = function () { if (!self.collected) { self.y += self.fallSpeed; } }; self.down = function (x, y, obj) { if (!self.collected) { self.collected = true; collectItem(self); } }; return self; }); var FallingOperator = Container.expand(function (operator) { var self = Container.call(this); self.value = operator; self.fallSpeed = 3 + Math.random() * 2; self.collected = false; var background = self.attachAsset('operatorBg', { anchorX: 0.5, anchorY: 0.5 }); var operatorText = new Text2(operator, { size: 70, fill: 0xFFFFFF }); operatorText.anchor.set(0.5, 0.5); self.addChild(operatorText); self.update = function () { if (!self.collected) { self.y += self.fallSpeed; } }; self.down = function (x, y, obj) { if (!self.collected) { self.collected = true; collectItem(self); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2C3E50 }); /**** * Game Code ****/ var fallingItems = []; var currentEquation = []; var gameSpeed = 1; var spawnTimer = 0; var maxItemsOnScreen = 8; var consecutiveCorrect = 0; var gameLevel = 1; // UI Elements var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -20; scoreText.y = 20; var levelText = new Text2('Level: 1', { size: 50, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); LK.gui.topRight.addChild(levelText); levelText.x = -20; levelText.y = 90; var equationDisplay = new Text2('', { size: 80, fill: 0x000000 }); equationDisplay.anchor.set(0.5, 0.5); var equationContainer = game.addChild(new Container()); equationContainer.x = 1024; equationContainer.y = 150; var equationBg = equationContainer.attachAsset('equationBar', { anchorX: 0.5, anchorY: 0.5 }); equationContainer.addChild(equationDisplay); function getRandomNumber() { var maxNum = Math.min(9, Math.floor(gameLevel / 2) + 3); return Math.floor(Math.random() * maxNum) + 1; } function getRandomOperator() { var operators = ['+', '-']; if (gameLevel > 3) operators.push('×'); if (gameLevel > 5) operators.push('÷'); return operators[Math.floor(Math.random() * operators.length)]; } function spawnItem() { if (fallingItems.length >= maxItemsOnScreen) return; var x = 200 + Math.random() * 1648; var y = -100; var item; if (Math.random() < 0.3) { // Spawn operator item = new FallingOperator(getRandomOperator()); } else { // Spawn number var isBonus = Math.random() < 0.1 && gameLevel > 2; item = new FallingNumber(getRandomNumber(), isBonus); } item.x = x; item.y = y; fallingItems.push(item); game.addChild(item); } function collectItem(item) { currentEquation.push(item.value); updateEquationDisplay(); LK.getSound('collect').play(); tween(item, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 200, onFinish: function onFinish() { removeItem(item); } }); checkEquation(); } function updateEquationDisplay() { equationDisplay.setText(currentEquation.join(' ')); } function checkEquation() { if (currentEquation.length >= 3) { var equation = currentEquation.join(''); if (isValidEquation()) { evaluateEquation(); } } } function isValidEquation() { if (currentEquation.length < 3) return false; // Check pattern: number operator number var hasNumber1 = typeof currentEquation[0] === 'number'; var hasOperator = typeof currentEquation[1] === 'string' && ['+', '-', '×', '÷'].includes(currentEquation[1]); var hasNumber2 = typeof currentEquation[2] === 'number'; return hasNumber1 && hasOperator && hasNumber2; } function evaluateEquation() { var num1 = currentEquation[0]; var operator = currentEquation[1]; var num2 = currentEquation[2]; var result; switch (operator) { case '+': result = num1 + num2; break; case '-': result = num1 - num2; break; case '×': result = num1 * num2; break; case '÷': result = Math.floor(num1 / num2); break; } var points = calculatePoints(num1, operator, num2); LK.setScore(LK.getScore() + points); scoreText.setText('Score: ' + LK.getScore()); consecutiveCorrect++; LK.getSound('correct').play(); LK.effects.flashObject(equationContainer, 0x00FF00, 500); currentEquation = []; updateEquationDisplay(); // Level progression if (LK.getScore() > gameLevel * 500) { gameLevel++; levelText.setText('Level: ' + gameLevel); gameSpeed += 0.2; maxItemsOnScreen = Math.min(12, maxItemsOnScreen + 1); } } function calculatePoints(num1, operator, num2) { var basePoints = 10; switch (operator) { case '+': case '-': basePoints = 10; break; case '×': basePoints = 20; break; case '÷': basePoints = 25; break; } // Bonus for consecutive correct answers basePoints += consecutiveCorrect * 5; return basePoints; } function removeItem(item) { var index = fallingItems.indexOf(item); if (index > -1) { fallingItems.splice(index, 1); } item.destroy(); } function checkGameOver() { var itemsAtBottom = 0; for (var i = 0; i < fallingItems.length; i++) { if (fallingItems[i].y > 2732) { itemsAtBottom++; } } if (itemsAtBottom >= 5) { LK.showGameOver(); } } game.update = function () { spawnTimer++; var spawnRate = Math.max(30, 120 - gameLevel * 10); if (spawnTimer >= spawnRate) { spawnItem(); spawnTimer = 0; } // Remove items that have fallen off screen for (var i = fallingItems.length - 1; i >= 0; i--) { var item = fallingItems[i]; if (item.y > 2800) { removeItem(item); } } checkGameOver(); }; game.down = function (x, y, obj) { // Clear equation if clicked on empty space if (currentEquation.length > 0) { currentEquation = []; updateEquationDisplay(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var FallingNumber = Container.expand(function (value, isBonus) {
var self = Container.call(this);
self.value = value;
self.isBonus = isBonus || false;
self.fallSpeed = 3 + Math.random() * 2;
self.collected = false;
var bgAsset = self.isBonus ? 'bonusBg' : 'numberBg';
var background = self.attachAsset(bgAsset, {
anchorX: 0.5,
anchorY: 0.5
});
var numberText = new Text2(value.toString(), {
size: 60,
fill: 0xFFFFFF
});
numberText.anchor.set(0.5, 0.5);
self.addChild(numberText);
if (self.isBonus) {
background.tint = 0xFFD700;
tween(background, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(background, {
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
}
self.update = function () {
if (!self.collected) {
self.y += self.fallSpeed;
}
};
self.down = function (x, y, obj) {
if (!self.collected) {
self.collected = true;
collectItem(self);
}
};
return self;
});
var FallingOperator = Container.expand(function (operator) {
var self = Container.call(this);
self.value = operator;
self.fallSpeed = 3 + Math.random() * 2;
self.collected = false;
var background = self.attachAsset('operatorBg', {
anchorX: 0.5,
anchorY: 0.5
});
var operatorText = new Text2(operator, {
size: 70,
fill: 0xFFFFFF
});
operatorText.anchor.set(0.5, 0.5);
self.addChild(operatorText);
self.update = function () {
if (!self.collected) {
self.y += self.fallSpeed;
}
};
self.down = function (x, y, obj) {
if (!self.collected) {
self.collected = true;
collectItem(self);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2C3E50
});
/****
* Game Code
****/
var fallingItems = [];
var currentEquation = [];
var gameSpeed = 1;
var spawnTimer = 0;
var maxItemsOnScreen = 8;
var consecutiveCorrect = 0;
var gameLevel = 1;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -20;
scoreText.y = 20;
var levelText = new Text2('Level: 1', {
size: 50,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
LK.gui.topRight.addChild(levelText);
levelText.x = -20;
levelText.y = 90;
var equationDisplay = new Text2('', {
size: 80,
fill: 0x000000
});
equationDisplay.anchor.set(0.5, 0.5);
var equationContainer = game.addChild(new Container());
equationContainer.x = 1024;
equationContainer.y = 150;
var equationBg = equationContainer.attachAsset('equationBar', {
anchorX: 0.5,
anchorY: 0.5
});
equationContainer.addChild(equationDisplay);
function getRandomNumber() {
var maxNum = Math.min(9, Math.floor(gameLevel / 2) + 3);
return Math.floor(Math.random() * maxNum) + 1;
}
function getRandomOperator() {
var operators = ['+', '-'];
if (gameLevel > 3) operators.push('×');
if (gameLevel > 5) operators.push('÷');
return operators[Math.floor(Math.random() * operators.length)];
}
function spawnItem() {
if (fallingItems.length >= maxItemsOnScreen) return;
var x = 200 + Math.random() * 1648;
var y = -100;
var item;
if (Math.random() < 0.3) {
// Spawn operator
item = new FallingOperator(getRandomOperator());
} else {
// Spawn number
var isBonus = Math.random() < 0.1 && gameLevel > 2;
item = new FallingNumber(getRandomNumber(), isBonus);
}
item.x = x;
item.y = y;
fallingItems.push(item);
game.addChild(item);
}
function collectItem(item) {
currentEquation.push(item.value);
updateEquationDisplay();
LK.getSound('collect').play();
tween(item, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
removeItem(item);
}
});
checkEquation();
}
function updateEquationDisplay() {
equationDisplay.setText(currentEquation.join(' '));
}
function checkEquation() {
if (currentEquation.length >= 3) {
var equation = currentEquation.join('');
if (isValidEquation()) {
evaluateEquation();
}
}
}
function isValidEquation() {
if (currentEquation.length < 3) return false;
// Check pattern: number operator number
var hasNumber1 = typeof currentEquation[0] === 'number';
var hasOperator = typeof currentEquation[1] === 'string' && ['+', '-', '×', '÷'].includes(currentEquation[1]);
var hasNumber2 = typeof currentEquation[2] === 'number';
return hasNumber1 && hasOperator && hasNumber2;
}
function evaluateEquation() {
var num1 = currentEquation[0];
var operator = currentEquation[1];
var num2 = currentEquation[2];
var result;
switch (operator) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '×':
result = num1 * num2;
break;
case '÷':
result = Math.floor(num1 / num2);
break;
}
var points = calculatePoints(num1, operator, num2);
LK.setScore(LK.getScore() + points);
scoreText.setText('Score: ' + LK.getScore());
consecutiveCorrect++;
LK.getSound('correct').play();
LK.effects.flashObject(equationContainer, 0x00FF00, 500);
currentEquation = [];
updateEquationDisplay();
// Level progression
if (LK.getScore() > gameLevel * 500) {
gameLevel++;
levelText.setText('Level: ' + gameLevel);
gameSpeed += 0.2;
maxItemsOnScreen = Math.min(12, maxItemsOnScreen + 1);
}
}
function calculatePoints(num1, operator, num2) {
var basePoints = 10;
switch (operator) {
case '+':
case '-':
basePoints = 10;
break;
case '×':
basePoints = 20;
break;
case '÷':
basePoints = 25;
break;
}
// Bonus for consecutive correct answers
basePoints += consecutiveCorrect * 5;
return basePoints;
}
function removeItem(item) {
var index = fallingItems.indexOf(item);
if (index > -1) {
fallingItems.splice(index, 1);
}
item.destroy();
}
function checkGameOver() {
var itemsAtBottom = 0;
for (var i = 0; i < fallingItems.length; i++) {
if (fallingItems[i].y > 2732) {
itemsAtBottom++;
}
}
if (itemsAtBottom >= 5) {
LK.showGameOver();
}
}
game.update = function () {
spawnTimer++;
var spawnRate = Math.max(30, 120 - gameLevel * 10);
if (spawnTimer >= spawnRate) {
spawnItem();
spawnTimer = 0;
}
// Remove items that have fallen off screen
for (var i = fallingItems.length - 1; i >= 0; i--) {
var item = fallingItems[i];
if (item.y > 2800) {
removeItem(item);
}
}
checkGameOver();
};
game.down = function (x, y, obj) {
// Clear equation if clicked on empty space
if (currentEquation.length > 0) {
currentEquation = [];
updateEquationDisplay();
}
};