User prompt
I said left, not right
User prompt
Rec team unit buttons should go a little to the left
User prompt
I said unit buttons on the top right corner, not top lettori
User prompt
Red team unit buttons should be in the top right corner
User prompt
Red team faction buttons should be in the top right corner
User prompt
The pause button should be in the top right corner instead
User prompt
Please fix the bug: 'factions is not defined' in or related to this line: 'var factionNames = Object.keys(factions);' Line Number: 573
User prompt
Add a button for each faction to place units from that faction
User prompt
Add a button to change fiction
User prompt
Add factions to simplify unit buttons (farm: wobbler, farmer; Medieval: sword, archer, crossbowman, king; magic: mirror shield, wizard; Vikings: berserker; Rome: spearman)
User prompt
Add new unit types: Mirror shield: has a chance to reflect projectiles (special type); King: strongest usit with massive damage and health, but slow (melee type); Crossbow man: Fires arrows like archer but faster; has a chance to deal critical damage
User prompt
Add new units: Priest: deals 0 damage,heals allies instead (support type); Berserker: deals dobule damage and moves faster when at half health (melee type); Spearman: versitile melee unit that has a chance to throw its spear
Code edit (1 edits merged)
Please save this source code
User prompt
Now you can dobule tap on AN unit to see their stats, unique abilities and what type of unit they are (melee, ranged.)
Code edit (1 edits merged)
Please save this source code
User prompt
Ultimate Battle Simulator
Initial prompt
Really accurate battle simulator: a game where you place units in 2 teams (red team and blue team) to fight themselves! Units: wobbler: punches the enemies; Farmer: uses its hayfork to slice up the enemies, deals dobule damage on its first hit; archer: shoots arrows with its mighty bow; Shield: has a shield that makes the unit resistant to arrows; Swordsman: uses its sword to slice through everything; Wizard: shoots out magic form its staff that deals high area damage and penetrates armor!
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Battlefield = Container.expand(function () { var self = Container.call(this); self.width = 2048; self.height = 1366; self.initialized = false; // Create background var bg = self.attachAsset('background', { anchorX: 0, anchorY: 0 }); self.projectiles = []; self.createProjectile = function (source, target, type) { var projectile = new Projectile(source, target, type); projectile.x = source.x; projectile.y = source.y; self.addChild(projectile); self.projectiles.push(projectile); }; self.removeUnit = function (unit) { var index = units.indexOf(unit); if (index !== -1) { units.splice(index, 1); } // Check win condition self.checkWinCondition(); }; self.checkWinCondition = function () { var redTeamUnits = 0; var blueTeamUnits = 0; for (var i = 0; i < units.length; i++) { if (units[i].active) { if (units[i].team === 'red') { redTeamUnits++; } else { blueTeamUnits++; } } } if (self.initialized && (redTeamUnits === 0 || blueTeamUnits === 0)) { var winningTeam = redTeamUnits > 0 ? "Red" : "Blue"; winText.setText(winningTeam + " Team Wins!"); winText.visible = true; LK.getSound('victory').play(); // Create reset button if (!resetButton) { resetButton = new ResetButton(); resetButton.x = self.width / 2; resetButton.y = self.height / 2 + 100; game.addChild(resetButton); } } }; self.update = function () { // Update all projectiles for (var i = self.projectiles.length - 1; i >= 0; i--) { self.projectiles[i].update(); // Remove destroyed projectiles if (!self.projectiles[i].parent) { self.projectiles.splice(i, 1); } } }; return self; }); var FactionButton = Container.expand(function (team, faction, x, y) { var self = Container.call(this); self.team = team; self.faction = faction; self.x = x; self.y = y; // Create button appearance var buttonShape = self.attachAsset('button' + team.charAt(0).toUpperCase() + team.slice(1), { anchorX: 0.5, anchorY: 0.5, width: 150, height: 80 }); // Add faction name text var nameText = new Text2(faction.charAt(0).toUpperCase() + faction.slice(1), { size: 24, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.y = 30; self.addChild(nameText); self.down = function (x, y, obj) { // When button is pressed, create unit buttons for the faction var xOffset = 120; for (var i = 0; i < factions[faction].length; i++) { var unitButton = new UnitButton(self.team, factions[faction][i], xOffset, self.y); game.addChild(unitButton); xOffset += 180; } // Highlight button LK.effects.flashObject(self, 0xffffff, 300); }; return self; }); var Projectile = Container.expand(function (source, target, type) { var self = Container.call(this); self.source = source; self.target = target; self.speed = type === 'arrow' ? 12 : 6; self.damage = source.attackDamage; var projectileAsset = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { if (!self.target || !self.target.active) { self.destroy(); return; } // Calculate direction to target var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // Rotate projectile to face target self.rotation = Math.atan2(dy, dx); // Move towards target if (dist > self.speed) { self.x += dx / dist * self.speed; self.y += dy / dist * self.speed; } else { // Hit target if (type === 'arrow') { self.target.takeDamage(self.damage, self.source); } self.destroy(); } }; return self; }); var ResetButton = Container.expand(function () { var self = Container.call(this); var buttonShape = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2("Reset Battle", { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.down = function (x, y, obj) { // Reset the battle resetBattle(); }; return self; }); var StartButton = Container.expand(function () { var self = Container.call(this); var buttonShape = self.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2("Start Battle!", { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.down = function (x, y, obj) { // Start the battle (mark battlefield as initialized) if (units.length > 0) { battlefield.initialized = true; self.visible = false; instructions.visible = false; LK.playMusic('battleMusic'); } }; return self; }); var Unit = Container.expand(function (team, type, x, y) { var self = Container.call(this); self.team = team; self.type = type; self.x = x; self.y = y; self.active = true; self.target = null; self.attackCooldown = 0; self.attackRange = 0; self.attackDamage = 0; self.moveSpeed = 0; self.health = 100; self.maxHealth = 100; self.special = ""; // Default properties based on unit type switch (type) { case 'wobbler': self.attackRange = 50; self.attackDamage = 15; self.moveSpeed = 1.5; self.attackCooldowsn = 40; break; case 'farmer': self.attackRange = 70; self.attackDamage = 25; // High first hit self.moveSpeed = 1.2; self.attackCooldown = 60; self.special = "extra damage on first hit"; break; case 'archer': self.attackRange = 400; self.attackDamage = 12; self.moveSpeed = 1.0; self.attackCooldown = 80; self.special = "ranged"; break; case 'shield': self.attackRange = 60; self.attackDamage = 8; self.moveSpeed = 0.8; self.health = 150; self.maxHealth = 150; self.attackCooldown = 50; self.special = "resistant to arrow"; break; case 'sword': self.attackRange = 80; self.attackDamage = 20; self.moveSpeed = 1.3; self.attackCooldown = 45; break; case 'wizard': self.attackRange = 300; self.attackDamage = 10; self.moveSpeed = 0.9; self.attackCooldown = 100; self.special = "splash damage"; break; case 'priest': self.attackRange = 0; self.attackDamage = 0; self.moveSpeed = 1.0; self.attackCooldown = 100; self.special = "heals allies"; break; case 'berserker': self.attackRange = 70; self.attackDamage = 20; self.moveSpeed = 1.5; self.attackCooldown = 50; self.special = "double damage at half health"; break; case 'spearman': self.attackRange = 100; self.attackDamage = 18; self.moveSpeed = 1.2; self.attackCooldown = 60; self.special = "chance to throw spear"; break; case 'mirrorShield': self.attackRange = 60; self.attackDamage = 5; self.moveSpeed = 0.8; self.health = 120; self.maxHealth = 120; self.attackCooldown = 50; self.special = "chance to reflect projectiles"; break; case 'king': self.attackRange = 80; self.attackDamage = 50; self.moveSpeed = 0.5; self.health = 300; self.maxHealth = 300; self.attackCooldown = 100; self.special = "massive damage and health"; break; case 'crossbowMan': self.attackRange = 400; self.attackDamage = 15; self.moveSpeed = 1.0; self.attackCooldown = 60; self.special = "fast firing, chance for critical damage"; break; } // Create unit appearance var unitShape = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5 }); // Add team color indicator on top var teamIndicator = self.attachAsset('character' + team.charAt(0).toUpperCase() + team.slice(1), { anchorX: 0.5, anchorY: 0.5, width: 20, height: 20 }); teamIndicator.y = -40; // Add health bar self.healthBarBg = self.attachAsset('healthBarBackground', { anchorX: 0.5, anchorY: 0.5 }); self.healthBarBg.y = 40; self.healthBarFill = self.attachAsset('healthBar', { anchorX: 0, // Left anchored for easy scaling anchorY: 0.5 }); self.healthBarFill.x = -35; // Half the width self.healthBarFill.y = 40; self.updateHealthBar = function () { var healthPercent = self.health / self.maxHealth; self.healthBarFill.scaleX = healthPercent; }; self.takeDamage = function (amount, attacker) { if (!self.active) { return; } // Shield units take less damage from archers if (self.type === 'shield' && attacker && attacker.type === 'archer') { amount = Math.floor(amount * 0.5); } // Wizards do extra damage to shields if (attacker && attacker.type === 'wizard' && self.type === 'shield') { amount = Math.floor(amount * 1.5); } self.health -= amount; self.updateHealthBar(); // Flash unit when hit LK.effects.flashObject(self, 0xff0000, 300); if (self.health <= 0) { self.die(); } }; self.die = function () { self.active = false; LK.getSound('death').play(); // Fade out and remove from battlefield tween(self, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { battlefield.removeUnit(self); self.destroy(); } }); }; self.findNearestEnemy = function () { var closestDist = Infinity; var closestEnemy = null; for (var i = 0; i < units.length; i++) { var unit = units[i]; if (unit.active && unit.team !== self.team) { var dist = getDistance(self.x, self.y, unit.x, unit.y); if (dist < closestDist) { closestDist = dist; closestEnemy = unit; } } } return closestEnemy; }; self.moveTowardsTarget = function () { if (!self.target || !self.target.active) { self.target = self.findNearestEnemy(); if (!self.target) { return; } } var dx = self.target.x - self.x; var dy = self.target.y - self.y; var dist = Math.sqrt(dx * dx + dy * dy); // If in attack range, stop moving if (dist <= self.attackRange) { return; } // Normalize direction and move var moveX = dx / dist * self.moveSpeed; var moveY = dy / dist * self.moveSpeed; self.x += moveX; self.y += moveY; }; self.attack = function () { if (!self.target || !self.target.active) { self.target = self.findNearestEnemy(); if (!self.target) { return; } } var dist = getDistance(self.x, self.y, self.target.x, self.target.y); if (dist <= self.attackRange) { // Reset attack cooldown self.attackCooldown = self.type === 'wobbler' ? 40 : self.type === 'farmer' ? 60 : self.type === 'archer' ? 80 : self.type === 'shield' ? 50 : self.type === 'sword' ? 45 : 100; // Handle special attacks if (self.special === "ranged") { // Create arrow projectile battlefield.createProjectile(self, self.target, 'arrow'); LK.getSound('arrow').play(); } else if (self.special === "aoe") { // Wizard AOE attack battlefield.createProjectile(self, self.target, 'spell'); LK.getSound('spell').play(); // Damage the target and nearby enemies var damage = self.attackDamage; for (var i = 0; i < units.length; i++) { var unit = units[i]; if (unit.active && unit.team !== self.team) { var aoeDistance = getDistance(self.target.x, self.target.y, unit.x, unit.y); if (aoeDistance < 150) { // Damage falls off with distance var aoeDamage = Math.floor(damage * (1 - aoeDistance / 150)); if (aoeDamage > 0) { unit.takeDamage(aoeDamage, self); } } } } } else { // Melee attack LK.getSound('attack').play(); var damage = self.attackDamage; // First strike bonus for farmers if (self.special === "firstStrike" && !self.hasAttacked) { damage *= 1.5; // 50% bonus on first hit self.hasAttacked = true; } self.target.takeDamage(damage, self); } } }; self.showStats = function () { var statsText = "Type: " + self.type.charAt(0).toUpperCase() + self.type.slice(1) + "\n" + "Health: " + self.health + "/" + self.maxHealth + "\n" + "Attack Damage: " + self.attackDamage + "\n" + "Attack Range: " + self.attackRange + "\n" + "Special: " + (self.special ? self.special : "None"); var statsDisplay = new Text2(statsText, { size: 30, fill: 0xFFFFFF }); statsDisplay.anchor.set(0.5, 0.5); statsDisplay.x = self.x; statsDisplay.y = self.y - 100; game.addChild(statsDisplay); // Remove stats display after 3 seconds LK.setTimeout(function () { if (statsDisplay.parent) { statsDisplay.destroy(); } }, 3000); }; self.down = function (x, y, obj) { if (self.lastTap && Date.now() - self.lastTap < 300) { self.showStats(); } self.lastTap = Date.now(); }; self.update = function () { if (!self.active) { return; } // Update health bar position to follow unit self.updateHealthBar(); // Decrease attack cooldown if (self.attackCooldown > 0) { self.attackCooldown--; } // Find and move towards target self.moveTowardsTarget(); // Attack if cooldown is ready if (self.attackCooldown === 0) { self.attack(); } }; return self; }); var UnitButton = Container.expand(function (team, type, x, y) { var self = Container.call(this); self.team = team; self.type = type; self.x = x; self.y = y; // Create button appearance var buttonShape = self.attachAsset('button' + team.charAt(0).toUpperCase() + team.slice(1), { anchorX: 0.5, anchorY: 0.5, width: 150, height: 80 }); // Add unit icon var unitIcon = self.attachAsset(type, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // Add unit name text var nameText = new Text2(type.charAt(0).toUpperCase() + type.slice(1), { size: 24, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0.5); nameText.y = 30; self.addChild(nameText); self.down = function (x, y, obj) { // When button is pressed, start dragging a new unit var unit = new Unit(self.team, self.type, x, y); // Mark as dragging unit draggingUnit = unit; game.addChild(unit); // Highlight button LK.effects.flashObject(self, 0xffffff, 300); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Pause button var pauseButton = new Container(); var pauseButtonShape = pauseButton.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 100, height: 50 }); var pauseButtonText = new Text2("Pause", { size: 24, fill: 0xFFFFFF }); pauseButtonText.anchor.set(0.5, 0.5); pauseButton.addChild(pauseButtonText); pauseButton.x = 2048 - 60; // Top right corner pauseButton.y = 60; pauseButton.down = function (x, y, obj) { LK.pauseGame(); }; game.addChild(pauseButton); var factions = { farm: ['wobbler', 'farmer'], medieval: ['sword', 'archer', 'crossbowMan', 'king'], magic: ['mirrorShield', 'wizard'], vikings: ['berserker'], rome: ['spearman'] }; // Game state variables var units = []; var draggingUnit = null; var battlefield = null; var resetButton = null; // Create the battlefield battlefield = new Battlefield(); battlefield.x = 0; battlefield.y = 0; game.addChild(battlefield); // Create faction buttons for red team var redFactionButtons = []; var factionNames = Object.keys(factions); var factionYOffset = 80; for (var i = 0; i < factionNames.length; i++) { var factionButton = new FactionButton('red', factionNames[i], 60, factionYOffset); redFactionButtons.push(factionButton); game.addChild(factionButton); factionYOffset += 100; } // Create faction buttons for blue team var blueFactionButtons = []; factionYOffset = 2732 - 80; for (var i = 0; i < factionNames.length; i++) { var factionButton = new FactionButton('blue', factionNames[i], 60, factionYOffset); blueFactionButtons.push(factionButton); game.addChild(factionButton); factionYOffset -= 100; } // Start button var startButton = new StartButton(); startButton.x = 2048 / 2; startButton.y = 2732 / 2; game.addChild(startButton); // Win text var winText = new Text2("", { size: 80, fill: 0xFFFF00 }); winText.anchor.set(0.5, 0.5); winText.x = 2048 / 2; winText.y = 2732 / 2 - 100; winText.visible = false; game.addChild(winText); // Instructions text var instructions = new Text2("Place units on the battlefield\nand press Start Battle!", { size: 40, fill: 0xFFFFFF }); instructions.anchor.set(0.5, 0.5); instructions.x = 2048 / 2; instructions.y = 2732 / 2 - 100; game.addChild(instructions); // Helper function to calculate distance between two points function getDistance(x1, y1, x2, y2) { var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt(dx * dx + dy * dy); } // Reset the battle function resetBattle() { // Remove all units for (var i = units.length - 1; i >= 0; i--) { if (units[i].parent) { units[i].destroy(); } } units = []; // Clear projectiles for (var i = battlefield.projectiles.length - 1; i >= 0; i--) { if (battlefield.projectiles[i].parent) { battlefield.projectiles[i].destroy(); } } battlefield.projectiles = []; // Reset battlefield state battlefield.initialized = false; // Show start button and instructions again startButton.visible = true; instructions.visible = true; // Hide win text and reset button winText.visible = false; if (resetButton && resetButton.parent) { resetButton.destroy(); resetButton = null; } // Stop music LK.stopMusic(); } // Handle dragging game.move = function (x, y, obj) { if (draggingUnit) { draggingUnit.x = x; draggingUnit.y = y; } }; game.up = function (x, y, obj) { if (draggingUnit) { // Check if unit is placed on the battlefield (not on buttons) var validPlacement = y > 150 && y < 2732 - 150; if (validPlacement) { // Add to units array units.push(draggingUnit); } else { // Not valid placement, destroy the unit draggingUnit.destroy(); } draggingUnit = null; } }; // Game update loop game.update = function () { // Update all units if battle has started if (battlefield.initialized) { for (var i = 0; i < units.length; i++) { if (units[i].active) { units[i].update(); } } } // Update projectiles battlefield.update(); };
===================================================================
--- original.js
+++ change.js
@@ -525,9 +525,28 @@
/****
* Game Code
****/
-// Define factions and their respective units
+// Pause button
+var pauseButton = new Container();
+var pauseButtonShape = pauseButton.attachAsset('button', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 100,
+ height: 50
+});
+var pauseButtonText = new Text2("Pause", {
+ size: 24,
+ fill: 0xFFFFFF
+});
+pauseButtonText.anchor.set(0.5, 0.5);
+pauseButton.addChild(pauseButtonText);
+pauseButton.x = 2048 - 60; // Top right corner
+pauseButton.y = 60;
+pauseButton.down = function (x, y, obj) {
+ LK.pauseGame();
+};
+game.addChild(pauseButton);
var factions = {
farm: ['wobbler', 'farmer'],
medieval: ['sword', 'archer', 'crossbowMan', 'king'],
magic: ['mirrorShield', 'wizard'],
victory
Sound effect
battleMusic
Music
death
Sound effect
arrow
Sound effect
spell
Sound effect
attack
Sound effect
Explosion
Sound effect
Destroyed
Sound effect
Kiss
Sound effect
Gnehehe
Sound effect
Defend
Sound effect
Girldeath
Sound effect
Shoot
Sound effect
RAWR
Sound effect
Malfunction
Sound effect
Blaster
Sound effect
Holy
Sound effect