/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
bestScore: 0
});
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var Base = Container.expand(function () {
var self = Container.call(this);
self.graphics = self.attachAsset('base', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.isPlayerBase = true;
// Health bar background
self.healthBarBg = self.attachAsset('unit', {
width: 300,
height: 20,
color: 0x000000,
anchorX: 0.5,
anchorY: 0.5,
y: -180
});
// Health bar foreground
self.healthBar = self.attachAsset('unit', {
width: 300,
height: 20,
color: 0x00ff00,
anchorX: 0,
anchorY: 0.5,
y: -180,
x: -150
});
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health < 0) {
self.health = 0;
}
// Update health bar width
self.healthBar.width = self.health / 100 * 300;
if (self.health <= 0 && self.isPlayerBase) {
LK.showGameOver();
} else if (self.health <= 0 && !self.isPlayerBase) {
// Player wins
LK.setScore(LK.getScore() + 1000);
LK.showYouWin();
}
};
return self;
});
var EnemyBase = Base.expand(function () {
var self = Base.call(this);
// Override base graphics with enemy base
self.graphics.destroy();
self.graphics = self.attachAsset('enemyBase', {
anchorX: 0.5,
anchorY: 0.5
});
self.healthBar.tint = 0xff0000;
self.isPlayerBase = false;
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.graphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.alive = true;
self.targetUnit = null;
self.lastPosition = {
x: 0,
y: 0
};
self.update = function () {
if (!self.alive) {
return;
}
self.lastPosition.x = self.x;
self.lastPosition.y = self.y;
// If we have a target unit, move toward it
if (self.targetUnit && self.targetUnit.alive) {
var dx = self.targetUnit.x - self.x;
var dy = self.targetUnit.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else {
// No target or target is dead, find new target
self.findNewTarget();
}
};
self.findNewTarget = function () {
var closestUnit = null;
var closestDistance = Infinity;
// Find the closest military unit
for (var i = 0; i < units.length; i++) {
var unit = units[i];
if (!unit.alive) {
continue;
}
var dx = unit.x - self.x;
var dy = unit.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If target is in stealth mode and not super close, can't detect it
if (unit.state === "stealth" && distance > 100) {
continue;
}
if (distance < closestDistance) {
closestDistance = distance;
closestUnit = unit;
}
}
self.targetUnit = closestUnit;
};
self.kill = function () {
if (!self.alive) {
return;
}
self.alive = false;
tween(self, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var MilitaryUnit = Container.expand(function () {
var self = Container.call(this);
// Default state is normal
self.state = "normal";
self.targetPosition = null;
self.speed = 5;
self.alive = true;
self.score = 0;
// Normal unit representation
self.normalGraphics = self.attachAsset('unit', {
anchorX: 0.5,
anchorY: 0.5
});
// Stealth unit representation (initially hidden)
self.stealthGraphics = self.attachAsset('stealth', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Attack unit representation (initially hidden)
self.attackGraphics = self.attachAsset('attack', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Set initial state
self.setState = function (newState) {
if (newState === self.state) {
return;
}
// Hide all graphics first
self.normalGraphics.alpha = 0;
self.stealthGraphics.alpha = 0;
self.attackGraphics.alpha = 0;
// Show the appropriate graphics
if (newState === "normal") {
self.normalGraphics.alpha = 1;
self.speed = 5;
} else if (newState === "stealth") {
self.stealthGraphics.alpha = 1;
self.speed = 3; // Slower in stealth mode
} else if (newState === "attack") {
self.attackGraphics.alpha = 1;
self.speed = 7; // Faster in attack mode
}
self.state = newState;
};
// Move toward target if one is set
self.update = function () {
if (!self.alive) {
return;
}
if (self.targetPosition) {
var dx = self.targetPosition.x - self.x;
var dy = self.targetPosition.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
self.x = self.targetPosition.x;
self.y = self.targetPosition.y;
self.targetPosition = null;
}
}
};
// Destroy unit
self.kill = function () {
if (!self.alive) {
return;
}
self.alive = false;
tween(self, {
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
self.destroy();
}
});
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
self.graphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
// Pulse animation
self.pulse = function () {
tween(self.graphics, {
alpha: 0.8,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self.graphics, {
alpha: 0.5,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
easing: tween.easeIn
});
}
});
};
self.pulse();
return self;
});
var VoiceIndicator = Container.expand(function () {
var self = Container.call(this);
// Background
self.bg = self.attachAsset('unit', {
width: 400,
height: 100,
color: 0x000000,
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
// Voice level indicator
self.level = self.attachAsset('unit', {
width: 0,
height: 80,
color: 0x00ff00,
anchorX: 0,
anchorY: 0.5,
x: -190
});
// Text labels
self.whisperText = new Text2("Whisper", {
size: 40,
fill: 0xFFFFFF
});
self.whisperText.anchor.set(0.5);
self.whisperText.x = -135;
self.whisperText.y = 50;
self.addChild(self.whisperText);
self.normalText = new Text2("Normal", {
size: 40,
fill: 0xFFFFFF
});
self.normalText.anchor.set(0.5);
self.normalText.x = 0;
self.normalText.y = 50;
self.addChild(self.normalText);
self.shoutText = new Text2("Shout", {
size: 40,
fill: 0xFFFFFF
});
self.shoutText.anchor.set(0.5);
self.shoutText.x = 135;
self.shoutText.y = 50;
self.addChild(self.shoutText);
// Update the indicator based on volume
self.update = function () {
var volume = facekit.volume;
// Calculate width based on volume (0-1)
var width = volume * 380;
self.level.width = width;
// Change color based on volume
if (volume < 0.3) {
self.level.tint = 0x33cc33; // Green for whisper
} else if (volume > 0.7) {
self.level.tint = 0xcc3333; // Red for shout
} else {
self.level.tint = 0x3366cc; // Blue for normal
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// Game state variables
var units = [];
var enemies = [];
var target = null;
var playerBase = null;
var enemyBase = null;
var voiceIndicator = null;
var voiceMode = "normal";
var lastVoiceMode = "normal";
var lastSpawnTime = 0;
var currentWave = 1;
var gameStarted = false;
// Setup GUI
var scoreTxt = new Text2("Score: 0", {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var waveTxt = new Text2("Wave: 1", {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(1, 0);
waveTxt.x = -50;
LK.gui.topRight.addChild(waveTxt);
var instructionsTxt = new Text2("Use your voice to command units:\nWhisper - Stealth Mode\nNormal Voice - Normal Mode\nShout - Attack Mode\n\nTap to place target location", {
size: 50,
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(instructionsTxt);
var startButton = LK.getAsset('unit', {
width: 300,
height: 100,
color: 0x3366cc,
anchorX: 0.5,
anchorY: 0.5
});
LK.gui.center.addChild(startButton);
startButton.y = 200;
var startText = new Text2("START", {
size: 60,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startButton.addChild(startText);
// Start game when button is pressed
startButton.down = function () {
startGame();
};
function startGame() {
gameStarted = true;
LK.gui.center.removeChild(instructionsTxt);
LK.gui.center.removeChild(startButton);
// Create bases
playerBase = new Base();
playerBase.x = 1024;
playerBase.y = 2300;
game.addChild(playerBase);
enemyBase = new EnemyBase();
enemyBase.x = 1024;
enemyBase.y = 400;
game.addChild(enemyBase);
// Create voice indicator
voiceIndicator = new VoiceIndicator();
voiceIndicator.x = 1024;
voiceIndicator.y = 2600;
game.addChild(voiceIndicator);
// Create initial units
createUnit(900, 2000);
createUnit(1150, 2000);
// Start background music
LK.playMusic('bgmusic');
}
function createUnit(x, y) {
var unit = new MilitaryUnit();
unit.x = x;
unit.y = y;
game.addChild(unit);
units.push(unit);
return unit;
}
function createEnemy(x, y) {
var enemy = new Enemy();
enemy.x = x;
enemy.y = y;
game.addChild(enemy);
enemies.push(enemy);
return enemy;
}
function spawnEnemies() {
var now = Date.now();
if (now - lastSpawnTime > 5000) {
// Spawn every 5 seconds
lastSpawnTime = now;
// Spawn enemies based on wave
var count = Math.min(2 + currentWave, 8);
for (var i = 0; i < count; i++) {
var x = 400 + Math.random() * 1248;
var y = 400 + Math.random() * 200;
createEnemy(x, y);
}
// Increase wave
currentWave++;
waveTxt.setText("Wave: " + currentWave);
}
}
function createTarget(x, y) {
// Remove existing target if there is one
if (target) {
target.destroy();
}
// Create new target
target = new Target();
target.x = x;
target.y = y;
game.addChild(target);
// Command all units to move to target
for (var i = 0; i < units.length; i++) {
if (units[i].alive) {
units[i].targetPosition = {
x: x,
y: y
};
}
}
// Play sound based on voice mode
if (voiceMode === "stealth") {
LK.getSound('stealth').play();
} else if (voiceMode === "attack") {
LK.getSound('attack').play();
} else {
LK.getSound('order').play();
}
}
function checkCollisions() {
// Check for enemy-unit collisions
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (!enemy.alive) {
continue;
}
// Check collision with player base
if (playerBase && enemy.intersects(playerBase)) {
playerBase.takeDamage(1);
enemy.kill();
enemies.splice(i, 1);
continue;
}
// Check collision with units
for (var j = units.length - 1; j >= 0; j--) {
var unit = units[j];
if (!unit.alive) {
continue;
}
if (unit.intersects(enemy)) {
// Combat outcome depends on unit state
if (unit.state === "attack") {
// Unit is in attack mode, more likely to win
enemy.kill();
enemies.splice(i, 1);
LK.setScore(LK.getScore() + 100);
break;
} else if (unit.state === "stealth") {
// Stealth units can sometimes evade
if (Math.random() > 0.7) {
// Unit escapes
unit.x += Math.random() * 100 - 50;
unit.y += Math.random() * 100 - 50;
} else {
unit.kill();
units.splice(j, 1);
}
} else {
// Normal combat, 50/50 chance
if (Math.random() > 0.5) {
enemy.kill();
enemies.splice(i, 1);
LK.setScore(LK.getScore() + 50);
} else {
unit.kill();
units.splice(j, 1);
}
break;
}
}
}
}
// Check for units reaching enemy base
for (var k = units.length - 1; k >= 0; k--) {
var unit = units[k];
if (!unit.alive) {
continue;
}
if (enemyBase && unit.intersects(enemyBase)) {
// Unit is attacking enemy base
var damage = unit.state === "attack" ? 20 : 10;
enemyBase.takeDamage(damage);
unit.kill();
units.splice(k, 1);
LK.setScore(LK.getScore() + 200);
}
}
}
function determineVoiceMode() {
var volume = facekit.volume;
if (volume < 0.1) {
// No sound, keep previous mode
return voiceMode;
} else if (volume < 0.3) {
return "stealth";
} else if (volume > 0.7) {
return "attack";
} else {
return "normal";
}
}
function spawnNewUnits() {
// Spawn new units every 10 seconds if we have fewer than 5
if (LK.ticks % 600 === 0 && units.length < 5) {
createUnit(900 + Math.random() * 250, 2000 + Math.random() * 200);
}
}
function updateScore() {
scoreTxt.setText("Score: " + LK.getScore());
// Store best score if current score is higher
if (LK.getScore() > storage.bestScore) {
storage.bestScore = LK.getScore();
}
}
// Game down event - place target
game.down = function (x, y) {
if (!gameStarted) {
return;
}
// Don't place target too close to enemy base or on bases
var distToEnemyBase = Math.sqrt(Math.pow(x - enemyBase.x, 2) + Math.pow(y - enemyBase.y, 2));
var distToPlayerBase = Math.sqrt(Math.pow(x - playerBase.x, 2) + Math.pow(y - playerBase.y, 2));
if (distToEnemyBase > 350 && distToPlayerBase > 350) {
createTarget(x, y);
}
};
// Game tick event
game.update = function () {
if (!gameStarted) {
return;
}
// Update voice mode based on audio input
voiceMode = determineVoiceMode();
// Update voice indicator
if (voiceIndicator) {
voiceIndicator.update();
}
// Update all units with current voice mode
if (voiceMode !== lastVoiceMode) {
for (var i = 0; i < units.length; i++) {
if (units[i].alive) {
units[i].setState(voiceMode);
}
}
lastVoiceMode = voiceMode;
}
// Check for collisions
checkCollisions();
// Spawn enemies
spawnEnemies();
// Spawn new units if needed
spawnNewUnits();
// Update score display
updateScore();
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,599 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ bestScore: 0
+});
+var facekit = LK.import("@upit/facekit.v1");
+
+/****
+* Classes
+****/
+var Base = Container.expand(function () {
+ var self = Container.call(this);
+ self.graphics = self.attachAsset('base', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.health = 100;
+ self.isPlayerBase = true;
+ // Health bar background
+ self.healthBarBg = self.attachAsset('unit', {
+ width: 300,
+ height: 20,
+ color: 0x000000,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: -180
+ });
+ // Health bar foreground
+ self.healthBar = self.attachAsset('unit', {
+ width: 300,
+ height: 20,
+ color: 0x00ff00,
+ anchorX: 0,
+ anchorY: 0.5,
+ y: -180,
+ x: -150
+ });
+ self.takeDamage = function (amount) {
+ self.health -= amount;
+ if (self.health < 0) {
+ self.health = 0;
+ }
+ // Update health bar width
+ self.healthBar.width = self.health / 100 * 300;
+ if (self.health <= 0 && self.isPlayerBase) {
+ LK.showGameOver();
+ } else if (self.health <= 0 && !self.isPlayerBase) {
+ // Player wins
+ LK.setScore(LK.getScore() + 1000);
+ LK.showYouWin();
+ }
+ };
+ return self;
+});
+var EnemyBase = Base.expand(function () {
+ var self = Base.call(this);
+ // Override base graphics with enemy base
+ self.graphics.destroy();
+ self.graphics = self.attachAsset('enemyBase', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.healthBar.tint = 0xff0000;
+ self.isPlayerBase = false;
+ return self;
+});
+var Enemy = Container.expand(function () {
+ var self = Container.call(this);
+ self.graphics = self.attachAsset('enemy', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 3;
+ self.alive = true;
+ self.targetUnit = null;
+ self.lastPosition = {
+ x: 0,
+ y: 0
+ };
+ self.update = function () {
+ if (!self.alive) {
+ return;
+ }
+ self.lastPosition.x = self.x;
+ self.lastPosition.y = self.y;
+ // If we have a target unit, move toward it
+ if (self.targetUnit && self.targetUnit.alive) {
+ var dx = self.targetUnit.x - self.x;
+ var dy = self.targetUnit.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > self.speed) {
+ self.x += dx / distance * self.speed;
+ self.y += dy / distance * self.speed;
+ }
+ } else {
+ // No target or target is dead, find new target
+ self.findNewTarget();
+ }
+ };
+ self.findNewTarget = function () {
+ var closestUnit = null;
+ var closestDistance = Infinity;
+ // Find the closest military unit
+ for (var i = 0; i < units.length; i++) {
+ var unit = units[i];
+ if (!unit.alive) {
+ continue;
+ }
+ var dx = unit.x - self.x;
+ var dy = unit.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ // If target is in stealth mode and not super close, can't detect it
+ if (unit.state === "stealth" && distance > 100) {
+ continue;
+ }
+ if (distance < closestDistance) {
+ closestDistance = distance;
+ closestUnit = unit;
+ }
+ }
+ self.targetUnit = closestUnit;
+ };
+ self.kill = function () {
+ if (!self.alive) {
+ return;
+ }
+ self.alive = false;
+ tween(self, {
+ alpha: 0
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ };
+ return self;
+});
+var MilitaryUnit = Container.expand(function () {
+ var self = Container.call(this);
+ // Default state is normal
+ self.state = "normal";
+ self.targetPosition = null;
+ self.speed = 5;
+ self.alive = true;
+ self.score = 0;
+ // Normal unit representation
+ self.normalGraphics = self.attachAsset('unit', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Stealth unit representation (initially hidden)
+ self.stealthGraphics = self.attachAsset('stealth', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0
+ });
+ // Attack unit representation (initially hidden)
+ self.attackGraphics = self.attachAsset('attack', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0
+ });
+ // Set initial state
+ self.setState = function (newState) {
+ if (newState === self.state) {
+ return;
+ }
+ // Hide all graphics first
+ self.normalGraphics.alpha = 0;
+ self.stealthGraphics.alpha = 0;
+ self.attackGraphics.alpha = 0;
+ // Show the appropriate graphics
+ if (newState === "normal") {
+ self.normalGraphics.alpha = 1;
+ self.speed = 5;
+ } else if (newState === "stealth") {
+ self.stealthGraphics.alpha = 1;
+ self.speed = 3; // Slower in stealth mode
+ } else if (newState === "attack") {
+ self.attackGraphics.alpha = 1;
+ self.speed = 7; // Faster in attack mode
+ }
+ self.state = newState;
+ };
+ // Move toward target if one is set
+ self.update = function () {
+ if (!self.alive) {
+ return;
+ }
+ if (self.targetPosition) {
+ var dx = self.targetPosition.x - self.x;
+ var dy = self.targetPosition.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance > self.speed) {
+ self.x += dx / distance * self.speed;
+ self.y += dy / distance * self.speed;
+ } else {
+ self.x = self.targetPosition.x;
+ self.y = self.targetPosition.y;
+ self.targetPosition = null;
+ }
+ }
+ };
+ // Destroy unit
+ self.kill = function () {
+ if (!self.alive) {
+ return;
+ }
+ self.alive = false;
+ tween(self, {
+ alpha: 0
+ }, {
+ duration: 500,
+ onFinish: function onFinish() {
+ self.destroy();
+ }
+ });
+ };
+ return self;
+});
+var Target = Container.expand(function () {
+ var self = Container.call(this);
+ self.graphics = self.attachAsset('target', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.5
+ });
+ // Pulse animation
+ self.pulse = function () {
+ tween(self.graphics, {
+ alpha: 0.8,
+ scaleX: 1.2,
+ scaleY: 1.2
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(self.graphics, {
+ alpha: 0.5,
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 500,
+ easing: tween.easeIn
+ });
+ }
+ });
+ };
+ self.pulse();
+ return self;
+});
+var VoiceIndicator = Container.expand(function () {
+ var self = Container.call(this);
+ // Background
+ self.bg = self.attachAsset('unit', {
+ width: 400,
+ height: 100,
+ color: 0x000000,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.5
+ });
+ // Voice level indicator
+ self.level = self.attachAsset('unit', {
+ width: 0,
+ height: 80,
+ color: 0x00ff00,
+ anchorX: 0,
+ anchorY: 0.5,
+ x: -190
+ });
+ // Text labels
+ self.whisperText = new Text2("Whisper", {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ self.whisperText.anchor.set(0.5);
+ self.whisperText.x = -135;
+ self.whisperText.y = 50;
+ self.addChild(self.whisperText);
+ self.normalText = new Text2("Normal", {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ self.normalText.anchor.set(0.5);
+ self.normalText.x = 0;
+ self.normalText.y = 50;
+ self.addChild(self.normalText);
+ self.shoutText = new Text2("Shout", {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ self.shoutText.anchor.set(0.5);
+ self.shoutText.x = 135;
+ self.shoutText.y = 50;
+ self.addChild(self.shoutText);
+ // Update the indicator based on volume
+ self.update = function () {
+ var volume = facekit.volume;
+ // Calculate width based on volume (0-1)
+ var width = volume * 380;
+ self.level.width = width;
+ // Change color based on volume
+ if (volume < 0.3) {
+ self.level.tint = 0x33cc33; // Green for whisper
+ } else if (volume > 0.7) {
+ self.level.tint = 0xcc3333; // Red for shout
+ } else {
+ self.level.tint = 0x3366cc; // Blue for normal
+ }
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222222
+});
+
+/****
+* Game Code
+****/
+// Game state variables
+var units = [];
+var enemies = [];
+var target = null;
+var playerBase = null;
+var enemyBase = null;
+var voiceIndicator = null;
+var voiceMode = "normal";
+var lastVoiceMode = "normal";
+var lastSpawnTime = 0;
+var currentWave = 1;
+var gameStarted = false;
+// Setup GUI
+var scoreTxt = new Text2("Score: 0", {
+ size: 60,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+var waveTxt = new Text2("Wave: 1", {
+ size: 60,
+ fill: 0xFFFFFF
+});
+waveTxt.anchor.set(1, 0);
+waveTxt.x = -50;
+LK.gui.topRight.addChild(waveTxt);
+var instructionsTxt = new Text2("Use your voice to command units:\nWhisper - Stealth Mode\nNormal Voice - Normal Mode\nShout - Attack Mode\n\nTap to place target location", {
+ size: 50,
+ fill: 0xFFFFFF
+});
+instructionsTxt.anchor.set(0.5, 0.5);
+LK.gui.center.addChild(instructionsTxt);
+var startButton = LK.getAsset('unit', {
+ width: 300,
+ height: 100,
+ color: 0x3366cc,
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+LK.gui.center.addChild(startButton);
+startButton.y = 200;
+var startText = new Text2("START", {
+ size: 60,
+ fill: 0xFFFFFF
+});
+startText.anchor.set(0.5, 0.5);
+startButton.addChild(startText);
+// Start game when button is pressed
+startButton.down = function () {
+ startGame();
+};
+function startGame() {
+ gameStarted = true;
+ LK.gui.center.removeChild(instructionsTxt);
+ LK.gui.center.removeChild(startButton);
+ // Create bases
+ playerBase = new Base();
+ playerBase.x = 1024;
+ playerBase.y = 2300;
+ game.addChild(playerBase);
+ enemyBase = new EnemyBase();
+ enemyBase.x = 1024;
+ enemyBase.y = 400;
+ game.addChild(enemyBase);
+ // Create voice indicator
+ voiceIndicator = new VoiceIndicator();
+ voiceIndicator.x = 1024;
+ voiceIndicator.y = 2600;
+ game.addChild(voiceIndicator);
+ // Create initial units
+ createUnit(900, 2000);
+ createUnit(1150, 2000);
+ // Start background music
+ LK.playMusic('bgmusic');
+}
+function createUnit(x, y) {
+ var unit = new MilitaryUnit();
+ unit.x = x;
+ unit.y = y;
+ game.addChild(unit);
+ units.push(unit);
+ return unit;
+}
+function createEnemy(x, y) {
+ var enemy = new Enemy();
+ enemy.x = x;
+ enemy.y = y;
+ game.addChild(enemy);
+ enemies.push(enemy);
+ return enemy;
+}
+function spawnEnemies() {
+ var now = Date.now();
+ if (now - lastSpawnTime > 5000) {
+ // Spawn every 5 seconds
+ lastSpawnTime = now;
+ // Spawn enemies based on wave
+ var count = Math.min(2 + currentWave, 8);
+ for (var i = 0; i < count; i++) {
+ var x = 400 + Math.random() * 1248;
+ var y = 400 + Math.random() * 200;
+ createEnemy(x, y);
+ }
+ // Increase wave
+ currentWave++;
+ waveTxt.setText("Wave: " + currentWave);
+ }
+}
+function createTarget(x, y) {
+ // Remove existing target if there is one
+ if (target) {
+ target.destroy();
+ }
+ // Create new target
+ target = new Target();
+ target.x = x;
+ target.y = y;
+ game.addChild(target);
+ // Command all units to move to target
+ for (var i = 0; i < units.length; i++) {
+ if (units[i].alive) {
+ units[i].targetPosition = {
+ x: x,
+ y: y
+ };
+ }
+ }
+ // Play sound based on voice mode
+ if (voiceMode === "stealth") {
+ LK.getSound('stealth').play();
+ } else if (voiceMode === "attack") {
+ LK.getSound('attack').play();
+ } else {
+ LK.getSound('order').play();
+ }
+}
+function checkCollisions() {
+ // Check for enemy-unit collisions
+ for (var i = enemies.length - 1; i >= 0; i--) {
+ var enemy = enemies[i];
+ if (!enemy.alive) {
+ continue;
+ }
+ // Check collision with player base
+ if (playerBase && enemy.intersects(playerBase)) {
+ playerBase.takeDamage(1);
+ enemy.kill();
+ enemies.splice(i, 1);
+ continue;
+ }
+ // Check collision with units
+ for (var j = units.length - 1; j >= 0; j--) {
+ var unit = units[j];
+ if (!unit.alive) {
+ continue;
+ }
+ if (unit.intersects(enemy)) {
+ // Combat outcome depends on unit state
+ if (unit.state === "attack") {
+ // Unit is in attack mode, more likely to win
+ enemy.kill();
+ enemies.splice(i, 1);
+ LK.setScore(LK.getScore() + 100);
+ break;
+ } else if (unit.state === "stealth") {
+ // Stealth units can sometimes evade
+ if (Math.random() > 0.7) {
+ // Unit escapes
+ unit.x += Math.random() * 100 - 50;
+ unit.y += Math.random() * 100 - 50;
+ } else {
+ unit.kill();
+ units.splice(j, 1);
+ }
+ } else {
+ // Normal combat, 50/50 chance
+ if (Math.random() > 0.5) {
+ enemy.kill();
+ enemies.splice(i, 1);
+ LK.setScore(LK.getScore() + 50);
+ } else {
+ unit.kill();
+ units.splice(j, 1);
+ }
+ break;
+ }
+ }
+ }
+ }
+ // Check for units reaching enemy base
+ for (var k = units.length - 1; k >= 0; k--) {
+ var unit = units[k];
+ if (!unit.alive) {
+ continue;
+ }
+ if (enemyBase && unit.intersects(enemyBase)) {
+ // Unit is attacking enemy base
+ var damage = unit.state === "attack" ? 20 : 10;
+ enemyBase.takeDamage(damage);
+ unit.kill();
+ units.splice(k, 1);
+ LK.setScore(LK.getScore() + 200);
+ }
+ }
+}
+function determineVoiceMode() {
+ var volume = facekit.volume;
+ if (volume < 0.1) {
+ // No sound, keep previous mode
+ return voiceMode;
+ } else if (volume < 0.3) {
+ return "stealth";
+ } else if (volume > 0.7) {
+ return "attack";
+ } else {
+ return "normal";
+ }
+}
+function spawnNewUnits() {
+ // Spawn new units every 10 seconds if we have fewer than 5
+ if (LK.ticks % 600 === 0 && units.length < 5) {
+ createUnit(900 + Math.random() * 250, 2000 + Math.random() * 200);
+ }
+}
+function updateScore() {
+ scoreTxt.setText("Score: " + LK.getScore());
+ // Store best score if current score is higher
+ if (LK.getScore() > storage.bestScore) {
+ storage.bestScore = LK.getScore();
+ }
+}
+// Game down event - place target
+game.down = function (x, y) {
+ if (!gameStarted) {
+ return;
+ }
+ // Don't place target too close to enemy base or on bases
+ var distToEnemyBase = Math.sqrt(Math.pow(x - enemyBase.x, 2) + Math.pow(y - enemyBase.y, 2));
+ var distToPlayerBase = Math.sqrt(Math.pow(x - playerBase.x, 2) + Math.pow(y - playerBase.y, 2));
+ if (distToEnemyBase > 350 && distToPlayerBase > 350) {
+ createTarget(x, y);
+ }
+};
+// Game tick event
+game.update = function () {
+ if (!gameStarted) {
+ return;
+ }
+ // Update voice mode based on audio input
+ voiceMode = determineVoiceMode();
+ // Update voice indicator
+ if (voiceIndicator) {
+ voiceIndicator.update();
+ }
+ // Update all units with current voice mode
+ if (voiceMode !== lastVoiceMode) {
+ for (var i = 0; i < units.length; i++) {
+ if (units[i].alive) {
+ units[i].setState(voiceMode);
+ }
+ }
+ lastVoiceMode = voiceMode;
+ }
+ // Check for collisions
+ checkCollisions();
+ // Spawn enemies
+ spawnEnemies();
+ // Spawn new units if needed
+ spawnNewUnits();
+ // Update score display
+ updateScore();
+};
\ No newline at end of file