User prompt
No es necesario que agreges el texto (+2) y que ese bonus solo sea para el mismo nivel y no mas
User prompt
No me esta dando mas fhleas cuando le doy al bonus flecha
User prompt
pero quiero que el bonus flehca te de 2 o 3 flechas mas de manera aleatoria (2-3)
User prompt
Quiero que si el bonus de flechas te de mas de 5 arrows, no imparta pero solo si es el que te da el bonus flecha
User prompt
Asi esta perfecto
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'active')' in or related to this line: 'if (!arrow.active) {' Line Number: 1105
User prompt
quiero que el bonus flecha aumente aleatoriamente 2 o 3 flehcas mas y que en arrows: 5 aparezcan las 2 o 3 felchas exytras
User prompt
cuando disparo, los arrows no bajan su numero
User prompt
Revierte lo que te dije
User prompt
Pero ahora en arrows: hay NaN
User prompt
pero cuando agarrlo el bonus de flehca, arriba en arrows: solo hay 5 y no 2 o 3 mas
User prompt
Quiero que el bonus flecha me de aleatoriamente de 2 a 3 flehcas mas
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'active')' in or related to this line: 'if (!arrow.active) {' Line Number: 1105
User prompt
mejor que sean de 2 a 3 felchas mas
User prompt
Quiero que el bonus flechas me den aleatoriamente de 1 a 3 flechas mas
User prompt
Quiero que solo tengamos 5 flechas y que el arco solo pueda disparar 5 flehcas, no mas
User prompt
Quiero que tire varias flechas pero si en arrows: 5 esta 0, ya no pueda torar mas felchas hasta que tenga flechas
User prompt
elimina lo ultimo que dije
User prompt
pero si tengo 2 o 3 o 4 o 5, si pueda tirar las flechas varias veces
User prompt
Siguen saliendo flehcas infinitas cuando no dejo de disparar, solo quiero que salgan 5
User prompt
si en arrows: hay 0 flehcas, que el arco no pueda volver a disparar mas flechas
User prompt
Como te explico, las flechas que salen del arco son infinitas, solo quiero que salgan 5 flehcas
User prompt
Hablo que el arco (bow) sale flechas infinitas y no las 5 que tenemos
User prompt
cuando disparo muchoas veces, sale varias flechas, deberia salir solo las 5 o depedndiendo de cuantas me quedan
User prompt
Solo quiero que salga la misma cantidad de flehcas que tenemos en el arco
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Archer = Container.expand(function () { var self = Container.call(this); var bowGraphics = self.attachAsset('bow', { anchorX: 0.5, anchorY: 0.5 }); self.bow = bowGraphics; self.aimAngle = 0; self.aimAt = function (targetX, targetY) { var dx = targetX - (self.x + self.bow.x); var dy = targetY - (self.y + self.bow.y); self.aimAngle = Math.atan2(dy, dx); self.bow.rotation = self.aimAngle; }; self.shoot = function () { // Check if we can shoot - either normal arrows (under 5) or bonus arrows available if (!window.bonusArrows) window.bonusArrows = 0; var canShoot = arrows.length < 5 || window.bonusArrows > 0; if (!canShoot) { return; // Can't shoot } var arrow = new Arrow(); var bowWorldX = self.x + self.bow.x + Math.cos(self.aimAngle) * 40; var bowWorldY = self.y + self.bow.y + Math.sin(self.aimAngle) * 40; arrow.x = bowWorldX; arrow.y = bowWorldY; arrow.rotation = self.aimAngle; var power = currentPower; // Use dynamic power based on mouse distance arrow.velocityX = Math.cos(self.aimAngle) * power; arrow.velocityY = Math.sin(self.aimAngle) * power; arrows.push(arrow); game.addChild(arrow); // Use bonus arrow if we're over the 5 arrow limit if (arrows.length > 5 && window.bonusArrows > 0) { window.bonusArrows--; } LK.getSound('shoot').play(); }; return self; }); var Arrow = Container.expand(function () { var self = Container.call(this); var arrowGraphics = self.attachAsset('arrow', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.gravity = 0.3; self.active = true; self.update = function () { if (!self.active) return; self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; // Update arrow rotation to follow movement direction if (self.velocityX !== 0 || self.velocityY !== 0) { self.rotation = Math.atan2(self.velocityY, self.velocityX); } // Check platform collisions with smaller collision area for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; // Calculate distance between arrow and platform center var dx = self.x - platform.x; var dy = self.y - platform.y; // Reduce vertical collision sensitivity by using separate X and Y checks var horizontalDistance = Math.abs(dx); var verticalDistance = Math.abs(dy); // Use collision radius for platforms (100 pixels horizontal, 60 pixels vertical) if (horizontalDistance < 100 && verticalDistance < 60) { self.active = false; self.velocityX = 0; self.velocityY = 0; break; } } // Remove arrow if it goes off screen // Remove arrow if it goes off screen if (self.x > 2100 || self.y > 2800 || self.x < -50 || self.y < -50) { // Give bonus points if arrow didn't hit any platform if (self.active) { LK.setScore(LK.getScore() + 5); scoreTxt.setText(LK.getScore()); } self.destroy(); for (var i = arrows.length - 1; i >= 0; i--) { if (arrows[i] === self) { arrows.splice(i, 1); break; } } } }; return self; }); var ArrowBonus = Container.expand(function () { var self = Container.call(this); var bonusGraphics = self.attachAsset('arrowBonus', { anchorX: 0.5, anchorY: 0.5 }); self.hit = false; self.getHit = function () { if (self.hit) return; self.hit = true; // Give random 2-3 arrows var bonusArrows = Math.floor(Math.random() * 2) + 2; // Random number between 2-3 // Store bonus arrows in global variable so archer can use them if (!window.bonusArrows) window.bonusArrows = 0; window.bonusArrows += bonusArrows; // Flash effect LK.effects.flashObject(self, 0x00ff00, 300); // Remove from arrowBonuses array for (var i = arrowBonuses.length - 1; i >= 0; i--) { if (arrowBonuses[i] === self) { arrowBonuses.splice(i, 1); break; } } // Animate bonus disappearing tween(self, { alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 300, onFinish: function onFinish() { self.destroy(); } }); LK.getSound('arrowBonus').play(); // Update arrows display to show the bonus amount var remainingArrows = Math.max(0, 5 - arrows.length); var totalAvailable = remainingArrows + window.bonusArrows; arrowsTxt.setText('Arrows: ' + totalAvailable + ' (+' + bonusArrows + ')'); }; return self; }); var Bomb = Container.expand(function () { var self = Container.call(this); var bombGraphics = self.attachAsset('bomb', { anchorX: 0.5, anchorY: 0.5 }); self.hit = false; self.getHit = function () { if (self.hit) return; self.hit = true; // Flash effect LK.effects.flashObject(self, 0xff0000, 300); // Remove from bombs array for (var i = bombs.length - 1; i >= 0; i--) { if (bombs[i] === self) { bombs.splice(i, 1); break; } } // Flash screen red and show game over LK.effects.flashScreen(0xff0000, 1000); LK.getSound('explosion').play(); // Animate bomb explosion tween(self, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 300, onFinish: function onFinish() { self.destroy(); // Show game over after explosion animation LK.setTimeout(function () { LK.showGameOver(); }, 200); } }); }; return self; }); var Fruit = Container.expand(function (type) { var self = Container.call(this); var fruitType = type || 'apple'; var fruitGraphics = self.attachAsset(fruitType, { anchorX: 0.5, anchorY: 0.5 }); self.fruitType = fruitType; self.points = fruitType === 'apple' ? 10 : fruitType === 'orange' ? 15 : 20; self.hit = false; // Start idle floating animation self.startIdleAnimation = function () { var animationDuration = 1500 + Math.random() * 1000; // 1.5-2.5 seconds var moveRange = 8 + Math.random() * 12; // 8-20 pixels movement if (self.initialY === undefined) { self.initialY = self.y; // Store the original position only once } // Find the platform this fruit is on var platformY = self.initialY + 60; // Platform is 60 pixels below fruit // Limit upward movement to not go above initial position too much var upwardY = self.initialY - moveRange; // Limit downward movement to not go below platform level var downwardY = Math.min(self.initialY + moveRange, platformY - 50); tween(self, { y: upwardY }, { duration: animationDuration, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.hit) { tween(self, { y: downwardY }, { duration: animationDuration, easing: tween.easeInOut, onFinish: function onFinish() { if (!self.hit) { self.startIdleAnimation(); } } }); } } }); }; self.getHit = function () { if (self.hit) return; self.hit = true; LK.setScore(LK.getScore() + self.points); scoreTxt.setText(LK.getScore()); // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 300); // Remove from fruits array for (var i = fruits.length - 1; i >= 0; i--) { if (fruits[i] === self) { fruits.splice(i, 1); break; } } // Only remove arrows when level is completed (no fruits remain) // The arrows will be cleared when spawnFruits() is called for next level // Create explosion/disintegration effect tween(self, { scaleX: 1.5, scaleY: 1.5, rotation: Math.PI * 2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Second phase: shrink and fade out tween(self, { alpha: 0, scaleX: 0, scaleY: 0 }, { duration: 200, easing: tween.easeIn, onFinish: function onFinish() { self.destroy(); } }); } }); LK.getSound('hit').play(); // Check win condition if (fruits.length === 0) { // Show level complete animation immediately showLevelCompleteAnimation(); } }; return self; }); var Menu = Container.expand(function () { var self = Container.call(this); // Animated background layers var menuBg1 = self.attachAsset('menuBg1', { anchorX: 0, anchorY: 0, x: 0, y: 0, alpha: 1 }); var menuBg2 = self.attachAsset('menuBg2', { anchorX: 0, anchorY: 0, x: 0, y: 0, alpha: 0.7 }); self.addChild(menuBg2); // Background stars removed as requested // Animate background layers tween(menuBg2, { alpha: 0.3 }, { duration: 3000, easing: tween.easeInOut, onFinish: function onFinish() { tween(menuBg2, { alpha: 0.7 }, { duration: 3000, easing: tween.easeInOut, onFinish: function onFinish() { // Continue background animation loop } }); } }); // Animated title image var titleImage = self.attachAsset('titleImage', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, scaleY: 0, rotation: 0 }); titleImage.x = 1024; titleImage.y = 700; // Title entrance animation with continuous effects tween(titleImage, { scaleX: 1.2, scaleY: 1.2, rotation: Math.PI * 0.1 }, { duration: 1000, easing: tween.elasticOut, onFinish: function onFinish() { // Continuous title animation loop function animateTitle() { tween(titleImage, { scaleX: 1.1, scaleY: 1.1, rotation: -Math.PI * 0.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(titleImage, { scaleX: 1.3, scaleY: 1.3, rotation: Math.PI * 0.05 }, { duration: 2000, easing: tween.easeInOut, onFinish: animateTitle }); } }); } animateTitle(); } }); // Title glow effect with enhanced animation using duplicate image var titleGlow = self.attachAsset('titleImage', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, scaleY: 0, alpha: 0.2, tint: 0xFFFFFF }); titleGlow.x = 1024; titleGlow.y = 700; self.addChildAt(titleGlow, self.getChildIndex(titleImage)); // Enhanced glow animation tween(titleGlow, { scaleX: 1.3, scaleY: 1.3 }, { duration: 1100, easing: tween.elasticOut, onFinish: function onFinish() { // Continuous pulsing glow effect function pulseGlow() { tween(titleGlow, { alpha: 0.8, scaleX: 1.4, scaleY: 1.4 }, { duration: 1800, easing: tween.easeInOut, onFinish: function onFinish() { tween(titleGlow, { alpha: 0.2, scaleX: 1.2, scaleY: 1.2 }, { duration: 1800, easing: tween.easeInOut, onFinish: pulseGlow }); } }); } pulseGlow(); } }); // Enhanced start button with image background var startButtonBg = self.attachAsset('startButtonBg', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); startButtonBg.x = 1024; startButtonBg.y = 1950; self.addChild(startButtonBg); // Start button image overlay - removed bow as requested // Button entrance animation LK.setTimeout(function () { tween(startButtonBg, { scaleX: 1.1, scaleY: 1.1 }, { duration: 600, easing: tween.elasticOut }); // Bow animation removed as bow is no longer present }, 1200); // Button hover effect function animateButton() { tween(startButtonBg, { scaleX: 1.05, scaleY: 1.05 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(startButtonBg, { scaleX: 1.1, scaleY: 1.1 }, { duration: 1000, easing: tween.easeInOut, onFinish: animateButton }); } }); } LK.setTimeout(animateButton, 2000); // Start button click handler - make the whole button area clickable startButtonBg.down = function (x, y, obj) { // Button press animation tween(startButtonBg, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(startButtonBg, { scaleX: 1.1, scaleY: 1.1 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { // Transition to game scene showGameScene(); } }); } }); }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Star = Container.expand(function () { var self = Container.call(this); var starGraphics = self.attachAsset('starBonus', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 1.0, tint: 0xFFD700 // Golden color }); self.hit = false; self.getHit = function () { if (self.hit) return; self.hit = true; // Clear all fruits to complete level immediately for (var i = fruits.length - 1; i >= 0; i--) { var fruit = fruits[i]; LK.setScore(LK.getScore() + fruit.points); fruit.destroy(); fruits.splice(i, 1); } scoreTxt.setText(LK.getScore()); // Flash effect LK.effects.flashObject(self, 0xFFD700, 300); // Remove from stars array for (var i = stars.length - 1; i >= 0; i--) { if (stars[i] === self) { stars.splice(i, 1); break; } } // Animate star disappearing tween(self, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 300, onFinish: function onFinish() { self.destroy(); } }); LK.getSound('starBonus').play(); // Update arrows display to show bonus effect var remainingArrows = Math.max(0, Math.min(5, maxArrows || 5) - arrows.length); arrowsTxt.setText('Arrows: ' + remainingArrows); // Show level complete animation immediately showLevelCompleteAnimation(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Black background as fallback }); /**** * Game Code ****/ // Menu scene var menuScene = null; var gameStarted = false; function showMenuScene() { // Clear game elements if they exist if (gameStarted) { // Clear all game objects for (var i = 0; i < arrows.length; i++) { arrows[i].destroy(); } arrows = []; for (var i = 0; i < fruits.length; i++) { fruits[i].destroy(); } fruits = []; for (var i = 0; i < platforms.length; i++) { platforms[i].destroy(); } platforms = []; for (var i = 0; i < bombs.length; i++) { bombs[i].destroy(); } bombs = []; for (var i = 0; i < arrowBonuses.length; i++) { arrowBonuses[i].destroy(); } arrowBonuses = []; for (var i = 0; i < stars.length; i++) { stars[i].destroy(); } stars = []; for (var i = 0; i < clouds.length; i++) { clouds[i].destroy(); } clouds = []; if (archer) { archer.destroy(); archer = null; } } // Create and show menu menuScene = new Menu(); game.addChild(menuScene); gameStarted = false; } // Define showLevelCompleteAnimation in global scope function showLevelCompleteAnimation() { // Play level complete sound for level completion LK.getSound('levelComplete').play(); // Create a large golden star in the center of the screen var star = LK.getAsset('star', { anchorX: 0.5, anchorY: 0.5, scaleX: 0, scaleY: 0, alpha: 0, tint: 0xFFD700 // Golden color }); star.x = 1024; // Center of screen horizontally (2048/2) star.y = 1366; // Center of screen vertically (2732/2) game.addChild(star); // Simple growing animation tween(star, { scaleX: 2.5, scaleY: 2.5, alpha: 1 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { // Fade out after growing tween(star, { alpha: 0 }, { duration: 400, easing: tween.easeIn, onFinish: function onFinish() { star.destroy(); // After star animation completes, proceed to next level LK.setTimeout(function () { var currentLevel = Math.floor(LK.getScore() / 200) + 1; var nextTargetScore = currentLevel * 200; if (LK.getScore() >= targetScore) { targetScore = nextTargetScore + 200; targetTxt.setText('Target: ' + targetScore); spawnFruits(); } else { spawnFruits(); } }, 100); } }); } }); } // Define spawnFruits function in global scope so it can be accessed from anywhere function spawnFruits() { // Clear existing fruits for (var i = 0; i < fruits.length; i++) { fruits[i].destroy(); } fruits = []; // Clear existing bombs for (var i = 0; i < bombs.length; i++) { bombs[i].destroy(); } bombs = []; // Clear existing arrow bonuses for (var i = 0; i < arrowBonuses.length; i++) { arrowBonuses[i].destroy(); } arrowBonuses = []; // Clear existing stars for (var i = 0; i < stars.length; i++) { stars[i].destroy(); } stars = []; // Clear all arrows (including those stuck on platforms) for (var i = 0; i < arrows.length; i++) { arrows[i].destroy(); } arrows = []; // Ensure enough arrows for the number of fruits (minimum 3, but at least equal to fruits) var currentLevel = Math.floor(LK.getScore() / 200) + 1; var baseArrows = Math.max(3, 6 - Math.floor(currentLevel / 2)); var calculatedArrows = Math.max(baseArrows, numFruits + 1); maxArrows = Math.min(5, calculatedArrows); // Always have at least 1 more arrow than fruits, but max 5 // Clear existing platforms for (var i = 0; i < platforms.length; i++) { platforms[i].destroy(); } platforms = []; var fruitTypes = ['apple', 'orange', 'banana']; // Calculate level based on score progression var currentLevel = Math.floor(LK.getScore() / 200) + 1; // Increase number of fruits with each level (start with 2, add 1 every 2 levels, max 6) var numFruits = Math.min(6, 2 + Math.floor(currentLevel / 2)); for (var i = 0; i < numFruits; i++) { // Create platform with collision detection var platform = new Platform(); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { // Make platforms more spread out and harder to reach in higher levels var currentLevel = Math.floor(LK.getScore() / 200) + 1; var spreadFactor = Math.min(2, 1 + currentLevel * 0.2); // Ensure platforms stay within screen boundaries and don't appear too low var maxX = 2048 - 150; // Right boundary var maxY = 1800; // Bottom boundary - prevent platforms from appearing too low var minX = 150; // Left boundary var minY = 600; // Top boundary - keep platforms in middle area platform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * (800 * spreadFactor))); platform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * (1000 * spreadFactor))); validPosition = true; // Check distance from character to ensure platforms spawn far away var distanceFromCharacter = Math.sqrt((platform.x - 300) * (platform.x - 300) + (platform.y - 1366) * (platform.y - 1366)); if (distanceFromCharacter < 500) { validPosition = false; } // Check collision with existing platforms for (var j = 0; j < platforms.length; j++) { var existingPlatform = platforms[j]; var dx = platform.x - existingPlatform.x; var dy = platform.y - existingPlatform.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 400) { // Minimum distance between platforms validPosition = false; break; } } attempts++; } platforms.push(platform); game.addChild(platform); // Create fruit on platform var fruitType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)]; var fruit = new Fruit(fruitType); fruit.x = platform.x; fruit.y = platform.y - 80; // Position above platform fruits.push(fruit); game.addChild(fruit); // Start idle animation immediately for all fruits fruit.startIdleAnimation(); } // Create separate platforms for bombs // Calculate level based on score progression (every 200 points is roughly a level) var currentLevel = Math.floor(LK.getScore() / 200) + 1; // Increase bomb count with each level, starting with 1 every 2 levels, maximum 3 var numBombs = Math.min(3, Math.floor(currentLevel / 2)); for (var i = 0; i < numBombs; i++) { // Create bomb platform with collision detection var bombPlatform = new Platform(); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { // Make bomb platforms more spread out and harder to avoid in higher levels var currentLevel = Math.floor(LK.getScore() / 200) + 1; var spreadFactor = Math.min(2, 1 + currentLevel * 0.2); // Ensure bomb platforms stay within screen boundaries and don't appear too low var maxX = 2048 - 150; // Right boundary var maxY = 1800; // Bottom boundary - prevent platforms from appearing too low var minX = 150; // Left boundary var minY = 600; // Top boundary - keep platforms in middle area bombPlatform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * (800 * spreadFactor))); bombPlatform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * (1000 * spreadFactor))); validPosition = true; // Check distance from character to ensure bomb platforms spawn far away var distanceFromCharacter = Math.sqrt((bombPlatform.x - 300) * (bombPlatform.x - 300) + (bombPlatform.y - 1366) * (bombPlatform.y - 1366)); if (distanceFromCharacter < 500) { validPosition = false; } // Check collision with existing platforms (both fruit and bomb platforms) for (var j = 0; j < platforms.length; j++) { var existingPlatform = platforms[j]; var dx = bombPlatform.x - existingPlatform.x; var dy = bombPlatform.y - existingPlatform.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 400) { // Minimum distance between platforms validPosition = false; break; } } attempts++; } platforms.push(bombPlatform); game.addChild(bombPlatform); // Create bomb on its own platform var bomb = new Bomb(); bomb.x = bombPlatform.x; bomb.y = bombPlatform.y - 75; // Position above platform bombs.push(bomb); game.addChild(bomb); } // Create arrow bonuses (only sometimes, based on level) var currentLevel = Math.floor(LK.getScore() / 200) + 1; // 60% chance to spawn arrow bonus, but only every 2-3 levels var shouldSpawnBonus = Math.random() < 0.6 && currentLevel > 1 && (currentLevel % 2 === 0 || currentLevel % 3 === 0); if (shouldSpawnBonus) { // Create arrow bonus platform with collision detection var bonusPlatform = new Platform(); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { // Ensure bonus platforms stay within screen boundaries and don't appear too low var maxX = 2048 - 150; // Right boundary var maxY = 1800; // Bottom boundary - prevent platforms from appearing too low var minX = 150; // Left boundary var minY = 600; // Top boundary - keep platforms in middle area bonusPlatform.x = Math.max(minX, Math.min(maxX, 600 + Math.random() * 800)); bonusPlatform.y = Math.max(minY, Math.min(maxY, 800 + Math.random() * 1200)); validPosition = true; // Check distance from character to ensure bonus platforms spawn far away var distanceFromCharacter = Math.sqrt((bonusPlatform.x - 300) * (bonusPlatform.x - 300) + (bonusPlatform.y - 1366) * (bonusPlatform.y - 1366)); if (distanceFromCharacter < 500) { validPosition = false; } // Check collision with existing platforms for (var j = 0; j < platforms.length; j++) { var existingPlatform = platforms[j]; var dx = bonusPlatform.x - existingPlatform.x; var dy = bonusPlatform.y - existingPlatform.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 400) { validPosition = false; break; } } attempts++; } platforms.push(bonusPlatform); game.addChild(bonusPlatform); // Create arrow bonus on platform var arrowBonus = new ArrowBonus(); arrowBonus.x = bonusPlatform.x; arrowBonus.y = bonusPlatform.y - 75; // Position above platform arrowBonuses.push(arrowBonus); game.addChild(arrowBonus); } // Create star bonuses (more frequent random appearance) var currentLevel = Math.floor(LK.getScore() / 200) + 1; // 30% chance to spawn, completely random regardless of level var shouldSpawnStar = Math.random() < 0.30 && currentLevel > 1; if (shouldSpawnStar) { // Create star platform in a very difficult to reach position var starPlatform = new Platform(); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { // Place in very hard to reach areas - corners and edges of map var cornerChoice = Math.floor(Math.random() * 4); // Define screen boundaries and prevent stars from appearing too low var maxX = 2048 - 150; // Right boundary var maxY = 1600; // Bottom boundary - prevent stars from appearing too low var minX = 150; // Left boundary var minY = 500; // Top boundary - keep stars in middle-upper area if (cornerChoice === 0) { // Top right corner starPlatform.x = Math.max(minX, Math.min(maxX, 1400 + Math.random() * 500)); starPlatform.y = Math.max(minY, Math.min(maxY, 600 + Math.random() * 400)); } else if (cornerChoice === 1) { // Bottom right corner starPlatform.x = Math.max(minX, Math.min(maxX, 1300 + Math.random() * 600)); starPlatform.y = Math.max(minY, Math.min(maxY, 1200 + Math.random() * 400)); } else if (cornerChoice === 2) { // Top center (high up) starPlatform.x = Math.max(minX, Math.min(maxX, 800 + Math.random() * 800)); starPlatform.y = Math.max(minY, Math.min(maxY, 500 + Math.random() * 300)); } else { // Far right edge starPlatform.x = Math.max(minX, Math.min(maxX, 1600 + Math.random() * 300)); starPlatform.y = Math.max(minY, Math.min(maxY, 1000 + Math.random() * 600)); } validPosition = true; // Ensure star platforms spawn very far from character (harder to reach) var distanceFromCharacter = Math.sqrt((starPlatform.x - 300) * (starPlatform.x - 300) + (starPlatform.y - 1366) * (starPlatform.y - 1366)); if (distanceFromCharacter < 700) { validPosition = false; } // Check collision with existing platforms for (var j = 0; j < platforms.length; j++) { var existingPlatform = platforms[j]; var dx = starPlatform.x - existingPlatform.x; var dy = starPlatform.y - existingPlatform.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 350) { validPosition = false; break; } } attempts++; } platforms.push(starPlatform); game.addChild(starPlatform); // Create star on platform - make it smaller and harder to hit var star = new Star(); star.x = starPlatform.x; star.y = starPlatform.y - 75; // Position above platform // Make star smaller and harder to hit star.scaleX = 0.8; star.scaleY = 0.8; stars.push(star); game.addChild(star); } } function showGameScene() { // Remove menu scene if (menuScene) { menuScene.destroy(); menuScene = null; } // Initialize game scene gameStarted = true; // Add background image var backgroundImage = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0, scaleX: 1, scaleY: 1 }); game.addChildAt(backgroundImage, 0); // Add to back layer // Initialize game variables arrows = []; fruits = []; platforms = []; bombs = []; arrowBonuses = []; stars = []; clouds = []; groundVegetation = []; maxArrows = 5; targetScore = 200; // Create ground vegetation (no bushes) function createGroundVegetation() { // No ground vegetation to create } // Create background clouds function createClouds() { for (var i = 0; i < 8; i++) { var cloud = LK.getAsset('cloud', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7, scaleX: 0.8 + Math.random() * 0.6, scaleY: 0.6 + Math.random() * 0.4 }); cloud.x = Math.random() * 2200; // Spread across screen width plus some overflow cloud.y = 300 + Math.random() * 600; // Position clouds in more visible area cloud.speed = 0.3 + Math.random() * 0.7; // Random slow speed clouds.push(cloud); game.addChildAt(cloud, 1); // Add above background layer // Start floating animation animateCloud(cloud); } } function animateCloud(cloud) { var floatRange = 30 + Math.random() * 40; var originalY = cloud.y; tween(cloud, { y: originalY - floatRange }, { duration: 3000 + Math.random() * 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(cloud, { y: originalY + floatRange }, { duration: 3000 + Math.random() * 2000, easing: tween.easeInOut, onFinish: function onFinish() { animateCloud(cloud); } }); } }); } // Create archer archer = new Archer(); archer.x = 300; archer.y = 1366; game.addChild(archer); // Create score display scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create target score display targetTxt = new Text2('Target: ' + targetScore, { size: 60, fill: 0xFFFF00 }); targetTxt.anchor.set(1, 0); targetTxt.y = 120; LK.gui.topRight.addChild(targetTxt); // Create arrows remaining display arrowsTxt = new Text2('Arrows: ' + maxArrows, { size: 60, fill: 0xFFFFFF }); arrowsTxt.anchor.set(0, 0); arrowsTxt.y = 120; LK.gui.topLeft.addChild(arrowsTxt); // Initialize clouds background createClouds(); // Initialize ground vegetation createGroundVegetation(); // Play background music LK.playMusic('Fondo'); // Initialize first level spawnFruits(); } // Declare game variables in global scope var arrows = []; var fruits = []; var platforms = []; var bombs = []; var arrowBonuses = []; var stars = []; var clouds = []; var groundVegetation = []; var maxArrows = 5; var targetScore = 200; var archer = null; var scoreTxt = null; var targetTxt = null; var arrowsTxt = null; // Start with menu scene showMenuScene(); // Mouse controls var mouseX = 0; var mouseY = 0; var currentPower = 12; // Default power game.move = function (x, y, obj) { if (!gameStarted || !archer) return; mouseX = x; mouseY = y; // Update archer aiming archer.aimAt(x, y); // Calculate power based on distance from archer position var dx = x - 300; var dy = y - 1366; var distance = Math.sqrt(dx * dx + dy * dy); // Scale power based on distance (minimum 12, maximum 28) currentPower = Math.min(28, Math.max(12, distance / 25)); }; game.down = function (x, y, obj) { if (!gameStarted || !archer) return; mouseX = x; mouseY = y; // Update archer aiming archer.aimAt(x, y); // Calculate power based on distance from archer position var dx = x - 300; var dy = y - 1366; var distance = Math.sqrt(dx * dx + dy * dy); // Scale power based on distance from archer position (minimum 12, maximum 28) currentPower = Math.min(28, Math.max(12, distance / 25)); // Use archer's shoot method archer.shoot(); // Update arrows remaining display if (arrowsTxt) { arrowsTxt.setText('Arrows: ' + (maxArrows - arrows.length)); } }; game.update = function () { if (!gameStarted) return; // Check arrow-fruit collisions for (var i = arrows.length - 1; i >= 0; i--) { var arrow = arrows[i]; if (!arrow.active) continue; // Check bomb collisions first for (var j = 0; j < bombs.length; j++) { var bomb = bombs[j]; if (!bomb.hit) { // Use distance-based collision for larger bomb sprites var dx = arrow.x - bomb.x; var dy = arrow.y - bomb.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 80) { arrow.active = false; bomb.getHit(); arrow.destroy(); arrows.splice(i, 1); return; // Exit immediately as game will be over } } } // Check arrow bonus collisions for (var j = 0; j < arrowBonuses.length; j++) { var arrowBonus = arrowBonuses[j]; if (!arrowBonus.hit) { // Use distance-based collision for larger arrow bonus sprites var dx = arrow.x - arrowBonus.x; var dy = arrow.y - arrowBonus.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 70) { arrow.active = false; arrowBonus.getHit(); arrow.destroy(); arrows.splice(i, 1); break; } } } // Check star collisions with smaller hit area (harder to hit) for (var j = 0; j < stars.length; j++) { var star = stars[j]; if (!star.hit) { // Use distance-based collision with smaller radius for stars (harder to hit) var dx = arrow.x - star.x; var dy = arrow.y - star.y; var distance = Math.sqrt(dx * dx + dy * dy); // Collision radius for star sprites (40 pixels) if (distance < 40) { arrow.active = false; star.getHit(); arrow.destroy(); arrows.splice(i, 1); break; } } } for (var j = 0; j < fruits.length; j++) { var fruit = fruits[j]; if (!fruit.hit) { // Calculate distance between arrow and fruit center for larger collision var dx = arrow.x - fruit.x; var dy = arrow.y - fruit.y; var distance = Math.sqrt(dx * dx + dy * dy); // Use collision radius for fruits (80 pixels) if (distance < 80) { arrow.active = false; fruit.getHit(); arrow.destroy(); arrows.splice(i, 1); break; } } } } // Check if out of arrows and all arrows have stopped moving if (arrows.length >= 5 && fruits.length > 0) { var allArrowsStopped = true; for (var i = 0; i < arrows.length; i++) { if (arrows[i].active && (Math.abs(arrows[i].velocityX) > 0.5 || Math.abs(arrows[i].velocityY) > 0.5)) { allArrowsStopped = false; break; } } if (allArrowsStopped) { // Game over if all 5 arrows used and fruits still remain if (fruits.length > 0) { LK.showGameOver(); } } } // Update clouds movement for (var i = 0; i < clouds.length; i++) { var cloud = clouds[i]; cloud.x += cloud.speed; // Reset cloud position when it goes off screen if (cloud.x > 2200) { cloud.x = -200; cloud.y = 300 + Math.random() * 600; // Match new cloud positioning } } // Update arrows remaining display - always show remaining out of 5 plus bonus if (!window.bonusArrows) window.bonusArrows = 0; var remainingArrows = Math.max(0, 5 - arrows.length); var totalAvailable = remainingArrows + window.bonusArrows; if (window.bonusArrows > 0) { arrowsTxt.setText('Arrows: ' + totalAvailable + ' (+' + window.bonusArrows + ')'); } else { arrowsTxt.setText('Arrows: ' + remainingArrows); } };
===================================================================
--- original.js
+++ change.js
@@ -20,23 +20,14 @@
self.aimAngle = Math.atan2(dy, dx);
self.bow.rotation = self.aimAngle;
};
self.shoot = function () {
- // Check if we have reached the maximum arrow limit of 5, but allow if bonus arrows were given
- var effectiveMaxArrows = 5;
- // Check if player has bonus arrows (when display shows more than base 5)
- var currentText = arrowsTxt.text || '';
- if (currentText.includes('(+')) {
- // Extract bonus amount from display text
- var bonusMatch = currentText.match(/\(\+(\d+)\)/);
- if (bonusMatch) {
- var bonusAmount = parseInt(bonusMatch[1]);
- effectiveMaxArrows = 5 + bonusAmount;
- }
+ // Check if we can shoot - either normal arrows (under 5) or bonus arrows available
+ if (!window.bonusArrows) window.bonusArrows = 0;
+ var canShoot = arrows.length < 5 || window.bonusArrows > 0;
+ if (!canShoot) {
+ return; // Can't shoot
}
- if (arrows.length >= effectiveMaxArrows) {
- return; // Don't shoot if maximum arrows (including bonus) already used
- }
var arrow = new Arrow();
var bowWorldX = self.x + self.bow.x + Math.cos(self.aimAngle) * 40;
var bowWorldY = self.y + self.bow.y + Math.sin(self.aimAngle) * 40;
arrow.x = bowWorldX;
@@ -46,8 +37,12 @@
arrow.velocityX = Math.cos(self.aimAngle) * power;
arrow.velocityY = Math.sin(self.aimAngle) * power;
arrows.push(arrow);
game.addChild(arrow);
+ // Use bonus arrow if we're over the 5 arrow limit
+ if (arrows.length > 5 && window.bonusArrows > 0) {
+ window.bonusArrows--;
+ }
LK.getSound('shoot').play();
};
return self;
});
@@ -117,16 +112,11 @@
if (self.hit) return;
self.hit = true;
// Give random 2-3 arrows
var bonusArrows = Math.floor(Math.random() * 2) + 2; // Random number between 2-3
- // Remove the oldest arrows to make room for bonus arrows (but allow going beyond 5 total)
- var arrowsToRemove = Math.min(bonusArrows, arrows.length);
- for (var i = 0; i < arrowsToRemove; i++) {
- if (arrows.length > 0) {
- arrows[0].destroy();
- arrows.splice(0, 1);
- }
- }
+ // Store bonus arrows in global variable so archer can use them
+ if (!window.bonusArrows) window.bonusArrows = 0;
+ window.bonusArrows += bonusArrows;
// Flash effect
LK.effects.flashObject(self, 0x00ff00, 300);
// Remove from arrowBonuses array
for (var i = arrowBonuses.length - 1; i >= 0; i--) {
@@ -146,11 +136,12 @@
self.destroy();
}
});
LK.getSound('arrowBonus').play();
- // Update arrows display to show the bonus amount - can exceed 5 arrows when from bonus
- var totalArrowsAvailable = Math.max(0, 5 - arrows.length) + bonusArrows;
- arrowsTxt.setText('Arrows: ' + totalArrowsAvailable + ' (+' + bonusArrows + ')');
+ // Update arrows display to show the bonus amount
+ var remainingArrows = Math.max(0, 5 - arrows.length);
+ var totalAvailable = remainingArrows + window.bonusArrows;
+ arrowsTxt.setText('Arrows: ' + totalAvailable + ' (+' + bonusArrows + ')');
};
return self;
});
var Bomb = Container.expand(function () {
@@ -1160,8 +1151,14 @@
cloud.x = -200;
cloud.y = 300 + Math.random() * 600; // Match new cloud positioning
}
}
- // Update arrows remaining display - always show remaining out of 5
+ // Update arrows remaining display - always show remaining out of 5 plus bonus
+ if (!window.bonusArrows) window.bonusArrows = 0;
var remainingArrows = Math.max(0, 5 - arrows.length);
- arrowsTxt.setText('Arrows: ' + remainingArrows);
+ var totalAvailable = remainingArrows + window.bonusArrows;
+ if (window.bonusArrows > 0) {
+ arrowsTxt.setText('Arrows: ' + totalAvailable + ' (+' + window.bonusArrows + ')');
+ } else {
+ arrowsTxt.setText('Arrows: ' + remainingArrows);
+ }
};
\ No newline at end of file
Estrella animada. In-Game asset. 2d. High contrast. No shadows
Estrella. In-Game asset. 2d. High contrast. No shadows
Nube. In-Game asset. 2d. High contrast. No shadows
Bush. In-Game asset. 2d. High contrast. No shadows
tree. In-Game asset. 2d. High contrast. No shadows
Quita los arboles y las nubes
Boton de start. In-Game asset. 2d. High contrast. No shadows
Fondo para un juego de fruit archer. In-Game asset. 2d. High contrast. No shadows
Fruit Archer titulo. In-Game asset. 2d. High contrast. No shadows