User prompt
separar los botones de jugar y seleccion de personaje.
User prompt
agregar la imagen de jugador4 a la pantalla de seleccion de personaje.
User prompt
al presionar el boton seleccion de personaje se vera otra pantalla donde apareceran las imagenes de jugador, jugador 2 y jugador 3. debajo de las imagenes aparecera un boton de jugar, al presionarlo se comenzara el juego dependiendo de que imagen halla presionado el jugador.
User prompt
agregue un botón que diga selección de personaje debajo del botón jugar en la pantalla de inicio.
User prompt
borrar la imagen detras del boton de inicio.
User prompt
crear una pantalla de inicio del juego con el titulo en grande y debajo del titulo un boton para iniciar el juego.
User prompt
el enemigo jefe aparecerá cada 2 minutos de juego. aparecerán 2 enemigos jefe al mismo tiempo. cuando aparezcan no aparecerán otros enemigos. cuando los 2 enemigos sean derrotados volverán a aparecer los enemigos normales. se repetirá el ciclo.
User prompt
si 5 enemigos sobrepasan el lado izquierdo de la pantalla el jugador pierde el juego.
User prompt
los power-up aparecen cada 5 segundos.
User prompt
enemigo rapido radio de colision 85 pixeles. enemigo escudo radio de colision 90 pixeles.
User prompt
enemigo normal radio de colision 80 pixeles.
User prompt
el enemigo normal dispara cada 3 segundos. el enemigo rapido dispara cada 2 segundos.
User prompt
aparecen objetos que ayudan al jugador.
User prompt
los enemigos disparan con menor frecuencia.
User prompt
las balas ya no persiguen al jugador.
User prompt
garantizar el orden de inicialización adecuado: - Inicializar todas las `lastX`, `lastY` y otras variables de seguimiento en el constructor de la clase - Añadir comprobaciones nulas antes de utilizar estas variables en los métodos de actualización - Utilizar indicadores de inicialización para omitir la lógica en el primer fotograma si es necesario.
User prompt
utilizar patrones de iteración más seguros: - Continuar usando la iteración inversa (lo cual es correcto) - Considerar el uso de matrices "toRemove" independientes y procesarlas después de la iteración - Añadir comprobaciones de seguridad antes de acceder a los elementos de la matriz.
User prompt
Ajusta los valores alfa a rangos válidos: - Para enemigos jefes: asegúrate de que el alfa nunca baje de 0,3 ni supere 1,0 - Para enemigos con escudo: asegúrate de que el alfa se mantenga dentro del rango de 0,5 a 1,0 - Usa `Math.max()` y `Math.min()` para aplicar estos límites.
User prompt
Haz que las posiciones de aparición de balas sean relativas al tamaño y tipo de enemigo: - Calcula el desplazamiento de aparición según el ancho del enemigo: `enemy.x - (enemy.width/2 + bulletOffset)` - Usa una lógica consistente para todos los tipos de enemigos en lugar de valores codificados como -30 o -60.
User prompt
Ajusta los límites de rebote para tener en cuenta el tamaño escalado del jefe: - En lugar de rebotar entre 200 y 2532, calcula los límites según la altura real del jefe después de escalar. - Usa límites como `(boss.height/2 + margin)` para la parte superior y `(2732 - boss.height/2 - margin)` para la parte inferior. Esto garantiza que el jefe permanezca completamente visible dentro de los límites de la pantalla.
User prompt
Implementar una limpieza adecuada: - Agregar métodos de limpieza a las clases enemigas que eliminen adecuadamente los recursos - Asegurarse de que se borren todas las referencias cuando se destruyan los enemigos - Monitorear los tamaños de las matrices e implementar límites si es necesario.
User prompt
Implementa la limpieza diferida:- Marcar balas y enemigos para eliminarlos en lugar de destruirlos inmediatamente - Limpiar objetos marcados al final del bucle de actualización.
User prompt
Estandariza la detección de colisiones: - Usa radios de colisión consistentes para tipos de interacción similares - Haz que los radios de colisión sean proporcionales al tamaño y tipo de enemigo - Considera usar diferentes radios para diferentes niveles de amenaza (balas vs. contacto directo).
User prompt
Añadir un manejo de reserva adecuado: - Comprobar si la distancia es mayor que un umbral mínimo (p. ej., 1.0) antes de normalizar - Proporcionar direcciones predeterminadas significativas en lugar de reservas arbitrarias - Añadir protectores para evitar la división por números muy pequeños.
User prompt
Implementar optimización espacial: - Solo comprobar colisiones de enemigos y balas que estén dentro de los límites de la pantalla - Usar comprobaciones de cuadro delimitador antes de realizar cálculos de distancia costosos - Considerar dividir la pantalla en zonas y solo comprobar colisiones dentro de las zonas relevantes - Ordenar las entidades por posición para permitir la terminación temprana de los bucles de colisión.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BossEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('jefe', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); self.speed = -1; // Very slow self.lastX = undefined; self.shootCooldown = 0; self.health = 10; // Takes 10 hits to destroy self.verticalSpeed = 2; self.verticalDirection = 1; self.update = function () { // Initialize lastX on first frame if not set if (self.lastX === undefined) { self.lastX = self.x; return; // Skip first frame to avoid premature trigger } // Move enemy left self.x += self.speed; // Move vertically up and down self.y += self.verticalSpeed * self.verticalDirection; if (self.y <= 200 || self.y >= 2532) { self.verticalDirection *= -1; } // Update shooting cooldown if (self.shootCooldown > 0) { self.shootCooldown--; } // Update lastX for next frame self.lastX = self.x; }; self.canShoot = function () { return self.shootCooldown <= 0; }; self.shoot = function () { if (self.canShoot()) { self.shootCooldown = 30; // Fast shooting return true; } return false; }; self.takeDamage = function () { self.health--; // Visual feedback for taking damage enemyGraphics.alpha = 0.3 + self.health / 10 * 0.7; return self.health <= 0; }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.lastX = undefined; self.lastY = undefined; self.directionX = 1; // Default horizontal direction self.directionY = 0; // Default no vertical movement self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; // Set bullet rotation based on direction var angle = Math.atan2(self.directionY, self.directionX); bulletGraphics.rotation = angle; self.x += self.speed * self.directionX; self.y += self.speed * self.directionY; self.lastX = self.x; self.lastY = self.y; }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -3; self.lastX = undefined; self.shootCooldown = 0; self.update = function () { // Initialize lastX on first frame if not set if (self.lastX === undefined) { self.lastX = self.x; return; // Skip first frame to avoid premature trigger } // Move enemy left self.x += self.speed; // Update shooting cooldown if (self.shootCooldown > 0) { self.shootCooldown--; } // Update lastX for next frame self.lastX = self.x; }; self.canShoot = function () { return self.shootCooldown <= 0; }; self.shoot = function () { if (self.canShoot()) { self.shootCooldown = 60; // 1 second cooldown return true; } return false; }; return self; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 6; self.lastX = undefined; self.lastY = undefined; self.directionX = -1; // Default moving left self.directionY = 0; // Default no vertical movement self.update = function () { if (self.lastX === undefined) self.lastX = self.x; if (self.lastY === undefined) self.lastY = self.y; // Set bullet rotation based on direction var angle = Math.atan2(self.directionY, self.directionX); bulletGraphics.rotation = angle; self.x += self.speed * self.directionX; self.y += self.speed * self.directionY; self.lastX = self.x; self.lastY = self.y; }; return self; }); var FastEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemigorapido', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -6; // Faster than regular enemy self.lastX = undefined; self.shootCooldown = 0; self.update = function () { // Initialize lastX on first frame if not set if (self.lastX === undefined) { self.lastX = self.x; return; // Skip first frame to avoid premature trigger } // Move enemy left self.x += self.speed; // Update shooting cooldown if (self.shootCooldown > 0) { self.shootCooldown--; } // Update lastX for next frame self.lastX = self.x; }; self.canShoot = function () { return self.shootCooldown <= 0; }; self.shoot = function () { if (self.canShoot()) { self.shootCooldown = 40; // Faster shooting than regular enemy return true; } return false; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.shootCooldown = 0; self.update = function () { if (self.shootCooldown > 0) { self.shootCooldown--; } }; self.canShoot = function () { return self.shootCooldown <= 0; }; self.shoot = function () { if (self.canShoot()) { self.shootCooldown = 10; // 10 frames cooldown return true; } return false; }; return self; }); var ShieldEnemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemigoescudo', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -2; // Slower than regular enemy self.lastX = undefined; self.shootCooldown = 0; self.health = 3; // Takes 3 hits to destroy self.update = function () { // Initialize lastX on first frame if not set if (self.lastX === undefined) { self.lastX = self.x; return; // Skip first frame to avoid premature trigger } // Move enemy left self.x += self.speed; // Update shooting cooldown if (self.shootCooldown > 0) { self.shootCooldown--; } // Update lastX for next frame self.lastX = self.x; }; self.canShoot = function () { return self.shootCooldown <= 0; }; self.shoot = function () { if (self.canShoot()) { self.shootCooldown = 80; // Slower shooting than regular enemy return true; } return false; }; self.takeDamage = function () { self.health--; // Visual feedback for taking damage enemyGraphics.alpha = 0.5 + self.health / 3 * 0.5; return self.health <= 0; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ var player = new Player(); var enemies = []; var fastEnemies = []; var shieldEnemies = []; var bossEnemies = []; var bullets = []; var enemyBullets = []; var enemySpawnTimer = 0; var enemySpawnRate = 120; // Start spawning every 2 seconds (120 frames) var difficultyTimer = 0; var playerLives = 3; // Position player in bottom-left corner of screen player.x = 150; player.y = 2732 - 150; // Near bottom with some margin game.addChild(player); // Create score display var scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.setText(LK.getScore()); // Create lives display var livesTxt = new Text2('Lives: 3', { size: 80, fill: 0xFFFFFF }); livesTxt.anchor.set(0, 0); livesTxt.x = 120; livesTxt.y = 20; LK.gui.topLeft.addChild(livesTxt); var isDragging = false; // Touch/mouse down - start dragging and shoot game.down = function (x, y, obj) { isDragging = true; // Move player to touch position (constrain to vertical movement) player.y = Math.max(100, Math.min(2732 - 100, y)); if (player.shoot()) { var bullet = new Bullet(); bullet.x = player.x + 40; // Spawn slightly ahead of player bullet.y = player.y - 40; // Spawn slightly above player bullet.lastX = bullet.x; bullet.lastY = bullet.y; // Calculate direction vector from player to tap position var deltaX = x - player.x; var deltaY = y - player.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Normalize the direction vector with minimum distance threshold if (distance > 1.0) { bullet.directionX = deltaX / distance; bullet.directionY = deltaY / distance; } else { // Fallback if tap is too close to player - shoot right bullet.directionX = 1; bullet.directionY = 0; } bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); } }; // Touch/mouse move - move player vertically while dragging game.move = function (x, y, obj) { if (isDragging) { // Move player to touch position (constrain to vertical movement) player.y = Math.max(100, Math.min(2732 - 100, y)); } }; // Touch/mouse up - stop dragging game.up = function (x, y, obj) { isDragging = false; }; game.update = function () { // Update enemy spawn timer and difficulty enemySpawnTimer++; difficultyTimer++; // Increase difficulty every 10 seconds (600 frames) if (difficultyTimer % 600 === 0 && enemySpawnRate > 30) { enemySpawnRate -= 10; // Spawn enemies more frequently } // Spawn enemies if (enemySpawnTimer >= enemySpawnRate) { var spawnType = Math.random(); var spawnY = Math.random() * (2732 - 200) + 100; if (spawnType < 0.5) { // 50% chance for regular enemy var enemy = new Enemy(); enemy.x = 2048 + 30; enemy.y = spawnY; enemy.lastX = enemy.x; enemies.push(enemy); game.addChild(enemy); } else if (spawnType < 0.75) { // 25% chance for fast enemy var fastEnemy = new FastEnemy(); fastEnemy.x = 2048 + 30; fastEnemy.y = spawnY; fastEnemy.lastX = fastEnemy.x; fastEnemies.push(fastEnemy); game.addChild(fastEnemy); } else if (spawnType < 0.95) { // 20% chance for shield enemy var shieldEnemy = new ShieldEnemy(); shieldEnemy.x = 2048 + 30; shieldEnemy.y = spawnY; shieldEnemy.lastX = shieldEnemy.x; shieldEnemies.push(shieldEnemy); game.addChild(shieldEnemy); } else { // 5% chance for boss enemy var bossEnemy = new BossEnemy(); bossEnemy.x = 2048 + 30; bossEnemy.y = spawnY; bossEnemy.lastX = bossEnemy.x; bossEnemies.push(bossEnemy); game.addChild(bossEnemy); } enemySpawnTimer = 0; } // Update and check bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; // Remove bullets that go off screen if (bullet.x > 2048 + 50 || bullet.y < -50) { bullet.destroy(); bullets.splice(i, 1); continue; } // Skip collision detection for bullets outside meaningful collision zones if (bullet.x < -50 || bullet.x > 2100 || bullet.y < -50 || bullet.y > 2800) { continue; } // Check bullet vs enemy collisions var bulletHit = false; // Check regular enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; // Skip enemies outside collision zone (bounding box check) if (enemy.x < -250 || enemy.x > 2100 || enemy.y < -50 || enemy.y > 2800) { continue; } // Check bullet collision with regular enemy using distance-based detection var deltaX = bullet.x - enemy.x; var deltaY = bullet.y - enemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance < 40) { // 40px collision radius for regular enemies // Bullet hit enemy LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); // Check for victory condition if (LK.getScore() >= 10000) { LK.showYouWin(); return; } // Visual feedback tween(enemy, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 200, onFinish: function onFinish() { if (enemy.parent) { enemy.destroy(); } } }); enemies.splice(j, 1); bullet.destroy(); bullets.splice(i, 1); bulletHit = true; LK.getSound('hit').play(); break; } } // Check fast enemies for (var j = fastEnemies.length - 1; j >= 0; j--) { var fastEnemy = fastEnemies[j]; // Skip fast enemies outside collision zone (bounding box check) if (fastEnemy.x < -250 || fastEnemy.x > 2100 || fastEnemy.y < -50 || fastEnemy.y > 2800) { continue; } // Check bullet collision with fast enemy using distance-based detection var deltaX = bullet.x - fastEnemy.x; var deltaY = bullet.y - fastEnemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance < 45) { // 45px collision radius for fast enemies (slightly larger due to higher threat) LK.setScore(LK.getScore() + 15); scoreTxt.setText(LK.getScore()); if (LK.getScore() >= 10000) { LK.showYouWin(); return; } tween(fastEnemy, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 200, onFinish: function onFinish() { if (fastEnemy.parent) { fastEnemy.destroy(); } } }); fastEnemies.splice(j, 1); bullet.destroy(); bullets.splice(i, 1); bulletHit = true; LK.getSound('hit').play(); break; } } // Check shield enemies for (var j = shieldEnemies.length - 1; j >= 0; j--) { var shieldEnemy = shieldEnemies[j]; // Skip shield enemies outside collision zone (bounding box check) if (shieldEnemy.x < -250 || shieldEnemy.x > 2100 || shieldEnemy.y < -50 || shieldEnemy.y > 2800) { continue; } // Check bullet collision with shield enemy using distance-based detection var deltaX = bullet.x - shieldEnemy.x; var deltaY = bullet.y - shieldEnemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance < 50) { // 50px collision radius for shield enemies (larger due to shield) if (shieldEnemy.takeDamage()) { LK.setScore(LK.getScore() + 30); scoreTxt.setText(LK.getScore()); if (LK.getScore() >= 10000) { LK.showYouWin(); return; } tween(shieldEnemy, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 200, onFinish: function onFinish() { if (shieldEnemy.parent) { shieldEnemy.destroy(); } } }); shieldEnemies.splice(j, 1); } else { LK.setScore(LK.getScore() + 5); scoreTxt.setText(LK.getScore()); } bullet.destroy(); bullets.splice(i, 1); bulletHit = true; LK.getSound('hit').play(); break; } } // Check boss enemies for (var j = bossEnemies.length - 1; j >= 0; j--) { var bossEnemy = bossEnemies[j]; // Skip boss enemies outside collision zone (bounding box check) if (bossEnemy.x < -250 || bossEnemy.x > 2100 || bossEnemy.y < -50 || bossEnemy.y > 2800) { continue; } // Check bullet collision with boss enemy using distance-based detection var deltaX = bullet.x - bossEnemy.x; var deltaY = bullet.y - bossEnemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance < 80) { // 80px collision radius for boss enemies (much larger due to 2x scale and boss status) if (bossEnemy.takeDamage()) { LK.setScore(LK.getScore() + 100); scoreTxt.setText(LK.getScore()); if (LK.getScore() >= 10000) { LK.showYouWin(); return; } tween(bossEnemy, { scaleX: 3, scaleY: 3, alpha: 0 }, { duration: 500, onFinish: function onFinish() { if (bossEnemy.parent) { bossEnemy.destroy(); } } }); bossEnemies.splice(j, 1); } else { LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); } bullet.destroy(); bullets.splice(i, 1); bulletHit = true; LK.getSound('hit').play(); break; } } if (bulletHit) continue; } // Update and check enemy bullets for (var m = enemyBullets.length - 1; m >= 0; m--) { var enemyBullet = enemyBullets[m]; // Remove enemy bullets that go off screen if (enemyBullet.x < -50 || enemyBullet.y < -50 || enemyBullet.y > 2732 + 50) { enemyBullet.destroy(); enemyBullets.splice(m, 1); continue; } // Skip collision detection for enemy bullets outside meaningful collision zones if (enemyBullet.x < -50 || enemyBullet.x > 2100 || enemyBullet.y < -50 || enemyBullet.y > 2800) { continue; } // Check if enemy bullet hits player center (more precise collision) var deltaX = enemyBullet.x - player.x; var deltaY = enemyBullet.y - player.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance < 35) { // Only hits if within 35 pixels of player center (consistent bullet collision radius) playerLives--; livesTxt.setText('Lives: ' + playerLives); enemyBullet.destroy(); enemyBullets.splice(m, 1); LK.effects.flashScreen(0xFF0000, 500); if (playerLives <= 0) { LK.showGameOver(); return; } } } // Update and check regular enemies for (var k = enemies.length - 1; k >= 0; k--) { var enemy = enemies[k]; // Remove enemies that go off screen (too far left) if (enemy.x < -200) { // Regular enemy width is 200px enemy.destroy(); enemies.splice(k, 1); continue; } // Skip processing for enemies outside meaningful interaction zones if (enemy.x < -250 || enemy.x > 2100 || enemy.y < -50 || enemy.y > 2800) { continue; } // Calculate distance once for both shooting and collision var deltaX = player.x - enemy.x; var deltaY = player.y - enemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Enemy shooting logic if (enemy.shoot()) { var enemyBullet = new EnemyBullet(); enemyBullet.x = enemy.x - 30; // Spawn slightly ahead of enemy enemyBullet.y = enemy.y; enemyBullet.lastX = enemyBullet.x; enemyBullet.lastY = enemyBullet.y; // Normalize the direction vector using already calculated distance with minimum threshold if (distance > 1.0) { enemyBullet.directionX = deltaX / distance; enemyBullet.directionY = deltaY / distance; } else { // Fallback direction - shoot towards player's general direction enemyBullet.directionX = -1; enemyBullet.directionY = 0; } enemyBullets.push(enemyBullet); game.addChild(enemyBullet); } // Check if enemy collides with player center using same distance calculation if (distance < 60) { // Only hits if within 60 pixels of player center (larger radius for direct contact) playerLives--; livesTxt.setText('Lives: ' + playerLives); enemy.destroy(); enemies.splice(k, 1); LK.effects.flashScreen(0xFF0000, 500); if (playerLives <= 0) { LK.showGameOver(); return; } } } // Update and check fast enemies for (var k = fastEnemies.length - 1; k >= 0; k--) { var fastEnemy = fastEnemies[k]; // Remove fast enemies that go off screen (too far left) if (fastEnemy.x < -200) { // Fast enemy width is 200px fastEnemy.destroy(); fastEnemies.splice(k, 1); continue; } // Skip processing for fast enemies outside meaningful interaction zones if (fastEnemy.x < -250 || fastEnemy.x > 2100 || fastEnemy.y < -50 || fastEnemy.y > 2800) { continue; } // Calculate distance once for both shooting and collision var deltaX = player.x - fastEnemy.x; var deltaY = player.y - fastEnemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (fastEnemy.shoot()) { var enemyBullet = new EnemyBullet(); enemyBullet.x = fastEnemy.x - 30; enemyBullet.y = fastEnemy.y; enemyBullet.lastX = enemyBullet.x; enemyBullet.lastY = enemyBullet.y; if (distance > 1.0) { enemyBullet.directionX = deltaX / distance; enemyBullet.directionY = deltaY / distance; } else { // Fallback direction - shoot towards player's general direction enemyBullet.directionX = -1; enemyBullet.directionY = 0; } enemyBullets.push(enemyBullet); game.addChild(enemyBullet); } // Check if fast enemy collides with player center using same distance calculation if (distance < 65) { // Only hits if within 65 pixels of player center (slightly larger due to fast movement) playerLives--; livesTxt.setText('Lives: ' + playerLives); fastEnemy.destroy(); fastEnemies.splice(k, 1); LK.effects.flashScreen(0xFF0000, 500); if (playerLives <= 0) { LK.showGameOver(); return; } } } // Update and check shield enemies for (var k = shieldEnemies.length - 1; k >= 0; k--) { var shieldEnemy = shieldEnemies[k]; // Remove shield enemies that go off screen (too far left) if (shieldEnemy.x < -200) { // Shield enemy width is 200px shieldEnemy.destroy(); shieldEnemies.splice(k, 1); continue; } // Skip processing for shield enemies outside meaningful interaction zones if (shieldEnemy.x < -250 || shieldEnemy.x > 2100 || shieldEnemy.y < -50 || shieldEnemy.y > 2800) { continue; } // Calculate distance once for both shooting and collision var deltaX = player.x - shieldEnemy.x; var deltaY = player.y - shieldEnemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (shieldEnemy.shoot()) { var enemyBullet = new EnemyBullet(); enemyBullet.x = shieldEnemy.x - 30; enemyBullet.y = shieldEnemy.y; enemyBullet.lastX = enemyBullet.x; enemyBullet.lastY = enemyBullet.y; if (distance > 1.0) { enemyBullet.directionX = deltaX / distance; enemyBullet.directionY = deltaY / distance; } else { // Fallback direction - shoot towards player's general direction enemyBullet.directionX = -1; enemyBullet.directionY = 0; } enemyBullets.push(enemyBullet); game.addChild(enemyBullet); } // Check if shield enemy collides with player center using same distance calculation if (distance < 70) { // Only hits if within 70 pixels of player center (larger due to shield size) playerLives--; livesTxt.setText('Lives: ' + playerLives); shieldEnemy.destroy(); shieldEnemies.splice(k, 1); LK.effects.flashScreen(0xFF0000, 500); if (playerLives <= 0) { LK.showGameOver(); return; } } } // Update and check boss enemies for (var k = bossEnemies.length - 1; k >= 0; k--) { var bossEnemy = bossEnemies[k]; // Remove boss enemies that go off screen (too far left) if (bossEnemy.x < -200) { // Boss enemy width is 100px * 2 scale = 200px bossEnemy.destroy(); bossEnemies.splice(k, 1); continue; } // Skip processing for boss enemies outside meaningful interaction zones if (bossEnemy.x < -250 || bossEnemy.x > 2100 || bossEnemy.y < -50 || bossEnemy.y > 2800) { continue; } // Calculate distance once for both shooting and collision var deltaX = player.x - bossEnemy.x; var deltaY = player.y - bossEnemy.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (bossEnemy.shoot()) { var enemyBullet = new EnemyBullet(); enemyBullet.x = bossEnemy.x - 60; enemyBullet.y = bossEnemy.y; enemyBullet.lastX = enemyBullet.x; enemyBullet.lastY = enemyBullet.y; if (distance > 1.0) { enemyBullet.directionX = deltaX / distance; enemyBullet.directionY = deltaY / distance; } else { // Fallback direction - shoot towards player's general direction enemyBullet.directionX = -1; enemyBullet.directionY = 0; } enemyBullets.push(enemyBullet); game.addChild(enemyBullet); } // Check if boss enemy collides with player center using same distance calculation if (distance < 90) { // Only hits if within 90 pixels of player center (much larger due to 2x scale and boss size) playerLives--; livesTxt.setText('Lives: ' + playerLives); bossEnemy.destroy(); bossEnemies.splice(k, 1); LK.effects.flashScreen(0xFF0000, 500); if (playerLives <= 0) { LK.showGameOver(); return; } } } }; // Play background music LK.playMusic('bgmusic');
===================================================================
--- original.js
+++ change.js
@@ -397,9 +397,14 @@
// Skip enemies outside collision zone (bounding box check)
if (enemy.x < -250 || enemy.x > 2100 || enemy.y < -50 || enemy.y > 2800) {
continue;
}
- if (bullet.intersects(enemy)) {
+ // Check bullet collision with regular enemy using distance-based detection
+ var deltaX = bullet.x - enemy.x;
+ var deltaY = bullet.y - enemy.y;
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ if (distance < 40) {
+ // 40px collision radius for regular enemies
// Bullet hit enemy
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Check for victory condition
@@ -434,9 +439,14 @@
// Skip fast enemies outside collision zone (bounding box check)
if (fastEnemy.x < -250 || fastEnemy.x > 2100 || fastEnemy.y < -50 || fastEnemy.y > 2800) {
continue;
}
- if (bullet.intersects(fastEnemy)) {
+ // Check bullet collision with fast enemy using distance-based detection
+ var deltaX = bullet.x - fastEnemy.x;
+ var deltaY = bullet.y - fastEnemy.y;
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ if (distance < 45) {
+ // 45px collision radius for fast enemies (slightly larger due to higher threat)
LK.setScore(LK.getScore() + 15);
scoreTxt.setText(LK.getScore());
if (LK.getScore() >= 10000) {
LK.showYouWin();
@@ -468,9 +478,14 @@
// Skip shield enemies outside collision zone (bounding box check)
if (shieldEnemy.x < -250 || shieldEnemy.x > 2100 || shieldEnemy.y < -50 || shieldEnemy.y > 2800) {
continue;
}
- if (bullet.intersects(shieldEnemy)) {
+ // Check bullet collision with shield enemy using distance-based detection
+ var deltaX = bullet.x - shieldEnemy.x;
+ var deltaY = bullet.y - shieldEnemy.y;
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ if (distance < 50) {
+ // 50px collision radius for shield enemies (larger due to shield)
if (shieldEnemy.takeDamage()) {
LK.setScore(LK.getScore() + 30);
scoreTxt.setText(LK.getScore());
if (LK.getScore() >= 10000) {
@@ -507,9 +522,14 @@
// Skip boss enemies outside collision zone (bounding box check)
if (bossEnemy.x < -250 || bossEnemy.x > 2100 || bossEnemy.y < -50 || bossEnemy.y > 2800) {
continue;
}
- if (bullet.intersects(bossEnemy)) {
+ // Check bullet collision with boss enemy using distance-based detection
+ var deltaX = bullet.x - bossEnemy.x;
+ var deltaY = bullet.y - bossEnemy.y;
+ var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+ if (distance < 80) {
+ // 80px collision radius for boss enemies (much larger due to 2x scale and boss status)
if (bossEnemy.takeDamage()) {
LK.setScore(LK.getScore() + 100);
scoreTxt.setText(LK.getScore());
if (LK.getScore() >= 10000) {
@@ -558,10 +578,10 @@
// Check if enemy bullet hits player center (more precise collision)
var deltaX = enemyBullet.x - player.x;
var deltaY = enemyBullet.y - player.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
- if (distance < 30) {
- // Only hits if within 30 pixels of player center
+ if (distance < 35) {
+ // Only hits if within 35 pixels of player center (consistent bullet collision radius)
playerLives--;
livesTxt.setText('Lives: ' + playerLives);
enemyBullet.destroy();
enemyBullets.splice(m, 1);
@@ -609,10 +629,10 @@
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
}
// Check if enemy collides with player center using same distance calculation
- if (distance < 50) {
- // Only hits if within 50 pixels of player center
+ if (distance < 60) {
+ // Only hits if within 60 pixels of player center (larger radius for direct contact)
playerLives--;
livesTxt.setText('Lives: ' + playerLives);
enemy.destroy();
enemies.splice(k, 1);
@@ -658,10 +678,10 @@
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
}
// Check if fast enemy collides with player center using same distance calculation
- if (distance < 50) {
- // Only hits if within 50 pixels of player center
+ if (distance < 65) {
+ // Only hits if within 65 pixels of player center (slightly larger due to fast movement)
playerLives--;
livesTxt.setText('Lives: ' + playerLives);
fastEnemy.destroy();
fastEnemies.splice(k, 1);
@@ -707,10 +727,10 @@
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
}
// Check if shield enemy collides with player center using same distance calculation
- if (distance < 50) {
- // Only hits if within 50 pixels of player center
+ if (distance < 70) {
+ // Only hits if within 70 pixels of player center (larger due to shield size)
playerLives--;
livesTxt.setText('Lives: ' + playerLives);
shieldEnemy.destroy();
shieldEnemies.splice(k, 1);
@@ -756,10 +776,10 @@
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
}
// Check if boss enemy collides with player center using same distance calculation
- if (distance < 50) {
- // Only hits if within 50 pixels of player center
+ if (distance < 90) {
+ // Only hits if within 90 pixels of player center (much larger due to 2x scale and boss size)
playerLives--;
livesTxt.setText('Lives: ' + playerLives);
bossEnemy.destroy();
bossEnemies.splice(k, 1);
tommy vercetti de gta vice city hecho con pixeles apuntando con un rifle de asalto m4 con la perspcetiva lateral. In-Game asset. 2d. High contrast. No shadows
un mafioso italiano usando un m4 con la perspectiva lateral de cuerpo completo In-Game asset. 2d. High contrast. No shadows
un pandillero mexicano apuntando con un SMG con la perspectiva lateral. In-Game asset. 2d. High contrast. No shadows de cuerpo completo
un pandillero negro con camisa azul oscuro y pantalon blanco usando una escopeta con la perspectiva lateral de cuerpo completo. In-Game asset. 2d. High contrast. No shadows
chaleco antibalas. In-Game asset. 2d. High contrast. No shadows
corazon verde dibujado. In-Game asset. 2d. High contrast. No shadows
escopeta dibujada. In-Game asset. 2d. High contrast. No shadows
claude speed de gta 3 apuntando con una ak47 desde una perspectiva lateral de cuerpo completo In-Game asset. 2d. High contrast. No shadows
las letras play con un color celeste y rosa combinados con una cursiva In-Game asset. 2d. High contrast. No shadows con contorno negro
letras que dicen seleccion de personaje con un color rosa y un color celeste y con contorno azul y rosa cursiva. In-Game asset. 2d. High contrast. No shadows
las letras vidas con un color rosa y azul con contorno rosa y azul combinados hechos con pixeles. In-Game asset. 2d. High contrast. No shadows
una mansion con piso rojo vista completa y totalmente desde arriba y desde dentro con una escalera grande igual que la de scarface la pelicula y pasillos a los lados. In-Game asset. 2d. High contrast. No shadows
no va a tener ese brazo especificamente
un motociclista vestido de negro apuntando con una smg de cuerpo completo con perspectiva lateral In-Game asset. 2d. High contrast. No shadows sin casco y sin moto
letras de color rosa y azul y con cursiva que digan vice city wars. In-Game asset. 2d. High contrast. No shadows
un hombre usando una chaqueta negra pantalones azules disparando un ak47. In-Game asset. 2d. High contrast. No shadows con la perspectiva lateral de cuerpo completo
letras de color rosa que dicen seleccion de personaje en cursiva y con contorno blanco