/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highestWave: 1 }); /**** * Classes ****/ var Enemy = Container.expand(function () { var self = Container.call(this); self.speed = 2; self.health = 10; self.type = 'minion'; self.value = 1; // Score value self.knockback = 0; self.knockbackDirection = { x: 0, y: 0 }; self.graphics = null; self.init = function (type, wave) { self.type = type || 'minion'; if (self.type === 'minion') { self.graphics = self.attachAsset('minion', { anchorX: 0.5, anchorY: 0.5 }); // Make minions tougher as waves progress self.health = 5 + Math.floor(wave / 3); self.speed = 1 + Math.min(2, wave * 0.1); self.value = 1; } else if (self.type === 'boss') { self.graphics = self.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100 + wave * 5; self.speed = 0.7; self.value = 50; LK.getSound('bossAppear').play(); // Make boss appear with scale effect self.graphics.scaleX = 0.1; self.graphics.scaleY = 0.1; tween(self.graphics, { scaleX: 1, scaleY: 1 }, { duration: 1000, easing: tween.elasticOut }); } return self; }; self.update = function () { if (self.knockback > 0) { // Apply knockback movement self.x += self.knockbackDirection.x * (self.knockback / 10); self.y += self.knockbackDirection.y * (self.knockback / 10); self.knockback--; } else if (warrior) { // Move toward player var dx = warrior.x - self.x; var dy = warrior.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 10) { // Don't move if already very close self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // Rotate to face player (boss only) if (self.type === 'boss') { self.rotation = Math.atan2(dy, dx); } } // Keep within arena bounds var arenaRadius = 750; // Half of arena width var distanceFromCenter = Math.sqrt(Math.pow(self.x - 2048 / 2, 2) + Math.pow(self.y - 2732 / 2, 2)); if (distanceFromCenter > arenaRadius) { // Push back into arena var angle = Math.atan2(self.y - 2732 / 2, self.x - 2048 / 2); self.x = 2048 / 2 + Math.cos(angle) * arenaRadius; self.y = 2732 / 2 + Math.sin(angle) * arenaRadius; } // Check collision with warrior push attack if (warrior && warrior.isAttacking && warrior.pushAttack) { if (self.intersects(warrior.pushAttack)) { self.takeDamage(5); // Calculate knockback direction var dx = self.x - warrior.x; var dy = self.y - warrior.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.knockbackDirection = { x: dx / dist, y: dy / dist }; } // Apply knockback self.knockback = self.type === 'boss' ? 20 : 30; } } // Check collision with warrior if (warrior && self.intersects(warrior) && !warrior.isAttacking) { warrior.takeDamage(self.type === 'boss' ? 20 : 10); // Knockback both enemy and player var dx = self.x - warrior.x; var dy = self.y - warrior.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist > 0) { self.knockbackDirection = { x: dx / dist, y: dy / dist }; self.knockback = 20; } } }; self.takeDamage = function (amount) { self.health -= amount; // Flash the enemy white on hit LK.effects.flashObject(self, 0xffffff, 200); if (self.health <= 0) { // Enemy defeated LK.getSound('enemyDefeat').play(); LK.setScore(LK.getScore() + self.value); // Create explosion effect var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y }); game.addChild(explosion); tween(explosion, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 500, easing: tween.easeOut, onComplete: function onComplete() { explosion.destroy(); } }); return true; // Signal to remove this enemy } return false; }; return self; }); var Warrior = Container.expand(function () { var self = Container.call(this); var warriorGraphics = self.attachAsset('warrior', { anchorX: 0.5, anchorY: 0.5 }); self.health = 100; self.pushCooldown = 0; self.pushDuration = 0; self.isAttacking = false; self.invulnerable = 0; self.update = function () { if (self.pushCooldown > 0) { self.pushCooldown--; } if (self.pushDuration > 0) { self.pushDuration--; if (self.pushDuration <= 0) { self.isAttacking = false; if (self.pushAttack) { self.pushAttack.destroy(); self.pushAttack = null; } } } if (self.invulnerable > 0) { self.invulnerable--; // Flash effect when invulnerable warriorGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5; } else { warriorGraphics.alpha = 1; } }; self.doPushAttack = function () { if (self.pushCooldown <= 0 && !self.isAttacking) { self.pushCooldown = 45; // 45 frames = 3/4 second cooldown self.pushDuration = 15; // 15 frames = 1/4 second attack duration self.isAttacking = true; LK.getSound('push').play(); // Create push attack visual self.pushAttack = self.addChild(LK.getAsset('pushAttack', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 })); // Scale attack effect from 0 to 1 tween(self.pushAttack, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 350, easing: tween.easeOut }); } }; self.takeDamage = function (amount) { if (self.invulnerable <= 0) { self.health -= amount; self.invulnerable = 60; // 1 second invulnerability LK.getSound('playerHit').play(); // Flash the warrior red LK.effects.flashObject(self, 0xff0000, 500); if (self.health <= 0) { // Player died LK.showGameOver(); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x333333 }); /**** * Game Code ****/ // Game variables var warrior = null; var enemies = []; var currentWave = 1; var highestWave = storage.highestWave || 1; var enemiesRemaining = 0; var spawnTimer = 0; var gameStarted = false; var dragNode = null; // UI Elements var waveText = null; var scoreText = null; var healthBar = null; var healthBarBg = null; var healthBarFill = null; var startButton = null; var continueButton = null; // Initialize game arena var arena = game.addChild(LK.getAsset('arena', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.7 })); // Initialize the UI function initUI() { // Score text scoreText = new Text2('Score: 0', { size: 70, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); // Right aligned LK.gui.topRight.addChild(scoreText); // Wave text waveText = new Text2('Wave 1/35', { size: 70, fill: 0xFFFFFF }); waveText.anchor.set(0, 0); // Left aligned LK.gui.top.addChild(waveText); // Health bar background healthBarBg = new Container(); healthBarBg.x = 0; healthBarBg.y = 100; var bgRect = LK.getAsset('healthBarBg', { width: 800, height: 40, color: 0x333333, shape: 'box', anchorX: 0, anchorY: 0 }); healthBarBg.addChild(bgRect); // Health bar fill healthBarFill = LK.getAsset('healthBarFill', { width: 800, height: 40, color: 0x00cc00, shape: 'box', anchorX: 0, anchorY: 0 }); healthBarBg.addChild(healthBarFill); LK.gui.top.addChild(healthBarBg); // Start button startButton = new Container(); var startBg = startButton.addChild(LK.getAsset('startBg', { width: 500, height: 150, color: 0x4488ff, shape: 'box', anchorX: 0.5, anchorY: 0.5 })); var startText = new Text2('START GAME', { size: 80, fill: 0xFFFFFF }); startText.anchor.set(0.5, 0.5); startButton.addChild(startText); startButton.x = 0; startButton.y = 0; // Continue button (shown after game over) continueButton = new Container(); var continueBg = continueButton.addChild(LK.getAsset('continueBg', { width: 600, height: 150, color: 0x44aa44, shape: 'box', anchorX: 0.5, anchorY: 0.5 })); var continueText = new Text2('CONTINUE', { size: 80, fill: 0xFFFFFF }); continueText.anchor.set(0.5, 0.5); continueButton.addChild(continueText); continueButton.x = 0; continueButton.y = 150; continueButton.visible = false; // Add buttons to GUI LK.gui.center.addChild(startButton); LK.gui.center.addChild(continueButton); // Add info text about highest wave reached var infoText = new Text2('Highest Wave: ' + highestWave, { size: 50, fill: 0xCCCCCC }); infoText.anchor.set(0.5, 0); infoText.y = 100; LK.gui.center.addChild(infoText); } // Initialize the player function initPlayer() { warrior = game.addChild(new Warrior()); warrior.x = 2048 / 2; warrior.y = 2732 - warrior.height / 2; } // Start the game function startGame() { // Hide start UI startButton.visible = false; continueButton.visible = false; // Reset game state LK.setScore(0); currentWave = 1; enemies = []; // Create player if not exists if (!warrior) { initPlayer(); } else { warrior.health = 100; warrior.pushCooldown = 0; warrior.isAttacking = false; warrior.invulnerable = 60; // Brief invulnerability at start } // Start the wave startWave(currentWave); gameStarted = true; // Start the music LK.playMusic('battleMusic', { fade: { start: 0, end: 0.6, duration: 1000 } }); } // Continue after death function continueGame() { // Hide continue UI continueButton.visible = false; // Reset player initPlayer(); warrior.health = 100; warrior.invulnerable = 60; // Brief invulnerability at start // Start the current wave again startWave(currentWave); gameStarted = true; // Restart the music LK.playMusic('battleMusic'); } // Start a new wave function startWave(wave) { // Update UI waveText.setText('Wave ' + wave + '/35'); // Store highest wave reached if (wave > highestWave) { highestWave = wave; storage.highestWave = highestWave; } // Clear any existing enemies for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].destroy(); } enemies = []; // Determine enemy count for this wave if (wave === 35) { // Boss wave enemiesRemaining = 1; spawnTimer = 60; // Start boss spawn after 1 second } else { // Regular wave enemiesRemaining = Math.min(20, 3 + Math.floor(wave * 1.5)); spawnTimer = 60; // First spawn after 1 second } } // Spawn a new enemy function spawnEnemy(type) { var enemy = new Enemy(); enemy.init(type, currentWave); // Random position on the edge of the arena enemy.x = Math.random() * 2048; // Random x position across the width of the arena enemy.y = -enemy.graphics.height; // Start just above the top of the arena game.addChild(enemy); enemies.push(enemy); } // Update UI elements function updateUI() { // Update score scoreText.setText('Score: ' + LK.getScore()); // Update health bar if (warrior) { var healthPercent = Math.max(0, warrior.health / 100); healthBarFill.width = 800 * healthPercent; // Change color based on health if (healthPercent > 0.6) { healthBarFill.tint = 0x00cc00; // Green } else if (healthPercent > 0.3) { healthBarFill.tint = 0xffcc00; // Yellow } else { healthBarFill.tint = 0xff0000; // Red } } } // Handle touch/mouse events function handleMove(x, y, obj) { if (gameStarted && dragNode === warrior) { tween(warrior, { x: x, y: y }, { duration: 100, easing: tween.easeInOut }); // Keep warrior within arena bounds var arenaRadius = 700; // Slightly smaller than arena for player var distanceFromCenter = Math.sqrt(Math.pow(warrior.x - 2048 / 2, 2) + Math.pow(warrior.y - 2732 / 2, 2)); if (distanceFromCenter > arenaRadius) { // Push back into arena var angle = Math.atan2(warrior.y - 2732 / 2, warrior.x - 2048 / 2); warrior.x = 2048 / 2 + Math.cos(angle) * arenaRadius; warrior.y = 2732 / 2 + Math.sin(angle) * arenaRadius; } } } // Handle touch/mouse down function handleDown(x, y, obj) { // Check if we clicked any UI buttons if (!gameStarted) { var startPos = game.toLocal(startButton.parent.toGlobal(startButton.position)); if (Math.abs(x - startPos.x) < 250 && Math.abs(y - startPos.y) < 75) { startGame(); return; } var continuePos = game.toLocal(continueButton.parent.toGlobal(continueButton.position)); if (continueButton.visible && Math.abs(x - continuePos.x) < 300 && Math.abs(y - continuePos.y) < 75) { continueGame(); return; } } if (gameStarted) { // Start dragging warrior dragNode = warrior; // If not dragging, do a push attack if (warrior && !dragNode) { warrior.doPushAttack(); } } } // Handle touch/mouse up function handleUp(x, y, obj) { if (gameStarted && dragNode === warrior) { // End dragging, do push attack warrior.doPushAttack(); } dragNode = null; } // Set up event handlers game.move = handleMove; game.down = handleDown; game.up = handleUp; // Initialize the UI initUI(); // Main game update loop game.update = function () { if (!gameStarted) { return; } // Update warrior if (warrior) { warrior.update(); } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].update(); // Check if enemy is defeated if (enemies[i].health <= 0) { enemies[i].destroy(); enemies.splice(i, 1); } } // Spawn new enemies if (enemiesRemaining > 0) { if (spawnTimer <= 0) { if (currentWave === 35) { // Boss wave spawnEnemy('boss'); } else { // Regular wave spawnEnemy('minion'); } enemiesRemaining--; spawnTimer = currentWave === 35 ? 0 : Math.max(20, 60 - currentWave); // Faster spawns in later waves } else { spawnTimer--; } } // Check if wave is complete if (enemiesRemaining === 0 && enemies.length === 0) { currentWave++; if (currentWave > 35) { // Game complete - victory! LK.showYouWin(); } else { // Start next wave startWave(currentWave); } } // Update UI updateUI(); // Show continue button after game over if (!gameStarted && warrior && warrior.health <= 0) { continueButton.visible = true; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highestWave: 1
});
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.speed = 2;
self.health = 10;
self.type = 'minion';
self.value = 1; // Score value
self.knockback = 0;
self.knockbackDirection = {
x: 0,
y: 0
};
self.graphics = null;
self.init = function (type, wave) {
self.type = type || 'minion';
if (self.type === 'minion') {
self.graphics = self.attachAsset('minion', {
anchorX: 0.5,
anchorY: 0.5
});
// Make minions tougher as waves progress
self.health = 5 + Math.floor(wave / 3);
self.speed = 1 + Math.min(2, wave * 0.1);
self.value = 1;
} else if (self.type === 'boss') {
self.graphics = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100 + wave * 5;
self.speed = 0.7;
self.value = 50;
LK.getSound('bossAppear').play();
// Make boss appear with scale effect
self.graphics.scaleX = 0.1;
self.graphics.scaleY = 0.1;
tween(self.graphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 1000,
easing: tween.elasticOut
});
}
return self;
};
self.update = function () {
if (self.knockback > 0) {
// Apply knockback movement
self.x += self.knockbackDirection.x * (self.knockback / 10);
self.y += self.knockbackDirection.y * (self.knockback / 10);
self.knockback--;
} else if (warrior) {
// Move toward player
var dx = warrior.x - self.x;
var dy = warrior.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
// Don't move if already very close
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// Rotate to face player (boss only)
if (self.type === 'boss') {
self.rotation = Math.atan2(dy, dx);
}
}
// Keep within arena bounds
var arenaRadius = 750; // Half of arena width
var distanceFromCenter = Math.sqrt(Math.pow(self.x - 2048 / 2, 2) + Math.pow(self.y - 2732 / 2, 2));
if (distanceFromCenter > arenaRadius) {
// Push back into arena
var angle = Math.atan2(self.y - 2732 / 2, self.x - 2048 / 2);
self.x = 2048 / 2 + Math.cos(angle) * arenaRadius;
self.y = 2732 / 2 + Math.sin(angle) * arenaRadius;
}
// Check collision with warrior push attack
if (warrior && warrior.isAttacking && warrior.pushAttack) {
if (self.intersects(warrior.pushAttack)) {
self.takeDamage(5);
// Calculate knockback direction
var dx = self.x - warrior.x;
var dy = self.y - warrior.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.knockbackDirection = {
x: dx / dist,
y: dy / dist
};
}
// Apply knockback
self.knockback = self.type === 'boss' ? 20 : 30;
}
}
// Check collision with warrior
if (warrior && self.intersects(warrior) && !warrior.isAttacking) {
warrior.takeDamage(self.type === 'boss' ? 20 : 10);
// Knockback both enemy and player
var dx = self.x - warrior.x;
var dy = self.y - warrior.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.knockbackDirection = {
x: dx / dist,
y: dy / dist
};
self.knockback = 20;
}
}
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash the enemy white on hit
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
// Enemy defeated
LK.getSound('enemyDefeat').play();
LK.setScore(LK.getScore() + self.value);
// Create explosion effect
var explosion = LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y
});
game.addChild(explosion);
tween(explosion, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 500,
easing: tween.easeOut,
onComplete: function onComplete() {
explosion.destroy();
}
});
return true; // Signal to remove this enemy
}
return false;
};
return self;
});
var Warrior = Container.expand(function () {
var self = Container.call(this);
var warriorGraphics = self.attachAsset('warrior', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.pushCooldown = 0;
self.pushDuration = 0;
self.isAttacking = false;
self.invulnerable = 0;
self.update = function () {
if (self.pushCooldown > 0) {
self.pushCooldown--;
}
if (self.pushDuration > 0) {
self.pushDuration--;
if (self.pushDuration <= 0) {
self.isAttacking = false;
if (self.pushAttack) {
self.pushAttack.destroy();
self.pushAttack = null;
}
}
}
if (self.invulnerable > 0) {
self.invulnerable--;
// Flash effect when invulnerable
warriorGraphics.alpha = Math.sin(LK.ticks * 0.5) * 0.5 + 0.5;
} else {
warriorGraphics.alpha = 1;
}
};
self.doPushAttack = function () {
if (self.pushCooldown <= 0 && !self.isAttacking) {
self.pushCooldown = 45; // 45 frames = 3/4 second cooldown
self.pushDuration = 15; // 15 frames = 1/4 second attack duration
self.isAttacking = true;
LK.getSound('push').play();
// Create push attack visual
self.pushAttack = self.addChild(LK.getAsset('pushAttack', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
}));
// Scale attack effect from 0 to 1
tween(self.pushAttack, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 350,
easing: tween.easeOut
});
}
};
self.takeDamage = function (amount) {
if (self.invulnerable <= 0) {
self.health -= amount;
self.invulnerable = 60; // 1 second invulnerability
LK.getSound('playerHit').play();
// Flash the warrior red
LK.effects.flashObject(self, 0xff0000, 500);
if (self.health <= 0) {
// Player died
LK.showGameOver();
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x333333
});
/****
* Game Code
****/
// Game variables
var warrior = null;
var enemies = [];
var currentWave = 1;
var highestWave = storage.highestWave || 1;
var enemiesRemaining = 0;
var spawnTimer = 0;
var gameStarted = false;
var dragNode = null;
// UI Elements
var waveText = null;
var scoreText = null;
var healthBar = null;
var healthBarBg = null;
var healthBarFill = null;
var startButton = null;
var continueButton = null;
// Initialize game arena
var arena = game.addChild(LK.getAsset('arena', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.7
}));
// Initialize the UI
function initUI() {
// Score text
scoreText = new Text2('Score: 0', {
size: 70,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0); // Right aligned
LK.gui.topRight.addChild(scoreText);
// Wave text
waveText = new Text2('Wave 1/35', {
size: 70,
fill: 0xFFFFFF
});
waveText.anchor.set(0, 0); // Left aligned
LK.gui.top.addChild(waveText);
// Health bar background
healthBarBg = new Container();
healthBarBg.x = 0;
healthBarBg.y = 100;
var bgRect = LK.getAsset('healthBarBg', {
width: 800,
height: 40,
color: 0x333333,
shape: 'box',
anchorX: 0,
anchorY: 0
});
healthBarBg.addChild(bgRect);
// Health bar fill
healthBarFill = LK.getAsset('healthBarFill', {
width: 800,
height: 40,
color: 0x00cc00,
shape: 'box',
anchorX: 0,
anchorY: 0
});
healthBarBg.addChild(healthBarFill);
LK.gui.top.addChild(healthBarBg);
// Start button
startButton = new Container();
var startBg = startButton.addChild(LK.getAsset('startBg', {
width: 500,
height: 150,
color: 0x4488ff,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
}));
var startText = new Text2('START GAME', {
size: 80,
fill: 0xFFFFFF
});
startText.anchor.set(0.5, 0.5);
startButton.addChild(startText);
startButton.x = 0;
startButton.y = 0;
// Continue button (shown after game over)
continueButton = new Container();
var continueBg = continueButton.addChild(LK.getAsset('continueBg', {
width: 600,
height: 150,
color: 0x44aa44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
}));
var continueText = new Text2('CONTINUE', {
size: 80,
fill: 0xFFFFFF
});
continueText.anchor.set(0.5, 0.5);
continueButton.addChild(continueText);
continueButton.x = 0;
continueButton.y = 150;
continueButton.visible = false;
// Add buttons to GUI
LK.gui.center.addChild(startButton);
LK.gui.center.addChild(continueButton);
// Add info text about highest wave reached
var infoText = new Text2('Highest Wave: ' + highestWave, {
size: 50,
fill: 0xCCCCCC
});
infoText.anchor.set(0.5, 0);
infoText.y = 100;
LK.gui.center.addChild(infoText);
}
// Initialize the player
function initPlayer() {
warrior = game.addChild(new Warrior());
warrior.x = 2048 / 2;
warrior.y = 2732 - warrior.height / 2;
}
// Start the game
function startGame() {
// Hide start UI
startButton.visible = false;
continueButton.visible = false;
// Reset game state
LK.setScore(0);
currentWave = 1;
enemies = [];
// Create player if not exists
if (!warrior) {
initPlayer();
} else {
warrior.health = 100;
warrior.pushCooldown = 0;
warrior.isAttacking = false;
warrior.invulnerable = 60; // Brief invulnerability at start
}
// Start the wave
startWave(currentWave);
gameStarted = true;
// Start the music
LK.playMusic('battleMusic', {
fade: {
start: 0,
end: 0.6,
duration: 1000
}
});
}
// Continue after death
function continueGame() {
// Hide continue UI
continueButton.visible = false;
// Reset player
initPlayer();
warrior.health = 100;
warrior.invulnerable = 60; // Brief invulnerability at start
// Start the current wave again
startWave(currentWave);
gameStarted = true;
// Restart the music
LK.playMusic('battleMusic');
}
// Start a new wave
function startWave(wave) {
// Update UI
waveText.setText('Wave ' + wave + '/35');
// Store highest wave reached
if (wave > highestWave) {
highestWave = wave;
storage.highestWave = highestWave;
}
// Clear any existing enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].destroy();
}
enemies = [];
// Determine enemy count for this wave
if (wave === 35) {
// Boss wave
enemiesRemaining = 1;
spawnTimer = 60; // Start boss spawn after 1 second
} else {
// Regular wave
enemiesRemaining = Math.min(20, 3 + Math.floor(wave * 1.5));
spawnTimer = 60; // First spawn after 1 second
}
}
// Spawn a new enemy
function spawnEnemy(type) {
var enemy = new Enemy();
enemy.init(type, currentWave);
// Random position on the edge of the arena
enemy.x = Math.random() * 2048; // Random x position across the width of the arena
enemy.y = -enemy.graphics.height; // Start just above the top of the arena
game.addChild(enemy);
enemies.push(enemy);
}
// Update UI elements
function updateUI() {
// Update score
scoreText.setText('Score: ' + LK.getScore());
// Update health bar
if (warrior) {
var healthPercent = Math.max(0, warrior.health / 100);
healthBarFill.width = 800 * healthPercent;
// Change color based on health
if (healthPercent > 0.6) {
healthBarFill.tint = 0x00cc00; // Green
} else if (healthPercent > 0.3) {
healthBarFill.tint = 0xffcc00; // Yellow
} else {
healthBarFill.tint = 0xff0000; // Red
}
}
}
// Handle touch/mouse events
function handleMove(x, y, obj) {
if (gameStarted && dragNode === warrior) {
tween(warrior, {
x: x,
y: y
}, {
duration: 100,
easing: tween.easeInOut
});
// Keep warrior within arena bounds
var arenaRadius = 700; // Slightly smaller than arena for player
var distanceFromCenter = Math.sqrt(Math.pow(warrior.x - 2048 / 2, 2) + Math.pow(warrior.y - 2732 / 2, 2));
if (distanceFromCenter > arenaRadius) {
// Push back into arena
var angle = Math.atan2(warrior.y - 2732 / 2, warrior.x - 2048 / 2);
warrior.x = 2048 / 2 + Math.cos(angle) * arenaRadius;
warrior.y = 2732 / 2 + Math.sin(angle) * arenaRadius;
}
}
}
// Handle touch/mouse down
function handleDown(x, y, obj) {
// Check if we clicked any UI buttons
if (!gameStarted) {
var startPos = game.toLocal(startButton.parent.toGlobal(startButton.position));
if (Math.abs(x - startPos.x) < 250 && Math.abs(y - startPos.y) < 75) {
startGame();
return;
}
var continuePos = game.toLocal(continueButton.parent.toGlobal(continueButton.position));
if (continueButton.visible && Math.abs(x - continuePos.x) < 300 && Math.abs(y - continuePos.y) < 75) {
continueGame();
return;
}
}
if (gameStarted) {
// Start dragging warrior
dragNode = warrior;
// If not dragging, do a push attack
if (warrior && !dragNode) {
warrior.doPushAttack();
}
}
}
// Handle touch/mouse up
function handleUp(x, y, obj) {
if (gameStarted && dragNode === warrior) {
// End dragging, do push attack
warrior.doPushAttack();
}
dragNode = null;
}
// Set up event handlers
game.move = handleMove;
game.down = handleDown;
game.up = handleUp;
// Initialize the UI
initUI();
// Main game update loop
game.update = function () {
if (!gameStarted) {
return;
}
// Update warrior
if (warrior) {
warrior.update();
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].update();
// Check if enemy is defeated
if (enemies[i].health <= 0) {
enemies[i].destroy();
enemies.splice(i, 1);
}
}
// Spawn new enemies
if (enemiesRemaining > 0) {
if (spawnTimer <= 0) {
if (currentWave === 35) {
// Boss wave
spawnEnemy('boss');
} else {
// Regular wave
spawnEnemy('minion');
}
enemiesRemaining--;
spawnTimer = currentWave === 35 ? 0 : Math.max(20, 60 - currentWave); // Faster spawns in later waves
} else {
spawnTimer--;
}
}
// Check if wave is complete
if (enemiesRemaining === 0 && enemies.length === 0) {
currentWave++;
if (currentWave > 35) {
// Game complete - victory!
LK.showYouWin();
} else {
// Start next wave
startWave(currentWave);
}
}
// Update UI
updateUI();
// Show continue button after game over
if (!gameStarted && warrior && warrior.health <= 0) {
continueButton.visible = true;
}
};
2d evil winged gargoiyle monster anger taunt Single Game mTexture. In-Game asset. 2d. Blank background. High contrast. No shadows
2D armored evil minotaur. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
2d classic landscape. night sky .horizontaly soil surface road. far distance meadow wit dark green meadow and epic medieval city. Single Game Texture. In-Game asset. 2d.
blue thunder explosion. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
2d 16 bit image the blue knight ride armored grey horse run mode. horizontal image. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows