User prompt
War machines now shoot missiles that are like bombs but they deal more damage
User prompt
Cannon now uses the "Destroyed" sound when killer
User prompt
War machines arent shooting missiles, fix that
User prompt
Cannons are also war machines, just that they have weaker stats
User prompt
Make it so that the War machine can now shoot missiles that are just stronger bombs
User prompt
Add the Roman javelin thrower in the rome faction because i cant fino it
User prompt
Add new units: Cannon: a war machine-type unit that shoots bombs taht have a big explosion radius, is pretty fragile (Type: ranged war machine, Faction: medieval); Roman javellneer: throws a javelin that can pierce through 3 enemies! (Type: Ranged, Faction: rome); Queen: her kisees have a 10% chance to seduce enemies, making them switch sides (War machine type units and kings excluded.) (Unit type: ranged, Faction: medieval)
User prompt
The war machine is immune to all negative effects exept all forms of damage
User prompt
Have so that the war machine has the same health as kings
User prompt
War machines arent dying! Make them have the same HP as Kingston
User prompt
Make all types of war machine units (war machine and later units who are called like this) immune to Retarius's stun and future debuffs/abilities that arent area damage
User prompt
Tanks (war machines) are still debuffed and are using the "death" sound instead of the "Destroyed" sound when dead
User prompt
Tanks now are War machines, they are the same as regular troops, but immune to negative effects and die using the "Destroyed" sound instead of the "die" sound
User prompt
Now, all area damage units (exept wizard) use the "Explosion" sound
User prompt
I said only WIZARDS, not all area damage units
User prompt
Now wizards, when they attack, use the "spell" sound
User prompt
Axe thrower and tank have 500 attack range
User prompt
Add new projectile "Missile" that deals High area damage (exclusive to Tank)
User prompt
Add new projectile "Throwable axe" that acts like a boomerang (special to axe thrower)
User prompt
Allies of the apple thrower are attacking Apple thrower, fix that
User prompt
Apple thrower aims at allies instead of enemies
User prompt
Apple thrower unit isnt in the game at all, fix that
User prompt
Add new units: Apple thrower: throws apples at allies to heal them (unit type: ranged, faction: farm); Tank: tanky unit that shoots big bullets that deal area damage (unit type: ranged, faction: modern era); Axe thrower: throws its axe like a boomerang (unit type: ranged, faction: vikings).
User prompt
Cannot set properties of undefined (setting 'extend')
User prompt
Cannot set properties of undefined (setting 'extend')
/**** * 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], 2048 - 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') { if (self.target.type === 'mirrorShield' && Math.random() < 0.5) { // 50% chance to reflect // Reflect the projectile back to the source self.target = self.source; self.source = null; // No longer has a source } else { 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 '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; case 'sniper': self.attackRange = Infinity; self.attackDamage = 20; self.moveSpeed = 1.0; self.attackCooldown = 100; self.special = "ranged"; break; case 'hammer': self.attackRange = 50; self.attackDamage = 30; self.moveSpeed = 1.0; self.attackCooldown = 70; self.special = "aoe"; break; case 'retarius': self.attackRange = 100; self.attackDamage = 18; self.moveSpeed = 1.2; self.attackCooldown = 60; self.special = "stun every 3 attacks"; break; case 'appleThrower': self.attackRange = 300; self.attackDamage = -10; // Negative damage for healing self.moveSpeed = 1.0; self.attackCooldown = 100; self.special = "heals allies"; break; case 'tank': self.attackRange = 200; self.attackDamage = 30; self.moveSpeed = 0.5; self.attackCooldown = 120; self.special = "area damage"; break; case 'axeThrower': self.attackRange = 150; self.attackDamage = 20; self.moveSpeed = 1.0; self.attackCooldown = 80; self.special = "boomerang attack"; 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) { if (self.type === 'spearman' && Math.random() < 0.3) { // 30% chance to throw spear self.target = self.findNearestEnemy(); if (self.target) { battlefield.createProjectile(self, self.target, 'spear'); self.attackCooldown = 60; // Reset cooldown after throwing spear return; } } 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 () { // Track number of attacks for Retarius if (self.type === 'retarius') { if (!self.attackCount) { self.attackCount = 0; } self.attackCount++; // Stun effect every 3 attacks if (self.attackCount % 3 === 0 && self.target) { self.target.stunned = true; LK.setTimeout(function () { if (self.target) { self.target.stunned = false; } }, 2000); // Stun duration of 2 seconds } } 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; // Double damage if Berserker is enraged (health is at or below half) if (self.type === 'berserker' && self.health <= self.maxHealth / 2) { damage *= 2; self.moveSpeed = 2.0; // Increase move speed when enraged } // Implement critical hit chance for Crossbowman if (self.type === 'crossbowMan' && Math.random() < 0.2) { // 20% chance for critical hit damage *= 2; // Double damage for critical hit } // 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 || self.stunned) { 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 ****/ // Define factions and their respective units function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) { return t; } var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) { return i; } throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } var factions = _defineProperty(_defineProperty({ farm: ['wobbler', 'farmer'], medieval: ['sword', 'archer', 'crossbowMan', 'king', 'shield'], magic: ['mirrorShield', 'wizard'], vikings: ['berserker'], rome: ['spearman', 'retarius'] }, "vikings", ['berserker', 'hammer', 'axeThrower']), "modern", ['sniper', 'tank'], "farm", ['wobbler', 'farmer', 'appleThrower']); // 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], 2048 - 300, factionYOffset); factionButton.x = 2048 - 300; // Adjusted position even further to the left factionButton.y = 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
@@ -187,780 +187,424 @@
}
};
return self;
});
-var UnitButton = Container.expand(function (team, type, x, y) {
+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;
- // 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
-****/
-// Define factions and their respective units
-var Unit = function Unit(team, type, x, y) {
- this.team = team;
- this.type = type;
- this.x = x;
- this.y = y;
- this.active = true;
- this.target = null;
- this.attackCooldown = 0;
- this.attackRange = 0;
- this.attackDamage = 0;
- this.moveSpeed = 0;
- this.health = 100;
- this.maxHealth = 100;
- this.special = "";
+ 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':
- this.attackRange = 50;
- this.attackDamage = 15;
- this.moveSpeed = 1.5;
- this.attackCooldown = 40;
+ self.attackRange = 50;
+ self.attackDamage = 15;
+ self.moveSpeed = 1.5;
+ self.attackCooldowsn = 40;
break;
case 'farmer':
- this.attackRange = 70;
- this.attackDamage = 25; // High first hit
- this.moveSpeed = 1.2;
- this.attackCooldown = 60;
- this.special = "extra damage on first hit";
+ 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':
- this.attackRange = 400;
- this.attackDamage = 12;
- this.moveSpeed = 1.0;
- this.attackCooldown = 80;
- this.special = "ranged";
+ self.attackRange = 400;
+ self.attackDamage = 12;
+ self.moveSpeed = 1.0;
+ self.attackCooldown = 80;
+ self.special = "ranged";
break;
case 'shield':
- this.attackRange = 60;
- this.attackDamage = 8;
- this.moveSpeed = 0.8;
- this.health = 150;
- this.maxHealth = 150;
- this.attackCooldown = 50;
- this.special = "resistant to arrow";
+ 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':
- this.attackRange = 80;
- this.attackDamage = 20;
- this.moveSpeed = 1.3;
- this.attackCooldown = 45;
+ self.attackRange = 80;
+ self.attackDamage = 20;
+ self.moveSpeed = 1.3;
+ self.attackCooldown = 45;
break;
case 'wizard':
- this.attackRange = 300;
- this.attackDamage = 10;
- this.moveSpeed = 0.9;
- this.attackCooldown = 100;
- this.special = "splash damage";
+ self.attackRange = 300;
+ self.attackDamage = 10;
+ self.moveSpeed = 0.9;
+ self.attackCooldown = 100;
+ self.special = "splash damage";
break;
case 'berserker':
- this.attackRange = 70;
- this.attackDamage = 20;
- this.moveSpeed = 1.5;
- this.attackCooldown = 50;
- this.special = "double damage at half health";
+ self.attackRange = 70;
+ self.attackDamage = 20;
+ self.moveSpeed = 1.5;
+ self.attackCooldown = 50;
+ self.special = "double damage at half health";
break;
case 'spearman':
- this.attackRange = 100;
- this.attackDamage = 18;
- this.moveSpeed = 1.2;
- this.attackCooldown = 60;
- this.special = "chance to throw spear";
+ self.attackRange = 100;
+ self.attackDamage = 18;
+ self.moveSpeed = 1.2;
+ self.attackCooldown = 60;
+ self.special = "chance to throw spear";
break;
case 'mirrorShield':
- this.attackRange = 60;
- this.attackDamage = 5;
- this.moveSpeed = 0.8;
- this.health = 120;
- this.maxHealth = 120;
- this.attackCooldown = 50;
- this.special = "chance to reflect projectiles";
+ 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':
- this.attackRange = 80;
- this.attackDamage = 50;
- this.moveSpeed = 0.5;
- this.health = 300;
- this.maxHealth = 300;
- this.attackCooldown = 100;
- this.special = "massive damage and health";
+ 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':
- this.attackRange = 400;
- this.attackDamage = 15;
- this.moveSpeed = 1.0;
- this.attackCooldown = 60;
- this.special = "fast firing, chance for critical damage";
+ self.attackRange = 400;
+ self.attackDamage = 15;
+ self.moveSpeed = 1.0;
+ self.attackCooldown = 60;
+ self.special = "fast firing, chance for critical damage";
break;
case 'sniper':
- this.attackRange = Infinity;
- this.attackDamage = 20;
- this.moveSpeed = 1.0;
- this.attackCooldown = 100;
- this.special = "ranged";
+ self.attackRange = Infinity;
+ self.attackDamage = 20;
+ self.moveSpeed = 1.0;
+ self.attackCooldown = 100;
+ self.special = "ranged";
break;
case 'hammer':
- this.attackRange = 50;
- this.attackDamage = 30;
- this.moveSpeed = 1.0;
- this.attackCooldown = 70;
- this.special = "aoe";
+ self.attackRange = 50;
+ self.attackDamage = 30;
+ self.moveSpeed = 1.0;
+ self.attackCooldown = 70;
+ self.special = "aoe";
break;
case 'retarius':
- this.attackRange = 100;
- this.attackDamage = 18;
- this.moveSpeed = 1.2;
- this.attackCooldown = 60;
- this.special = "stun every 3 attacks";
+ self.attackRange = 100;
+ self.attackDamage = 18;
+ self.moveSpeed = 1.2;
+ self.attackCooldown = 60;
+ self.special = "stun every 3 attacks";
break;
+ case 'appleThrower':
+ self.attackRange = 300;
+ self.attackDamage = -10; // Negative damage for healing
+ self.moveSpeed = 1.0;
+ self.attackCooldown = 100;
+ self.special = "heals allies";
+ break;
+ case 'tank':
+ self.attackRange = 200;
+ self.attackDamage = 30;
+ self.moveSpeed = 0.5;
+ self.attackCooldown = 120;
+ self.special = "area damage";
+ break;
+ case 'axeThrower':
+ self.attackRange = 150;
+ self.attackDamage = 20;
+ self.moveSpeed = 1.0;
+ self.attackCooldown = 80;
+ self.special = "boomerang attack";
+ break;
}
// Create unit appearance
- var unitShape = this.attachAsset(type, {
+ var unitShape = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
// Add team color indicator on top
- var teamIndicator = this.attachAsset('character' + team.charAt(0).toUpperCase() + team.slice(1), {
+ 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
- this.healthBarBg = this.attachAsset('healthBarBackground', {
+ self.healthBarBg = self.attachAsset('healthBarBackground', {
anchorX: 0.5,
anchorY: 0.5
});
- this.healthBarBg.y = 40;
- this.healthBarFill = this.attachAsset('healthBar', {
+ self.healthBarBg.y = 40;
+ self.healthBarFill = self.attachAsset('healthBar', {
anchorX: 0,
// Left anchored for easy scaling
anchorY: 0.5
});
- this.healthBarFill.x = -35; // Half the width
- this.healthBarFill.y = 40;
-};
-Unit.extend = function (constructorFunction) {
- var self = this;
- function ExtendedUnit() {
- self.apply(this, arguments);
- constructorFunction.apply(this, arguments);
- }
- ExtendedUnit.prototype = Object.create(self.prototype);
- ExtendedUnit.prototype.constructor = ExtendedUnit;
- return ExtendedUnit;
-};
-Unit.extend = function (constructorFunction) {
- var self = this;
- function ExtendedUnit() {
- self.apply(this, arguments);
- constructorFunction.apply(this, arguments);
- }
- ExtendedUnit.prototype = Object.create(self.prototype);
- ExtendedUnit.prototype.constructor = ExtendedUnit;
- return ExtendedUnit;
-};
-function _typeof2(o) {
- "@babel/helpers - typeof";
- return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
- return typeof o;
- } : function (o) {
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
- }, _typeof2(o);
-}
-function _classCallCheck(a, n) {
- if (!(a instanceof n)) {
- throw new TypeError("Cannot call a class as a function");
- }
-}
-function _defineProperties(e, r) {
- for (var t = 0; t < r.length; t++) {
- var o = r[t];
- o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey2(o.key), o);
- }
-}
-function _createClass(e, r, t) {
- return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", {
- writable: !1
- }), e;
-}
-function _toPropertyKey2(t) {
- var i = _toPrimitive2(t, "string");
- return "symbol" == _typeof2(i) ? i : i + "";
-}
-function _toPrimitive2(t, r) {
- if ("object" != _typeof2(t) || !t) {
- return t;
- }
- var e = t[Symbol.toPrimitive];
- if (void 0 !== e) {
- var i = e.call(t, r || "default");
- if ("object" != _typeof2(i)) {
- return i;
+ 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;
}
- throw new TypeError("@@toPrimitive must return a primitive value.");
- }
- return ("string" === r ? String : Number)(t);
-}
-function _callSuper(t, o, e) {
- return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e));
-}
-function _possibleConstructorReturn(t, e) {
- if (e && ("object" == _typeof2(e) || "function" == typeof e)) {
- return e;
- }
- if (void 0 !== e) {
- throw new TypeError("Derived constructors may only return object or undefined");
- }
- return _assertThisInitialized(t);
-}
-function _assertThisInitialized(e) {
- if (void 0 === e) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
- return e;
-}
-function _isNativeReflectConstruct() {
- try {
- var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
- } catch (t) {}
- return (_isNativeReflectConstruct = function _isNativeReflectConstruct() {
- return !!t;
- })();
-}
-function _getPrototypeOf(t) {
- return _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function (t) {
- return t.__proto__ || Object.getPrototypeOf(t);
- }, _getPrototypeOf(t);
-}
-function _inherits(t, e) {
- if ("function" != typeof e && null !== e) {
- throw new TypeError("Super expression must either be null or a function");
- }
- t.prototype = Object.create(e && e.prototype, {
- constructor: {
- value: t,
- writable: !0,
- configurable: !0
+ // Shield units take less damage from archers
+ if (self.type === 'shield' && attacker && attacker.type === 'archer') {
+ amount = Math.floor(amount * 0.5);
}
- }), Object.defineProperty(t, "prototype", {
- writable: !1
- }), e && _setPrototypeOf(t, e);
-}
-function _setPrototypeOf(t, e) {
- return _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
- return t.__proto__ = e, t;
- }, _setPrototypeOf(t, e);
-}
-Unit.extend = function (constructorFunction) {
- var self = this;
- function ExtendedUnit() {
- self.apply(this, arguments);
- constructorFunction.apply(this, arguments);
- }
- ExtendedUnit.prototype = Object.create(self.prototype);
- ExtendedUnit.prototype.constructor = ExtendedUnit;
- return ExtendedUnit;
-};
-var Unit = /*#__PURE__*/function (_Container) {
- function Unit(team, type, x, y) {
- var _this;
- _classCallCheck(this, Unit);
- _this = _callSuper(this, Unit);
- _this.team = team;
- _this.type = type;
- _this.x = x;
- _this.y = y;
- _this.active = true;
- _this.target = null;
- _this.attackCooldown = 0;
- _this.attackRange = 0;
- _this.attackDamage = 0;
- _this.moveSpeed = 0;
- _this.health = 100;
- _this.maxHealth = 100;
- _this.special = "";
- // Default properties based on unit type
- switch (type) {
- case 'wobbler':
- _this.attackRange = 50;
- _this.attackDamage = 15;
- _this.moveSpeed = 1.5;
- _this.attackCooldown = 40;
- break;
- case 'farmer':
- _this.attackRange = 70;
- _this.attackDamage = 25; // High first hit
- _this.moveSpeed = 1.2;
- _this.attackCooldown = 60;
- _this.special = "extra damage on first hit";
- break;
- case 'archer':
- _this.attackRange = 400;
- _this.attackDamage = 12;
- _this.moveSpeed = 1.0;
- _this.attackCooldown = 80;
- _this.special = "ranged";
- break;
- case 'shield':
- _this.attackRange = 60;
- _this.attackDamage = 8;
- _this.moveSpeed = 0.8;
- _this.health = 150;
- _this.maxHealth = 150;
- _this.attackCooldown = 50;
- _this.special = "resistant to arrow";
- break;
- case 'sword':
- _this.attackRange = 80;
- _this.attackDamage = 20;
- _this.moveSpeed = 1.3;
- _this.attackCooldown = 45;
- break;
- case 'wizard':
- _this.attackRange = 300;
- _this.attackDamage = 10;
- _this.moveSpeed = 0.9;
- _this.attackCooldown = 100;
- _this.special = "splash damage";
- break;
- case 'berserker':
- _this.attackRange = 70;
- _this.attackDamage = 20;
- _this.moveSpeed = 1.5;
- _this.attackCooldown = 50;
- _this.special = "double damage at half health";
- break;
- case 'spearman':
- _this.attackRange = 100;
- _this.attackDamage = 18;
- _this.moveSpeed = 1.2;
- _this.attackCooldown = 60;
- _this.special = "chance to throw spear";
- break;
- case 'mirrorShield':
- _this.attackRange = 60;
- _this.attackDamage = 5;
- _this.moveSpeed = 0.8;
- _this.health = 120;
- _this.maxHealth = 120;
- _this.attackCooldown = 50;
- _this.special = "chance to reflect projectiles";
- break;
- case 'king':
- _this.attackRange = 80;
- _this.attackDamage = 50;
- _this.moveSpeed = 0.5;
- _this.health = 300;
- _this.maxHealth = 300;
- _this.attackCooldown = 100;
- _this.special = "massive damage and health";
- break;
- case 'crossbowMan':
- _this.attackRange = 400;
- _this.attackDamage = 15;
- _this.moveSpeed = 1.0;
- _this.attackCooldown = 60;
- _this.special = "fast firing, chance for critical damage";
- break;
- case 'sniper':
- _this.attackRange = Infinity;
- _this.attackDamage = 20;
- _this.moveSpeed = 1.0;
- _this.attackCooldown = 100;
- _this.special = "ranged";
- break;
- case 'hammer':
- _this.attackRange = 50;
- _this.attackDamage = 30;
- _this.moveSpeed = 1.0;
- _this.attackCooldown = 70;
- _this.special = "aoe";
- break;
- case 'retarius':
- _this.attackRange = 100;
- _this.attackDamage = 18;
- _this.moveSpeed = 1.2;
- _this.attackCooldown = 60;
- _this.special = "stun every 3 attacks";
- break;
+ // Wizards do extra damage to shields
+ if (attacker && attacker.type === 'wizard' && self.type === 'shield') {
+ amount = Math.floor(amount * 1.5);
}
- // Create unit appearance
- var unitShape = _this.attachAsset(type, {
- anchorX: 0.5,
- anchorY: 0.5
- });
- // Add team color indicator on top
- var teamIndicator = _this.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
- _this.healthBarBg = _this.attachAsset('healthBarBackground', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- _this.healthBarBg.y = 40;
- _this.healthBarFill = _this.attachAsset('healthBar', {
- anchorX: 0,
- // Left anchored for easy scaling
- anchorY: 0.5
- });
- _this.healthBarFill.x = -35; // Half the width
- _this.healthBarFill.y = 40;
- return _this;
- }
- _inherits(Unit, _Container);
- return _createClass(Unit, [{
- key: "updateHealthBar",
- value: function updateHealthBar() {
- var healthPercent = this.health / this.maxHealth;
- this.healthBarFill.scaleX = healthPercent;
+ self.health -= amount;
+ self.updateHealthBar();
+ // Flash unit when hit
+ LK.effects.flashObject(self, 0xff0000, 300);
+ if (self.health <= 0) {
+ self.die();
}
- }, {
- key: "takeDamage",
- value: function takeDamage(amount, attacker) {
- if (!this.active) {
- return;
+ };
+ 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();
}
- // Shield units take less damage from archers
- if (this.type === 'shield' && attacker && attacker.type === 'archer') {
- amount = Math.floor(amount * 0.5);
- }
- // Wizards do extra damage to shields
- if (attacker && attacker.type === 'wizard' && this.type === 'shield') {
- amount = Math.floor(amount * 1.5);
- }
- this.health -= amount;
- this.updateHealthBar();
- // Flash unit when hit
- LK.effects.flashObject(this, 0xff0000, 300);
- if (this.health <= 0) {
- this.die();
- }
- }
- }, {
- key: "die",
- value: function die() {
- var _this2 = this;
- this.active = false;
- LK.getSound('death').play();
- // Fade out and remove from battlefield
- tween(this, {
- alpha: 0
- }, {
- duration: 500,
- onFinish: function onFinish() {
- battlefield.removeUnit(_this2);
- _this2.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;
}
- });
- }
- }, {
- key: "findNearestEnemy",
- value: function findNearestEnemy() {
- var closestDist = Infinity;
- var closestEnemy = null;
- for (var i = 0; i < units.length; i++) {
- var unit = units[i];
- if (unit.active && unit.team !== this.team) {
- var dist = getDistance(this.x, this.y, unit.x, unit.y);
- if (dist < closestDist) {
- closestDist = dist;
- closestEnemy = unit;
- }
- }
}
- return closestEnemy;
}
- }, {
- key: "moveTowardsTarget",
- value: function moveTowardsTarget() {
- if (!this.target || !this.target.active) {
- if (this.type === 'spearman' && Math.random() < 0.3) {
- // 30% chance to throw spear
- this.target = this.findNearestEnemy();
- if (this.target) {
- battlefield.createProjectile(this, this.target, 'spear');
- this.attackCooldown = 60; // Reset cooldown after throwing spear
- return;
- }
- }
- this.target = this.findNearestEnemy();
- if (!this.target) {
+ return closestEnemy;
+ };
+ self.moveTowardsTarget = function () {
+ if (!self.target || !self.target.active) {
+ if (self.type === 'spearman' && Math.random() < 0.3) {
+ // 30% chance to throw spear
+ self.target = self.findNearestEnemy();
+ if (self.target) {
+ battlefield.createProjectile(self, self.target, 'spear');
+ self.attackCooldown = 60; // Reset cooldown after throwing spear
return;
}
}
- var dx = this.target.x - this.x;
- var dy = this.target.y - this.y;
- var dist = Math.sqrt(dx * dx + dy * dy);
- // If in attack range, stop moving
- if (dist <= this.attackRange) {
+ self.target = self.findNearestEnemy();
+ if (!self.target) {
return;
}
- // Normalize direction and move
- var moveX = dx / dist * this.moveSpeed;
- var moveY = dy / dist * this.moveSpeed;
- this.x += moveX;
- this.y += moveY;
}
- }, {
- key: "attack",
- value: function attack() {
- var _this3 = this;
- // Track number of attacks for Retarius
- if (this.type === 'retarius') {
- if (!this.attackCount) {
- this.attackCount = 0;
- }
- this.attackCount++;
- // Stun effect every 3 attacks
- if (this.attackCount % 3 === 0 && this.target) {
- this.target.stunned = true;
- LK.setTimeout(function () {
- if (_this3.target) {
- _this3.target.stunned = false;
- }
- }, 2000); // Stun duration of 2 seconds
- }
+ 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 () {
+ // Track number of attacks for Retarius
+ if (self.type === 'retarius') {
+ if (!self.attackCount) {
+ self.attackCount = 0;
}
- if (!this.target || !this.target.active) {
- this.target = this.findNearestEnemy();
- if (!this.target) {
- return;
- }
+ self.attackCount++;
+ // Stun effect every 3 attacks
+ if (self.attackCount % 3 === 0 && self.target) {
+ self.target.stunned = true;
+ LK.setTimeout(function () {
+ if (self.target) {
+ self.target.stunned = false;
+ }
+ }, 2000); // Stun duration of 2 seconds
}
- var dist = getDistance(this.x, this.y, this.target.x, this.target.y);
- if (dist <= this.attackRange) {
- // Reset attack cooldown
- this.attackCooldown = this.type === 'wobbler' ? 40 : this.type === 'farmer' ? 60 : this.type === 'archer' ? 80 : this.type === 'shield' ? 50 : this.type === 'sword' ? 45 : 100;
- // Handle special attacks
- if (this.special === "ranged") {
- // Create arrow projectile
- battlefield.createProjectile(this, this.target, 'arrow');
- LK.getSound('arrow').play();
- } else if (this.special === "aoe") {
- // Wizard AOE attack
- battlefield.createProjectile(this, this.target, 'spell');
- LK.getSound('spell').play();
- // Damage the target and nearby enemies
- var damage = this.attackDamage;
- for (var i = 0; i < units.length; i++) {
- var unit = units[i];
- if (unit.active && unit.team !== this.team) {
- var aoeDistance = getDistance(this.target.x, this.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, this);
- }
+ }
+ 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 = this.attackDamage;
- // Double damage if Berserker is enraged (health is at or below half)
- if (this.type === 'berserker' && this.health <= this.maxHealth / 2) {
- damage *= 2;
- this.moveSpeed = 2.0; // Increase move speed when enraged
- }
- // Implement critical hit chance for Crossbowman
- if (this.type === 'crossbowMan' && Math.random() < 0.2) {
- // 20% chance for critical hit
- damage *= 2; // Double damage for critical hit
- }
- // First strike bonus for farmers
- if (this.special === "firstStrike" && !this.hasAttacked) {
- damage *= 1.5; // 50% bonus on first hit
- this.hasAttacked = true;
- }
- this.target.takeDamage(damage, this);
}
- }
- }
- }, {
- key: "showStats",
- value: function showStats() {
- var statsText = "Type: " + this.type.charAt(0).toUpperCase() + this.type.slice(1) + "\n" + "Health: " + this.health + "/" + this.maxHealth + "\n" + "Attack Damage: " + this.attackDamage + "\n" + "Attack Range: " + this.attackRange + "\n" + "Special: " + (this.special ? this.special : "None");
- var statsDisplay = new Text2(statsText, {
- size: 30,
- fill: 0xFFFFFF
- });
- statsDisplay.anchor.set(0.5, 0.5);
- statsDisplay.x = this.x;
- statsDisplay.y = this.y - 100;
- game.addChild(statsDisplay);
- // Remove stats display after 3 seconds
- LK.setTimeout(function () {
- if (statsDisplay.parent) {
- statsDisplay.destroy();
+ } else {
+ // Melee attack
+ LK.getSound('attack').play();
+ var damage = self.attackDamage;
+ // Double damage if Berserker is enraged (health is at or below half)
+ if (self.type === 'berserker' && self.health <= self.maxHealth / 2) {
+ damage *= 2;
+ self.moveSpeed = 2.0; // Increase move speed when enraged
}
- }, 3000);
- }
- }, {
- key: "down",
- value: function down(x, y, obj) {
- if (this.lastTap && Date.now() - this.lastTap < 300) {
- this.showStats();
+ // Implement critical hit chance for Crossbowman
+ if (self.type === 'crossbowMan' && Math.random() < 0.2) {
+ // 20% chance for critical hit
+ damage *= 2; // Double damage for critical hit
+ }
+ // 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);
}
- this.lastTap = Date.now();
}
- }, {
- key: "update",
- value: function update() {
- if (!this.active || this.stunned) {
- return;
+ };
+ 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();
}
- // Update health bar position to follow unit
- this.updateHealthBar();
- // Decrease attack cooldown
- if (this.attackCooldown > 0) {
- this.attackCooldown--;
- }
- // Find and move towards target
- this.moveTowardsTarget();
- // Attack if cooldown is ready
- if (this.attackCooldown === 0) {
- this.attack();
- }
- }
- }]);
-}(Container);
-var GatlingGun = Unit.extend(function (team, x, y) {
- var self = Unit.call(this, team, 'gatlingGun', x, y);
- self.attackRange = 300;
- self.attackDamage = 5;
- self.moveSpeed = 0.5;
- self.special = "fast but inaccurate shooting";
- self.update = function () {
- if (!self.active || self.stunned) {
- return;
- }
- self.updateHealthBar();
- self.moveTowardsTarget();
- if (self.attackCooldown === 0 && self.target && getDistance(self.x, self.y, self.target.x, self.target.y) <= self.attackRange) {
- self.shootRapidly();
- }
+ }, 3000);
};
- self.shootRapidly = function () {
- for (var i = 0; i < 3; i++) {
- var randomOffset = Math.random() * 20 - 10; // Random offset for inaccuracy
- var targetX = self.target.x + randomOffset;
- var targetY = self.target.y + randomOffset;
- battlefield.createProjectile(self, {
- x: targetX,
- y: targetY
- }, 'bullet');
+ self.down = function (x, y, obj) {
+ if (self.lastTap && Date.now() - self.lastTap < 300) {
+ self.showStats();
}
- self.attackCooldown = 20;
+ self.lastTap = Date.now();
};
- return self;
-});
-var Wheelbarrow = Unit.extend(function (team, x, y) {
- var self = Unit.call(this, team, 'wheelbarrow', x, y);
- self.attackRange = 200;
- self.attackDamage = 10;
- self.moveSpeed = 2.5;
- self.special = "fast movement, shoots apples";
self.update = function () {
if (!self.active || self.stunned) {
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();
- if (self.attackCooldown === 0 && self.target && getDistance(self.x, self.y, self.target.x, self.target.y) <= self.attackRange) {
- self.shootApple();
+ // Attack if cooldown is ready
+ if (self.attackCooldown === 0) {
+ self.attack();
}
};
- self.shootApple = function () {
- battlefield.createProjectile(self, self.target, 'apple');
- self.attackCooldown = 30;
- };
return self;
});
-var Bomber = Unit.extend(function (team, x, y) {
- var self = Unit.call(this, team, 'bomber', x, y);
- self.attackRange = 50;
- self.attackDamage = 50;
- self.moveSpeed = 1.0;
- self.special = "self-destruct on contact";
- self.update = function () {
- if (!self.active || self.stunned) {
- return;
- }
- self.updateHealthBar();
- self.moveTowardsTarget();
- if (self.target && getDistance(self.x, self.y, self.target.x, self.target.y) <= self.attackRange) {
- self.selfDestruct();
- }
+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);
};
- self.selfDestruct = function () {
- // Damage all nearby enemies
- 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 < 100) {
- unit.takeDamage(self.attackDamage, self);
- }
- }
- }
- self.die();
- };
return self;
});
+
+/****
+* Initialize Game
+****/
+var game = new LK.Game({
+ backgroundColor: 0x87CEEB
+});
+
+/****
+* Game Code
+****/
+// Define factions and their respective units
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
return typeof o;
@@ -994,14 +638,14 @@
}
return ("string" === r ? String : Number)(t);
}
var factions = _defineProperty(_defineProperty({
- farm: ['wobbler', 'farmer', 'wheelbarrow'],
+ farm: ['wobbler', 'farmer'],
medieval: ['sword', 'archer', 'crossbowMan', 'king', 'shield'],
- magic: ['mirrorShield', 'wizard', 'bomber'],
+ magic: ['mirrorShield', 'wizard'],
vikings: ['berserker'],
rome: ['spearman', 'retarius']
-}, "vikings", ['berserker', 'hammer']), "modern", ['sniper', 'gatlingGun']);
+}, "vikings", ['berserker', 'hammer', 'axeThrower']), "modern", ['sniper', 'tank'], "farm", ['wobbler', 'farmer', 'appleThrower']);
// Game state variables
var units = [];
var draggingUnit = null;
var battlefield = null;
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