User prompt
Borre el asset del Kiwi, lo necesito de vuelta
User prompt
Limpia el codigo de partes que no sean necesarias.
User prompt
Cuando se reinicia el juego por un momento aparecen muchas frutas generadas en la parte inferior.
User prompt
Si reinicia cuando fallo las frutas pero no cuando las corto todas.
User prompt
Please fix the bug: 'TypeError: setTimeout is not a function' in or related to this line: 'frutasFalladasTimeout = setTimeout(function () {' Line Number: 644
Code edit (1 edits merged)
Please save this source code
User prompt
No reinicio la ronda después de los dos segundos.
User prompt
Cuando el contador llegue a 5 espera dos segundos e inicia nuevamente la ronda.
User prompt
Cuando el contador llegue a 5 inicia nuevamente la ronda.
User prompt
Cuando una fruta no sea cortada y se elimine el circulo blanco o la fruta salga de la pantalla tambien hay que contarla.
User prompt
Cambia el contador, que solo sume 1 cuando se corta o se pierde una fruta.
User prompt
Imprime en pantalla un contador de las frutas generadas.
User prompt
Limpia el codigo de partes que no sean necesarias
User prompt
"Implementa una variable llamada frutasFalladas que aumente en 1 cada vez que una fruta sea cortada incorrectamente o se pierda. Cuando frutasFalladas alcance 5, reinicia el juego, reseteando todas las variables y estados relevantes para empezar desde cero."
User prompt
Diagnóstico principal El sistema usa 3 estados para manejar las "rondas" de frutas: waiting: espera para iniciar nueva ronda spawning: lanza frutas, hasta 5 (roundBullets) waitingFruits: espera 2 segundos antes de reiniciar la ronda El problema puede estar en la transición entre estados y en la limpieza de las frutas para permitir que se inicie una nueva ronda. Posibles causas por las que no salen frutas tras la primera ronda Las frutas no se marcan correctamente como "destruidas" (destroyed) y quedan en las listas roundFruitsQueue o roundFruitsActive. Esto hace que la condición allGone sea siempre false y no pase a 'waitingFruits'. Las frutas que vuelven a aparecer (las que suben para ser cortadas) no se eliminan bien o no se gestionan correctamente en los arrays y el estado no avanza. La limpieza entre rondas no elimina todos los objetos ni limpia los arrays correctamente.
User prompt
El código solo lanza una ronda (5 frutas) y después no vuelve a lanzar más frutas. Quiero que el juego funcione de forma cíclica, es decir, que tras acabar una ronda y un pequeño delay, se inicie automáticamente la siguiente ronda, y así sucesivamente. Te paso el fragmento clave del código de la función de actualización (game.update) y manejo de rondas. El problema parece estar en la lógica que controla el estado de las rondas (roundState) y la forma en que verifico cuándo iniciar una nueva ronda. La lógica es esta: El estado roundState puede ser 'waiting', 'spawning', 'waitingFruits', 'reset'. En 'waiting' se prepara una nueva ronda y se pasa a 'spawning'. En 'spawning' se lanzan frutas cada 1s hasta 5. Cuando se terminan de lanzar las frutas y todas han sido destruidas o han salido de pantalla, paso a 'waitingFruits'. En 'waitingFruits' espero 2 segundos para reiniciar la ronda. Sin embargo, después de la primera ronda, el juego no vuelve a lanzar frutas. ¿Puedes revisar esta lógica y corregir el problema para que las rondas se reinicien correctamente? También, si ves alguna mejora o limpieza en el manejo de los arrays de frutas (fruits, fallingFruits, etc.), indícamela.
User prompt
El tiempo total que tarda en aparecer cada fruta en la pantalla superior debe ser proporcional al número de frutas lanzadas. Específicamente: la transición desde la pantalla inferior hasta su aparición en la pantalla superior debe tomar 1 segundo por cada fruta lanzada en esa ronda. Por ejemplo, si se lanzan 5 frutas, la transición deberá durar exactamente 5 segundos antes de que empiecen a salir hacia arriba. Además, cuando todas las frutas hayan sido destruidas o salgan de la pantalla, el juego debe reiniciar automáticamente una nueva ronda con las mismas condiciones.
User prompt
Prompt para corregir y completar el comportamiento de las balas Lanza solo 5 balas, con una separación de 1 segundo entre cada una. Cada bala, al transicionar de la pantalla inferior a la pantalla superior, no debe aparecer de inmediato. Espera exactamente 7 segundos desde que cruza a la pantalla superior antes de mostrarla. El temporizador de 7 segundos debe comenzar justo al cruzar, no antes. Si la bala es destruida o sale de pantalla antes de que pasen los 7 segundos, no debe mostrarse. Una vez que todas las 5 balas hayan sido destruidas o salieron de pantalla, el sistema debe reiniciar automáticamente el disparo de otras 5 balas bajo las mismas condiciones.
User prompt
Disparar solo 5 balas por ronda: Limita el disparo a exactamente 5 balas por ciclo/ronda. Esto puede ser mediante un contador o una lista con tiempo de disparo planificado. Separación de 1 segundo entre balas: Usa un temporizador para que cada bala se dispare con 1 segundo de diferencia. Ejemplo: si la primera bala se dispara en el segundo t0, la siguiente será en t0 + 1s, la siguiente en t0 + 2s, etc., hasta llegar a la quinta bala. Aumentar el tiempo de espera antes de salir (desaparecer): Una vez que la bala entra a la parte superior de la pantalla, espera más tiempo antes de salir. Ajusta este tiempo a 7 segundos en total desde que la bala entra (es decir, puede quedarse 7 segundos antes de ser eliminada, desvanecida, o salir por completo de pantalla). ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Prompt para corrección y mejora del código de frutas cortables: Habilitar corte desde la transición a la pantalla superior: Modifica la lógica para que las frutas sean cortables desde el momento en que comienzan a subir hacia la parte superior de la pantalla (es decir, desde que aparecen y suben en la parte superior, no solo cuando ya están en una zona fija). Esto implica que la fruta debe tener el estado que permita el corte ('cuttable' o similar) desde que empieza esa subida. Mostrar círculo blanco dentro de la fruta, con efecto difuminado y crecimiento progresivo: El círculo de corte debe aparecer centrado en la fruta, no alrededor ni separado de ella, y debe tener un efecto visual suave, como un difuminado o transparencia gradual (usando alpha bajo y borde suave). Además, el círculo debe empezar pequeño y crecer lentamente a un tamaño máximo mientras la fruta sube, dando una sensación de “preparación para corte”. Movimiento continuo de la fruta con círculo: Asegúrate de que mientras el círculo está visible, la fruta continúa moviéndose hacia arriba, sin detenerse, para que no se congele en pantalla. Condiciones para activar/desactivar el círculo: El círculo debe comenzar a aparecer justo cuando la fruta inicia su subida y crecer hasta un tamaño máximo al llegar cerca de la parte superior, luego debe desaparecer cuando la fruta sale de la pantalla o es cortada. Ajustar escala y posición del círculo para que siempre siga a la fruta: En cada frame, el círculo debe actualizar su posición para estar siempre centrado en la fruta y escalar de acuerdo al efecto de crecimiento. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Cuando la fruta entra en el estado 'cuttable' para mostrar el círculo blanco, actualmente la fruta no se mueve y queda congelada en pantalla. Para que siga subiendo, la lógica de movimiento vertical debe incluir también el estado 'cuttable', moviendo la fruta hacia arriba en ese estado y actualizando la posición del círculo blanco junto con la fruta. Esto hará que las frutas sigan su camino y no se detengan al mostrar el círculo.
User prompt
Las frutas suben y se pueden cortar en una zona específica. Pero cuando una fruta llega a la parte superior y no es cortada, se queda congelada ahí sin seguir moviéndose ni salir de la pantalla. Necesito que esas frutas que no se cortan sigan subiendo hasta salir por completo de la pantalla y que se eliminen correctamente cuando ya no se vean. También que cualquier efecto visual relacionado (como el círculo blanco de corte) desaparezca cuando la fruta se vaya.
User prompt
Please fix the bug: 'game.start is not a function' in or related to this line: 'game.start();' Line Number: 324
Code edit (1 edits merged)
Please save this source code
User prompt
Por favor, ajusta el juego con estas correcciones: Actualmente, las frutas que no se cortan se quedan congeladas en el punto de corte. Cambia la lógica para que si una fruta no es cortada, continúe su camino hacia arriba y eventualmente salga de la pantalla. El círculo blanco traslúcido que indica la zona de corte no debe aparecer de repente cuando la fruta llega a ese punto. En vez de eso, debe aparecer un poco antes, y mientras la fruta se acerca al punto de corte, el círculo debe ir apareciendo y agrandándose suavemente, creando una animación progresiva. Asegúrate que el círculo desaparezca correctamente si la fruta es cortada o si pasa sin cortarse. Modifica principalmente la parte del game.update donde se maneja la aparición y animación del círculo de corte, y el estado de la fruta cuando no es cortada.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Clase para la fruta entera var Fruit = Container.expand(function () { var self = Container.call(this); // Selección aleatoria de tipo de fruta var fruitTypes = ['fruit_apple', 'fruit_lemon', 'fruit_orange', 'fruit_kiwi', 'fruit_plum']; self.fruitType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)]; // Asset de la fruta self.fruitAsset = self.attachAsset(self.fruitType, { anchorX: 0.5, anchorY: 0.5 }); self.radius = self.fruitAsset.width / 2; // Estado self.isCut = false; self.isActive = true; // Si está en juego // Para saber si ya fue cortada self.cut = function () { if (self.isCut) return; self.isCut = true; self.isActive = false; self.visible = false; }; return self; }); // Clase para la fruta cortada (dos mitades) var FruitCut = Container.expand(function () { var self = Container.call(this); // Recibe tipo de fruta y posición base self.init = function (fruitType, x, y) { // Mitad izquierda self.left = self.attachAsset(fruitType, { anchorX: 1, anchorY: 0.5, scaleX: 0.5, x: 0, y: 0 }); // Mitad derecha self.right = self.attachAsset(fruitType, { anchorX: 0, anchorY: 0.5, scaleX: 0.5, x: 0, y: 0 }); self.x = x; self.y = y; self.left.rotation = 0; self.right.rotation = 0; }; // Animación de separación self.animate = function (_onFinish) { tween(self.left, { x: -80, rotation: -0.7 }, { duration: 500, easing: tween.cubicOut }); tween(self.right, { x: 80, rotation: 0.7 }, { duration: 500, easing: tween.cubicOut, onFinish: function onFinish() { if (_onFinish) _onFinish(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Sonido de corte // Efecto de corte (línea) // Frutas: Usamos formas básicas para representar diferentes frutas // Eliminado: zona de corte y línea de corte. Ahora el círculo de corte es dinámico y aparece solo cuando la fruta puede ser cortada. // Score var scoreTxt = new Text2('0', { size: 120, fill: "#222" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Variables globales var fruits = []; // Frutas lanzadas desde abajo var fallingFruits = []; // Frutas que caen desde arriba var cutFruits = []; // Frutas cortadas (animación) var spawnDelay = 40; // ticks entre frutas var fruitSpeed = 22; // velocidad de subida/bajada var fruitTimer = 0; // Obtener el radio del asset de zona de corte (cut_zone) usando LK.getAsset var cutZoneAsset = LK.getAsset('cut_zone', { anchorX: 0.5, anchorY: 0.5 }); var cutZoneRadius = cutZoneAsset.width / 2; cutZoneAsset.destroy(); // No lo necesitamos en pantalla, solo para el tamaño var canCut = true; // Para evitar múltiples cortes por fruta var lastTouchTick = -100; // Función para lanzar una fruta desde abajo hasta el centro function spawnFruit() { var fruit = new Fruit(); // Posición X aleatoria (dejando margen a los lados) var margin = 180; fruit.x = margin + Math.random() * (2048 - 2 * margin); fruit.y = 2732 + fruit.radius + 10; fruit.startY = fruit.y; fruit.targetY = 2732 / 2 + 420; // Centro inferior fruit.state = 'rising'; fruit.ticks = 0; fruits.push(fruit); game.addChild(fruit); } // Función para hacer aparecer la fruta en el centro y que suba hacia arriba function spawnFallingFruit(fruitType, x) { var fruit = new Fruit(); fruit.fruitType = fruitType; fruit.fruitAsset.destroy(); fruit.fruitAsset = fruit.attachAsset(fruitType, { anchorX: 0.5, anchorY: 0.5 }); fruit.x = x; fruit.y = 2732 / 2 + 420; // Aparece en el centro inferior fruit.startY = fruit.y; fruit.state = 'falling'; fruit.ticks = 0; // Rotación aleatoria y velocidad de rotación suave fruit.rotation = Math.random() * Math.PI * 2; fruit.rotationSpeed = (Math.random() - 0.5) * 0.04; fallingFruits.push(fruit); game.addChild(fruit); } // Actualiza score function updateScore(val) { LK.setScore(val); scoreTxt.setText(val); } // Nueva lógica de corte: el corte se detecta solo cuando la fruta está en la zona de corte visual (círculo blanco animado). function tryCutFruit(x, y) { // Solo permite un corte por tick if (!canCut) return; canCut = false; lastTouchTick = LK.ticks; // Buscar fruta que esté en estado 'cuttable', activa, y que el toque esté sobre la fruta for (var i = 0; i < fallingFruits.length; i++) { var fruit = fallingFruits[i]; if (!fruit.isActive) continue; // Solo permite cortar si la fruta está en la zona de corte, está subiendo (no cayendo), y el toque está sobre la fruta if (fruit.state === 'cuttable') { // Verifica si el toque está sobre la fruta (dentro del radio de la fruta) var dx = x - fruit.x; var dy = y - fruit.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist <= fruit.radius * fruit.scaleX) { // Cortar fruta fruit.cut(); // Destruir inmediatamente el círculo de corte si existe if (fruit.cutZoneCircle) { fruit.cutZoneCircle.destroy(); fruit.cutZoneCircle = null; } LK.getSound('cut').play(); // Animación de mitades var fruitCut = new FruitCut(); fruitCut.init(fruit.fruitType, fruit.x, fruit.y); game.addChild(fruitCut); fruitCut.animate(function () { fruitCut.destroy(); }); cutFruits.push(fruitCut); updateScore(LK.getScore() + 1); return; } } } } // Input: solo touch/click game.down = function (x, y, obj) { // Solo intenta cortar si hay fruta cortable y el toque es sobre la fruta tryCutFruit(x, y); }; game.up = function (x, y, obj) {}; game.move = function (x, y, obj) {}; // Main update game.update = function () { // Permitir corte nuevamente tras 6 ticks (~100ms) if (!canCut && LK.ticks - lastTouchTick > 6) canCut = true; // Lanzar frutas periódicamente fruitTimer++; if (fruitTimer >= spawnDelay) { fruitTimer = 0; spawnFruit(); } // Mover frutas que suben desde abajo hasta el centro for (var i = fruits.length - 1; i >= 0; i--) { var fruit = fruits[i]; if (fruit.state === 'rising') { fruit.y -= fruitSpeed; fruit.ticks++; // Cuando llega a la altura objetivo (centro), desaparece y tras breve delay aparece subiendo hacia arriba if (fruit.y <= fruit.targetY) { var fruitType = fruit.fruitType; var x = fruit.x; fruit.destroy(); fruits.splice(i, 1); // Tras breve delay, aparece en el centro y sube hacia arriba (function (ft, fx) { var delay = 18 + Math.floor(Math.random() * 8); LK.setTimeout(function () { spawnFallingFruit(ft, fx); }, delay * 16); })(fruitType, x); } } } // Mover frutas que suben de nuevo y gestionar zona de corte visual for (var i = fallingFruits.length - 1; i >= 0; i--) { var fruit = fallingFruits[i]; if (!fruit.isActive) continue; // Escalado según altura (más arriba, más grande) var minScale = 1.0; var maxScale = 1.25; var y0 = 2732 / 2 + 420; var y1 = 420; var t = (y0 - fruit.y) / (y0 - y1); if (t < 0) t = 0; if (t > 1) t = 1; var scale = minScale + (maxScale - minScale) * t; fruit.scaleX = fruit.scaleY = scale; // Rotación suave if (typeof fruit.rotationSpeed !== "undefined") { fruit.rotation += fruit.rotationSpeed; if (fruit.fruitAsset) fruit.fruitAsset.rotation = fruit.rotation; } // Movimiento hacia arriba if (fruit.state === 'falling') { fruit.y -= fruitSpeed; fruit.ticks++; // --- Animación progresiva del círculo de corte --- var cutY = 420; // Y donde puede ser cortada var cutWindow = 60; // margen de ventana de corte var cutAppearWindow = 120; // margen donde empieza a aparecer el círculo antes de la zona de corte var distToCut = fruit.y - cutY; // Si está dentro de la ventana de aparición del círculo (antes de la zona de corte) if (distToCut <= cutAppearWindow && distToCut >= -cutWindow) { // Si no existe el círculo, crearlo if (!fruit.cutZoneCircle) { fruit.cutZoneCircle = LK.getAsset('cut_zone', { anchorX: 0.5, anchorY: 0.5, x: fruit.x, y: fruit.y, alpha: 0.0, scaleX: 0.1, scaleY: 0.1 }); game.addChild(fruit.cutZoneCircle); } // Animar tamaño y alpha progresivamente según cercanía al punto de corte var appearT = 1 - (distToCut - -cutWindow) / (cutAppearWindow + cutWindow); if (appearT < 0) appearT = 0; if (appearT > 1) appearT = 1; var maxScaleZone = 1.1; var minScaleZone = 0.1; var maxAlpha = 0.5; var minAlpha = 0.0; var scaleZone = minScaleZone + (maxScaleZone - minScaleZone) * appearT; var alphaZone = minAlpha + (maxAlpha - minAlpha) * appearT; fruit.cutZoneCircle.scaleX = fruit.cutZoneCircle.scaleY = scaleZone; fruit.cutZoneCircle.alpha = alphaZone; fruit.cutZoneCircle.x = fruit.x; fruit.cutZoneCircle.y = fruit.y; // Si está en la zona de corte, permitir corte if (distToCut <= cutWindow && distToCut >= -cutWindow) { fruit.state = 'cuttable'; } } else { // Si sale de la ventana de aparición y existe el círculo, destruirlo if (fruit.cutZoneCircle) { fruit.cutZoneCircle.destroy(); fruit.cutZoneCircle = null; } } } // Si está en zona de corte, seguir el círculo con la fruta y permitir corte if (fruit.state === 'cuttable' && fruit.cutZoneCircle) { fruit.cutZoneCircle.x = fruit.x; fruit.cutZoneCircle.y = fruit.y; // Si sale de la ventana de corte sin ser cortada, destruir círculo y continuar subiendo var cutY = 420; var cutWindow = 60; if (fruit.y < cutY - cutWindow) { if (fruit.cutZoneCircle) { fruit.cutZoneCircle.destroy(); fruit.cutZoneCircle = null; } fruit.state = 'flyingup'; // Continúa subiendo, ya no puede ser cortada } } // Si fue cortada, eliminar círculo visual inmediatamente pero mantener la fruta visible if (!fruit.isActive && fruit.cutZoneCircle) { fruit.cutZoneCircle.destroy(); fruit.cutZoneCircle = null; } // Si está cayendo, animar caída if (fruit.state === 'dropping') { fruit.dropSpeed += 2.5; // gravedad fruit.y += fruit.dropSpeed; // Escalado decreciente al caer fruit.scaleX = fruit.scaleY = Math.max(0.7, fruit.scaleX - 0.01); if (fruit.cutZoneCircle) { fruit.cutZoneCircle.x = fruit.x; fruit.cutZoneCircle.y = fruit.y; } // Si sale de pantalla, marcar como inactivo pero mantener visible if (fruit.y > 2732 + fruit.radius + 20) { if (fruit.cutZoneCircle) { fruit.cutZoneCircle.destroy(); fruit.cutZoneCircle = null; } fruit.isActive = false; } } // Si la fruta sigue subiendo después de la zona de corte y no fue cortada if (fruit.state === 'flyingup') { fruit.y -= fruitSpeed; // Escalado sigue creciendo un poco fruit.scaleX = fruit.scaleY = Math.min(maxScale, fruit.scaleX + 0.01); // Si sale de pantalla por arriba, marcar como inactiva if (fruit.y < -fruit.radius - 20) { fruit.isActive = false; } } // Si la fruta ya fue cortada o salió de pantalla, eliminar if (!fruit.isActive || fruit.y > 2732 + fruit.radius + 20 || fruit.y < -fruit.radius - 20) { if (fruit.cutZoneCircle) { fruit.cutZoneCircle.destroy(); fruit.cutZoneCircle = null; } fruit.destroy(); fallingFruits.splice(i, 1); } } // Limpiar mitades cortadas que ya terminaron animación for (var i = cutFruits.length - 1; i >= 0; i--) { var fc = cutFruits[i]; if (!fc.left || !fc.right) { cutFruits.splice(i, 1); } } }; // Inicializar score updateScore(0);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Clase para la fruta entera
var Fruit = Container.expand(function () {
var self = Container.call(this);
// Selección aleatoria de tipo de fruta
var fruitTypes = ['fruit_apple', 'fruit_lemon', 'fruit_orange', 'fruit_kiwi', 'fruit_plum'];
self.fruitType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)];
// Asset de la fruta
self.fruitAsset = self.attachAsset(self.fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = self.fruitAsset.width / 2;
// Estado
self.isCut = false;
self.isActive = true; // Si está en juego
// Para saber si ya fue cortada
self.cut = function () {
if (self.isCut) return;
self.isCut = true;
self.isActive = false;
self.visible = false;
};
return self;
});
// Clase para la fruta cortada (dos mitades)
var FruitCut = Container.expand(function () {
var self = Container.call(this);
// Recibe tipo de fruta y posición base
self.init = function (fruitType, x, y) {
// Mitad izquierda
self.left = self.attachAsset(fruitType, {
anchorX: 1,
anchorY: 0.5,
scaleX: 0.5,
x: 0,
y: 0
});
// Mitad derecha
self.right = self.attachAsset(fruitType, {
anchorX: 0,
anchorY: 0.5,
scaleX: 0.5,
x: 0,
y: 0
});
self.x = x;
self.y = y;
self.left.rotation = 0;
self.right.rotation = 0;
};
// Animación de separación
self.animate = function (_onFinish) {
tween(self.left, {
x: -80,
rotation: -0.7
}, {
duration: 500,
easing: tween.cubicOut
});
tween(self.right, {
x: 80,
rotation: 0.7
}, {
duration: 500,
easing: tween.cubicOut,
onFinish: function onFinish() {
if (_onFinish) _onFinish();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Sonido de corte
// Efecto de corte (línea)
// Frutas: Usamos formas básicas para representar diferentes frutas
// Eliminado: zona de corte y línea de corte. Ahora el círculo de corte es dinámico y aparece solo cuando la fruta puede ser cortada.
// Score
var scoreTxt = new Text2('0', {
size: 120,
fill: "#222"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Variables globales
var fruits = []; // Frutas lanzadas desde abajo
var fallingFruits = []; // Frutas que caen desde arriba
var cutFruits = []; // Frutas cortadas (animación)
var spawnDelay = 40; // ticks entre frutas
var fruitSpeed = 22; // velocidad de subida/bajada
var fruitTimer = 0;
// Obtener el radio del asset de zona de corte (cut_zone) usando LK.getAsset
var cutZoneAsset = LK.getAsset('cut_zone', {
anchorX: 0.5,
anchorY: 0.5
});
var cutZoneRadius = cutZoneAsset.width / 2;
cutZoneAsset.destroy(); // No lo necesitamos en pantalla, solo para el tamaño
var canCut = true; // Para evitar múltiples cortes por fruta
var lastTouchTick = -100;
// Función para lanzar una fruta desde abajo hasta el centro
function spawnFruit() {
var fruit = new Fruit();
// Posición X aleatoria (dejando margen a los lados)
var margin = 180;
fruit.x = margin + Math.random() * (2048 - 2 * margin);
fruit.y = 2732 + fruit.radius + 10;
fruit.startY = fruit.y;
fruit.targetY = 2732 / 2 + 420; // Centro inferior
fruit.state = 'rising';
fruit.ticks = 0;
fruits.push(fruit);
game.addChild(fruit);
}
// Función para hacer aparecer la fruta en el centro y que suba hacia arriba
function spawnFallingFruit(fruitType, x) {
var fruit = new Fruit();
fruit.fruitType = fruitType;
fruit.fruitAsset.destroy();
fruit.fruitAsset = fruit.attachAsset(fruitType, {
anchorX: 0.5,
anchorY: 0.5
});
fruit.x = x;
fruit.y = 2732 / 2 + 420; // Aparece en el centro inferior
fruit.startY = fruit.y;
fruit.state = 'falling';
fruit.ticks = 0;
// Rotación aleatoria y velocidad de rotación suave
fruit.rotation = Math.random() * Math.PI * 2;
fruit.rotationSpeed = (Math.random() - 0.5) * 0.04;
fallingFruits.push(fruit);
game.addChild(fruit);
}
// Actualiza score
function updateScore(val) {
LK.setScore(val);
scoreTxt.setText(val);
}
// Nueva lógica de corte: el corte se detecta solo cuando la fruta está en la zona de corte visual (círculo blanco animado).
function tryCutFruit(x, y) {
// Solo permite un corte por tick
if (!canCut) return;
canCut = false;
lastTouchTick = LK.ticks;
// Buscar fruta que esté en estado 'cuttable', activa, y que el toque esté sobre la fruta
for (var i = 0; i < fallingFruits.length; i++) {
var fruit = fallingFruits[i];
if (!fruit.isActive) continue;
// Solo permite cortar si la fruta está en la zona de corte, está subiendo (no cayendo), y el toque está sobre la fruta
if (fruit.state === 'cuttable') {
// Verifica si el toque está sobre la fruta (dentro del radio de la fruta)
var dx = x - fruit.x;
var dy = y - fruit.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist <= fruit.radius * fruit.scaleX) {
// Cortar fruta
fruit.cut();
// Destruir inmediatamente el círculo de corte si existe
if (fruit.cutZoneCircle) {
fruit.cutZoneCircle.destroy();
fruit.cutZoneCircle = null;
}
LK.getSound('cut').play();
// Animación de mitades
var fruitCut = new FruitCut();
fruitCut.init(fruit.fruitType, fruit.x, fruit.y);
game.addChild(fruitCut);
fruitCut.animate(function () {
fruitCut.destroy();
});
cutFruits.push(fruitCut);
updateScore(LK.getScore() + 1);
return;
}
}
}
}
// Input: solo touch/click
game.down = function (x, y, obj) {
// Solo intenta cortar si hay fruta cortable y el toque es sobre la fruta
tryCutFruit(x, y);
};
game.up = function (x, y, obj) {};
game.move = function (x, y, obj) {};
// Main update
game.update = function () {
// Permitir corte nuevamente tras 6 ticks (~100ms)
if (!canCut && LK.ticks - lastTouchTick > 6) canCut = true;
// Lanzar frutas periódicamente
fruitTimer++;
if (fruitTimer >= spawnDelay) {
fruitTimer = 0;
spawnFruit();
}
// Mover frutas que suben desde abajo hasta el centro
for (var i = fruits.length - 1; i >= 0; i--) {
var fruit = fruits[i];
if (fruit.state === 'rising') {
fruit.y -= fruitSpeed;
fruit.ticks++;
// Cuando llega a la altura objetivo (centro), desaparece y tras breve delay aparece subiendo hacia arriba
if (fruit.y <= fruit.targetY) {
var fruitType = fruit.fruitType;
var x = fruit.x;
fruit.destroy();
fruits.splice(i, 1);
// Tras breve delay, aparece en el centro y sube hacia arriba
(function (ft, fx) {
var delay = 18 + Math.floor(Math.random() * 8);
LK.setTimeout(function () {
spawnFallingFruit(ft, fx);
}, delay * 16);
})(fruitType, x);
}
}
}
// Mover frutas que suben de nuevo y gestionar zona de corte visual
for (var i = fallingFruits.length - 1; i >= 0; i--) {
var fruit = fallingFruits[i];
if (!fruit.isActive) continue;
// Escalado según altura (más arriba, más grande)
var minScale = 1.0;
var maxScale = 1.25;
var y0 = 2732 / 2 + 420;
var y1 = 420;
var t = (y0 - fruit.y) / (y0 - y1);
if (t < 0) t = 0;
if (t > 1) t = 1;
var scale = minScale + (maxScale - minScale) * t;
fruit.scaleX = fruit.scaleY = scale;
// Rotación suave
if (typeof fruit.rotationSpeed !== "undefined") {
fruit.rotation += fruit.rotationSpeed;
if (fruit.fruitAsset) fruit.fruitAsset.rotation = fruit.rotation;
}
// Movimiento hacia arriba
if (fruit.state === 'falling') {
fruit.y -= fruitSpeed;
fruit.ticks++;
// --- Animación progresiva del círculo de corte ---
var cutY = 420; // Y donde puede ser cortada
var cutWindow = 60; // margen de ventana de corte
var cutAppearWindow = 120; // margen donde empieza a aparecer el círculo antes de la zona de corte
var distToCut = fruit.y - cutY;
// Si está dentro de la ventana de aparición del círculo (antes de la zona de corte)
if (distToCut <= cutAppearWindow && distToCut >= -cutWindow) {
// Si no existe el círculo, crearlo
if (!fruit.cutZoneCircle) {
fruit.cutZoneCircle = LK.getAsset('cut_zone', {
anchorX: 0.5,
anchorY: 0.5,
x: fruit.x,
y: fruit.y,
alpha: 0.0,
scaleX: 0.1,
scaleY: 0.1
});
game.addChild(fruit.cutZoneCircle);
}
// Animar tamaño y alpha progresivamente según cercanía al punto de corte
var appearT = 1 - (distToCut - -cutWindow) / (cutAppearWindow + cutWindow);
if (appearT < 0) appearT = 0;
if (appearT > 1) appearT = 1;
var maxScaleZone = 1.1;
var minScaleZone = 0.1;
var maxAlpha = 0.5;
var minAlpha = 0.0;
var scaleZone = minScaleZone + (maxScaleZone - minScaleZone) * appearT;
var alphaZone = minAlpha + (maxAlpha - minAlpha) * appearT;
fruit.cutZoneCircle.scaleX = fruit.cutZoneCircle.scaleY = scaleZone;
fruit.cutZoneCircle.alpha = alphaZone;
fruit.cutZoneCircle.x = fruit.x;
fruit.cutZoneCircle.y = fruit.y;
// Si está en la zona de corte, permitir corte
if (distToCut <= cutWindow && distToCut >= -cutWindow) {
fruit.state = 'cuttable';
}
} else {
// Si sale de la ventana de aparición y existe el círculo, destruirlo
if (fruit.cutZoneCircle) {
fruit.cutZoneCircle.destroy();
fruit.cutZoneCircle = null;
}
}
}
// Si está en zona de corte, seguir el círculo con la fruta y permitir corte
if (fruit.state === 'cuttable' && fruit.cutZoneCircle) {
fruit.cutZoneCircle.x = fruit.x;
fruit.cutZoneCircle.y = fruit.y;
// Si sale de la ventana de corte sin ser cortada, destruir círculo y continuar subiendo
var cutY = 420;
var cutWindow = 60;
if (fruit.y < cutY - cutWindow) {
if (fruit.cutZoneCircle) {
fruit.cutZoneCircle.destroy();
fruit.cutZoneCircle = null;
}
fruit.state = 'flyingup'; // Continúa subiendo, ya no puede ser cortada
}
}
// Si fue cortada, eliminar círculo visual inmediatamente pero mantener la fruta visible
if (!fruit.isActive && fruit.cutZoneCircle) {
fruit.cutZoneCircle.destroy();
fruit.cutZoneCircle = null;
}
// Si está cayendo, animar caída
if (fruit.state === 'dropping') {
fruit.dropSpeed += 2.5; // gravedad
fruit.y += fruit.dropSpeed;
// Escalado decreciente al caer
fruit.scaleX = fruit.scaleY = Math.max(0.7, fruit.scaleX - 0.01);
if (fruit.cutZoneCircle) {
fruit.cutZoneCircle.x = fruit.x;
fruit.cutZoneCircle.y = fruit.y;
}
// Si sale de pantalla, marcar como inactivo pero mantener visible
if (fruit.y > 2732 + fruit.radius + 20) {
if (fruit.cutZoneCircle) {
fruit.cutZoneCircle.destroy();
fruit.cutZoneCircle = null;
}
fruit.isActive = false;
}
}
// Si la fruta sigue subiendo después de la zona de corte y no fue cortada
if (fruit.state === 'flyingup') {
fruit.y -= fruitSpeed;
// Escalado sigue creciendo un poco
fruit.scaleX = fruit.scaleY = Math.min(maxScale, fruit.scaleX + 0.01);
// Si sale de pantalla por arriba, marcar como inactiva
if (fruit.y < -fruit.radius - 20) {
fruit.isActive = false;
}
}
// Si la fruta ya fue cortada o salió de pantalla, eliminar
if (!fruit.isActive || fruit.y > 2732 + fruit.radius + 20 || fruit.y < -fruit.radius - 20) {
if (fruit.cutZoneCircle) {
fruit.cutZoneCircle.destroy();
fruit.cutZoneCircle = null;
}
fruit.destroy();
fallingFruits.splice(i, 1);
}
}
// Limpiar mitades cortadas que ya terminaron animación
for (var i = cutFruits.length - 1; i >= 0; i--) {
var fc = cutFruits[i];
if (!fc.left || !fc.right) {
cutFruits.splice(i, 1);
}
}
};
// Inicializar score
updateScore(0);
Kiwi Fruta con ojos lindos. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Limon Circular Fruta con ojos lindos. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Naranja Circular Fruta con ojos lindos. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Manzana Fruta con ojos lindos. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Ciruela Fruta con ojos lindos. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Manzana Fruta cortada a la mitad. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Kiwi Fruta cortado por la mitad. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Limon Circular Cortado por la mitad. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Naranja Circular Cortada por la mitad. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Ciruela Fruta cortada por la mitad. In-Game asset. 2d. High contrast. No shadows. Cartoon.
Agrega una rueda en la parte trasera del cañon.
En lugar del numero 2 un numero 1
Letars GO! dentro del circulo.
Red cicle thiner but maintan the image size
En lugar del numero 1 un numero 2
Puedes hacer varias imagenes reemplazando el numero 2 por los numeros 3, 4, 5, 6, 7 y 8? Solo debe haber un numero en cada imagen.
En lugar del numero 3 un numero 4
En lugar del numero 4 un numero 5
En lugar del numero 5 un numero 6
En lugar del numero 6 un numero 7
En lugar del numero 1 un numero 8
En lugar del numero 1 un numero 9
En lugar del numero 9 un numero 10
En lugar del numero 1 un numero 11
Boton de juego que diga "START". In-Game asset. 2d. High contrast. No shadows
Boton de juego que diga "RESTART". In-Game asset. 2d. High contrast. No shadows
Boton de juego Azul que diga "MENU". In-Game asset. 2d. High contrast. No shadows
Un fondo colorido y brillante estilo caricatura. La escena es un bosque abierto alegre con colores pastel vibrantes, formas suaves y redondeadas, y un cielo azul claro con nubes esponjosas. El estilo es kawaii, juguetón y fantástico, con líneas suaves y una atmósfera feliz y amigable, perfecto para una introducción divertida y cute de un juego. In-Game asset. 2d. High contrast. No shadows
"Beat the Fruit" titulo para el juego, muestra las letras en grande blancas con un borde negro y sin fondo, con algunas frutitas felices junto a las letras. In-Game asset. 2d. High contrast. No shadows
Barra verde horizontal estilo caricatura.. In-Game asset. 2d. High contrast. No shadows