User prompt
Agrégale rotación a los caminos
Code edit (1 edits merged)
Please save this source code
User prompt
Crea un objeto llamado camino, asignarles una transparencia de 0.2, haz que las torres no se puedan colocar en el
User prompt
Elimina las upgrade de dmg, alcance y carencia de disparos. Agrega 2 marcos de izquierda a derecha aprovechando lo alto de UI. Un botón de comprar. La mejora de la izquierda es dmg +1 el de la izquierda carencia de disparos +30%
User prompt
Elimina torre rápida y los otros 3 botones
User prompt
Elimina los textos de info, remplaza info menú por upgrade menú
Code edit (2 edits merged)
Please save this source code
User prompt
Remplaza los valores de damage a 1. Haz que 1 = 1 capa, 2 = 2 capas
User prompt
Cambia damage para que 1 sea 1 capa y 2 dos, etc
User prompt
Agrégale al test de enemigo vida en forma de capas, verde -> azul -> rojo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Haz los textos de info cortos
Code edit (1 edits merged)
Please save this source code
User prompt
Desplaza tower info text al lado izquierdo y alineación izquierda
User prompt
Reposiciona los textos creando dos columnas de dos filas debido a que total damage no se ve
User prompt
Separa los textos de stat en dos columnas en el lado izquierdo y el botón de borrar al lado derecho
User prompt
Reposiciona y aumenta de tamaño los textos de info menú para aprovechar todo el largo de UI
User prompt
Reposiciona los textos de info menú para aprovechar todo UI
User prompt
Mejora la apariencia de menú info aprovechando todo UI
User prompt
El texto de total damage no se actualiza cuando se está en el menú info
User prompt
Haz que el texto de tota daño se actualice cuando está el menú abierto
User prompt
Agrega una variable local a cada torre que muestre el daño realizado
User prompt
Haz que teste enemy ni se mueva
User prompt
Agrega un botón para eliminar torre en info torre
User prompt
Haz una función reusable para fast tower y tower así ahorrar en líneas de codigo
User prompt
Optimiza la creación de torres usando funciones reusables
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('Bala', { anchorX: 0.5, anchorY: 0.5 }); self.target = null; self.speed = 600; // pixels per second self.damage = 0; self.update = function () { if (self.target && self.target.parent) { // Calculate direction to target var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distanceSquared = dx * dx + dy * dy; // If close enough to target, hit it (using squared distance to avoid sqrt) if (distanceSquared < 400) { // 20 * 20 = 400 // Remove bullet self.destroy(); return; } // Move towards target var distance = Math.sqrt(distanceSquared); var moveX = dx / distance * self.speed * frameTime; // 60 FPS var moveY = dy / distance * self.speed * frameTime; self.x += moveX; self.y += moveY; // Rotate bullet to face target self.rotation = Math.atan2(dy, dx); } else { // Target is gone, remove bullet self.destroy(); } }; return self; }); // Reusable tower creation function var Gameplay = Container.expand(function () { var self = Container.call(this); var gameplayGraphics = self.attachAsset('gameplayBackground', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var UI = Container.expand(function () { var self = Container.call(this); var uiGraphics = self.attachAsset('uiBackground', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Reusable tower creation function function createTowerBase(params) { return Container.expand(function () { var self = Container.call(this); // Tower parameters self.damage = params.damage; self.cadence = params.cadence; self.range = params.range; self.rangeSquared = self.range * self.range; // Cache squared range for optimization var areaGraphics = self.attachAsset('Area', { anchorX: 0.5, anchorY: 0.5 }); // Scale the area to match the tower's actual range var areaScale = self.range * 2 / 100; // Area asset is 100x100, so scale to range diameter areaGraphics.scaleX = areaScale; areaGraphics.scaleY = areaScale; areaGraphics.alpha = 0.3; areaGraphics.visible = false; // Hide range area by default var towerGraphics = self.attachAsset(params.asset, { anchorX: 0.5, anchorY: 0.5 }); // Method to show range area self.showRange = function () { areaGraphics.visible = true; }; // Method to hide range area self.hideRange = function () { areaGraphics.visible = false; }; // Tower selection state self.isSelected = false; // Tower placement state self.isPlaced = false; // Shooting properties self.lastShotTime = 0; self.bullets = []; // Method to find enemies in range self.findEnemiesInRange = function () { var enemies = []; // Check if enemyTest is in range if (enemyTest && enemyTest.parent) { var dx = enemyTest.x - self.x; var dy = enemyTest.y - self.y; var distanceSquared = dx * dx + dy * dy; if (distanceSquared <= self.rangeSquared) { enemies.push(enemyTest); } } return enemies; }; // Method to shoot at target self.shoot = function (target) { var currentTime = Date.now(); if (currentTime - self.lastShotTime >= self.cadence) { var bullet = new Bullet(); // Calculate direction to target for bullet offset var dx = target.x - self.x; var dy = target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var offsetDistance = 50; // Distance to spawn bullet ahead of tower // Spawn bullet slightly ahead in the direction of the target bullet.x = self.x + dx / distance * offsetDistance; bullet.y = self.y + dy / distance * offsetDistance; bullet.target = target; bullet.damage = self.damage; self.bullets.push(bullet); game.addChild(bullet); self.lastShotTime = currentTime; // Play bullet shooting sound LK.getSound('Balababa').play(); // Add squash animation to tower tween.stop(towerGraphics, { scaleX: true }); // Stop any existing scale tweens tween(towerGraphics, { scaleX: 0.7 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(towerGraphics, { scaleX: 1.0 }, { duration: 150, easing: tween.easeOut }); } }); } }; // Update method for tower self.update = function () { // Clean up destroyed bullets for (var i = self.bullets.length - 1; i >= 0; i--) { if (!self.bullets[i].parent) { self.bullets.splice(i, 1); } } // Only shoot if tower is placed (check cached status) if (self.isPlaced) { // Find and shoot at enemies var enemies = self.findEnemiesInRange(); if (enemies.length > 0) { var target = enemies[0]; // Calculate angle to target var dx = target.x - self.x; var dy = target.y - self.y; var targetAngle = Math.atan2(dy, dx); // Rotate tower to face target towerGraphics.rotation = targetAngle; // Flip tower horizontally if target is on the left side if (dx < 0) { towerGraphics.scaleY = -1; // Flip on Y axis when target is to the left } else { towerGraphics.scaleY = 1; // Normal orientation when target is to the right } // Shoot at the first enemy found self.shoot(target); } } }; // Handle tower selection self.down = function (x, y, obj) { // Deselect all other towers first for (var i = 0; i < placedTowers.length; i++) { if (placedTowers[i] !== self) { placedTowers[i].isSelected = false; placedTowers[i].hideRange(); } } // Toggle selection for this tower self.isSelected = !self.isSelected; if (self.isSelected) { self.showRange(); updateTowerInfo(self); // Update UI with this tower's info } else { self.hideRange(); updateTowerInfo(null); // Clear UI info when deselected } }; return self; }); } var FastTower = createTowerBase({ damage: 15, // Lower damage than regular tower cadence: 400, // Faster shooting (400ms vs 1000ms) range: 350, // Slightly shorter range asset: 'torreFast' }); var Tower = createTowerBase({ damage: 25, // Damage dealt per shot cadence: 1000, // Time between shots in milliseconds (1 second) range: 400, // Range in pixels asset: 'torreInicial' }); var draggedTower = null; var isDragging = false; var placedTowers = []; // Track all placed towers // Cache frequently used values var gameplayBounds = null; var uiBounds = null; var frameTime = 1 / 60; // Cache frame time calculation // Reusable tower creation function that accepts tower constructor function createTowerButton(color, x, y, TowerClass) { var buttonBG = game.addChild(LK.getAsset('BGbuttonTower', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 })); buttonBG.x = x; buttonBG.y = y; var button = game.addChild(new TowerClass()); button.x = x; button.y = y; button.tint = color; // Store reference to button background for easy access button.buttonBG = buttonBG; button.down = function (x, y, obj) { isDragging = true; draggedTower = game.addChild(new TowerClass()); draggedTower.x = button.x; draggedTower.y = button.y; draggedTower.alpha = 0.7; draggedTower.tint = color; draggedTower.showRange(); // Show range area when dragging }; return button; } // Game down handler to deselect towers when clicking on gameplay area game.down = function (x, y, obj) { // Check if click is in gameplay area (not on UI or towers) var gameplayBounds = getGameplayBounds(); var clickInGameplay = x >= gameplayBounds.left && x <= gameplayBounds.right && y >= gameplayBounds.top && y <= gameplayBounds.bottom; if (clickInGameplay) { // Deselect all towers for (var i = 0; i < placedTowers.length; i++) { placedTowers[i].isSelected = false; placedTowers[i].hideRange(); } updateTowerInfo(null); // Clear tower info when no tower is selected } }; // Helper functions for bounds calculations function getGameplayBounds() { return { left: gameplay.x - gameplay.width / 2, right: gameplay.x + gameplay.width / 2, top: gameplay.y - gameplay.height / 2, bottom: gameplay.y + gameplay.height / 2, centerX: gameplay.x, centerY: gameplay.y }; } function getUIBounds() { return { left: ui.x - ui.width / 2, right: ui.x + ui.width / 2, top: ui.y - ui.height / 2, bottom: ui.y + ui.height / 2 }; } function isPointInUI(x, y) { var bounds = getUIBounds(); return x >= bounds.left && x <= bounds.right && y >= bounds.top && y <= bounds.bottom; } function calculateDragOffset(x, y) { var bounds = getGameplayBounds(); var distanceFromCenterX = Math.abs(x - bounds.centerX); var distanceFromCenterY = Math.abs(y - bounds.centerY); var maxDistanceX = gameplay.width / 2; var maxDistanceY = gameplay.height / 2; var normalizedDistanceX = distanceFromCenterX / maxDistanceX; var normalizedDistanceY = distanceFromCenterY / maxDistanceY; var maxOffset = 200; var offsetMagnitudeX = maxOffset * normalizedDistanceX; var offsetMagnitudeY = maxOffset * normalizedDistanceY; var offsetX = 0; var offsetY = 0; if (x >= bounds.centerX && y <= bounds.centerY) { offsetX = offsetMagnitudeX; offsetY = -offsetMagnitudeY; } else if (x <= bounds.centerX && y <= bounds.centerY) { offsetX = -offsetMagnitudeX; offsetY = -offsetMagnitudeY; } else if (x <= bounds.centerX && y >= bounds.centerY) { offsetX = -offsetMagnitudeX; offsetY = offsetMagnitudeY; } else if (x >= bounds.centerX && y >= bounds.centerY) { offsetX = offsetMagnitudeX; offsetY = offsetMagnitudeY; } return { offsetX: offsetX, offsetY: offsetY }; } // Layer management - objects are added in z-index order (bottom to top) // Background layer var gameplay = game.addChild(new Gameplay()); gameplay.x = 1024; gameplay.y = 1093; // Game objects layer (towers will be added here) // UI layer var ui = game.addChild(new UI()); ui.x = 1024; ui.y = 2459; // Create multiple tower creation buttons with different colors var towerButtons = []; var buttonSpacing = 300; // Increased spacing between buttons var startX = 300; // Starting X position towerButtons.push(createTowerButton(0xffffff, startX, 2459, Tower)); // White tower (normal) towerButtons.push(createTowerButton(0xff0000, startX + buttonSpacing, 2459, FastTower)); // Red tower (fast) towerButtons.push(createTowerButton(0x00ff00, startX + buttonSpacing * 2, 2459, Tower)); // Green tower (normal) towerButtons.push(createTowerButton(0x0000ff, startX + buttonSpacing * 3, 2459, Tower)); // Blue tower (normal) // Enemy test object in the center var enemyTest = game.addChild(LK.getAsset('Puntero', { anchorX: 0.5, anchorY: 0.5, scaleX: 5, scaleY: 5, color: 0xff0000 })); enemyTest.x = 1024; enemyTest.y = 1093; // Set up vertical oscillation parameters enemyTest.originalY = 1093; enemyTest.oscillationRange = 200; // Range of up/down movement enemyTest.isMovingUp = true; // Start the oscillation loop function startEnemyOscillation() { var targetY = enemyTest.isMovingUp ? enemyTest.originalY - enemyTest.oscillationRange : enemyTest.originalY + enemyTest.oscillationRange; tween(enemyTest, { y: targetY }, { duration: 2000, // 2 seconds for each direction easing: tween.easeInOut, onFinish: function onFinish() { enemyTest.isMovingUp = !enemyTest.isMovingUp; // Toggle direction startEnemyOscillation(); // Start next oscillation } }); } // Start the oscillation startEnemyOscillation(); // UI mode management var UI_MODE_TOWER_CREATION = 'creation'; var UI_MODE_TOWER_INFO = 'info'; var currentUIMode = UI_MODE_TOWER_CREATION; // UI Information panel for selected tower var towerInfoContainer = game.addChild(new Container()); towerInfoContainer.x = 1600; // Position on the right side of UI towerInfoContainer.y = 2300; // Position in UI area // Create text elements for tower information var towerInfoTitle = towerInfoContainer.addChild(new Text2('Tower Info', { size: 60, fill: 0xFFFFFF })); towerInfoTitle.anchor.set(0.5, 0); towerInfoTitle.x = 0; towerInfoTitle.y = 0; var towerDamageText = towerInfoContainer.addChild(new Text2('Damage: --', { size: 40, fill: 0xFFFF00 })); towerDamageText.anchor.set(0.5, 0); towerDamageText.x = 0; towerDamageText.y = 80; var towerCadenceText = towerInfoContainer.addChild(new Text2('Fire Rate: --', { size: 40, fill: 0x00FF00 })); towerCadenceText.anchor.set(0.5, 0); towerCadenceText.x = 0; towerCadenceText.y = 140; var towerRangeText = towerInfoContainer.addChild(new Text2('Range: --', { size: 40, fill: 0x00FFFF })); towerRangeText.anchor.set(0.5, 0); towerRangeText.x = 0; towerRangeText.y = 200; // Create delete button for tower var deleteTowerButtonBG = towerInfoContainer.addChild(LK.getAsset('BGbuttonTower', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 })); deleteTowerButtonBG.x = 0; deleteTowerButtonBG.y = 300; deleteTowerButtonBG.tint = 0xff0000; // Red background for delete button var deleteTowerButtonText = towerInfoContainer.addChild(new Text2('DELETE', { size: 30, fill: 0xFFFFFF })); deleteTowerButtonText.anchor.set(0.5, 0.5); deleteTowerButtonText.x = 0; deleteTowerButtonText.y = 300; // Store reference to currently selected tower for deletion var selectedTowerForDeletion = null; // Function to switch UI modes function setUIMode(mode) { currentUIMode = mode; if (mode === UI_MODE_TOWER_CREATION) { // Show tower creation buttons and their backgrounds for (var i = 0; i < towerButtons.length; i++) { towerButtons[i].visible = true; if (towerButtons[i].buttonBG) { towerButtons[i].buttonBG.visible = true; } } // Hide tower info panel towerInfoContainer.visible = false; } else if (mode === UI_MODE_TOWER_INFO) { // Hide tower creation buttons and their backgrounds for (var i = 0; i < towerButtons.length; i++) { towerButtons[i].visible = false; if (towerButtons[i].buttonBG) { towerButtons[i].buttonBG.visible = false; } } // Show tower info panel towerInfoContainer.visible = true; } } // Function to update tower info display function updateTowerInfo(tower) { if (tower) { towerDamageText.setText('Damage: ' + tower.damage); towerCadenceText.setText('Fire Rate: ' + (1000 / tower.cadence).toFixed(1) + '/s'); towerRangeText.setText('Range: ' + tower.range); // Store reference to selected tower for deletion selectedTowerForDeletion = tower; // Switch to tower info mode when a tower is selected setUIMode(UI_MODE_TOWER_INFO); } else { towerDamageText.setText('Damage: --'); towerCadenceText.setText('Fire Rate: --'); towerRangeText.setText('Range: --'); // Clear reference to selected tower selectedTowerForDeletion = null; // Switch back to tower creation mode when no tower is selected setUIMode(UI_MODE_TOWER_CREATION); } } // Delete button click handler deleteTowerButtonBG.down = function (x, y, obj) { if (selectedTowerForDeletion) { // Remove tower from placed towers array for (var i = 0; i < placedTowers.length; i++) { if (placedTowers[i] === selectedTowerForDeletion) { placedTowers.splice(i, 1); break; } } // Destroy the tower selectedTowerForDeletion.destroy(); // Clear tower info and switch back to creation mode updateTowerInfo(null); } }; // Initialize with no tower selected and tower creation mode updateTowerInfo(null); setUIMode(UI_MODE_TOWER_CREATION); // Top overlay layer (pointer on top of everything) var puntero = game.addChild(LK.getAsset('Puntero', { anchorX: 0.5, anchorY: 0.5 })); puntero.x = 1024; puntero.y = 1366; puntero.alpha = 0; // Game move handler for dragging game.move = function (x, y, obj) { puntero.x = x; puntero.y = y; if (isDragging && draggedTower) { var gameplayBounds = getGameplayBounds(); var uiBounds = getUIBounds(); var offset = calculateDragOffset(x, y); var targetX = x + offset.offsetX; var targetY = y + offset.offsetY; // Apply boundary constraints if (targetY > uiBounds.top) { targetY = uiBounds.top - 70; } if (targetY < gameplayBounds.top) { targetY = gameplayBounds.top + 70; } if (targetX < uiBounds.left) { targetX = uiBounds.left + 70; } if (targetX > uiBounds.right) { targetX = uiBounds.right - 70; } // Check if tower is too close to existing towers var minDistance = 200; // Minimum distance between towers var minDistanceSquared = minDistance * minDistance; var tooCloseToOtherTowers = false; for (var i = 0; i < placedTowers.length; i++) { var existingTower = placedTowers[i]; var dx = targetX - existingTower.x; var dy = targetY - existingTower.y; var distanceSquared = dx * dx + dy * dy; if (distanceSquared < minDistanceSquared) { tooCloseToOtherTowers = true; break; } } // Update area tint based on pointer position and tower proximity var pointerInUI = isPointInUI(puntero.x, puntero.y); var cannotPlace = pointerInUI || tooCloseToOtherTowers; if (cannotPlace) { // Apply red tint to area when cannot place tower if (draggedTower.children[0]) { draggedTower.children[0].tint = 0xff0000; } } else { // Remove tint from area when tower can be placed if (draggedTower.children[0]) { draggedTower.children[0].tint = 0xFFFFFF; } } // Smooth movement var smoothness = 0.15; draggedTower.x += (targetX - draggedTower.x) * smoothness; draggedTower.y += (targetY - draggedTower.y) * smoothness; } }; // Game release handler game.up = function (x, y, obj) { if (isDragging && draggedTower) { var gameplayBounds = getGameplayBounds(); var uiBounds = getUIBounds(); var pointerInUI = isPointInUI(puntero.x, puntero.y); var towerInUI = draggedTower.x >= uiBounds.left && draggedTower.x <= uiBounds.right && draggedTower.y >= uiBounds.top && draggedTower.y <= uiBounds.bottom; if (pointerInUI || towerInUI) { draggedTower.destroy(); } else if (draggedTower.x >= gameplayBounds.left && draggedTower.x <= gameplayBounds.right && draggedTower.y >= gameplayBounds.top && draggedTower.y <= gameplayBounds.bottom) { // Check if tower is too close to existing towers var minDistance = 200; // Minimum distance between towers var minDistanceSquared = minDistance * minDistance; var canPlace = true; for (var i = 0; i < placedTowers.length; i++) { var existingTower = placedTowers[i]; var dx = draggedTower.x - existingTower.x; var dy = draggedTower.y - existingTower.y; var distanceSquared = dx * dx + dy * dy; if (distanceSquared < minDistanceSquared) { canPlace = false; break; } } if (canPlace) { draggedTower.alpha = 1.0; draggedTower.tint = 0xffffff; draggedTower.hideRange(); // Hide range area when placed draggedTower.isPlaced = true; // Set placement status placedTowers.push(draggedTower); // Add to placed towers array LK.getSound('TorreColocada').play(); // Play tower placement sound } else { // Tower is too close to existing towers, destroy it draggedTower.destroy(); } } else { draggedTower.destroy(); } isDragging = false; draggedTower = null; } };
===================================================================
--- original.js
+++ change.js
@@ -421,8 +421,27 @@
}));
towerRangeText.anchor.set(0.5, 0);
towerRangeText.x = 0;
towerRangeText.y = 200;
+// Create delete button for tower
+var deleteTowerButtonBG = towerInfoContainer.addChild(LK.getAsset('BGbuttonTower', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 0.8,
+ scaleY: 0.8
+}));
+deleteTowerButtonBG.x = 0;
+deleteTowerButtonBG.y = 300;
+deleteTowerButtonBG.tint = 0xff0000; // Red background for delete button
+var deleteTowerButtonText = towerInfoContainer.addChild(new Text2('DELETE', {
+ size: 30,
+ fill: 0xFFFFFF
+}));
+deleteTowerButtonText.anchor.set(0.5, 0.5);
+deleteTowerButtonText.x = 0;
+deleteTowerButtonText.y = 300;
+// Store reference to currently selected tower for deletion
+var selectedTowerForDeletion = null;
// Function to switch UI modes
function setUIMode(mode) {
currentUIMode = mode;
if (mode === UI_MODE_TOWER_CREATION) {
@@ -452,18 +471,38 @@
if (tower) {
towerDamageText.setText('Damage: ' + tower.damage);
towerCadenceText.setText('Fire Rate: ' + (1000 / tower.cadence).toFixed(1) + '/s');
towerRangeText.setText('Range: ' + tower.range);
+ // Store reference to selected tower for deletion
+ selectedTowerForDeletion = tower;
// Switch to tower info mode when a tower is selected
setUIMode(UI_MODE_TOWER_INFO);
} else {
towerDamageText.setText('Damage: --');
towerCadenceText.setText('Fire Rate: --');
towerRangeText.setText('Range: --');
+ // Clear reference to selected tower
+ selectedTowerForDeletion = null;
// Switch back to tower creation mode when no tower is selected
setUIMode(UI_MODE_TOWER_CREATION);
}
}
+// Delete button click handler
+deleteTowerButtonBG.down = function (x, y, obj) {
+ if (selectedTowerForDeletion) {
+ // Remove tower from placed towers array
+ for (var i = 0; i < placedTowers.length; i++) {
+ if (placedTowers[i] === selectedTowerForDeletion) {
+ placedTowers.splice(i, 1);
+ break;
+ }
+ }
+ // Destroy the tower
+ selectedTowerForDeletion.destroy();
+ // Clear tower info and switch back to creation mode
+ updateTowerInfo(null);
+ }
+};
// Initialize with no tower selected and tower creation mode
updateTowerInfo(null);
setUIMode(UI_MODE_TOWER_CREATION);
// Top overlay layer (pointer on top of everything)