User prompt
baja las imagenes de los botones de la seleccion de personaje
User prompt
girar las imagenes de la seleccion de personaje a la izquierda
User prompt
aumentalo un poco mas.
User prompt
aumenta un poco el radio de detección de colisión de las balas enemigas para requerir una mayor proximidad al jugador para causar daño. aumenta un poco el radio de detección de colisiones para que las colisiones enemigas requieran una mayor proximidad al jugador para causar daño.
User prompt
las letras lives remplazalas por el activo vidas
User prompt
coloca los numeros un poco mas a la dercha
User prompt
los numeros a la derecha de las letras score
User prompt
coloca las letras score y numeros en medio de la pantalla hasta arriba igual
User prompt
las letras score estaran a la izquierda y el puntaje al jugar se vera a la dercha estaran juntos
User prompt
las letras que dicen score al jugar cambialas por la imagen score
User prompt
las balas deben de estar mas cerca del jugador para hacer daño
User prompt
coloca la imagen de seleccion de personaje un poco mas arriba
User prompt
la imagen selecciona un personaje seran las letras que dicen select your character en la seleccion de personaje
User prompt
la imagen letras del titulo seran las letras que apareceran en el menu de inicio
User prompt
con contorno blanco
User prompt
las letras en el menu de inicio que dicen san andreas stories seran negras con un borde blanco
User prompt
las letras en el menu de inicio que dicen san andreas stories seran blancas
User prompt
el texto que dice select your character en la seleccion de personaje estaran un poco mas arriba
User prompt
el escudopowerup aparezca con mas frecuencia
User prompt
elimina el laser
User prompt
los enemigos disparan con menor frecuencia
User prompt
reducir la cantidad de enemigos que aparecen a la mitad
User prompt
baja el boton de start de la seleccion de personaje un poco mas
User prompt
el boton start de la seleccion de personaje bajalo un poco
User prompt
separar un poco los botones back y start en select your character
/****
* Classes
****/
var BomberEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('bomberEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
// Bomber enemy properties
self.speed = 2; // Medium speed
self.hitPoints = 2; // Takes 2 hits to destroy
self.maxHitPoints = 2;
self.shootCooldown = 0;
self.shootRate = 120; // Shoots every 2 seconds
// Visual feedback for damage
self.updateTint = function () {
var damageRatio = self.hitPoints / self.maxHitPoints;
if (damageRatio > 0.5) {
enemyGraphics.tint = 0xFFFFFF; // White (no damage)
} else {
enemyGraphics.tint = 0xFFAAAA; // Light red (damaged)
}
};
self.updateTint(); // Initialize tint
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Update shooting cooldown
self.shootCooldown--;
// Check if enemy went off screen (transition from on-screen to off-screen)
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
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 = -15;
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Check if bullet went off screen (transition from on-screen to off-screen)
if (self.lastY >= -50 && self.y < -50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var CustomizationMenu = Container.expand(function () {
var self = Container.call(this);
self.selectedShipType = 'playerShip'; // Default ship
self.shipPreviews = [];
// Create ship selection buttons
var shipTypes = ['playerShip', 'playerShip2', 'playerShip3'];
var shipNames = ['Warrior', 'Archer', 'Mage'];
for (var i = 0; i < shipTypes.length; i++) {
var shipContainer = new Container();
// Ship preview
var shipPreview = LK.getAsset(shipTypes[i], {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
rotation: Math.PI / 2
});
shipPreview.x = 0;
shipPreview.y = -40;
shipContainer.addChild(shipPreview);
// Character preview only (no name text)
// Selection border - removed bullet graphic
var border = new Container();
border.alpha = 0;
border.x = 0;
border.y = -40;
shipContainer.addChild(border);
// Position ships horizontally
shipContainer.x = 2048 / 2 + (i - 1) * 400;
shipContainer.y = 2732 / 2;
// Store references
shipContainer.shipType = shipTypes[i];
shipContainer.border = border;
shipContainer.preview = shipPreview;
self.shipPreviews.push(shipContainer);
self.addChild(shipContainer);
}
// Highlight default selection
self.shipPreviews[0].preview.tint = 0x00FF00;
self.selectShip = function (shipType) {
self.selectedShipType = shipType;
// Update visual selection using character tint instead of border
for (var i = 0; i < self.shipPreviews.length; i++) {
if (self.shipPreviews[i].shipType === shipType) {
self.shipPreviews[i].preview.tint = 0x00FF00; // Green tint for selected
} else {
self.shipPreviews[i].preview.tint = 0xFFFFFF; // Normal tint for unselected
}
}
};
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.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Check if enemy went off screen (transition from on-screen to off-screen)
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.PI
});
self.speed = 8;
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Check if bullet went off screen (transition from on-screen to off-screen)
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var FastEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('fastEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
// FastEnemy without red tint for differentiation
self.speed = 6; // Faster than regular enemy
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Check if enemy went off screen (transition from on-screen to off-screen)
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var HealthPowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('healthPowerUp', {
anchorX: 0.5,
anchorY: 0.5
});
powerUpGraphics.rotation = Math.PI / 4; // 45 degree rotation for visual appeal
self.speed = 3;
self.rotationSpeed = 0.1;
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
powerUpGraphics.rotation += self.rotationSpeed;
// Check if power-up went off screen
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var Laser = Container.expand(function () {
var self = Container.call(this);
var laserGraphics = self.attachAsset('laser', {
anchorX: 0.5,
anchorY: 0.5
});
laserGraphics.tint = 0x00FF00; // Green laser color
self.speed = -20; // Faster than bullets
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Check if laser went off screen (transition from on-screen to off-screen)
if (self.lastY >= -50 && self.y < -50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var RapidFirePowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('rapidFirePowerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.scaleTimer = 0;
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Scaling effect
self.scaleTimer += 0.15;
var scale = 1 + 0.2 * Math.sin(self.scaleTimer);
powerUpGraphics.scaleX = scale;
powerUpGraphics.scaleY = scale;
// Check if power-up went off screen
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var ShieldPowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('shieldPowerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.pulseTimer = 0;
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Pulsing effect
self.pulseTimer += 0.2;
powerUpGraphics.alpha = 0.7 + 0.3 * Math.sin(self.pulseTimer);
// Check if power-up went off screen
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
var TankEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('tankEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
// Tank enemy properties
self.speed = 1.5; // Slower than other enemies
self.hitPoints = 3; // Takes 3 hits to destroy
self.maxHitPoints = 3;
// Visual feedback for damage
self.updateTint = function () {
var damageRatio = self.hitPoints / self.maxHitPoints;
if (damageRatio > 0.66) {
enemyGraphics.tint = 0xFFFFFF; // White (no damage)
} else if (damageRatio > 0.33) {
enemyGraphics.tint = 0xFFAAAA; // Light red (medium damage)
} else {
enemyGraphics.tint = 0xFF6666; // Red (heavy damage)
}
};
self.updateTint(); // Initialize tint
self.update = function () {
if (self.lastY === undefined) self.lastY = self.y;
self.y += self.speed;
// Check if enemy went off screen (transition from on-screen to off-screen)
if (self.lastY <= 2732 + 50 && self.y > 2732 + 50) {
self.shouldDestroy = true;
}
self.lastY = self.y;
};
return self;
});
/****
* Initialize Game
****/
// Game variables
var game = new LK.Game({
backgroundColor: 0x001122
});
/****
* Game Code
****/
// Add background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
scaleX: 1,
scaleY: 1.33
});
game.addChild(background);
// Game variables
var gameStarted = false;
var showingCustomization = false;
var startMenu;
var customizationMenu;
var selectedShipType = 'playerShip';
var player;
var bullets = [];
var enemyBullets = [];
var enemies = [];
var enemySpawnTimer = 0;
var enemySpawnRate = 120; // Frames between enemy spawns (doubled to halve enemy count)
var enemyShootTimer = 0;
var dragNode = null;
var enemiesPassed = 0; // Track how many enemies have passed the bottom
var playerLives = 3; // Player starts with 3 lives
var currentWeapon = 'bullet'; // Current weapon type: 'bullet' or 'laser'
var lasers = []; // Array to track laser projectiles
var isHoldingDown = false; // Track if player is holding down
var laserCooldown = 0; // Cooldown for laser firing
var powerUps = []; // Array to track power-ups
var powerUpSpawnTimer = 0;
var powerUpSpawnRate = 600; // Spawn power-up every 10 seconds
var shieldActive = false; // Shield power-up status
var shieldTimer = 0; // Shield duration timer
var rapidFireActive = false; // Rapid fire power-up status
var rapidFireTimer = 0; // Rapid fire duration timer
var shieldEffect; // Visual shield effect
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Lives display
var livesTxt = new Text2('Lives: 3', {
size: 60,
fill: 0xFFFFFF
});
livesTxt.anchor.set(0.5, 0);
livesTxt.x = 0;
livesTxt.y = 100;
LK.gui.top.addChild(livesTxt);
// Weapon display
var weaponTxt = new Text2('Weapon: Bullets', {
size: 50,
fill: 0xFFFFFF
});
weaponTxt.anchor.set(0.5, 0);
weaponTxt.x = 0;
weaponTxt.y = 170;
LK.gui.top.addChild(weaponTxt);
// Create start menu
startMenu = new Container();
game.addChild(startMenu);
// Animated background elements
var menuBg1 = LK.getAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 6,
alpha: 0.1,
tint: 0x0066FF
});
menuBg1.x = 2048 / 2 - 300;
menuBg1.y = 2732 / 2 - 300;
startMenu.addChild(menuBg1);
var menuBg2 = LK.getAsset('playerShip3', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4,
alpha: 0.15,
tint: 0x00AAFF
});
menuBg2.x = 2048 / 2 + 400;
menuBg2.y = 2732 / 2 + 100;
startMenu.addChild(menuBg2);
var menuBg3 = LK.getAsset('playerShip2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 5,
scaleY: 5,
alpha: 0.08,
tint: 0x66AAFF
});
menuBg3.x = 2048 / 2;
menuBg3.y = 2732 / 2 + 400;
startMenu.addChild(menuBg3);
// Game title with gradient-like effect using multiple text layers
var titleShadow = new Text2('SAN ANDREAS STORIES', {
size: 140,
fill: 0x000066
});
titleShadow.anchor.set(0.5, 0.5);
titleShadow.x = 2048 / 2 + 5;
titleShadow.y = 2732 / 2 - 395;
startMenu.addChild(titleShadow);
var titleTxt = new Text2('SAN ANDREAS STORIES', {
size: 140,
fill: 0x00AAFF
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 2048 / 2;
titleTxt.y = 2732 / 2 - 400;
startMenu.addChild(titleTxt);
// Modern instruction cards
var instructionBg = LK.getAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 6,
scaleY: 3,
alpha: 0.1,
tint: 0x00AAFF
});
instructionBg.x = 2048 / 2;
instructionBg.y = 2732 / 2 - 100;
startMenu.addChild(instructionBg);
var instructionsTxt = new Text2('🚀 DRAG TO MOVE • 💥 TAP TO SHOOT • ⭐ DESTROY ENEMIES', {
size: 50,
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0.5);
instructionsTxt.x = 2048 / 2;
instructionsTxt.y = 2732 / 2 - 100;
startMenu.addChild(instructionsTxt);
// Customize button with background (moved to left side)
var customizeBg = LK.getAsset('playerShip2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 2,
alpha: 0.2,
tint: 0xFFAA00
});
customizeBg.x = 2048 / 2 - 400;
customizeBg.y = 2732 / 2 + 200;
startMenu.addChild(customizeBg);
// Add customize character icon as the main button
var customizeIcon = LK.getAsset('selecciondepersonaje', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
customizeIcon.x = 2048 / 2 - 400;
customizeIcon.y = 2732 / 2 + 200;
startMenu.addChild(customizeIcon);
// Start button with glow effect (moved to right side)
var startBtnGlow = LK.getAsset('botondeinicio', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 8.5,
scaleY: 8.5,
alpha: 0.3,
tint: 0x00FF00
});
startBtnGlow.x = 2048 / 2 + 400;
startBtnGlow.y = 2732 / 2 + 200;
startMenu.addChild(startBtnGlow);
var startBtnTxt = LK.getAsset('botondeinicio', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7,
scaleY: 7
});
startBtnTxt.x = 2048 / 2 + 400;
startBtnTxt.y = 2732 / 2 + 200;
startMenu.addChild(startBtnTxt);
// Start button text overlay removed
// Create customization menu
customizationMenu = new CustomizationMenu();
game.addChild(customizationMenu);
customizationMenu.visible = false;
// Add title to customization menu
var customTitle = new Text2('SELECT YOUR CHARACTER', {
size: 80,
fill: 0xFFFFFF
});
customTitle.anchor.set(0.5, 0.5);
customTitle.x = 2048 / 2;
customTitle.y = 2732 / 2 - 300;
customizationMenu.addChild(customTitle);
// Add back button to customization menu
var backBtnTxt = LK.getAsset('botonback', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
backBtnTxt.x = 2048 / 2 - 300;
backBtnTxt.y = 2732 / 2 + 300;
customizationMenu.addChild(backBtnTxt);
// Add play button to customization menu
var playBtnTxt = LK.getAsset('botondeinicio', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
playBtnTxt.x = 2048 / 2 + 300;
playBtnTxt.y = 2732 / 2 + 300;
customizationMenu.addChild(playBtnTxt);
// Hide game elements initially
scoreTxt.visible = false;
livesTxt.visible = false;
weaponTxt.visible = false;
// Create player with selected ship type function
function createPlayer() {
if (player) {
player.destroy();
}
player = game.addChild(new Player());
// Replace player graphics with selected character
player.removeChildren();
var newCharacterGraphics = player.attachAsset(selectedShipType, {
anchorX: 0.5,
anchorY: 0.5
});
player.x = 2048 / 2;
player.y = 2732 - 150; // Position near bottom of screen
playerLives = 3; // Reset lives when creating new player
livesTxt.setText('Lives: ' + playerLives);
// Create shield effect (initially invisible)
shieldEffect = LK.getAsset('shieldPowerUp', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
alpha: 0
});
player.addChild(shieldEffect);
shieldActive = false;
shieldTimer = 0;
rapidFireActive = false;
rapidFireTimer = 0;
}
createPlayer();
// Touch/mouse controls
game.down = function (x, y, obj) {
if (!gameStarted && !showingCustomization) {
// Check if start button was tapped (now at right side position)
if (x >= 2048 / 2 + 300 && x <= 2048 / 2 + 500 && y >= 2732 / 2 + 170 && y <= 2732 / 2 + 230) {
gameStarted = true;
startMenu.visible = false;
scoreTxt.visible = true;
livesTxt.visible = true;
weaponTxt.visible = true;
createPlayer(); // Create player with default character
LK.playMusic('rap'); // Start background music when game begins
return;
}
// Check if customize button was tapped (now at left side position)
if (x >= 2048 / 2 - 500 && x <= 2048 / 2 - 300 && y >= 2732 / 2 + 170 && y <= 2732 / 2 + 230) {
// Show customization menu
showingCustomization = true;
startMenu.visible = false;
customizationMenu.visible = true;
return;
}
return;
}
if (showingCustomization) {
// Handle customization menu clicks
// Check ship selection
for (var i = 0; i < customizationMenu.shipPreviews.length; i++) {
var shipContainer = customizationMenu.shipPreviews[i];
var shipX = shipContainer.x;
var shipY = shipContainer.y;
if (x >= shipX - 100 && x <= shipX + 100 && y >= shipY - 100 && y <= shipY + 100) {
selectedShipType = shipContainer.shipType;
customizationMenu.selectShip(selectedShipType);
return;
}
}
// Check back button
if (x >= 2048 / 2 - 400 && x <= 2048 / 2 - 200 && y >= 2732 / 2 + 270 && y <= 2732 / 2 + 330) {
showingCustomization = false;
customizationMenu.visible = false;
startMenu.visible = true;
return;
}
// Check play button
if (x >= 2048 / 2 + 200 && x <= 2048 / 2 + 400 && y >= 2732 / 2 + 270 && y <= 2732 / 2 + 330) {
gameStarted = true;
showingCustomization = false;
customizationMenu.visible = false;
scoreTxt.visible = true;
livesTxt.visible = true;
weaponTxt.visible = true;
createPlayer(); // Recreate player with selected character
LK.playMusic('rap'); // Start background music when game begins
return;
}
return;
}
dragNode = player;
player.x = x;
isHoldingDown = true;
// Check for weapon switching (tap on upper area of screen)
if (y < 500) {
// Switch weapon
if (currentWeapon === 'bullet') {
currentWeapon = 'laser';
weaponTxt.setText('Weapon: Laser');
} else {
currentWeapon = 'bullet';
weaponTxt.setText('Weapon: Bullets');
}
return;
}
// Shoot based on current weapon
if (currentWeapon === 'bullet') {
// Shoot bullet
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 30;
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
// If rapid fire is active, shoot additional bullets
if (rapidFireActive) {
for (var rb = 0; rb < 2; rb++) {
var rapidBullet = new Bullet();
rapidBullet.x = player.x + (rb - 0.5) * 40; // Spread bullets
rapidBullet.y = player.y - 30;
bullets.push(rapidBullet);
game.addChild(rapidBullet);
}
}
} else if (currentWeapon === 'laser' && laserCooldown <= 0) {
// Shoot laser
var laser = new Laser();
laser.x = player.x;
laser.y = player.y - 30;
lasers.push(laser);
game.addChild(laser);
LK.getSound('laserShoot').play();
var baseCooldown = rapidFireActive ? 3 : 10; // 3 times faster with rapid fire
laserCooldown = baseCooldown;
}
};
game.move = function (x, y, obj) {
if (gameStarted && dragNode) {
// Keep player within screen bounds
dragNode.x = Math.max(40, Math.min(2048 - 40, x));
}
};
game.up = function (x, y, obj) {
dragNode = null;
isHoldingDown = false;
};
// Main game update loop
game.update = function () {
if (!gameStarted) {
return;
}
// Update laser cooldown
if (laserCooldown > 0) {
laserCooldown--;
}
// Update power-up effects
if (shieldActive) {
// Update shield visual effect
shieldEffect.alpha = 0.5 + 0.3 * Math.sin(LK.ticks * 0.3);
shieldEffect.rotation += 0.1;
}
if (rapidFireActive) {
rapidFireTimer--;
if (rapidFireTimer <= 0) {
rapidFireActive = false;
}
}
// Continuous laser firing when holding down
var laserFireRate = rapidFireActive ? 1 : 5; // 3 times faster firing with rapid fire (5/1 = 5x, but limiting to reasonable rate)
if (isHoldingDown && currentWeapon === 'laser' && laserCooldown <= 0 && dragNode) {
var laser = new Laser();
laser.x = player.x;
laser.y = player.y - 30;
lasers.push(laser);
game.addChild(laser);
laserCooldown = laserFireRate; // Variable firing rate
}
// Update lasers
for (var l = lasers.length - 1; l >= 0; l--) {
var laser = lasers[l];
if (laser.shouldDestroy) {
laser.destroy();
lasers.splice(l, 1);
continue;
}
// Check laser vs enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (laser.intersects(enemy)) {
// Store hit enemy position for area damage
var hitX = enemy.x;
var hitY = enemy.y;
// Destroy laser
laser.destroy();
lasers.splice(l, 1);
// Handle different enemy types (lasers do slightly less damage)
if (enemy instanceof TankEnemy) {
// Tank enemy takes multiple hits
enemy.hitPoints--;
enemy.updateTint(); // Update visual damage
if (enemy.hitPoints <= 0) {
enemy.destroy();
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 45); // Slightly less score for laser
scoreTxt.setText('Score: ' + LK.getScore());
}
LK.getSound('enemyHit').play();
} else if (enemy instanceof BomberEnemy) {
// Bomber enemy takes 2 hits
enemy.hitPoints--;
enemy.updateTint(); // Update visual damage
if (enemy.hitPoints <= 0) {
enemy.destroy();
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 25); // Slightly less score for laser
scoreTxt.setText('Score: ' + LK.getScore());
}
LK.getSound('enemyHit').play();
} else {
// Regular and fast enemies destroyed in one hit
enemy.destroy();
enemies.splice(j, 1);
// Increase score - slightly less points for laser
var points = enemy instanceof FastEnemy ? 15 : 8;
LK.setScore(LK.getScore() + points);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('enemyHit').play();
}
// Laser area damage - destroy nearby enemies
for (var k = enemies.length - 1; k >= 0; k--) {
var nearbyEnemy = enemies[k];
var distance = Math.sqrt(Math.pow(nearbyEnemy.x - hitX, 2) + Math.pow(nearbyEnemy.y - hitY, 2));
if (distance <= 150) {
// Area damage radius
nearbyEnemy.destroy();
enemies.splice(k, 1);
var areaPoints = nearbyEnemy instanceof FastEnemy ? 15 : 8;
LK.setScore(LK.getScore() + areaPoints);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('enemyHit').play();
}
}
break;
}
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.shouldDestroy) {
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check bullet vs enemy collisions
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Destroy bullet
bullet.destroy();
bullets.splice(i, 1);
// Handle different enemy types
if (enemy instanceof TankEnemy) {
// Tank enemy takes multiple hits
enemy.hitPoints--;
enemy.updateTint(); // Update visual damage
if (enemy.hitPoints <= 0) {
enemy.destroy();
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 50); // High score for tank
scoreTxt.setText('Score: ' + LK.getScore());
}
LK.getSound('enemyHit').play();
} else if (enemy instanceof BomberEnemy) {
// Bomber enemy takes 2 hits
enemy.hitPoints--;
enemy.updateTint(); // Update visual damage
if (enemy.hitPoints <= 0) {
enemy.destroy();
enemies.splice(j, 1);
LK.setScore(LK.getScore() + 30); // Medium score for bomber
scoreTxt.setText('Score: ' + LK.getScore());
}
LK.getSound('enemyHit').play();
} else {
// Regular and fast enemies destroyed in one hit
enemy.destroy();
enemies.splice(j, 1);
// Increase score - more points for fast enemies
var points = enemy instanceof FastEnemy ? 20 : 10;
LK.setScore(LK.getScore() + points);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('enemyHit').play();
}
break;
}
}
}
// Update enemy bullets
for (var m = enemyBullets.length - 1; m >= 0; m--) {
var enemyBullet = enemyBullets[m];
if (enemyBullet.shouldDestroy) {
enemyBullet.destroy();
enemyBullets.splice(m, 1);
continue;
}
// Check enemy bullet vs player collision
if (enemyBullet.intersects(player)) {
// Remove bullet
enemyBullet.destroy();
enemyBullets.splice(m, 1);
// Only take damage if shield is not active
if (!shieldActive) {
playerLives--;
livesTxt.setText('Lives: ' + playerLives);
LK.effects.flashObject(player, 0xff0000, 500);
LK.getSound('sonidodolor').play(); // Play pain sound when bullet hits player
if (playerLives <= 0) {
// Game Over
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
} else {
// Shield absorbed the hit - deactivate shield
shieldActive = false;
shieldEffect.alpha = 0;
LK.effects.flashObject(player, 0x00AAFF, 300);
}
}
}
// Update enemies
for (var k = enemies.length - 1; k >= 0; k--) {
var enemy = enemies[k];
if (enemy.shouldDestroy) {
// Check if enemy passed the bottom (went off screen)
if (enemy.y > 2732 + 50) {
enemiesPassed++;
// Check if 5 or more enemies have passed
if (enemiesPassed >= 5) {
// Game Over
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
enemy.destroy();
enemies.splice(k, 1);
continue;
}
// Bomber enemy shooting behavior
if (enemy instanceof BomberEnemy && enemy.shootCooldown <= 0 && enemy.y > 0 && enemy.y < 2400) {
enemy.shootCooldown = enemy.shootRate;
var bomberBullet = new EnemyBullet();
bomberBullet.x = enemy.x;
bomberBullet.y = enemy.y + 50;
enemyBullets.push(bomberBullet);
game.addChild(bomberBullet);
LK.getSound('disparoenemigo').play();
}
// Check enemy vs player collision
if (enemy.intersects(player)) {
// Remove enemy
enemy.destroy();
enemies.splice(k, 1);
// Only take damage if shield is not active
if (!shieldActive) {
playerLives--;
livesTxt.setText('Lives: ' + playerLives);
LK.effects.flashObject(player, 0xff0000, 500);
LK.getSound('sonidodolor').play(); // Play pain sound when enemy collides with player
if (playerLives <= 0) {
// Game Over
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
} else {
// Shield absorbed the hit - deactivate shield
shieldActive = false;
shieldEffect.alpha = 0;
LK.effects.flashObject(player, 0x00AAFF, 300);
}
continue;
}
}
// Update power-ups
for (var p = powerUps.length - 1; p >= 0; p--) {
var powerUp = powerUps[p];
if (powerUp.shouldDestroy) {
powerUp.destroy();
powerUps.splice(p, 1);
continue;
}
// Check power-up vs player collision
if (powerUp.intersects(player)) {
// Apply power-up effect based on type
if (powerUp instanceof HealthPowerUp) {
playerLives = Math.min(playerLives + 1, 5); // Max 5 lives - gives extra life
livesTxt.setText('Lives: ' + playerLives);
} else if (powerUp instanceof ShieldPowerUp) {
shieldActive = true;
shieldTimer = 300; // 5 seconds at 60 FPS - protects from one hit
} else if (powerUp instanceof RapidFirePowerUp) {
rapidFireActive = true;
rapidFireTimer = 300; // 5 seconds at 60 FPS - fires 3 times faster
}
// Remove power-up and play sound
powerUp.destroy();
powerUps.splice(p, 1);
LK.getSound('powerUpCollect').play();
LK.effects.flashObject(player, 0x00FF00, 300);
}
}
// Enemy shooting
enemyShootTimer++;
if (enemyShootTimer >= 90) {
// Enemies shoot every 1.5 seconds
enemyShootTimer = 0;
// Random enemy shoots
if (enemies.length > 0) {
var shootingEnemy = enemies[Math.floor(Math.random() * enemies.length)];
var enemyBullet = new EnemyBullet();
enemyBullet.x = shootingEnemy.x;
enemyBullet.y = shootingEnemy.y + 30;
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
LK.getSound('disparoenemigo').play();
}
}
// Spawn enemies
enemySpawnTimer++;
if (enemySpawnTimer >= enemySpawnRate) {
enemySpawnTimer = 0;
var enemy;
var randomValue = Math.random();
// 8% tank, 15% bomber, 25% fast, 52% regular enemy
if (randomValue < 0.08) {
enemy = new TankEnemy();
} else if (randomValue < 0.23) {
enemy = new BomberEnemy();
} else if (randomValue < 0.48) {
enemy = new FastEnemy();
} else {
enemy = new Enemy();
}
enemy.x = Math.random() * (2048 - 120) + 60; // Random X position within bounds
enemy.y = -30; // Start above screen
enemies.push(enemy);
game.addChild(enemy);
// Gradually increase difficulty
if (enemySpawnRate > 40) {
enemySpawnRate -= 0.5;
}
}
// Spawn power-ups
powerUpSpawnTimer++;
if (powerUpSpawnTimer >= powerUpSpawnRate) {
powerUpSpawnTimer = 0;
var powerUp;
var randomValue = Math.random();
// 40% health, 30% shield, 30% rapid fire
if (randomValue < 0.4) {
powerUp = new HealthPowerUp();
} else if (randomValue < 0.7) {
powerUp = new ShieldPowerUp();
} else {
powerUp = new RapidFirePowerUp();
}
powerUp.x = Math.random() * (2048 - 120) + 60; // Random X position within bounds
powerUp.y = -30; // Start above screen
powerUps.push(powerUp);
game.addChild(powerUp);
}
}; ===================================================================
--- original.js
+++ change.js
@@ -321,9 +321,9 @@
var bullets = [];
var enemyBullets = [];
var enemies = [];
var enemySpawnTimer = 0;
-var enemySpawnRate = 60; // Frames between enemy spawns
+var enemySpawnRate = 120; // Frames between enemy spawns (doubled to halve enemy count)
var enemyShootTimer = 0;
var dragNode = null;
var enemiesPassed = 0; // Track how many enemies have passed the bottom
var playerLives = 3; // Player starts with 3 lives
@@ -968,9 +968,9 @@
enemy.y = -30; // Start above screen
enemies.push(enemy);
game.addChild(enemy);
// Gradually increase difficulty
- if (enemySpawnRate > 20) {
+ if (enemySpawnRate > 40) {
enemySpawnRate -= 0.5;
}
}
// Spawn power-ups
bala de rifle de asalto hecha con pixeles. In-Game asset. 2d. High contrast. No shadows
una calle muy ancha de un vecindario peligroso hecho con pixeles y la perspectiva desde el cielo In-Game asset. 2d. High contrast. No shadows
una pistola negra hecha con pixeles que diga start en medio In-Game asset. 2d. High contrast. No shadows
chaleco antibalas negro hecho con pixeles.. In-Game asset. 2d. High contrast. No shadows
corazon rojo hecho con pixeles. In-Game asset. 2d. High contrast. No shadows
minigun negra hecha con pixeles.. In-Game asset. 2d. High contrast. No shadows
un rifle de asalto m4 negro que en medio diga seleccion de personaje hecho con pixeles. In-Game asset. 2d. High contrast. No shadows
un cuchillo hecho con pixeles que tenga escrito back. In-Game asset. 2d. High contrast. No shadows
letras negras con contorno blanco que dicen select your character con letra cursiva. In-Game asset. 2d. High contrast. No shadows
texto hecho con pixeles que diga lives. In-Game asset. 2d. High contrast. No shadows
texto hecho con pixeles que diga score. In-Game asset. 2d. High contrast. No shadows
cj de gta san andreas con perspectiva trasera desde arriba usando un arma, hecho con pixeles.
un pandillero peligroso vestido de verde usando un arma con perspectiva trasera desde arriba hecho con pixeles. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
pandillero de morado hecho con pixeles. con perspectiva desde arriba visto de frente apuntando con un m4 In-Game asset. 2d. High contrast. No shadows
pandillero de amarillo hecho con pixeles con perspectiva desde arriba visto de frente apuntando hacia enfrente con un arma In-Game asset. 2d. High contrast. No shadows
pandillero de morado hecho con pixeles con perspectiva desde arriba visto de frente apuntando hacia enfrente con un arma In-Game asset. 2d. High contrast. No shadows
sicario vestido de negro hecho con pixeles y con armas con perspectiva desde arriba visto de frente apuntando con un arma
letras blancas con un contorno negro con cursiva. que dicen san andreas stories In-Game asset. 2d. High contrast. No shadows con el tipo de letra del el juego gta san andreas
letras que dicen san andreas stories blancas hechas con pixeles. In-Game asset. 2d. High contrast. No shadows
pero no la imagen estara recta apuntando hacia el frente totalmente sin inclinacion con perspectiva desde arriba y trasera