User prompt
as que una ves que ganas te regrese al menu principar
User prompt
as que aya un sonido para cada tipo de unidad cuando la destrullen o cuando disparan
User prompt
as que aya un sonido unico de destruccion para cada tipo de unidad
User prompt
quiero que la palabra beta este en el menu principal
User prompt
en la esquina superior izquierda que aya en letras grandes y azules que dijan BETA¡¡¡¡¡¡¡
User prompt
quita las palabras strategic ai battle simulator del menu
User prompt
musica para el menu
User prompt
uma ,usica de fondo cuando pulsas el boton stard
User prompt
as que la imagen del menu no sea opaca
User prompt
as que en el territorio aya una imagen que avarque toda la pantalla
User prompt
elimina las lineas de codijos inesesarias
User prompt
elimina los cuadrados del territorio
User prompt
as que ayan 10 unidades por ia
User prompt
as que solo ayan 15 unidades de cada ia
User prompt
AS QUE LAS UNIDADES DE LA IA ROJA SEAN DIFERENTES
User prompt
AS QUE NO PUEDAN AVER MAS DE 30 UNIDADES EN LA PANTALLA
User prompt
AS QUE EL BOTOS SEA UNA IMAGEN MODIFICABLE Y EL NUMERO ESTE ALADO
User prompt
ASQUE LOS CONTADORES DE CIUDADES SEAN BOTONES CON EL NUMERO DE CIUDADES
User prompt
as que en ves del titulo aya una imagen
User prompt
as que la imagen sea del porte de la pantalla con buena resolucion
User prompt
as que aya una imagen grande en el menu
User prompt
elimina las letras de start
User prompt
as que aya 50 unidades maximas
User prompt
as que no se superpongan las unidades
User prompt
as que en el menu aya un botosn en ves de letra para iniciar
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bullet = Container.expand(function (startX, startY, targetX, targetY, damage, faction) { var self = Container.call(this); self.x = startX; self.y = startY; self.damage = damage; self.faction = faction; self.speed = 8; var dx = targetX - startX; var dy = targetY - startY; var distance = Math.sqrt(dx * dx + dy * dy); self.velocityX = dx / distance * self.speed; self.velocityY = dy / distance * self.speed; self.maxDistance = distance; self.traveled = 0; var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x += self.velocityX; self.y += self.velocityY; self.traveled += self.speed; // Check if bullet reached target area or max distance if (self.traveled >= self.maxDistance) { self.explode(); } }; self.explode = function () { // Find units in explosion radius var explosionRadius = 30; var explosionPlayed = false; for (var i = 0; i < allUnits.length; i++) { var unit = allUnits[i]; if (unit.faction !== self.faction && unit.health > 0) { var dx = unit.x - self.x; var dy = unit.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < explosionRadius) { var destroyed = unit.takeDamage(self.damage); if (destroyed && !explosionPlayed) { LK.getSound('explosion').play(); explosionPlayed = true; } } } } // Check cities var enemyCities = self.faction === 'red' ? blueCities : redCities; for (var i = 0; i < enemyCities.length; i++) { var city = enemyCities[i]; if (city.health > 0) { var dx = city.x - self.x; var dy = city.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < explosionRadius) { var destroyed = city.takeDamage(self.damage); if (destroyed && !explosionPlayed) { LK.getSound('explosion').play(); explosionPlayed = true; } } } } // Remove bullet for (var i = 0; i < bullets.length; i++) { if (bullets[i] === self) { bullets.splice(i, 1); break; } } self.destroy(); }; return self; }); var City = Container.expand(function (faction) { var self = Container.call(this); self.faction = faction; self.health = 1000; self.maxHealth = 1000; self.lastProduction = 0; self.productionCooldown = 180; // 3 seconds at 60fps var cityGraphics = self.attachAsset('city', { anchorX: 0.5, anchorY: 0.5 }); // Color based on faction if (faction === 'red') { cityGraphics.tint = 0xff4444; } else { cityGraphics.tint = 0x4444ff; } // Health bar background var healthBarBg = self.attachAsset('healthBarBg', { anchorX: 0.5, anchorY: 0.5, y: -50 }); // Health bar var healthBar = self.attachAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, y: -50 }); self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; return true; // City destroyed } // Update health bar var healthPercent = self.health / self.maxHealth; healthBar.width = 80 * healthPercent; return false; }; self.produceUnit = function () { if (LK.ticks - self.lastProduction < self.productionCooldown) return; // Choose random unit type var unitTypes = ['infantry', 'tank', 'artillery']; var unitType = unitTypes[Math.floor(Math.random() * unitTypes.length)]; var unit = new Unit(unitType, self.faction); // Simple positioning around the city var angle = Math.random() * Math.PI * 2; var distance = 100 + Math.random() * 50; unit.x = self.x + Math.cos(angle) * distance; unit.y = self.y + Math.sin(angle) * distance; // Keep within bounds unit.x = Math.max(50, Math.min(1998, unit.x)); unit.y = Math.max(50, Math.min(2682, unit.y)); allUnits.push(unit); game.addChild(unit); self.lastProduction = LK.ticks; }; self.update = function () { if (self.health <= 0) return; self.produceUnit(); }; return self; }); var Unit = Container.expand(function (type, faction) { var self = Container.call(this); self.type = type; self.faction = faction; self.target = null; self.lastShot = 0; self.health = 100; self.maxHealth = 100; self.moveSpeed = 2; self.range = 100; self.damage = 20; self.shootCooldown = 60; self.lastMoveTime = 0; // Set unit stats based on type if (type === 'infantry') { self.moveSpeed = 2; self.health = 60; self.maxHealth = 60; self.damage = 15; self.range = 80; self.shootCooldown = 40; } else if (type === 'tank') { self.moveSpeed = 2.5; self.health = 120; self.maxHealth = 120; self.damage = 30; self.range = 100; self.shootCooldown = 60; } else if (type === 'artillery') { self.moveSpeed = 1; self.health = 80; self.maxHealth = 80; self.damage = 50; self.range = 180; self.shootCooldown = 90; } var unitGraphics = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); // Color based on faction if (faction === 'red') { unitGraphics.tint = 0xff4444; } else { unitGraphics.tint = 0x4444ff; } // Health bar background var healthBarBg = self.attachAsset('healthBarBg', { anchorX: 0.5, anchorY: 0.5, y: -50 }); // Health bar var healthBar = self.attachAsset('healthBar', { anchorX: 0.5, anchorY: 0.5, y: -50 }); self.takeDamage = function (damage) { self.health -= damage; if (self.health <= 0) { self.health = 0; return true; // Unit destroyed } // Update health bar var healthPercent = self.health / self.maxHealth; healthBar.width = 80 * healthPercent; return false; }; self.findTarget = function () { var closestDistance = Infinity; var closestTarget = null; // Find closest enemy unit for (var i = 0; i < allUnits.length; i++) { var unit = allUnits[i]; if (unit.faction !== self.faction && unit.health > 0) { var dx = unit.x - self.x; var dy = unit.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < closestDistance) { closestDistance = distance; closestTarget = unit; } } } // Check enemy cities var enemyCities = self.faction === 'red' ? blueCities : redCities; for (var i = 0; i < enemyCities.length; i++) { var city = enemyCities[i]; if (city.health > 0) { var dx = city.x - self.x; var dy = city.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < closestDistance) { closestDistance = distance; closestTarget = city; } } } return closestTarget; }; self.update = function () { if (self.health <= 0) return; self.target = self.findTarget(); if (self.target && self.target.health > 0) { var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.range) { // Move towards target var moveX = dx / distance * self.moveSpeed; var moveY = dy / distance * self.moveSpeed; // Calculate new position var newX = self.x + moveX; var newY = self.y + moveY; // Check for collision with other units var canMove = true; var unitRadius = 40; // Minimum distance between units for (var i = 0; i < allUnits.length; i++) { var otherUnit = allUnits[i]; if (otherUnit !== self && otherUnit.health > 0) { var otherDx = newX - otherUnit.x; var otherDy = newY - otherUnit.y; var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy); if (otherDistance < unitRadius) { canMove = false; break; } } } // Only move if no collision if (canMove) { self.x = newX; self.y = newY; // Keep units within bounds self.x = Math.max(40, Math.min(2008, self.x)); self.y = Math.max(40, Math.min(2692, self.y)); } } else { // In range, shoot if (LK.ticks - self.lastShot > self.shootCooldown) { self.shoot(); self.lastShot = LK.ticks; } } } }; self.shoot = function () { if (!self.target || self.target.health <= 0) return; var bullet = new Bullet(self.x, self.y, self.target.x, self.target.y, self.damage, self.faction); bullets.push(bullet); game.addChild(bullet); LK.getSound('shoot').play(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228B22 }); /**** * Game Code ****/ // Game state var allUnits = []; var bullets = []; var redCities = []; var blueCities = []; var gameStarted = false; var territorialGrid = []; var showingMenu = true; // UI var statusText = new Text2('Europa 1941: AI War', { size: 40, fill: 0xFFFFFF }); statusText.anchor.set(0.5, 0); LK.gui.top.addChild(statusText); // Main Menu UI var menuTitle = new Text2('EUROPA 1941: AI WAR', { size: 60, fill: 0xFFFFFF }); menuTitle.anchor.set(0.5, 0.5); LK.gui.center.addChild(menuTitle); var menuSubtitle = new Text2('Strategic AI Battle Simulation', { size: 30, fill: 0xCCCCCC }); menuSubtitle.anchor.set(0.5, 0.5); menuSubtitle.y = 80; LK.gui.center.addChild(menuSubtitle); var startButton = LK.getAsset('startButton', { anchorX: 0.5, anchorY: 0.5 }); startButton.y = 200; LK.gui.center.addChild(startButton); // Add text on top of button var startButtonText = new Text2('START BATTLE', { size: 32, fill: 0xFFFFFF }); startButtonText.anchor.set(0.5, 0.5); startButtonText.y = 200; LK.gui.center.addChild(startButtonText); var instructionsText = new Text2('Red vs Blue AI armies\nDestroy all enemy cities to win', { size: 25, fill: 0xAAAAA }); instructionsText.anchor.set(0.5, 0.5); instructionsText.y = 300; LK.gui.center.addChild(instructionsText); // Animate start button function animateStartButton() { tween(startButton, { scaleX: 1.2, scaleY: 1.2 }, { duration: 800, yoyo: true, repeat: Infinity }); tween(startButtonText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 800, yoyo: true, repeat: Infinity }); } animateStartButton(); var redScoreText = new Text2('Red Cities: 0', { size: 30, fill: 0xFF4444 }); redScoreText.anchor.set(0, 0); redScoreText.x = 20; redScoreText.y = 120; LK.gui.top.addChild(redScoreText); var blueScoreText = new Text2('Blue Cities: 0', { size: 30, fill: 0x4444FF }); blueScoreText.anchor.set(1, 0); blueScoreText.x = -20; blueScoreText.y = 50; LK.gui.topRight.addChild(blueScoreText); // Initialize cities function initializeCities() { var minDistance = 120; // Minimum distance between cities // Red cities (left side) for (var i = 0; i < 5; i++) { var city = new City('red'); var attempts = 0; var maxAttempts = 50; var validPosition = false; while (!validPosition && attempts < maxAttempts) { city.x = 150 + Math.random() * 500; // Random x between 150-650 city.y = 200 + Math.random() * 2300; // Random y between 200-2500 validPosition = true; // Check distance from other red cities for (var j = 0; j < redCities.length; j++) { var dx = city.x - redCities[j].x; var dy = city.y - redCities[j].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < minDistance) { validPosition = false; break; } } attempts++; } redCities.push(city); game.addChild(city); } // Blue cities (right side) for (var i = 0; i < 5; i++) { var city = new City('blue'); var attempts = 0; var maxAttempts = 50; var validPosition = false; while (!validPosition && attempts < maxAttempts) { city.x = 1400 + Math.random() * 500; // Random x between 1400-1900 city.y = 200 + Math.random() * 2300; // Random y between 200-2500 validPosition = true; // Check distance from other blue cities for (var j = 0; j < blueCities.length; j++) { var dx = city.x - blueCities[j].x; var dy = city.y - blueCities[j].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < minDistance) { validPosition = false; break; } } attempts++; } blueCities.push(city); game.addChild(city); } } function updateUI() { var redAlive = 0; var blueAlive = 0; var previousRedAlive = 0; var previousBlueAlive = 0; // Count previous alive cities for (var i = 0; i < redCities.length; i++) { if (redCities[i].health > 0) { redAlive++; } else if (redCities[i].health === 0) { // Check if this was just destroyed previousRedAlive++; } } for (var i = 0; i < blueCities.length; i++) { if (blueCities[i].health > 0) { blueAlive++; } else if (blueCities[i].health === 0) { // Check if this was just destroyed previousBlueAlive++; } } // Update territorial grid when cities are destroyed var totalCitiesNow = redAlive + blueAlive; var totalCitiesBefore = redCities.length + blueCities.length; if (totalCitiesNow < totalCitiesBefore) { createTerritorialGrid(); } redScoreText.setText('Red Cities: ' + redAlive); blueScoreText.setText('Blue Cities: ' + blueAlive); // Check win conditions if (redAlive === 0) { statusText.setText('Blue AI Wins!'); LK.showYouWin(); } else if (blueAlive === 0) { statusText.setText('Red AI Wins!'); LK.showYouWin(); } } function createTerritorialGrid() { // Clear existing grid for (var i = 0; i < territorialGrid.length; i++) { territorialGrid[i].destroy(); } territorialGrid = []; var gridSize = 80; // Same size as cities var rows = Math.floor(2732 / gridSize); var cols = Math.floor(2048 / gridSize); var halfGridSize = gridSize / 2; for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var x = col * gridSize + halfGridSize; var y = row * gridSize + halfGridSize; // Determine territory based on closest surviving city var closestRedDistance = Infinity; var closestBlueDistance = Infinity; // Check red cities for (var i = 0; i < redCities.length; i++) { if (redCities[i].health > 0) { var dx = x - redCities[i].x; var dy = y - redCities[i].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < closestRedDistance) { closestRedDistance = distance; } } } // Check blue cities for (var i = 0; i < blueCities.length; i++) { if (blueCities[i].health > 0) { var dx = x - blueCities[i].x; var dy = y - blueCities[i].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < closestBlueDistance) { closestBlueDistance = distance; } } } // Create territory square var territorySquare = LK.getAsset('territory', { anchorX: 0.5, anchorY: 0.5 }); territorySquare.x = x; territorySquare.y = y; territorySquare.alpha = 0.6; // Color based on closest territory if (closestRedDistance < closestBlueDistance) { territorySquare.tint = 0xff4444; } else { territorySquare.tint = 0x4444ff; } territorialGrid.push(territorySquare); game.addChild(territorySquare); // Add pulsing effect to make colors more visible tween(territorySquare, { alpha: 0.3 }, { duration: 2000 }); } } } function cleanupDeadUnits() { for (var i = allUnits.length - 1; i >= 0; i--) { if (allUnits[i].health <= 0) { allUnits[i].destroy(); allUnits.splice(i, 1); } } } // Function to start the game function startGame() { // Hide menu elements menuTitle.visible = false; menuSubtitle.visible = false; startButton.visible = false; startButtonText.visible = false; instructionsText.visible = false; showingMenu = false; // Start game initialization LK.setTimeout(function () { initializeCities(); createTerritorialGrid(); gameStarted = true; statusText.setText('Battle in Progress...'); }, 500); } // Touch handler for menu game.down = function (x, y, obj) { if (showingMenu) { startGame(); } }; // Game update loop game.update = function () { if (showingMenu || !gameStarted) return; // Update all units for (var i = 0; i < allUnits.length; i++) { if (allUnits[i].health > 0) { allUnits[i].update(); } } // Update all cities for (var i = 0; i < redCities.length; i++) { redCities[i].update(); } for (var i = 0; i < blueCities.length; i++) { blueCities[i].update(); } // Update all bullets for (var i = 0; i < bullets.length; i++) { bullets[i].update(); } // Cleanup dead units cleanupDeadUnits(); // Update UI updateUI(); };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function (startX, startY, targetX, targetY, damage, faction) {
var self = Container.call(this);
self.x = startX;
self.y = startY;
self.damage = damage;
self.faction = faction;
self.speed = 8;
var dx = targetX - startX;
var dy = targetY - startY;
var distance = Math.sqrt(dx * dx + dy * dy);
self.velocityX = dx / distance * self.speed;
self.velocityY = dy / distance * self.speed;
self.maxDistance = distance;
self.traveled = 0;
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.x += self.velocityX;
self.y += self.velocityY;
self.traveled += self.speed;
// Check if bullet reached target area or max distance
if (self.traveled >= self.maxDistance) {
self.explode();
}
};
self.explode = function () {
// Find units in explosion radius
var explosionRadius = 30;
var explosionPlayed = false;
for (var i = 0; i < allUnits.length; i++) {
var unit = allUnits[i];
if (unit.faction !== self.faction && unit.health > 0) {
var dx = unit.x - self.x;
var dy = unit.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosionRadius) {
var destroyed = unit.takeDamage(self.damage);
if (destroyed && !explosionPlayed) {
LK.getSound('explosion').play();
explosionPlayed = true;
}
}
}
}
// Check cities
var enemyCities = self.faction === 'red' ? blueCities : redCities;
for (var i = 0; i < enemyCities.length; i++) {
var city = enemyCities[i];
if (city.health > 0) {
var dx = city.x - self.x;
var dy = city.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < explosionRadius) {
var destroyed = city.takeDamage(self.damage);
if (destroyed && !explosionPlayed) {
LK.getSound('explosion').play();
explosionPlayed = true;
}
}
}
}
// Remove bullet
for (var i = 0; i < bullets.length; i++) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
self.destroy();
};
return self;
});
var City = Container.expand(function (faction) {
var self = Container.call(this);
self.faction = faction;
self.health = 1000;
self.maxHealth = 1000;
self.lastProduction = 0;
self.productionCooldown = 180; // 3 seconds at 60fps
var cityGraphics = self.attachAsset('city', {
anchorX: 0.5,
anchorY: 0.5
});
// Color based on faction
if (faction === 'red') {
cityGraphics.tint = 0xff4444;
} else {
cityGraphics.tint = 0x4444ff;
}
// Health bar background
var healthBarBg = self.attachAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
y: -50
});
// Health bar
var healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -50
});
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
return true; // City destroyed
}
// Update health bar
var healthPercent = self.health / self.maxHealth;
healthBar.width = 80 * healthPercent;
return false;
};
self.produceUnit = function () {
if (LK.ticks - self.lastProduction < self.productionCooldown) return;
// Choose random unit type
var unitTypes = ['infantry', 'tank', 'artillery'];
var unitType = unitTypes[Math.floor(Math.random() * unitTypes.length)];
var unit = new Unit(unitType, self.faction);
// Simple positioning around the city
var angle = Math.random() * Math.PI * 2;
var distance = 100 + Math.random() * 50;
unit.x = self.x + Math.cos(angle) * distance;
unit.y = self.y + Math.sin(angle) * distance;
// Keep within bounds
unit.x = Math.max(50, Math.min(1998, unit.x));
unit.y = Math.max(50, Math.min(2682, unit.y));
allUnits.push(unit);
game.addChild(unit);
self.lastProduction = LK.ticks;
};
self.update = function () {
if (self.health <= 0) return;
self.produceUnit();
};
return self;
});
var Unit = Container.expand(function (type, faction) {
var self = Container.call(this);
self.type = type;
self.faction = faction;
self.target = null;
self.lastShot = 0;
self.health = 100;
self.maxHealth = 100;
self.moveSpeed = 2;
self.range = 100;
self.damage = 20;
self.shootCooldown = 60;
self.lastMoveTime = 0;
// Set unit stats based on type
if (type === 'infantry') {
self.moveSpeed = 2;
self.health = 60;
self.maxHealth = 60;
self.damage = 15;
self.range = 80;
self.shootCooldown = 40;
} else if (type === 'tank') {
self.moveSpeed = 2.5;
self.health = 120;
self.maxHealth = 120;
self.damage = 30;
self.range = 100;
self.shootCooldown = 60;
} else if (type === 'artillery') {
self.moveSpeed = 1;
self.health = 80;
self.maxHealth = 80;
self.damage = 50;
self.range = 180;
self.shootCooldown = 90;
}
var unitGraphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
// Color based on faction
if (faction === 'red') {
unitGraphics.tint = 0xff4444;
} else {
unitGraphics.tint = 0x4444ff;
}
// Health bar background
var healthBarBg = self.attachAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0.5,
y: -50
});
// Health bar
var healthBar = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 0.5,
y: -50
});
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
return true; // Unit destroyed
}
// Update health bar
var healthPercent = self.health / self.maxHealth;
healthBar.width = 80 * healthPercent;
return false;
};
self.findTarget = function () {
var closestDistance = Infinity;
var closestTarget = null;
// Find closest enemy unit
for (var i = 0; i < allUnits.length; i++) {
var unit = allUnits[i];
if (unit.faction !== self.faction && unit.health > 0) {
var dx = unit.x - self.x;
var dy = unit.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestDistance) {
closestDistance = distance;
closestTarget = unit;
}
}
}
// Check enemy cities
var enemyCities = self.faction === 'red' ? blueCities : redCities;
for (var i = 0; i < enemyCities.length; i++) {
var city = enemyCities[i];
if (city.health > 0) {
var dx = city.x - self.x;
var dy = city.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestDistance) {
closestDistance = distance;
closestTarget = city;
}
}
}
return closestTarget;
};
self.update = function () {
if (self.health <= 0) return;
self.target = self.findTarget();
if (self.target && self.target.health > 0) {
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.range) {
// Move towards target
var moveX = dx / distance * self.moveSpeed;
var moveY = dy / distance * self.moveSpeed;
// Calculate new position
var newX = self.x + moveX;
var newY = self.y + moveY;
// Check for collision with other units
var canMove = true;
var unitRadius = 40; // Minimum distance between units
for (var i = 0; i < allUnits.length; i++) {
var otherUnit = allUnits[i];
if (otherUnit !== self && otherUnit.health > 0) {
var otherDx = newX - otherUnit.x;
var otherDy = newY - otherUnit.y;
var otherDistance = Math.sqrt(otherDx * otherDx + otherDy * otherDy);
if (otherDistance < unitRadius) {
canMove = false;
break;
}
}
}
// Only move if no collision
if (canMove) {
self.x = newX;
self.y = newY;
// Keep units within bounds
self.x = Math.max(40, Math.min(2008, self.x));
self.y = Math.max(40, Math.min(2692, self.y));
}
} else {
// In range, shoot
if (LK.ticks - self.lastShot > self.shootCooldown) {
self.shoot();
self.lastShot = LK.ticks;
}
}
}
};
self.shoot = function () {
if (!self.target || self.target.health <= 0) return;
var bullet = new Bullet(self.x, self.y, self.target.x, self.target.y, self.damage, self.faction);
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
// Game state
var allUnits = [];
var bullets = [];
var redCities = [];
var blueCities = [];
var gameStarted = false;
var territorialGrid = [];
var showingMenu = true;
// UI
var statusText = new Text2('Europa 1941: AI War', {
size: 40,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0);
LK.gui.top.addChild(statusText);
// Main Menu UI
var menuTitle = new Text2('EUROPA 1941: AI WAR', {
size: 60,
fill: 0xFFFFFF
});
menuTitle.anchor.set(0.5, 0.5);
LK.gui.center.addChild(menuTitle);
var menuSubtitle = new Text2('Strategic AI Battle Simulation', {
size: 30,
fill: 0xCCCCCC
});
menuSubtitle.anchor.set(0.5, 0.5);
menuSubtitle.y = 80;
LK.gui.center.addChild(menuSubtitle);
var startButton = LK.getAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
startButton.y = 200;
LK.gui.center.addChild(startButton);
// Add text on top of button
var startButtonText = new Text2('START BATTLE', {
size: 32,
fill: 0xFFFFFF
});
startButtonText.anchor.set(0.5, 0.5);
startButtonText.y = 200;
LK.gui.center.addChild(startButtonText);
var instructionsText = new Text2('Red vs Blue AI armies\nDestroy all enemy cities to win', {
size: 25,
fill: 0xAAAAA
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.y = 300;
LK.gui.center.addChild(instructionsText);
// Animate start button
function animateStartButton() {
tween(startButton, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
yoyo: true,
repeat: Infinity
});
tween(startButtonText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
yoyo: true,
repeat: Infinity
});
}
animateStartButton();
var redScoreText = new Text2('Red Cities: 0', {
size: 30,
fill: 0xFF4444
});
redScoreText.anchor.set(0, 0);
redScoreText.x = 20;
redScoreText.y = 120;
LK.gui.top.addChild(redScoreText);
var blueScoreText = new Text2('Blue Cities: 0', {
size: 30,
fill: 0x4444FF
});
blueScoreText.anchor.set(1, 0);
blueScoreText.x = -20;
blueScoreText.y = 50;
LK.gui.topRight.addChild(blueScoreText);
// Initialize cities
function initializeCities() {
var minDistance = 120; // Minimum distance between cities
// Red cities (left side)
for (var i = 0; i < 5; i++) {
var city = new City('red');
var attempts = 0;
var maxAttempts = 50;
var validPosition = false;
while (!validPosition && attempts < maxAttempts) {
city.x = 150 + Math.random() * 500; // Random x between 150-650
city.y = 200 + Math.random() * 2300; // Random y between 200-2500
validPosition = true;
// Check distance from other red cities
for (var j = 0; j < redCities.length; j++) {
var dx = city.x - redCities[j].x;
var dy = city.y - redCities[j].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
redCities.push(city);
game.addChild(city);
}
// Blue cities (right side)
for (var i = 0; i < 5; i++) {
var city = new City('blue');
var attempts = 0;
var maxAttempts = 50;
var validPosition = false;
while (!validPosition && attempts < maxAttempts) {
city.x = 1400 + Math.random() * 500; // Random x between 1400-1900
city.y = 200 + Math.random() * 2300; // Random y between 200-2500
validPosition = true;
// Check distance from other blue cities
for (var j = 0; j < blueCities.length; j++) {
var dx = city.x - blueCities[j].x;
var dy = city.y - blueCities[j].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
validPosition = false;
break;
}
}
attempts++;
}
blueCities.push(city);
game.addChild(city);
}
}
function updateUI() {
var redAlive = 0;
var blueAlive = 0;
var previousRedAlive = 0;
var previousBlueAlive = 0;
// Count previous alive cities
for (var i = 0; i < redCities.length; i++) {
if (redCities[i].health > 0) {
redAlive++;
} else if (redCities[i].health === 0) {
// Check if this was just destroyed
previousRedAlive++;
}
}
for (var i = 0; i < blueCities.length; i++) {
if (blueCities[i].health > 0) {
blueAlive++;
} else if (blueCities[i].health === 0) {
// Check if this was just destroyed
previousBlueAlive++;
}
}
// Update territorial grid when cities are destroyed
var totalCitiesNow = redAlive + blueAlive;
var totalCitiesBefore = redCities.length + blueCities.length;
if (totalCitiesNow < totalCitiesBefore) {
createTerritorialGrid();
}
redScoreText.setText('Red Cities: ' + redAlive);
blueScoreText.setText('Blue Cities: ' + blueAlive);
// Check win conditions
if (redAlive === 0) {
statusText.setText('Blue AI Wins!');
LK.showYouWin();
} else if (blueAlive === 0) {
statusText.setText('Red AI Wins!');
LK.showYouWin();
}
}
function createTerritorialGrid() {
// Clear existing grid
for (var i = 0; i < territorialGrid.length; i++) {
territorialGrid[i].destroy();
}
territorialGrid = [];
var gridSize = 80; // Same size as cities
var rows = Math.floor(2732 / gridSize);
var cols = Math.floor(2048 / gridSize);
var halfGridSize = gridSize / 2;
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var x = col * gridSize + halfGridSize;
var y = row * gridSize + halfGridSize;
// Determine territory based on closest surviving city
var closestRedDistance = Infinity;
var closestBlueDistance = Infinity;
// Check red cities
for (var i = 0; i < redCities.length; i++) {
if (redCities[i].health > 0) {
var dx = x - redCities[i].x;
var dy = y - redCities[i].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestRedDistance) {
closestRedDistance = distance;
}
}
}
// Check blue cities
for (var i = 0; i < blueCities.length; i++) {
if (blueCities[i].health > 0) {
var dx = x - blueCities[i].x;
var dy = y - blueCities[i].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < closestBlueDistance) {
closestBlueDistance = distance;
}
}
}
// Create territory square
var territorySquare = LK.getAsset('territory', {
anchorX: 0.5,
anchorY: 0.5
});
territorySquare.x = x;
territorySquare.y = y;
territorySquare.alpha = 0.6;
// Color based on closest territory
if (closestRedDistance < closestBlueDistance) {
territorySquare.tint = 0xff4444;
} else {
territorySquare.tint = 0x4444ff;
}
territorialGrid.push(territorySquare);
game.addChild(territorySquare);
// Add pulsing effect to make colors more visible
tween(territorySquare, {
alpha: 0.3
}, {
duration: 2000
});
}
}
}
function cleanupDeadUnits() {
for (var i = allUnits.length - 1; i >= 0; i--) {
if (allUnits[i].health <= 0) {
allUnits[i].destroy();
allUnits.splice(i, 1);
}
}
}
// Function to start the game
function startGame() {
// Hide menu elements
menuTitle.visible = false;
menuSubtitle.visible = false;
startButton.visible = false;
startButtonText.visible = false;
instructionsText.visible = false;
showingMenu = false;
// Start game initialization
LK.setTimeout(function () {
initializeCities();
createTerritorialGrid();
gameStarted = true;
statusText.setText('Battle in Progress...');
}, 500);
}
// Touch handler for menu
game.down = function (x, y, obj) {
if (showingMenu) {
startGame();
}
};
// Game update loop
game.update = function () {
if (showingMenu || !gameStarted) return;
// Update all units
for (var i = 0; i < allUnits.length; i++) {
if (allUnits[i].health > 0) {
allUnits[i].update();
}
}
// Update all cities
for (var i = 0; i < redCities.length; i++) {
redCities[i].update();
}
for (var i = 0; i < blueCities.length; i++) {
blueCities[i].update();
}
// Update all bullets
for (var i = 0; i < bullets.length; i++) {
bullets[i].update();
}
// Cleanup dead units
cleanupDeadUnits();
// Update UI
updateUI();
};
con estilo de hoi4
prollectil de un flak 8,8cm. In-Game asset. 2d. High contrast. No shadows
boton de inicio al estilo hoi4. In-Game asset. 2d. High contrast. No shadows
QUE LAS LETRAS TENGAN UN COLOR MAS LLAMATIVO
SOLDADOS SOVIETICOS. In-Game asset. 2d. High contrast. No shadows
tanque t34-85. In-Game asset. 2d. High contrast. No shadows
artilleria sobietica yag 10 g. In-Game asset. 2d. High contrast. No shadows
mas cuadros