User prompt
Poner bola de pinchos
User prompt
Al comenzar empezar en el menú
User prompt
Un botón de menú
User prompt
Que haya otro modo que sea resta y comienza con 20
User prompt
Que el texto desaparezca en 15 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Pon un texto que tienes que sumar números
User prompt
Que los números sean más visibles
Code edit (1 edits merged)
Please save this source code
User prompt
Number Drop
Initial prompt
123
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var FallingNumber = Container.expand(function (value) {
var self = Container.call(this);
self.value = value;
self.speed = 3 + Math.random() * 2;
self.collected = false;
var numberGraphics = self.attachAsset('number' + value, {
anchorX: 0.5,
anchorY: 0.5
});
var numberText = new Text2(value.toString(), {
size: 60,
fill: '#ffffff'
});
numberText.anchor.set(0.5, 0.5);
self.addChild(numberText);
self.update = function () {
if (!self.collected) {
self.y += self.speed;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.move = function (targetX) {
self.x = Math.max(60, Math.min(2048 - 60, targetX));
};
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var SpikeBall = Container.expand(function () {
var self = Container.call(this);
self.speed = 2 + Math.random() * 3;
self.rotationSpeed = 0.1 + Math.random() * 0.1;
var spikeGraphics = self.attachAsset('spikeBall', {
anchorX: 0.5,
anchorY: 0.5
});
// Add spikes as visual elements
for (var i = 0; i < 8; i++) {
var spike = LK.getAsset('spikeBall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.8
});
var angle = i / 8 * Math.PI * 2;
spike.x = Math.cos(angle) * 40;
spike.y = Math.sin(angle) * 40;
spike.rotation = angle + Math.PI / 2;
self.addChild(spike);
}
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'playing'
var player = null;
var fallingNumbers = [];
var spikeBalls = [];
var collectedNumbers = [];
var gameMode = 'subtraction'; // 'addition' or 'subtraction'
var targetSum = 0;
var currentSum = 20; // Start with 20 for subtraction mode
var lives = 3;
var gameSpeed = 1;
var spawnTimer = 0;
var spawnRate = 90;
// Menu UI Elements
var menuTitle = new Text2('MATH CATCHER', {
size: 80,
fill: '#ffffff'
});
menuTitle.anchor.set(0.5, 0.5);
LK.gui.center.addChild(menuTitle);
menuTitle.y = -300;
var additionButton = new Text2('SUMA (+)', {
size: 60,
fill: '#4caf50'
});
additionButton.anchor.set(0.5, 0.5);
LK.gui.center.addChild(additionButton);
additionButton.y = -100;
var subtractionButton = new Text2('RESTA (-)', {
size: 60,
fill: '#2196f3'
});
subtractionButton.anchor.set(0.5, 0.5);
LK.gui.center.addChild(subtractionButton);
subtractionButton.y = 0;
var menuInstructions = new Text2('Selecciona un modo de juego', {
size: 40,
fill: '#ffffff'
});
menuInstructions.anchor.set(0.5, 0.5);
LK.gui.center.addChild(menuInstructions);
menuInstructions.y = 150;
// Game UI Elements (hidden initially)
var targetSumText = new Text2('Target: 0', {
size: 60,
fill: '#ffffff'
});
targetSumText.anchor.set(0.5, 0);
LK.gui.top.addChild(targetSumText);
targetSumText.y = 80;
targetSumText.visible = false;
var currentSumText = new Text2('Current: 0', {
size: 50,
fill: '#ffeb3b'
});
currentSumText.anchor.set(0.5, 0);
LK.gui.top.addChild(currentSumText);
currentSumText.y = 160;
currentSumText.visible = false;
var livesText = new Text2('Lives: 3', {
size: 50,
fill: '#f44336'
});
livesText.anchor.set(1, 0);
LK.gui.topRight.addChild(livesText);
livesText.x = -20;
livesText.y = 20;
livesText.visible = false;
var scoreText = new Text2('Score: 0', {
size: 50,
fill: '#ffffff'
});
scoreText.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreText);
scoreText.x = 120;
scoreText.y = 20;
scoreText.visible = false;
var menuButton = new Text2('MENU', {
size: 40,
fill: '#ffffff'
});
menuButton.anchor.set(0, 0);
LK.gui.topLeft.addChild(menuButton);
menuButton.x = 20;
menuButton.y = 80;
menuButton.visible = false;
var instructionText = new Text2('Arrastra para atrapar números\ny restarlos para llegar al objetivo', {
size: 40,
fill: '#ffffff'
});
instructionText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionText);
instructionText.y = -200;
instructionText.visible = false;
function generateTargetSum() {
if (gameMode === 'subtraction') {
targetSum = Math.floor(Math.random() * 15) + 1; // Target between 1-15
targetSumText.setText('Target: ' + targetSum);
} else {
targetSum = Math.floor(Math.random() * 20) + 5;
targetSumText.setText('Target: ' + targetSum);
}
}
function updateCurrentSum() {
if (gameMode === 'subtraction') {
currentSum = 20; // Reset to starting value
for (var i = 0; i < collectedNumbers.length; i++) {
currentSum -= collectedNumbers[i]; // Subtract instead of add
}
} else {
currentSum = 0;
for (var i = 0; i < collectedNumbers.length; i++) {
currentSum += collectedNumbers[i];
}
}
currentSumText.setText('Current: ' + currentSum);
}
function checkSum() {
if (currentSum === targetSum) {
LK.setScore(LK.getScore() + targetSum * 10);
LK.getSound('correct').play();
collectedNumbers = [];
generateTargetSum();
gameSpeed += 0.1;
spawnRate = Math.max(30, spawnRate - 2);
// Flash effect
tween(game, {}, {
duration: 200,
onFinish: function onFinish() {
LK.effects.flashScreen(0x00ff00, 300);
}
});
} else if (gameMode === 'subtraction' && currentSum < targetSum || gameMode === 'addition' && currentSum > targetSum) {
lives--;
LK.getSound('wrong').play();
collectedNumbers = [];
generateTargetSum();
if (lives <= 0) {
LK.showGameOver();
}
// Flash effect
LK.effects.flashScreen(0xff0000, 500);
}
}
function spawnNumber() {
var value = Math.floor(Math.random() * 10);
var number = new FallingNumber(value);
number.x = Math.random() * (2048 - 240) + 120;
number.y = -50;
number.speed *= gameSpeed;
fallingNumbers.push(number);
game.addChild(number);
}
function spawnSpikeBall() {
var spikeBall = new SpikeBall();
spikeBall.x = Math.random() * (2048 - 200) + 100;
spikeBall.y = -100;
spikeBall.speed *= gameSpeed;
spikeBalls.push(spikeBall);
game.addChild(spikeBall);
}
var dragNode = null;
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.move(x);
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (gameState === 'playing' && player) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
if (gameState === 'playing') {
dragNode = null;
}
};
function showMenu() {
gameState = 'menu';
// Show menu UI
menuTitle.visible = true;
additionButton.visible = true;
subtractionButton.visible = true;
menuInstructions.visible = true;
// Hide game UI
targetSumText.visible = false;
currentSumText.visible = false;
livesText.visible = false;
scoreText.visible = false;
menuButton.visible = false;
instructionText.visible = false;
// Clear game objects
if (player) {
player.destroy();
player = null;
}
for (var i = 0; i < fallingNumbers.length; i++) {
fallingNumbers[i].destroy();
}
fallingNumbers = [];
for (var i = 0; i < spikeBalls.length; i++) {
spikeBalls[i].destroy();
}
spikeBalls = [];
}
function startGame(mode) {
gameState = 'playing';
gameMode = mode;
// Hide menu UI
menuTitle.visible = false;
additionButton.visible = false;
subtractionButton.visible = false;
menuInstructions.visible = false;
// Show game UI
targetSumText.visible = true;
currentSumText.visible = true;
livesText.visible = true;
scoreText.visible = true;
menuButton.visible = true;
instructionText.visible = true;
// Initialize game
player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2732 - 100;
collectedNumbers = [];
spikeBalls = [];
lives = 3;
gameSpeed = 1;
spawnTimer = 0;
spawnRate = 90;
if (gameMode === 'subtraction') {
currentSum = 20;
instructionText.setText('Arrastra para atrapar números\ny restarlos para llegar al objetivo');
} else {
currentSum = 0;
instructionText.setText('Arrastra para atrapar números\ny sumarlos para llegar al objetivo');
}
generateTargetSum();
updateCurrentSum();
// Make instruction text disappear after 15 seconds
tween(instructionText, {
alpha: 0
}, {
duration: 15000,
onFinish: function onFinish() {
instructionText.visible = false;
instructionText.alpha = 1;
}
});
}
additionButton.down = function (x, y, obj) {
startGame('addition');
};
subtractionButton.down = function (x, y, obj) {
startGame('subtraction');
};
menuButton.down = function (x, y, obj) {
showMenu();
};
game.update = function () {
if (gameState !== 'playing') return;
spawnTimer++;
if (spawnTimer >= spawnRate) {
spawnNumber();
spawnTimer = 0;
}
// Spawn spike balls occasionally
if (LK.ticks % 180 === 0) {
spawnSpikeBall();
}
// Update spike balls
for (var i = spikeBalls.length - 1; i >= 0; i--) {
var spikeBall = spikeBalls[i];
if (spikeBall.lastY === undefined) spikeBall.lastY = spikeBall.y;
if (spikeBall.lastIntersecting === undefined) spikeBall.lastIntersecting = false;
// Check if off screen
if (spikeBall.lastY < 2732 + 100 && spikeBall.y >= 2732 + 100) {
spikeBall.destroy();
spikeBalls.splice(i, 1);
continue;
}
// Check collision with player
var currentIntersecting = spikeBall.intersects(player);
if (!spikeBall.lastIntersecting && currentIntersecting) {
lives--;
LK.getSound('wrong').play();
LK.effects.flashScreen(0xff0000, 500);
spikeBall.destroy();
spikeBalls.splice(i, 1);
if (lives <= 0) {
LK.showGameOver();
}
continue;
}
spikeBall.lastY = spikeBall.y;
spikeBall.lastIntersecting = currentIntersecting;
}
// Update falling numbers
for (var i = fallingNumbers.length - 1; i >= 0; i--) {
var number = fallingNumbers[i];
if (number.lastY === undefined) number.lastY = number.y;
if (number.lastIntersecting === undefined) number.lastIntersecting = false;
// Check if off screen
if (number.lastY < 2732 + 50 && number.y >= 2732 + 50) {
number.destroy();
fallingNumbers.splice(i, 1);
continue;
}
// Check collision with player
var currentIntersecting = number.intersects(player);
if (!number.lastIntersecting && currentIntersecting && !number.collected) {
number.collected = true;
collectedNumbers.push(number.value);
LK.getSound('collect').play();
// Animate collected number
tween(number, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
onFinish: function onFinish() {
number.destroy();
}
});
fallingNumbers.splice(i, 1);
updateCurrentSum();
checkSum();
continue;
}
number.lastY = number.y;
number.lastIntersecting = currentIntersecting;
}
// Update UI
scoreText.setText('Score: ' + LK.getScore());
livesText.setText('Lives: ' + lives);
};
// Start in menu state
showMenu(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var FallingNumber = Container.expand(function (value) {
var self = Container.call(this);
self.value = value;
self.speed = 3 + Math.random() * 2;
self.collected = false;
var numberGraphics = self.attachAsset('number' + value, {
anchorX: 0.5,
anchorY: 0.5
});
var numberText = new Text2(value.toString(), {
size: 60,
fill: '#ffffff'
});
numberText.anchor.set(0.5, 0.5);
self.addChild(numberText);
self.update = function () {
if (!self.collected) {
self.y += self.speed;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.move = function (targetX) {
self.x = Math.max(60, Math.min(2048 - 60, targetX));
};
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var SpikeBall = Container.expand(function () {
var self = Container.call(this);
self.speed = 2 + Math.random() * 3;
self.rotationSpeed = 0.1 + Math.random() * 0.1;
var spikeGraphics = self.attachAsset('spikeBall', {
anchorX: 0.5,
anchorY: 0.5
});
// Add spikes as visual elements
for (var i = 0; i < 8; i++) {
var spike = LK.getAsset('spikeBall', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.8
});
var angle = i / 8 * Math.PI * 2;
spike.x = Math.cos(angle) * 40;
spike.y = Math.sin(angle) * 40;
spike.rotation = angle + Math.PI / 2;
self.addChild(spike);
}
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state management
var gameState = 'menu'; // 'menu', 'playing'
var player = null;
var fallingNumbers = [];
var spikeBalls = [];
var collectedNumbers = [];
var gameMode = 'subtraction'; // 'addition' or 'subtraction'
var targetSum = 0;
var currentSum = 20; // Start with 20 for subtraction mode
var lives = 3;
var gameSpeed = 1;
var spawnTimer = 0;
var spawnRate = 90;
// Menu UI Elements
var menuTitle = new Text2('MATH CATCHER', {
size: 80,
fill: '#ffffff'
});
menuTitle.anchor.set(0.5, 0.5);
LK.gui.center.addChild(menuTitle);
menuTitle.y = -300;
var additionButton = new Text2('SUMA (+)', {
size: 60,
fill: '#4caf50'
});
additionButton.anchor.set(0.5, 0.5);
LK.gui.center.addChild(additionButton);
additionButton.y = -100;
var subtractionButton = new Text2('RESTA (-)', {
size: 60,
fill: '#2196f3'
});
subtractionButton.anchor.set(0.5, 0.5);
LK.gui.center.addChild(subtractionButton);
subtractionButton.y = 0;
var menuInstructions = new Text2('Selecciona un modo de juego', {
size: 40,
fill: '#ffffff'
});
menuInstructions.anchor.set(0.5, 0.5);
LK.gui.center.addChild(menuInstructions);
menuInstructions.y = 150;
// Game UI Elements (hidden initially)
var targetSumText = new Text2('Target: 0', {
size: 60,
fill: '#ffffff'
});
targetSumText.anchor.set(0.5, 0);
LK.gui.top.addChild(targetSumText);
targetSumText.y = 80;
targetSumText.visible = false;
var currentSumText = new Text2('Current: 0', {
size: 50,
fill: '#ffeb3b'
});
currentSumText.anchor.set(0.5, 0);
LK.gui.top.addChild(currentSumText);
currentSumText.y = 160;
currentSumText.visible = false;
var livesText = new Text2('Lives: 3', {
size: 50,
fill: '#f44336'
});
livesText.anchor.set(1, 0);
LK.gui.topRight.addChild(livesText);
livesText.x = -20;
livesText.y = 20;
livesText.visible = false;
var scoreText = new Text2('Score: 0', {
size: 50,
fill: '#ffffff'
});
scoreText.anchor.set(0, 0);
LK.gui.topLeft.addChild(scoreText);
scoreText.x = 120;
scoreText.y = 20;
scoreText.visible = false;
var menuButton = new Text2('MENU', {
size: 40,
fill: '#ffffff'
});
menuButton.anchor.set(0, 0);
LK.gui.topLeft.addChild(menuButton);
menuButton.x = 20;
menuButton.y = 80;
menuButton.visible = false;
var instructionText = new Text2('Arrastra para atrapar números\ny restarlos para llegar al objetivo', {
size: 40,
fill: '#ffffff'
});
instructionText.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionText);
instructionText.y = -200;
instructionText.visible = false;
function generateTargetSum() {
if (gameMode === 'subtraction') {
targetSum = Math.floor(Math.random() * 15) + 1; // Target between 1-15
targetSumText.setText('Target: ' + targetSum);
} else {
targetSum = Math.floor(Math.random() * 20) + 5;
targetSumText.setText('Target: ' + targetSum);
}
}
function updateCurrentSum() {
if (gameMode === 'subtraction') {
currentSum = 20; // Reset to starting value
for (var i = 0; i < collectedNumbers.length; i++) {
currentSum -= collectedNumbers[i]; // Subtract instead of add
}
} else {
currentSum = 0;
for (var i = 0; i < collectedNumbers.length; i++) {
currentSum += collectedNumbers[i];
}
}
currentSumText.setText('Current: ' + currentSum);
}
function checkSum() {
if (currentSum === targetSum) {
LK.setScore(LK.getScore() + targetSum * 10);
LK.getSound('correct').play();
collectedNumbers = [];
generateTargetSum();
gameSpeed += 0.1;
spawnRate = Math.max(30, spawnRate - 2);
// Flash effect
tween(game, {}, {
duration: 200,
onFinish: function onFinish() {
LK.effects.flashScreen(0x00ff00, 300);
}
});
} else if (gameMode === 'subtraction' && currentSum < targetSum || gameMode === 'addition' && currentSum > targetSum) {
lives--;
LK.getSound('wrong').play();
collectedNumbers = [];
generateTargetSum();
if (lives <= 0) {
LK.showGameOver();
}
// Flash effect
LK.effects.flashScreen(0xff0000, 500);
}
}
function spawnNumber() {
var value = Math.floor(Math.random() * 10);
var number = new FallingNumber(value);
number.x = Math.random() * (2048 - 240) + 120;
number.y = -50;
number.speed *= gameSpeed;
fallingNumbers.push(number);
game.addChild(number);
}
function spawnSpikeBall() {
var spikeBall = new SpikeBall();
spikeBall.x = Math.random() * (2048 - 200) + 100;
spikeBall.y = -100;
spikeBall.speed *= gameSpeed;
spikeBalls.push(spikeBall);
game.addChild(spikeBall);
}
var dragNode = null;
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.move(x);
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (gameState === 'playing' && player) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
if (gameState === 'playing') {
dragNode = null;
}
};
function showMenu() {
gameState = 'menu';
// Show menu UI
menuTitle.visible = true;
additionButton.visible = true;
subtractionButton.visible = true;
menuInstructions.visible = true;
// Hide game UI
targetSumText.visible = false;
currentSumText.visible = false;
livesText.visible = false;
scoreText.visible = false;
menuButton.visible = false;
instructionText.visible = false;
// Clear game objects
if (player) {
player.destroy();
player = null;
}
for (var i = 0; i < fallingNumbers.length; i++) {
fallingNumbers[i].destroy();
}
fallingNumbers = [];
for (var i = 0; i < spikeBalls.length; i++) {
spikeBalls[i].destroy();
}
spikeBalls = [];
}
function startGame(mode) {
gameState = 'playing';
gameMode = mode;
// Hide menu UI
menuTitle.visible = false;
additionButton.visible = false;
subtractionButton.visible = false;
menuInstructions.visible = false;
// Show game UI
targetSumText.visible = true;
currentSumText.visible = true;
livesText.visible = true;
scoreText.visible = true;
menuButton.visible = true;
instructionText.visible = true;
// Initialize game
player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2732 - 100;
collectedNumbers = [];
spikeBalls = [];
lives = 3;
gameSpeed = 1;
spawnTimer = 0;
spawnRate = 90;
if (gameMode === 'subtraction') {
currentSum = 20;
instructionText.setText('Arrastra para atrapar números\ny restarlos para llegar al objetivo');
} else {
currentSum = 0;
instructionText.setText('Arrastra para atrapar números\ny sumarlos para llegar al objetivo');
}
generateTargetSum();
updateCurrentSum();
// Make instruction text disappear after 15 seconds
tween(instructionText, {
alpha: 0
}, {
duration: 15000,
onFinish: function onFinish() {
instructionText.visible = false;
instructionText.alpha = 1;
}
});
}
additionButton.down = function (x, y, obj) {
startGame('addition');
};
subtractionButton.down = function (x, y, obj) {
startGame('subtraction');
};
menuButton.down = function (x, y, obj) {
showMenu();
};
game.update = function () {
if (gameState !== 'playing') return;
spawnTimer++;
if (spawnTimer >= spawnRate) {
spawnNumber();
spawnTimer = 0;
}
// Spawn spike balls occasionally
if (LK.ticks % 180 === 0) {
spawnSpikeBall();
}
// Update spike balls
for (var i = spikeBalls.length - 1; i >= 0; i--) {
var spikeBall = spikeBalls[i];
if (spikeBall.lastY === undefined) spikeBall.lastY = spikeBall.y;
if (spikeBall.lastIntersecting === undefined) spikeBall.lastIntersecting = false;
// Check if off screen
if (spikeBall.lastY < 2732 + 100 && spikeBall.y >= 2732 + 100) {
spikeBall.destroy();
spikeBalls.splice(i, 1);
continue;
}
// Check collision with player
var currentIntersecting = spikeBall.intersects(player);
if (!spikeBall.lastIntersecting && currentIntersecting) {
lives--;
LK.getSound('wrong').play();
LK.effects.flashScreen(0xff0000, 500);
spikeBall.destroy();
spikeBalls.splice(i, 1);
if (lives <= 0) {
LK.showGameOver();
}
continue;
}
spikeBall.lastY = spikeBall.y;
spikeBall.lastIntersecting = currentIntersecting;
}
// Update falling numbers
for (var i = fallingNumbers.length - 1; i >= 0; i--) {
var number = fallingNumbers[i];
if (number.lastY === undefined) number.lastY = number.y;
if (number.lastIntersecting === undefined) number.lastIntersecting = false;
// Check if off screen
if (number.lastY < 2732 + 50 && number.y >= 2732 + 50) {
number.destroy();
fallingNumbers.splice(i, 1);
continue;
}
// Check collision with player
var currentIntersecting = number.intersects(player);
if (!number.lastIntersecting && currentIntersecting && !number.collected) {
number.collected = true;
collectedNumbers.push(number.value);
LK.getSound('collect').play();
// Animate collected number
tween(number, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
onFinish: function onFinish() {
number.destroy();
}
});
fallingNumbers.splice(i, 1);
updateCurrentSum();
checkSum();
continue;
}
number.lastY = number.y;
number.lastIntersecting = currentIntersecting;
}
// Update UI
scoreText.setText('Score: ' + LK.getScore());
livesText.setText('Lives: ' + lives);
};
// Start in menu state
showMenu();