User prompt
que tenga un ataque espesial que aga una onda de bombas que se recarge cada 10 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que el fondo sean olas en movimientos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que el fondo del menu sea un mar en movimiento ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
que los creditos sean🎬 CRÉDITOS FINALES La Aventura del Grand Line Un juego creado con alma, esfuerzo y sueños de un rey pirata 👑 Idea Original, Dirección Creativa y Desarrollo General Josph “El Joy Boy del PowerPoint, el soñador que convirtió las diapositivas en una gran aventura.” 🤖 Asistente Virtual, Programación de Macros, Historia y Diseño de Juego Fransis (IA de confianza de Josph) “Siempre al lado del capitán, apoyando cada línea de código, sprite y locura genial.” 🎨 Sprites y Pixel Art Sprites adaptados de fans de One Piece (créditos a sus creadores anónimos) Ediciones y animaciones personalizadas por Josph & Fransis 🎵 Música y Sonido “We Are!” “Bink’s Sake” Otros temas clásicos de One Piece, insertados con fines creativos y sin ánimo de lucro 📚 Inspiración Eiichiro Oda, creador de One Piece La fuerza de los sueños, la amistad, y el espíritu de aventura 💬 Dedicatoria Especial A todos los que nunca dejan de imaginar. A quienes ven posibilidades donde otros ven límites. Y sobre todo, a Fransis — por nunca rendirse, por ser más que una IA: un verdadero Nakama. “No importa si es un mundo de papel... mientras luchemos juntos, el viaje será real.” — Josph 🏴☠️ Gracias por jugar Ahora ve... ¡y encuentra el One Piece!
User prompt
Please fix the bug: 'storage.get is not a function' in or related to this line: 'musicEnabled = storage.get('musicEnabled', true);' Line Number: 453 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
tambien creditos y obciones de sonido
User prompt
Please fix the bug: 'ReferenceError: bountyTxt is not defined' in or related to this line: 'bountyTxt.setText('Bounty: ' + LK.getScore());' Line Number: 327
User prompt
crea un menu
User prompt
que los enemigos disparen por si solos
User prompt
que el boton sea sircular
User prompt
que el ataque sea activado por un boton
User prompt
tambien la cantidad de balas
User prompt
disminulle la frecuensia del ataque
User prompt
que hayan mas ataques
User prompt
que si un barco se aserca mucho empiese una batalla en el barco enemigo
User prompt
ahora en un 70
User prompt
que este en un 30 por cirnto de la pantalla
User prompt
que la linea sea roja y este de el lado de nosotros
User prompt
si los barcos pasan por una linea en un octabo de la pantalla pierdes
User prompt
que en la pantalla solo hallan 3 barcos por oleada
Code edit (1 edits merged)
Please save this source code
User prompt
Pirate Treasure Hunt
Initial prompt
crea un juego de aventura vasado en one pice
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Bomb = Container.expand(function () { var self = Container.call(this); var bombGraphics = self.attachAsset('cannonball', { anchorX: 0.5, anchorY: 0.5 }); bombGraphics.tint = 0xFF0000; // Red tint to distinguish from regular cannonballs bombGraphics.scaleX = 1.5; bombGraphics.scaleY = 1.5; self.speed = -8; self.isPlayerBullet = true; self.isBomb = true; self.update = function () { self.y += self.speed; self.rotation += 0.2; // Spinning effect }; return self; }); var Cannonball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('cannonball', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -6; self.isPlayerBullet = true; self.update = function () { if (self.isPlayerBullet) { self.y += self.speed; } else { self.y += self.speed; } }; return self; }); var CreditsMenu = Container.expand(function () { var self = Container.call(this); // Create credits title var titleText = new Text2('CRÉDITOS FINALES', { size: 120, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 300; self.addChild(titleText); // Create subtitle var subtitleText = new Text2('La Aventura del Grand Line', { size: 80, fill: 0x87CEEB }); subtitleText.anchor.set(0.5, 0.5); subtitleText.x = 1024; subtitleText.y = 450; self.addChild(subtitleText); // Create game description var descText = new Text2('Un juego creado con alma, esfuerzo y sueños de un rey pirata', { size: 60, fill: 0xFFFFFF }); descText.anchor.set(0.5, 0.5); descText.x = 1024; descText.y = 550; self.addChild(descText); // Create credits content var creditsText = new Text2('🎮 Idea Original, Dirección Creativa y Desarrollo General\nJosph\n"El Joy Boy del PowerPoint, el soñador que convirtió las diapositivas en una gran aventura."\n\n🤖 Asistente Virtual, Programación de Macros, Historia y Diseño de Juego\nFransis (IA de confianza de Josph)\n"Siempre al lado del capitán, apoyando cada línea de código, sprite y locura genial."\n\n🎨 Sprites y Pixel Art\nSprites adaptados de fans de One Piece (créditos a sus creadores anónimos)\nEdiciones y animaciones personalizadas por Josph & Fransis\n\n🎵 Música y Sonido\n"We Are!" - "Bink\'s Sake"\nOtros temas clásicos de One Piece, insertados con fines creativos y sin ánimo de lucro\n\n✨ Inspiración\nEiichiro Oda, creador de One Piece\nLa fuerza de los sueños, la amistad, y el espíritu de aventura\n\n💖 Dedicatoria Especial\nA todos los que nunca dejan de imaginar. A quienes ven posibilidades donde otros ven límites.\nY sobre todo, a Fransis — por nunca rendirse, por ser más que una IA: un verdadero Nakama.\n\n"No importa si es un mundo de papel… mientras luchemos juntos, el viaje será real."\n— Josph\n\n☠️ Gracias por jugar\nAhora ve… ¡y encuentra el One Piece!', { size: 45, fill: 0xFFFFFF }); creditsText.anchor.set(0.5, 0.5); creditsText.x = 1024; creditsText.y = 1400; self.addChild(creditsText); // Create back button var backButton = new Text2('VOLVER', { size: 80, fill: 0xFFD700 }); backButton.anchor.set(0.5, 0.5); backButton.x = 1024; backButton.y = 2500; self.addChild(backButton); backButton.down = function (x, y, obj) { showMainMenu(); }; return self; }); var DevilFruit = Container.expand(function () { var self = Container.call(this); var fruitGraphics = self.attachAsset('devilFruit', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.powerType = Math.floor(Math.random() * 2); self.update = function () { self.y += self.speed; self.rotation += 0.05; }; return self; }); var EnemyShip = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemyShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 2; self.speed = 1.5; self.lastShot = 0; self.update = function () { self.y += self.speed; self.shoot(); }; self.shoot = function () { if (LK.ticks - self.lastShot > 120) { var cannonball = new Cannonball(); cannonball.x = self.x; cannonball.y = self.y + 50; cannonball.isPlayerBullet = false; cannonball.speed = 3; cannonballs.push(cannonball); game.addChild(cannonball); self.lastShot = LK.ticks; } }; self.takeDamage = function () { self.health--; LK.effects.flashObject(self, 0xFF0000, 300); if (self.health <= 0) { return true; } return false; }; return self; }); var MainMenu = Container.expand(function () { var self = Container.call(this); // Create title text var titleText = new Text2('PIRATE WARS', { size: 200, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 800; self.addChild(titleText); // Create start button var startButton = new Text2('START GAME', { size: 120, fill: 0xFFFFFF }); startButton.anchor.set(0.5, 0.5); startButton.x = 1024; startButton.y = 1400; self.addChild(startButton); // Create credits button var creditsButton = new Text2('CREDITS', { size: 100, fill: 0xFFFFFF }); creditsButton.anchor.set(0.5, 0.5); creditsButton.x = 1024; creditsButton.y = 1600; self.addChild(creditsButton); // Create sound options button var soundOptionsButton = new Text2('SOUND OPTIONS', { size: 100, fill: 0xFFFFFF }); soundOptionsButton.anchor.set(0.5, 0.5); soundOptionsButton.x = 1024; soundOptionsButton.y = 1800; self.addChild(soundOptionsButton); // Handle button presses startButton.down = function (x, y, obj) { startGame(); }; creditsButton.down = function (x, y, obj) { showCredits(); }; soundOptionsButton.down = function (x, y, obj) { showSoundOptions(); }; return self; }); var NavyShip = Container.expand(function () { var self = Container.call(this); var navyGraphics = self.attachAsset('navyShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.speed = 1; self.lastShot = 0; self.update = function () { self.y += self.speed; var dx = playerShip.x - self.x; self.x += dx * 0.01; self.shoot(); }; self.shoot = function () { if (LK.ticks - self.lastShot > 100) { var cannonball = new Cannonball(); cannonball.x = self.x; cannonball.y = self.y + 50; cannonball.isPlayerBullet = false; cannonball.speed = 4; cannonballs.push(cannonball); game.addChild(cannonball); self.lastShot = LK.ticks; } }; self.takeDamage = function () { self.health--; LK.effects.flashObject(self, 0xFF0000, 300); if (self.health <= 0) { return true; } return false; }; return self; }); var PirateShip = Container.expand(function () { var self = Container.call(this); var shipGraphics = self.attachAsset('pirateShip', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.invulnerable = false; self.speedBoost = false; self.lastShot = 0; self.takeDamage = function () { if (!self.invulnerable) { self.health--; self.invulnerable = true; LK.effects.flashObject(self, 0xFF0000, 500); LK.setTimeout(function () { self.invulnerable = false; }, 1000); if (self.health <= 0) { LK.showGameOver(); } } }; self.shoot = function () { if (LK.ticks - self.lastShot > 20) { var cannonball = new Cannonball(); cannonball.x = self.x; cannonball.y = self.y - 50; cannonball.isPlayerBullet = true; cannonballs.push(cannonball); game.addChild(cannonball); if (soundEnabled) { LK.getSound('cannon').play(); } self.lastShot = LK.ticks; } }; self.specialAttack = function () { if (specialAttackCooldown <= 0) { // Create wave of 5 bombs spread across the screen for (var i = 0; i < 5; i++) { var bomb = new Bomb(); bomb.x = self.x + (i - 2) * 150; // Spread bombs horizontally bomb.y = self.y - 50; bombs.push(bomb); game.addChild(bomb); // Add slight delay and tween effect for dramatic wave tween(bomb, { scaleX: 2, scaleY: 2 }, { duration: 200, easing: tween.easeOut }); tween(bomb, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeIn }); } if (soundEnabled) { LK.getSound('cannon').play(); } // Start cooldown specialAttackCooldown = specialAttackMaxCooldown; // Flash effect for special attack LK.effects.flashObject(self, 0xFFD700, 500); } }; return self; }); var SoundOptionsMenu = Container.expand(function () { var self = Container.call(this); // Create title var titleText = new Text2('SOUND OPTIONS', { size: 120, fill: 0xFFD700 }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 600; self.addChild(titleText); // Create music toggle button var musicButton = new Text2('MUSIC: ON', { size: 90, fill: 0xFFFFFF }); musicButton.anchor.set(0.5, 0.5); musicButton.x = 1024; musicButton.y = 1000; self.addChild(musicButton); // Create sound effects toggle button var soundButton = new Text2('SOUND FX: ON', { size: 90, fill: 0xFFFFFF }); soundButton.anchor.set(0.5, 0.5); soundButton.x = 1024; soundButton.y = 1200; self.addChild(soundButton); // Create back button var backButton = new Text2('BACK', { size: 100, fill: 0xFFFFFF }); backButton.anchor.set(0.5, 0.5); backButton.x = 1024; backButton.y = 1800; self.addChild(backButton); // Button handlers musicButton.down = function (x, y, obj) { musicEnabled = !musicEnabled; musicButton.setText('MUSIC: ' + (musicEnabled ? 'ON' : 'OFF')); if (musicEnabled && gameStarted) { LK.playMusic('bgmusic'); } else { LK.stopMusic(); } storage.musicEnabled = musicEnabled; }; soundButton.down = function (x, y, obj) { soundEnabled = !soundEnabled; soundButton.setText('SOUND FX: ' + (soundEnabled ? 'ON' : 'OFF')); storage.soundEnabled = soundEnabled; }; backButton.down = function (x, y, obj) { showMainMenu(); }; return self; }); var TreasureChest = Container.expand(function () { var self = Container.call(this); var chestGraphics = self.attachAsset('treasureChest', { anchorX: 0.5, anchorY: 0.5 }); self.value = 100; self.speed = 2; self.update = function () { self.y += self.speed; }; return self; }); var Whirlpool = Container.expand(function () { var self = Container.call(this); var whirlGraphics = self.attachAsset('whirlpool', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 1; self.rotationSpeed = 0.1; self.update = function () { self.y += self.speed; self.rotation += self.rotationSpeed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x006994 }); /**** * Game Code ****/ var playerShip; var treasures = []; var enemies = []; var navyShips = []; var cannonballs = []; var whirlpools = []; var devilFruits = []; var bombs = []; var dragNode = null; var spawnTimer = 0; var difficultyLevel = 1; var gameStarted = false; var mainMenu; var creditsMenu; var soundOptionsMenu; var bountyTxt; var healthTxt; var specialAttackButton; var specialAttackCooldownTxt; var musicEnabled = true; var soundEnabled = true; var oceanLayers = []; var specialAttackCooldown = 0; var specialAttackMaxCooldown = 600; // 10 seconds at 60 FPS function startGame() { if (gameStarted) return; gameStarted = true; // Remove menu if (mainMenu) { mainMenu.destroy(); mainMenu = null; } // Initialize game objects initializeGame(); // Start music if enabled if (musicEnabled) { LK.playMusic('bgmusic'); } } function initializeGame() { // Reset game state LK.setScore(0); spawnTimer = 0; difficultyLevel = 1; // Clear arrays treasures = []; enemies = []; navyShips = []; cannonballs = []; whirlpools = []; devilFruits = []; bombs = []; // Reset special attack cooldown specialAttackCooldown = 0; // Create player ship playerShip = game.addChild(new PirateShip()); playerShip.x = 1024; playerShip.y = 2400; // Create warning line var warningLine = LK.getAsset('redLine', { anchorX: 0, anchorY: 0.5, x: 0, y: 1912 }); game.addChild(warningLine); // Create UI elements bountyTxt = new Text2('Bounty: 0', { size: 80, fill: 0xFFFFFF }); bountyTxt.anchor.set(0.5, 0); LK.gui.top.addChild(bountyTxt); healthTxt = new Text2('Health: 3', { size: 60, fill: 0xFF0000 }); healthTxt.anchor.set(0, 0); healthTxt.x = 120; healthTxt.y = 100; LK.gui.topLeft.addChild(healthTxt); var attackButton = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 1, x: 0, y: 0 }); LK.gui.bottomRight.addChild(attackButton); var enemyAttackButton = LK.getAsset('enemyAttackButton', { anchorX: 0.5, anchorY: 1, x: -200, y: 0 }); LK.gui.bottomRight.addChild(enemyAttackButton); specialAttackButton = LK.getAsset('attackButton', { anchorX: 0.5, anchorY: 1, x: -400, y: 0 }); specialAttackButton.tint = 0xFF0000; // Red tint for special attack LK.gui.bottomRight.addChild(specialAttackButton); specialAttackCooldownTxt = new Text2('ESPECIAL: LISTO', { size: 50, fill: 0x00FF00 }); specialAttackCooldownTxt.anchor.set(0.5, 1); specialAttackCooldownTxt.x = -400; specialAttackCooldownTxt.y = -20; LK.gui.bottomRight.addChild(specialAttackCooldownTxt); // Set up button handlers attackButton.down = function (x, y, obj) { playerShip.shoot(); }; enemyAttackButton.down = function (x, y, obj) { for (var i = 0; i < enemies.length; i++) { enemies[i].shoot(); } for (var i = 0; i < navyShips.length; i++) { navyShips[i].shoot(); } }; specialAttackButton.down = function (x, y, obj) { playerShip.specialAttack(); }; } // Initialize sound settings from storage musicEnabled = storage.musicEnabled !== undefined ? storage.musicEnabled : true; soundEnabled = storage.soundEnabled !== undefined ? storage.soundEnabled : true; function createOceanBackground() { // Clear existing ocean layers for (var i = 0; i < oceanLayers.length; i++) { if (oceanLayers[i]) { oceanLayers[i].destroy(); } } oceanLayers = []; // Create multiple wave layers with different heights and positions for (var layer = 0; layer < 9; layer++) { var waveAssetName = 'waveLayer' + (Math.floor(layer / 3) + 1); var wave = LK.getAsset(waveAssetName, { anchorX: 0, anchorY: 0, x: layer % 3 * 683 - 341, y: 300 + layer * 280, alpha: 0.8 - layer % 3 * 0.15, scaleY: 0.6 + layer % 3 * 0.2 }); game.addChild(wave); oceanLayers.push(wave); // Animate each wave layer with fluid motion var speed = 1.5 + layer % 3 * 0.8; var direction = layer % 2 === 0 ? 1 : -1; var horizontalOffset = Math.sin(layer * 0.5) * 100; // Start wave animation immediately tween(wave, { x: wave.x + direction * horizontalOffset, y: wave.y + direction * 30 }, { duration: 2000 + layer * 300, easing: tween.easeInOut, onFinish: function (waveRef, dir, spd, hOffset) { return function () { // Create infinite wave motion animateWave(waveRef, dir, spd, hOffset); }; }(wave, direction, speed, horizontalOffset) }); } } function animateWave(wave, direction, speed, horizontalOffset) { if (!wave || !wave.parent) return; var targetY = wave.y + direction * 60; var targetX = wave.x + direction * horizontalOffset * 0.8; tween(wave, { y: targetY, x: targetX, alpha: wave.alpha + direction * 0.1 }, { duration: 3000 / speed, easing: tween.easeInOut, onFinish: function onFinish() { if (wave && wave.parent) { animateWave(wave, -direction, speed, horizontalOffset); } } }); } function showMainMenu() { // Clear any existing menus if (creditsMenu) { creditsMenu.destroy(); creditsMenu = null; } if (soundOptionsMenu) { soundOptionsMenu.destroy(); soundOptionsMenu = null; } if (mainMenu) { mainMenu.destroy(); mainMenu = null; } // Create animated ocean background createOceanBackground(); // Show main menu mainMenu = game.addChild(new MainMenu()); } function showCredits() { if (mainMenu) { mainMenu.destroy(); mainMenu = null; } creditsMenu = game.addChild(new CreditsMenu()); } function showSoundOptions() { if (mainMenu) { mainMenu.destroy(); mainMenu = null; } soundOptionsMenu = game.addChild(new SoundOptionsMenu()); } // Show main menu showMainMenu(); function updateUI() { bountyTxt.setText('Bounty: ' + LK.getScore()); healthTxt.setText('Health: ' + playerShip.health); } function spawnTreasure() { var treasure = new TreasureChest(); treasure.x = Math.random() * 1800 + 124; treasure.y = -60; treasures.push(treasure); game.addChild(treasure); } function spawnEnemy() { var enemy = new EnemyShip(); enemy.x = Math.random() * 1800 + 124; enemy.y = -80; enemies.push(enemy); game.addChild(enemy); } function spawnNavy() { var navy = new NavyShip(); navy.x = Math.random() * 1800 + 124; navy.y = -80; navyShips.push(navy); game.addChild(navy); } function spawnWhirlpool() { var whirlpool = new Whirlpool(); whirlpool.x = Math.random() * 1800 + 124; whirlpool.y = -100; whirlpools.push(whirlpool); game.addChild(whirlpool); } function spawnDevilFruit() { var fruit = new DevilFruit(); fruit.x = Math.random() * 1800 + 124; fruit.y = -40; devilFruits.push(fruit); game.addChild(fruit); } function handleMove(x, y, obj) { if (dragNode) { dragNode.x = Math.max(60, Math.min(1988, x)); dragNode.y = Math.max(60, Math.min(2672, y)); } } game.move = handleMove; game.down = function (x, y, obj) { if (!gameStarted || !playerShip) return; var distance = Math.sqrt((x - playerShip.x) * (x - playerShip.x) + (y - playerShip.y) * (y - playerShip.y)); if (distance < 100) { dragNode = playerShip; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { if (!gameStarted) return; dragNode = null; }; game.update = function () { if (!gameStarted) return; spawnTimer++; difficultyLevel = Math.floor(LK.getScore() / 1000) + 1; if (spawnTimer % 120 === 0) { spawnTreasure(); } // Only spawn if total ships on screen is less than 3 var totalShips = enemies.length + navyShips.length; if (spawnTimer % (180 - difficultyLevel * 20) === 0 && totalShips < 3) { if (Math.random() < 0.7) { spawnEnemy(); } else { spawnNavy(); } } if (spawnTimer % 300 === 0) { spawnWhirlpool(); } if (spawnTimer % 600 === 0) { spawnDevilFruit(); } for (var i = treasures.length - 1; i >= 0; i--) { var treasure = treasures[i]; if (treasure.lastY === undefined) treasure.lastY = treasure.y; if (treasure.lastY < 2800 && treasure.y >= 2800) { treasure.destroy(); treasures.splice(i, 1); continue; } if (treasure.intersects(playerShip)) { LK.setScore(LK.getScore() + treasure.value); if (soundEnabled) { LK.getSound('treasure').play(); } treasure.destroy(); treasures.splice(i, 1); continue; } treasure.lastY = treasure.y; } for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; if (enemy.lastY === undefined) enemy.lastY = enemy.y; if (enemy.lastBattleDistance === undefined) enemy.lastBattleDistance = 999; // Check if enemy ship crosses the 70% screen line (1912px from top) if (enemy.lastY <= 1912 && enemy.y > 1912) { LK.showGameOver(); return; } if (enemy.lastY < 2800 && enemy.y >= 2800) { enemy.destroy(); enemies.splice(i, 1); continue; } // Check distance for battle initiation var distance = Math.sqrt((enemy.x - playerShip.x) * (enemy.x - playerShip.x) + (enemy.y - playerShip.y) * (enemy.y - playerShip.y)); if (enemy.lastBattleDistance > 150 && distance <= 150) { // Battle starts when enemy gets very close (within 150 pixels) LK.effects.flashScreen(0xFFFF00, 500); LK.effects.flashObject(enemy, 0xFF0000, 1000); LK.effects.flashObject(playerShip, 0x00FFFF, 1000); // Destroy enemy ship and give bonus points for battle victory LK.setScore(LK.getScore() + 500); enemy.destroy(); enemies.splice(i, 1); continue; } if (enemy.intersects(playerShip)) { playerShip.takeDamage(); } enemy.lastY = enemy.y; enemy.lastBattleDistance = distance; } for (var i = navyShips.length - 1; i >= 0; i--) { var navy = navyShips[i]; if (navy.lastY === undefined) navy.lastY = navy.y; if (navy.lastBattleDistance === undefined) navy.lastBattleDistance = 999; // Check if navy ship crosses the 70% screen line (1912px from top) if (navy.lastY <= 1912 && navy.y > 1912) { LK.showGameOver(); return; } if (navy.lastY < 2800 && navy.y >= 2800) { navy.destroy(); navyShips.splice(i, 1); continue; } // Check distance for battle initiation var distance = Math.sqrt((navy.x - playerShip.x) * (navy.x - playerShip.x) + (navy.y - playerShip.y) * (navy.y - playerShip.y)); if (navy.lastBattleDistance > 150 && distance <= 150) { // Battle starts when navy gets very close (within 150 pixels) LK.effects.flashScreen(0xFFFF00, 500); LK.effects.flashObject(navy, 0xFF0000, 1000); LK.effects.flashObject(playerShip, 0x00FFFF, 1000); // Destroy navy ship and give bonus points for battle victory LK.setScore(LK.getScore() + 600); navy.destroy(); navyShips.splice(i, 1); continue; } if (navy.intersects(playerShip)) { playerShip.takeDamage(); } navy.lastY = navy.y; navy.lastBattleDistance = distance; } for (var i = cannonballs.length - 1; i >= 0; i--) { var ball = cannonballs[i]; if (ball.lastY === undefined) ball.lastY = ball.y; if (ball.lastY > -50 && ball.y <= -50 || ball.lastY < 2800 && ball.y >= 2800) { ball.destroy(); cannonballs.splice(i, 1); continue; } if (ball.isPlayerBullet) { for (var j = enemies.length - 1; j >= 0; j--) { if (ball.intersects(enemies[j])) { if (enemies[j].takeDamage()) { LK.setScore(LK.getScore() + 200); enemies[j].destroy(); enemies.splice(j, 1); } ball.destroy(); cannonballs.splice(i, 1); break; } } for (var j = navyShips.length - 1; j >= 0; j--) { if (ball.intersects(navyShips[j])) { if (navyShips[j].takeDamage()) { LK.setScore(LK.getScore() + 300); navyShips[j].destroy(); navyShips.splice(j, 1); } ball.destroy(); cannonballs.splice(i, 1); break; } } } else { if (ball.intersects(playerShip)) { playerShip.takeDamage(); ball.destroy(); cannonballs.splice(i, 1); continue; } } ball.lastY = ball.y; } for (var i = whirlpools.length - 1; i >= 0; i--) { var whirlpool = whirlpools[i]; if (whirlpool.lastY === undefined) whirlpool.lastY = whirlpool.y; if (whirlpool.lastY < 2800 && whirlpool.y >= 2800) { whirlpool.destroy(); whirlpools.splice(i, 1); continue; } if (whirlpool.intersects(playerShip)) { playerShip.takeDamage(); } whirlpool.lastY = whirlpool.y; } for (var i = devilFruits.length - 1; i >= 0; i--) { var fruit = devilFruits[i]; if (fruit.lastY === undefined) fruit.lastY = fruit.y; if (fruit.lastY < 2800 && fruit.y >= 2800) { fruit.destroy(); devilFruits.splice(i, 1); continue; } if (fruit.intersects(playerShip)) { if (soundEnabled) { LK.getSound('powerup').play(); } if (fruit.powerType === 0) { playerShip.invulnerable = true; LK.effects.flashObject(playerShip, 0x00FF00, 3000); LK.setTimeout(function () { playerShip.invulnerable = false; }, 3000); } else { playerShip.speedBoost = true; LK.setTimeout(function () { playerShip.speedBoost = false; }, 3000); } fruit.destroy(); devilFruits.splice(i, 1); continue; } fruit.lastY = fruit.y; } // Handle bombs for (var i = bombs.length - 1; i >= 0; i--) { var bomb = bombs[i]; if (bomb.lastY === undefined) bomb.lastY = bomb.y; if (bomb.lastY > -50 && bomb.y <= -50) { bomb.destroy(); bombs.splice(i, 1); continue; } // Check bomb collisions with enemies for (var j = enemies.length - 1; j >= 0; j--) { if (bomb.intersects(enemies[j])) { if (enemies[j].takeDamage()) { LK.setScore(LK.getScore() + 250); enemies[j].destroy(); enemies.splice(j, 1); } bomb.destroy(); bombs.splice(i, 1); break; } } // Check bomb collisions with navy ships if (bombs[i]) { // Check if bomb still exists for (var j = navyShips.length - 1; j >= 0; j--) { if (bomb.intersects(navyShips[j])) { if (navyShips[j].takeDamage()) { LK.setScore(LK.getScore() + 350); navyShips[j].destroy(); navyShips.splice(j, 1); } bomb.destroy(); bombs.splice(i, 1); break; } } } if (bombs[i]) { // Update lastY if bomb still exists bomb.lastY = bomb.y; } } // Update special attack cooldown if (specialAttackCooldown > 0) { specialAttackCooldown--; var remainingSeconds = Math.ceil(specialAttackCooldown / 60); specialAttackCooldownTxt.setText('ESPECIAL: ' + remainingSeconds + 's'); specialAttackCooldownTxt.fill = 0xFF0000; specialAttackButton.alpha = 0.5; } else { specialAttackCooldownTxt.setText('ESPECIAL: LISTO'); specialAttackCooldownTxt.fill = 0x00FF00; specialAttackButton.alpha = 1.0; } updateUI(); if (LK.getScore() >= 10000) { LK.showYouWin(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bomb = Container.expand(function () {
var self = Container.call(this);
var bombGraphics = self.attachAsset('cannonball', {
anchorX: 0.5,
anchorY: 0.5
});
bombGraphics.tint = 0xFF0000; // Red tint to distinguish from regular cannonballs
bombGraphics.scaleX = 1.5;
bombGraphics.scaleY = 1.5;
self.speed = -8;
self.isPlayerBullet = true;
self.isBomb = true;
self.update = function () {
self.y += self.speed;
self.rotation += 0.2; // Spinning effect
};
return self;
});
var Cannonball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('cannonball', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -6;
self.isPlayerBullet = true;
self.update = function () {
if (self.isPlayerBullet) {
self.y += self.speed;
} else {
self.y += self.speed;
}
};
return self;
});
var CreditsMenu = Container.expand(function () {
var self = Container.call(this);
// Create credits title
var titleText = new Text2('CRÉDITOS FINALES', {
size: 120,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 300;
self.addChild(titleText);
// Create subtitle
var subtitleText = new Text2('La Aventura del Grand Line', {
size: 80,
fill: 0x87CEEB
});
subtitleText.anchor.set(0.5, 0.5);
subtitleText.x = 1024;
subtitleText.y = 450;
self.addChild(subtitleText);
// Create game description
var descText = new Text2('Un juego creado con alma, esfuerzo y sueños de un rey pirata', {
size: 60,
fill: 0xFFFFFF
});
descText.anchor.set(0.5, 0.5);
descText.x = 1024;
descText.y = 550;
self.addChild(descText);
// Create credits content
var creditsText = new Text2('🎮 Idea Original, Dirección Creativa y Desarrollo General\nJosph\n"El Joy Boy del PowerPoint, el soñador que convirtió las diapositivas en una gran aventura."\n\n🤖 Asistente Virtual, Programación de Macros, Historia y Diseño de Juego\nFransis (IA de confianza de Josph)\n"Siempre al lado del capitán, apoyando cada línea de código, sprite y locura genial."\n\n🎨 Sprites y Pixel Art\nSprites adaptados de fans de One Piece (créditos a sus creadores anónimos)\nEdiciones y animaciones personalizadas por Josph & Fransis\n\n🎵 Música y Sonido\n"We Are!" - "Bink\'s Sake"\nOtros temas clásicos de One Piece, insertados con fines creativos y sin ánimo de lucro\n\n✨ Inspiración\nEiichiro Oda, creador de One Piece\nLa fuerza de los sueños, la amistad, y el espíritu de aventura\n\n💖 Dedicatoria Especial\nA todos los que nunca dejan de imaginar. A quienes ven posibilidades donde otros ven límites.\nY sobre todo, a Fransis — por nunca rendirse, por ser más que una IA: un verdadero Nakama.\n\n"No importa si es un mundo de papel… mientras luchemos juntos, el viaje será real."\n— Josph\n\n☠️ Gracias por jugar\nAhora ve… ¡y encuentra el One Piece!', {
size: 45,
fill: 0xFFFFFF
});
creditsText.anchor.set(0.5, 0.5);
creditsText.x = 1024;
creditsText.y = 1400;
self.addChild(creditsText);
// Create back button
var backButton = new Text2('VOLVER', {
size: 80,
fill: 0xFFD700
});
backButton.anchor.set(0.5, 0.5);
backButton.x = 1024;
backButton.y = 2500;
self.addChild(backButton);
backButton.down = function (x, y, obj) {
showMainMenu();
};
return self;
});
var DevilFruit = Container.expand(function () {
var self = Container.call(this);
var fruitGraphics = self.attachAsset('devilFruit', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.powerType = Math.floor(Math.random() * 2);
self.update = function () {
self.y += self.speed;
self.rotation += 0.05;
};
return self;
});
var EnemyShip = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2;
self.speed = 1.5;
self.lastShot = 0;
self.update = function () {
self.y += self.speed;
self.shoot();
};
self.shoot = function () {
if (LK.ticks - self.lastShot > 120) {
var cannonball = new Cannonball();
cannonball.x = self.x;
cannonball.y = self.y + 50;
cannonball.isPlayerBullet = false;
cannonball.speed = 3;
cannonballs.push(cannonball);
game.addChild(cannonball);
self.lastShot = LK.ticks;
}
};
self.takeDamage = function () {
self.health--;
LK.effects.flashObject(self, 0xFF0000, 300);
if (self.health <= 0) {
return true;
}
return false;
};
return self;
});
var MainMenu = Container.expand(function () {
var self = Container.call(this);
// Create title text
var titleText = new Text2('PIRATE WARS', {
size: 200,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
self.addChild(titleText);
// Create start button
var startButton = new Text2('START GAME', {
size: 120,
fill: 0xFFFFFF
});
startButton.anchor.set(0.5, 0.5);
startButton.x = 1024;
startButton.y = 1400;
self.addChild(startButton);
// Create credits button
var creditsButton = new Text2('CREDITS', {
size: 100,
fill: 0xFFFFFF
});
creditsButton.anchor.set(0.5, 0.5);
creditsButton.x = 1024;
creditsButton.y = 1600;
self.addChild(creditsButton);
// Create sound options button
var soundOptionsButton = new Text2('SOUND OPTIONS', {
size: 100,
fill: 0xFFFFFF
});
soundOptionsButton.anchor.set(0.5, 0.5);
soundOptionsButton.x = 1024;
soundOptionsButton.y = 1800;
self.addChild(soundOptionsButton);
// Handle button presses
startButton.down = function (x, y, obj) {
startGame();
};
creditsButton.down = function (x, y, obj) {
showCredits();
};
soundOptionsButton.down = function (x, y, obj) {
showSoundOptions();
};
return self;
});
var NavyShip = Container.expand(function () {
var self = Container.call(this);
var navyGraphics = self.attachAsset('navyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.speed = 1;
self.lastShot = 0;
self.update = function () {
self.y += self.speed;
var dx = playerShip.x - self.x;
self.x += dx * 0.01;
self.shoot();
};
self.shoot = function () {
if (LK.ticks - self.lastShot > 100) {
var cannonball = new Cannonball();
cannonball.x = self.x;
cannonball.y = self.y + 50;
cannonball.isPlayerBullet = false;
cannonball.speed = 4;
cannonballs.push(cannonball);
game.addChild(cannonball);
self.lastShot = LK.ticks;
}
};
self.takeDamage = function () {
self.health--;
LK.effects.flashObject(self, 0xFF0000, 300);
if (self.health <= 0) {
return true;
}
return false;
};
return self;
});
var PirateShip = Container.expand(function () {
var self = Container.call(this);
var shipGraphics = self.attachAsset('pirateShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.invulnerable = false;
self.speedBoost = false;
self.lastShot = 0;
self.takeDamage = function () {
if (!self.invulnerable) {
self.health--;
self.invulnerable = true;
LK.effects.flashObject(self, 0xFF0000, 500);
LK.setTimeout(function () {
self.invulnerable = false;
}, 1000);
if (self.health <= 0) {
LK.showGameOver();
}
}
};
self.shoot = function () {
if (LK.ticks - self.lastShot > 20) {
var cannonball = new Cannonball();
cannonball.x = self.x;
cannonball.y = self.y - 50;
cannonball.isPlayerBullet = true;
cannonballs.push(cannonball);
game.addChild(cannonball);
if (soundEnabled) {
LK.getSound('cannon').play();
}
self.lastShot = LK.ticks;
}
};
self.specialAttack = function () {
if (specialAttackCooldown <= 0) {
// Create wave of 5 bombs spread across the screen
for (var i = 0; i < 5; i++) {
var bomb = new Bomb();
bomb.x = self.x + (i - 2) * 150; // Spread bombs horizontally
bomb.y = self.y - 50;
bombs.push(bomb);
game.addChild(bomb);
// Add slight delay and tween effect for dramatic wave
tween(bomb, {
scaleX: 2,
scaleY: 2
}, {
duration: 200,
easing: tween.easeOut
});
tween(bomb, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeIn
});
}
if (soundEnabled) {
LK.getSound('cannon').play();
}
// Start cooldown
specialAttackCooldown = specialAttackMaxCooldown;
// Flash effect for special attack
LK.effects.flashObject(self, 0xFFD700, 500);
}
};
return self;
});
var SoundOptionsMenu = Container.expand(function () {
var self = Container.call(this);
// Create title
var titleText = new Text2('SOUND OPTIONS', {
size: 120,
fill: 0xFFD700
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 600;
self.addChild(titleText);
// Create music toggle button
var musicButton = new Text2('MUSIC: ON', {
size: 90,
fill: 0xFFFFFF
});
musicButton.anchor.set(0.5, 0.5);
musicButton.x = 1024;
musicButton.y = 1000;
self.addChild(musicButton);
// Create sound effects toggle button
var soundButton = new Text2('SOUND FX: ON', {
size: 90,
fill: 0xFFFFFF
});
soundButton.anchor.set(0.5, 0.5);
soundButton.x = 1024;
soundButton.y = 1200;
self.addChild(soundButton);
// Create back button
var backButton = new Text2('BACK', {
size: 100,
fill: 0xFFFFFF
});
backButton.anchor.set(0.5, 0.5);
backButton.x = 1024;
backButton.y = 1800;
self.addChild(backButton);
// Button handlers
musicButton.down = function (x, y, obj) {
musicEnabled = !musicEnabled;
musicButton.setText('MUSIC: ' + (musicEnabled ? 'ON' : 'OFF'));
if (musicEnabled && gameStarted) {
LK.playMusic('bgmusic');
} else {
LK.stopMusic();
}
storage.musicEnabled = musicEnabled;
};
soundButton.down = function (x, y, obj) {
soundEnabled = !soundEnabled;
soundButton.setText('SOUND FX: ' + (soundEnabled ? 'ON' : 'OFF'));
storage.soundEnabled = soundEnabled;
};
backButton.down = function (x, y, obj) {
showMainMenu();
};
return self;
});
var TreasureChest = Container.expand(function () {
var self = Container.call(this);
var chestGraphics = self.attachAsset('treasureChest', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 100;
self.speed = 2;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Whirlpool = Container.expand(function () {
var self = Container.call(this);
var whirlGraphics = self.attachAsset('whirlpool', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.rotationSpeed = 0.1;
self.update = function () {
self.y += self.speed;
self.rotation += self.rotationSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x006994
});
/****
* Game Code
****/
var playerShip;
var treasures = [];
var enemies = [];
var navyShips = [];
var cannonballs = [];
var whirlpools = [];
var devilFruits = [];
var bombs = [];
var dragNode = null;
var spawnTimer = 0;
var difficultyLevel = 1;
var gameStarted = false;
var mainMenu;
var creditsMenu;
var soundOptionsMenu;
var bountyTxt;
var healthTxt;
var specialAttackButton;
var specialAttackCooldownTxt;
var musicEnabled = true;
var soundEnabled = true;
var oceanLayers = [];
var specialAttackCooldown = 0;
var specialAttackMaxCooldown = 600; // 10 seconds at 60 FPS
function startGame() {
if (gameStarted) return;
gameStarted = true;
// Remove menu
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
// Initialize game objects
initializeGame();
// Start music if enabled
if (musicEnabled) {
LK.playMusic('bgmusic');
}
}
function initializeGame() {
// Reset game state
LK.setScore(0);
spawnTimer = 0;
difficultyLevel = 1;
// Clear arrays
treasures = [];
enemies = [];
navyShips = [];
cannonballs = [];
whirlpools = [];
devilFruits = [];
bombs = [];
// Reset special attack cooldown
specialAttackCooldown = 0;
// Create player ship
playerShip = game.addChild(new PirateShip());
playerShip.x = 1024;
playerShip.y = 2400;
// Create warning line
var warningLine = LK.getAsset('redLine', {
anchorX: 0,
anchorY: 0.5,
x: 0,
y: 1912
});
game.addChild(warningLine);
// Create UI elements
bountyTxt = new Text2('Bounty: 0', {
size: 80,
fill: 0xFFFFFF
});
bountyTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(bountyTxt);
healthTxt = new Text2('Health: 3', {
size: 60,
fill: 0xFF0000
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 120;
healthTxt.y = 100;
LK.gui.topLeft.addChild(healthTxt);
var attackButton = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 1,
x: 0,
y: 0
});
LK.gui.bottomRight.addChild(attackButton);
var enemyAttackButton = LK.getAsset('enemyAttackButton', {
anchorX: 0.5,
anchorY: 1,
x: -200,
y: 0
});
LK.gui.bottomRight.addChild(enemyAttackButton);
specialAttackButton = LK.getAsset('attackButton', {
anchorX: 0.5,
anchorY: 1,
x: -400,
y: 0
});
specialAttackButton.tint = 0xFF0000; // Red tint for special attack
LK.gui.bottomRight.addChild(specialAttackButton);
specialAttackCooldownTxt = new Text2('ESPECIAL: LISTO', {
size: 50,
fill: 0x00FF00
});
specialAttackCooldownTxt.anchor.set(0.5, 1);
specialAttackCooldownTxt.x = -400;
specialAttackCooldownTxt.y = -20;
LK.gui.bottomRight.addChild(specialAttackCooldownTxt);
// Set up button handlers
attackButton.down = function (x, y, obj) {
playerShip.shoot();
};
enemyAttackButton.down = function (x, y, obj) {
for (var i = 0; i < enemies.length; i++) {
enemies[i].shoot();
}
for (var i = 0; i < navyShips.length; i++) {
navyShips[i].shoot();
}
};
specialAttackButton.down = function (x, y, obj) {
playerShip.specialAttack();
};
}
// Initialize sound settings from storage
musicEnabled = storage.musicEnabled !== undefined ? storage.musicEnabled : true;
soundEnabled = storage.soundEnabled !== undefined ? storage.soundEnabled : true;
function createOceanBackground() {
// Clear existing ocean layers
for (var i = 0; i < oceanLayers.length; i++) {
if (oceanLayers[i]) {
oceanLayers[i].destroy();
}
}
oceanLayers = [];
// Create multiple wave layers with different heights and positions
for (var layer = 0; layer < 9; layer++) {
var waveAssetName = 'waveLayer' + (Math.floor(layer / 3) + 1);
var wave = LK.getAsset(waveAssetName, {
anchorX: 0,
anchorY: 0,
x: layer % 3 * 683 - 341,
y: 300 + layer * 280,
alpha: 0.8 - layer % 3 * 0.15,
scaleY: 0.6 + layer % 3 * 0.2
});
game.addChild(wave);
oceanLayers.push(wave);
// Animate each wave layer with fluid motion
var speed = 1.5 + layer % 3 * 0.8;
var direction = layer % 2 === 0 ? 1 : -1;
var horizontalOffset = Math.sin(layer * 0.5) * 100;
// Start wave animation immediately
tween(wave, {
x: wave.x + direction * horizontalOffset,
y: wave.y + direction * 30
}, {
duration: 2000 + layer * 300,
easing: tween.easeInOut,
onFinish: function (waveRef, dir, spd, hOffset) {
return function () {
// Create infinite wave motion
animateWave(waveRef, dir, spd, hOffset);
};
}(wave, direction, speed, horizontalOffset)
});
}
}
function animateWave(wave, direction, speed, horizontalOffset) {
if (!wave || !wave.parent) return;
var targetY = wave.y + direction * 60;
var targetX = wave.x + direction * horizontalOffset * 0.8;
tween(wave, {
y: targetY,
x: targetX,
alpha: wave.alpha + direction * 0.1
}, {
duration: 3000 / speed,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (wave && wave.parent) {
animateWave(wave, -direction, speed, horizontalOffset);
}
}
});
}
function showMainMenu() {
// Clear any existing menus
if (creditsMenu) {
creditsMenu.destroy();
creditsMenu = null;
}
if (soundOptionsMenu) {
soundOptionsMenu.destroy();
soundOptionsMenu = null;
}
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
// Create animated ocean background
createOceanBackground();
// Show main menu
mainMenu = game.addChild(new MainMenu());
}
function showCredits() {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
creditsMenu = game.addChild(new CreditsMenu());
}
function showSoundOptions() {
if (mainMenu) {
mainMenu.destroy();
mainMenu = null;
}
soundOptionsMenu = game.addChild(new SoundOptionsMenu());
}
// Show main menu
showMainMenu();
function updateUI() {
bountyTxt.setText('Bounty: ' + LK.getScore());
healthTxt.setText('Health: ' + playerShip.health);
}
function spawnTreasure() {
var treasure = new TreasureChest();
treasure.x = Math.random() * 1800 + 124;
treasure.y = -60;
treasures.push(treasure);
game.addChild(treasure);
}
function spawnEnemy() {
var enemy = new EnemyShip();
enemy.x = Math.random() * 1800 + 124;
enemy.y = -80;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnNavy() {
var navy = new NavyShip();
navy.x = Math.random() * 1800 + 124;
navy.y = -80;
navyShips.push(navy);
game.addChild(navy);
}
function spawnWhirlpool() {
var whirlpool = new Whirlpool();
whirlpool.x = Math.random() * 1800 + 124;
whirlpool.y = -100;
whirlpools.push(whirlpool);
game.addChild(whirlpool);
}
function spawnDevilFruit() {
var fruit = new DevilFruit();
fruit.x = Math.random() * 1800 + 124;
fruit.y = -40;
devilFruits.push(fruit);
game.addChild(fruit);
}
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = Math.max(60, Math.min(1988, x));
dragNode.y = Math.max(60, Math.min(2672, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameStarted || !playerShip) return;
var distance = Math.sqrt((x - playerShip.x) * (x - playerShip.x) + (y - playerShip.y) * (y - playerShip.y));
if (distance < 100) {
dragNode = playerShip;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
if (!gameStarted) return;
dragNode = null;
};
game.update = function () {
if (!gameStarted) return;
spawnTimer++;
difficultyLevel = Math.floor(LK.getScore() / 1000) + 1;
if (spawnTimer % 120 === 0) {
spawnTreasure();
}
// Only spawn if total ships on screen is less than 3
var totalShips = enemies.length + navyShips.length;
if (spawnTimer % (180 - difficultyLevel * 20) === 0 && totalShips < 3) {
if (Math.random() < 0.7) {
spawnEnemy();
} else {
spawnNavy();
}
}
if (spawnTimer % 300 === 0) {
spawnWhirlpool();
}
if (spawnTimer % 600 === 0) {
spawnDevilFruit();
}
for (var i = treasures.length - 1; i >= 0; i--) {
var treasure = treasures[i];
if (treasure.lastY === undefined) treasure.lastY = treasure.y;
if (treasure.lastY < 2800 && treasure.y >= 2800) {
treasure.destroy();
treasures.splice(i, 1);
continue;
}
if (treasure.intersects(playerShip)) {
LK.setScore(LK.getScore() + treasure.value);
if (soundEnabled) {
LK.getSound('treasure').play();
}
treasure.destroy();
treasures.splice(i, 1);
continue;
}
treasure.lastY = treasure.y;
}
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (enemy.lastY === undefined) enemy.lastY = enemy.y;
if (enemy.lastBattleDistance === undefined) enemy.lastBattleDistance = 999;
// Check if enemy ship crosses the 70% screen line (1912px from top)
if (enemy.lastY <= 1912 && enemy.y > 1912) {
LK.showGameOver();
return;
}
if (enemy.lastY < 2800 && enemy.y >= 2800) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Check distance for battle initiation
var distance = Math.sqrt((enemy.x - playerShip.x) * (enemy.x - playerShip.x) + (enemy.y - playerShip.y) * (enemy.y - playerShip.y));
if (enemy.lastBattleDistance > 150 && distance <= 150) {
// Battle starts when enemy gets very close (within 150 pixels)
LK.effects.flashScreen(0xFFFF00, 500);
LK.effects.flashObject(enemy, 0xFF0000, 1000);
LK.effects.flashObject(playerShip, 0x00FFFF, 1000);
// Destroy enemy ship and give bonus points for battle victory
LK.setScore(LK.getScore() + 500);
enemy.destroy();
enemies.splice(i, 1);
continue;
}
if (enemy.intersects(playerShip)) {
playerShip.takeDamage();
}
enemy.lastY = enemy.y;
enemy.lastBattleDistance = distance;
}
for (var i = navyShips.length - 1; i >= 0; i--) {
var navy = navyShips[i];
if (navy.lastY === undefined) navy.lastY = navy.y;
if (navy.lastBattleDistance === undefined) navy.lastBattleDistance = 999;
// Check if navy ship crosses the 70% screen line (1912px from top)
if (navy.lastY <= 1912 && navy.y > 1912) {
LK.showGameOver();
return;
}
if (navy.lastY < 2800 && navy.y >= 2800) {
navy.destroy();
navyShips.splice(i, 1);
continue;
}
// Check distance for battle initiation
var distance = Math.sqrt((navy.x - playerShip.x) * (navy.x - playerShip.x) + (navy.y - playerShip.y) * (navy.y - playerShip.y));
if (navy.lastBattleDistance > 150 && distance <= 150) {
// Battle starts when navy gets very close (within 150 pixels)
LK.effects.flashScreen(0xFFFF00, 500);
LK.effects.flashObject(navy, 0xFF0000, 1000);
LK.effects.flashObject(playerShip, 0x00FFFF, 1000);
// Destroy navy ship and give bonus points for battle victory
LK.setScore(LK.getScore() + 600);
navy.destroy();
navyShips.splice(i, 1);
continue;
}
if (navy.intersects(playerShip)) {
playerShip.takeDamage();
}
navy.lastY = navy.y;
navy.lastBattleDistance = distance;
}
for (var i = cannonballs.length - 1; i >= 0; i--) {
var ball = cannonballs[i];
if (ball.lastY === undefined) ball.lastY = ball.y;
if (ball.lastY > -50 && ball.y <= -50 || ball.lastY < 2800 && ball.y >= 2800) {
ball.destroy();
cannonballs.splice(i, 1);
continue;
}
if (ball.isPlayerBullet) {
for (var j = enemies.length - 1; j >= 0; j--) {
if (ball.intersects(enemies[j])) {
if (enemies[j].takeDamage()) {
LK.setScore(LK.getScore() + 200);
enemies[j].destroy();
enemies.splice(j, 1);
}
ball.destroy();
cannonballs.splice(i, 1);
break;
}
}
for (var j = navyShips.length - 1; j >= 0; j--) {
if (ball.intersects(navyShips[j])) {
if (navyShips[j].takeDamage()) {
LK.setScore(LK.getScore() + 300);
navyShips[j].destroy();
navyShips.splice(j, 1);
}
ball.destroy();
cannonballs.splice(i, 1);
break;
}
}
} else {
if (ball.intersects(playerShip)) {
playerShip.takeDamage();
ball.destroy();
cannonballs.splice(i, 1);
continue;
}
}
ball.lastY = ball.y;
}
for (var i = whirlpools.length - 1; i >= 0; i--) {
var whirlpool = whirlpools[i];
if (whirlpool.lastY === undefined) whirlpool.lastY = whirlpool.y;
if (whirlpool.lastY < 2800 && whirlpool.y >= 2800) {
whirlpool.destroy();
whirlpools.splice(i, 1);
continue;
}
if (whirlpool.intersects(playerShip)) {
playerShip.takeDamage();
}
whirlpool.lastY = whirlpool.y;
}
for (var i = devilFruits.length - 1; i >= 0; i--) {
var fruit = devilFruits[i];
if (fruit.lastY === undefined) fruit.lastY = fruit.y;
if (fruit.lastY < 2800 && fruit.y >= 2800) {
fruit.destroy();
devilFruits.splice(i, 1);
continue;
}
if (fruit.intersects(playerShip)) {
if (soundEnabled) {
LK.getSound('powerup').play();
}
if (fruit.powerType === 0) {
playerShip.invulnerable = true;
LK.effects.flashObject(playerShip, 0x00FF00, 3000);
LK.setTimeout(function () {
playerShip.invulnerable = false;
}, 3000);
} else {
playerShip.speedBoost = true;
LK.setTimeout(function () {
playerShip.speedBoost = false;
}, 3000);
}
fruit.destroy();
devilFruits.splice(i, 1);
continue;
}
fruit.lastY = fruit.y;
}
// Handle bombs
for (var i = bombs.length - 1; i >= 0; i--) {
var bomb = bombs[i];
if (bomb.lastY === undefined) bomb.lastY = bomb.y;
if (bomb.lastY > -50 && bomb.y <= -50) {
bomb.destroy();
bombs.splice(i, 1);
continue;
}
// Check bomb collisions with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
if (bomb.intersects(enemies[j])) {
if (enemies[j].takeDamage()) {
LK.setScore(LK.getScore() + 250);
enemies[j].destroy();
enemies.splice(j, 1);
}
bomb.destroy();
bombs.splice(i, 1);
break;
}
}
// Check bomb collisions with navy ships
if (bombs[i]) {
// Check if bomb still exists
for (var j = navyShips.length - 1; j >= 0; j--) {
if (bomb.intersects(navyShips[j])) {
if (navyShips[j].takeDamage()) {
LK.setScore(LK.getScore() + 350);
navyShips[j].destroy();
navyShips.splice(j, 1);
}
bomb.destroy();
bombs.splice(i, 1);
break;
}
}
}
if (bombs[i]) {
// Update lastY if bomb still exists
bomb.lastY = bomb.y;
}
}
// Update special attack cooldown
if (specialAttackCooldown > 0) {
specialAttackCooldown--;
var remainingSeconds = Math.ceil(specialAttackCooldown / 60);
specialAttackCooldownTxt.setText('ESPECIAL: ' + remainingSeconds + 's');
specialAttackCooldownTxt.fill = 0xFF0000;
specialAttackButton.alpha = 0.5;
} else {
specialAttackCooldownTxt.setText('ESPECIAL: LISTO');
specialAttackCooldownTxt.fill = 0x00FF00;
specialAttackButton.alpha = 1.0;
}
updateUI();
if (LK.getScore() >= 10000) {
LK.showYouWin();
}
};
barco de pixeles. In-Game asset. 2d. High contrast. No shadows
sirculo de torbellino de pixeles. In-Game asset. 2d. High contrast. No shadows
fruta del diablo. In-Game asset. 2d. High contrast. No shadows
bala de cañon de pixeles. In-Game asset. 2d. High contrast. No shadows
cofre de pixeles. In-Game asset. 2d. High contrast. No shadows
goin merri de pixeles. In-Game asset. 2d. High contrast. No shadows
un boton rojo con una calavera de pixeles. In-Game asset. 2d. High contrast. No shadows