User prompt
make the blinking animation of all the 6 waves texts to blink 3 times only! βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Reduce the damage shots of towers and the speed
User prompt
Make the waves start if all enemies + boss of the wave are dead not by killing the boss only!
User prompt
Each wave increase the speed of the small serpent 1 2 3 4 by small amount 0.1
User prompt
Start from wave1 now.
User prompt
Go to wave4 when last boss of wave3 is been killed!
User prompt
After last boss in wave3 show wave4 text blinking then start respawning its enemies. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
After wave3 go to wave4, wave5, wave6.
User prompt
Remove what's preventing the game to continue from wave3 to wave4!
User prompt
Start from wave 3 now!
User prompt
Make the score 200
User prompt
Start from wave4
User prompt
Make enemies more slow
User prompt
Make the enemies close to each others and hard and slow
User prompt
Don't end game on wave3 continue till last wave wave 6
User prompt
Don't stop on wave3 continue
User prompt
Create wave4 with serpent3, wave5 with serpent4, then do a mix in wave6.
User prompt
do game over after wave 3 is finished.
User prompt
flip serpent1 serpent2 when they are moving to the right.
User prompt
Add wave 4 text with blinking animation centered on the middle of the screen same for wave 5, & wave 6, show wave 4 after wave 3 is finished and the bosses are dead. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
start wave 4 after wave 3 is finished! it didn't start no enemies respawned!
User prompt
After wave 3 bosses are dead do wave 4 text with blinking animation then start respawning enemies. βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
add wave 4 with same enemy of wave 1 the serpent1 but hard a bit then the first time. add wave 5 with same enemy of wave 2 the serpent2 but hard a bit then the first time. add wave 6 with mixed enemies the serpent1 and serpent2 as in the wave 3 but hard a bit then the first time.
User prompt
Do the wave 4 5 6 with same color 'orange' βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add wave 4,5,6 text with blinking animation βͺπ‘ Consider importing and using the following plugins: @upit/tween.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Enemy = Container.expand(function (path, enemyType) { var self = Container.call(this); var config = enemyConfigs[enemyType] || enemyConfigs['serpent1']; var enemyGraphics = self.attachAsset(config.asset, { anchorX: 0.5, anchorY: 0.5 }); if (config.scale) { enemyGraphics.scaleX = config.scale; enemyGraphics.scaleY = config.scale; } if (config.tint) { enemyGraphics.tint = config.tint; } self.health = config.health; self.maxHealth = config.health; self.speed = config.speed; self.path = path; self.currentWaypointIndex = 1; self.value = config.value; // Score awarded on defeat self.enemyType = enemyType; // Store enemy type for boss tracking // Create health bar only if config says to show it if (config.showHealthBar) { self.healthBar = self.addChild(LK.getAsset('healthBar', { anchorX: 0.5, anchorY: 0.5 })); self.healthBar.y = -80; // Position above enemy } self.update = function () { if (self.currentWaypointIndex >= self.path.length) { // Reached the end LK.showGameOver(); self.destroy(); // Self-destruct to avoid multiple game overs return; } var targetWaypoint = self.path[self.currentWaypointIndex]; var dx = targetWaypoint.x - self.x; var dy = targetWaypoint.y - self.y; if (config.asset === 'Serpent1' || config.asset === 'Serpent2' || config.asset === 'Serpent3' || config.asset === 'Serpent4') { var scale = config.scale || 1; if (dx > 0.1) { // moving right enemyGraphics.scaleX = -scale; } else if (dx < -0.1) { // moving left enemyGraphics.scaleX = scale; } } var angle = Math.atan2(dy, dx); self.x += Math.cos(angle) * self.speed; self.y += Math.sin(angle) * self.speed; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.speed) { self.currentWaypointIndex++; } }; self.takeDamage = function (amount) { self.health -= amount; // Update health bar width based on remaining health if it exists if (self.healthBar) { var healthPercentage = self.health / self.maxHealth; self.healthBar.scaleX = healthPercentage; } if (self.health <= 0) { return true; // Is dead } LK.effects.flashObject(self, 0xffffff, 100); return false; // Is alive }; return self; }); var Projectile = Container.expand(function (start, target, damage, projectileType) { var self = Container.call(this); projectileType = projectileType || 'projectile'; self.attachAsset(projectileType, { anchorX: 0.5, anchorY: 0.5 }); self.x = start.x; self.y = start.y; self.target = target; self.damage = damage; self.speed = 20; self.update = function () { if (!self.target || self.target.health <= 0) { // Target is gone projectiles.splice(projectiles.indexOf(self), 1); self.destroy(); return; } var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.speed) { // Hit target if (self.target.takeDamage(self.damage)) { // Enemy died LK.getSound('enemy_die').play(); LK.setScore(LK.getScore() + self.target.value); scoreTxt.setText('SCORE: ' + LK.getScore()); // Check if this was a boss if (self.target.enemyType && (self.target.enemyType === 'boss1' || self.target.enemyType === 'boss2' || self.target.enemyType === 'boss3' || self.target.enemyType === 'boss4')) { // For wave 3 and 6, we need both bosses killed if (currentWave === 3 || currentWave === 6) { // Check if all bosses are killed var bossesRemaining = 0; for (var j = 0; j < enemies.length; j++) { if (enemies[j].enemyType === 'boss1' || enemies[j].enemyType === 'boss2' || enemies[j].enemyType === 'boss3' || enemies[j].enemyType === 'boss4') { bossesRemaining++; } } if (bossesRemaining === 0) { waveBossKilled = true; } } else { waveBossKilled = true; } } enemies.splice(enemies.indexOf(self.target), 1); self.target.destroy(); } projectiles.splice(projectiles.indexOf(self), 1); self.destroy(); } else { // Move towards target var angle = Math.atan2(dy, dx); self.x += Math.cos(angle) * self.speed; self.y += Math.sin(angle) * self.speed; } }; return self; }); var Tower = Container.expand(function (config) { var self = Container.call(this); self.config = config; self.attachAsset(config.asset, { anchorX: 0.5, anchorY: 0.5 }); self.cost = config.cost; self.damage = config.damage; self.range = 400; // All towers have same range for now self.fireRate = config.fireRate; // shots per second self.cooldown = 0; self.isTower = true; self.down = function (x, y, obj) { // This makes the tower a "button" console.log("Tower clicked! Damage: " + self.damage); LK.effects.flashObject(self, 0xffffff, 200); }; self.update = function () { if (self.cooldown > 0) { self.cooldown--; return; } var target = findClosestEnemy(self.x, self.y, self.range); if (target) { fireProjectile(self, target); self.cooldown = 60 / self.fireRate; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1e272e }); /**** * Game Code ****/ // The engine will automatically create these assets based on their usage below. // --- Constants & Game State --- var MAP_WIDTH = 4000; var MAP_HEIGHT = 4800; var CELL_SIZE = 200; var GRID_WIDTH = MAP_WIDTH / CELL_SIZE; var GRID_HEIGHT = MAP_HEIGHT / CELL_SIZE; // Grid states: 0=empty, 1=path, 2=buildable, 3=occupied var grid = []; // Wave system var currentWave = 4; var enemiesSpawnedInWave = 0; var waveSpawnTimer = null; var waveBossKilled = false; var isShowingWaveText = false; var enemyConfigs = { 'serpent1': { asset: 'Serpent1', health: 250, speed: 0.7, value: 10, showHealthBar: true }, 'serpent2': { asset: 'Serpent2', health: 300, speed: 0.6, value: 15, showHealthBar: true }, 'serpent1_big': { asset: 'Serpent1', health: 600, speed: 0.5, value: 30, scale: 1.5, showHealthBar: true }, 'serpent2_big': { asset: 'Serpent2', health: 750, speed: 0.4, value: 40, scale: 1.5, showHealthBar: true }, 'boss1': { asset: 'Serpent1', health: 2000, speed: 0.3, value: 100, scale: 2, tint: 0xff0000, showHealthBar: true }, 'boss2': { asset: 'Serpent2', health: 2500, speed: 0.3, value: 120, scale: 2, tint: 0xff0000, showHealthBar: true }, 'serpent3': { asset: 'Serpent3', health: 400, speed: 0.6, value: 20, showHealthBar: true }, 'serpent4': { asset: 'Serpent4', health: 500, speed: 0.5, value: 25, showHealthBar: true }, 'serpent3_big': { asset: 'Serpent3', health: 900, speed: 0.4, value: 50, scale: 1.5, showHealthBar: true }, 'serpent4_big': { asset: 'Serpent4', health: 1100, speed: 0.4, value: 60, scale: 1.5, showHealthBar: true }, 'boss3': { asset: 'Serpent3', health: 3000, speed: 0.3, value: 150, scale: 2, tint: 0xff0000, showHealthBar: true }, 'boss4': { asset: 'Serpent4', health: 3500, speed: 0.3, value: 180, scale: 2, tint: 0xff0000, showHealthBar: true } }; var pathWaypoints = [{ x: 2000 + CELL_SIZE / 2, y: -100 }, { x: 2000 + CELL_SIZE / 2, y: 800 + CELL_SIZE / 2 }, { x: 800 + CELL_SIZE / 2, y: 800 + CELL_SIZE / 2 }, { x: 800 + CELL_SIZE / 2, y: 1600 + CELL_SIZE / 2 }, { x: 3200 + CELL_SIZE / 2, y: 1600 + CELL_SIZE / 2 }, { x: 3200 + CELL_SIZE / 2, y: 2400 + CELL_SIZE / 2 }, { x: 1200 + CELL_SIZE / 2, y: 2400 + CELL_SIZE / 2 }, { x: 1200 + CELL_SIZE / 2, y: 3200 + CELL_SIZE / 2 }, { x: 2800 + CELL_SIZE / 2, y: 3200 + CELL_SIZE / 2 }, { x: 2800 + CELL_SIZE / 2, y: 4000 + CELL_SIZE / 2 }, { x: 2800 + CELL_SIZE / 2, y: 4900 }]; var enemies = []; var towers = []; var projectiles = []; var mapContainer = game.addChild(new Container()); mapContainer.width = MAP_WIDTH; mapContainer.height = MAP_HEIGHT; // Add background var gameBackground = mapContainer.addChild(LK.getAsset('gameBackground', { anchorX: 0, anchorY: 0 })); gameBackground.x = 0; gameBackground.y = 0; gameBackground.width = MAP_WIDTH; gameBackground.height = MAP_HEIGHT; var placingTowerConfig = null; var ghostTower = null; var isDraggingMap = false; var dragStart = { x: 0, y: 0 }; var mapStart = { x: 0, y: 0 }; // --- Tower Configurations --- var towerTypes = { '1': { asset: 'tower_1', cost: 50, damage: 25, fireRate: 1.5, projectileTypes: ['star'] }, '2': { asset: 'tower_2', cost: 100, damage: 60, fireRate: 1, projectileTypes: ['arrow'] }, '3': { asset: 'tower_3', cost: 150, damage: 100, fireRate: 0.75, projectileTypes: ['star', 'arrow'] } }; // --- UI --- LK.setScore(80); // Starting cash var scoreTxt = new Text2('SCORE: ' + LK.getScore(), { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.y = 20; LK.gui.top.addChild(scoreTxt); var uiContainer = LK.gui.bottom.addChild(new Container()); uiContainer.y = -20; // Move it up slightly from the absolute bottom // Create tower 1 group var towerButton1 = uiContainer.addChild(LK.getAsset('uiButton', { anchorX: 0.5, anchorY: 1 })); towerButton1.x = -300; var towerIcon1 = uiContainer.addChild(LK.getAsset('tower_1', { scaleX: 0.8, scaleY: 0.8, anchorX: 0.5, anchorY: 0.5 })); towerIcon1.x = -305; towerIcon1.y = -115; towerIcon1.down = function (x, y, obj) { startPlacingTower('1'); if (placingTowerConfig) { towerIcon1.isDragging = true; game.move(x, y, obj); } }; var towerText1 = uiContainer.addChild(new Text2('50', { size: 50, fill: '#fff', anchorX: 0.5, anchorY: 0.5 })); towerText1.x = -305 - 25; towerText1.y = -55; // Create tower 2 group var towerButton2 = uiContainer.addChild(LK.getAsset('uiButton', { anchorX: 0.5, anchorY: 1 })); var towerIcon2 = uiContainer.addChild(LK.getAsset('tower_2', { scaleX: 0.8, scaleY: 0.8, anchorX: 0.5, anchorY: 0.5 })); towerIcon2.x = -5; towerIcon2.y = -115; towerIcon2.down = function (x, y, obj) { startPlacingTower('2'); if (placingTowerConfig) { towerIcon2.isDragging = true; game.move(x, y, obj); } }; var towerText2 = uiContainer.addChild(new Text2('100', { size: 50, fill: '#fff', anchorX: 0.5, anchorY: 0.5 })); towerText2.x = -15 - 25; towerText2.y = -55; // Create tower 3 group var towerButton3 = uiContainer.addChild(LK.getAsset('uiButton', { anchorX: 0.5, anchorY: 1 })); towerButton3.x = 300; var towerIcon3 = uiContainer.addChild(LK.getAsset('tower_3', { scaleX: 0.8, scaleY: 0.8, anchorX: 0.5, anchorY: 0.5 })); towerIcon3.x = 300; towerIcon3.y = -115; towerIcon3.down = function (x, y, obj) { startPlacingTower('3'); if (placingTowerConfig) { towerIcon3.isDragging = true; game.move(x, y, obj); } }; var towerText3 = uiContainer.addChild(new Text2('150', { size: 50, fill: '#fff', anchorX: 0.5, anchorY: 0.5 })); towerText3.x = 285 - 25; towerText3.y = -55; // --- Initialization Functions --- function initializeGrid() { for (var i = 0; i < GRID_WIDTH; i++) { grid[i] = []; for (var j = 0; j < GRID_HEIGHT; j++) { grid[i][j] = 0; // Empty } } // Mark path tiles for (var k = 0; k < pathWaypoints.length - 1; k++) { var start = pathWaypoints[k]; var end = pathWaypoints[k + 1]; var p1 = { x: Math.floor(start.x / CELL_SIZE), y: Math.floor(start.y / CELL_SIZE) }; var p2 = { x: Math.floor(end.x / CELL_SIZE), y: Math.floor(end.y / CELL_SIZE) }; var x = p1.x; var y = p1.y; var dx = Math.abs(p2.x - x); var dy = Math.abs(p2.y - y); var sx = x < p2.x ? 1 : -1; var sy = y < p2.y ? 1 : -1; var err = dx - dy; while (true) { if (x >= 0 && x < GRID_WIDTH && y >= 0 && y < GRID_HEIGHT) { grid[x][y] = 1; } if (x === p2.x && y === p2.y) { break; } var e2 = 2 * err; if (e2 > -dy) { err -= dy; x += sx; } if (e2 < dx) { err += dx; y += sy; } } } // Mark buildable tiles - only those on the sides of the road segments for (var k = 0; k < pathWaypoints.length - 1; k++) { var start = pathWaypoints[k]; var end = pathWaypoints[k + 1]; var p1 = { x: Math.floor(start.x / CELL_SIZE), y: Math.floor(start.y / CELL_SIZE) }; var p2 = { x: Math.floor(end.x / CELL_SIZE), y: Math.floor(end.y / CELL_SIZE) }; // Determine if this segment is horizontal or vertical var isHorizontal = p1.y === p2.y; var isVertical = p1.x === p2.x; // Determine direction of movement to know which side to place tiles var movingRight = p2.x > p1.x; var movingDown = p2.y > p1.y; var movingLeft = p2.x < p1.x; var movingUp = p2.y < p1.y; if (isVertical) { // For vertical segments, place buildable tiles on left and right var x = p1.x; var minY = Math.min(p1.y, p2.y); var maxY = Math.max(p1.y, p2.y); for (var y = minY; y <= maxY; y++) { // Only place on sides, avoiding corners where segments meet var isCorner = false; // Check if this position is a corner (where path changes direction) for (var w = 0; w < pathWaypoints.length; w++) { var wp = pathWaypoints[w]; if (Math.floor(wp.x / CELL_SIZE) === x && Math.floor(wp.y / CELL_SIZE) === y) { isCorner = true; break; } } if (!isCorner) { // Left side if (x - 1 >= 0 && grid[x - 1][y] === 0) { grid[x - 1][y] = 2; } // Right side if (x + 1 < GRID_WIDTH && grid[x + 1][y] === 0) { grid[x + 1][y] = 2; } } } } else if (isHorizontal) { // For horizontal segments, only place on one side to avoid doubles var y = p1.y; var minX = Math.min(p1.x, p2.x); var maxX = Math.max(p1.x, p2.x); for (var x = minX; x <= maxX; x++) { // Only place on one side (top) to avoid double placement if (y - 1 >= 0 && grid[x][y - 1] === 0) { grid[x][y - 1] = 2; } } } } // Draw visual grid - buildable tiles first (background layer) for (var i = 0; i < GRID_WIDTH; i++) { for (var j = 0; j < GRID_HEIGHT; j++) { if (grid[i][j] === 2) { var buildableTile = mapContainer.addChild(LK.getAsset('buildableTile', {})); buildableTile.alpha = 0.5; buildableTile.x = i * CELL_SIZE; buildableTile.y = j * CELL_SIZE; } } } // Draw path tiles on top for (var i = 0; i < GRID_WIDTH; i++) { for (var j = 0; j < GRID_HEIGHT; j++) { if (grid[i][j] === 1) { var pathTile = mapContainer.addChild(LK.getAsset('pathTile', {})); pathTile.x = i * CELL_SIZE; pathTile.y = j * CELL_SIZE; } } } } initializeGrid(); function startPlacingTower(type) { var config = towerTypes[type]; if (LK.getScore() >= config.cost) { placingTowerConfig = config; ghostTower = mapContainer.addChild(LK.getAsset(config.asset, { anchorX: 0, anchorY: 0 })); ghostTower.alpha = 0.7; } } // --- Event Handlers --- game.down = function (x, y, obj) { var localPoint = uiContainer.toLocal({ x: x, y: y }); // If the clicked object is a tower on the map, duplicate it for placement if (obj && obj.target && (obj.target.isTower || obj.target.parent && obj.target.parent.isTower)) { var clickedTower = obj.target.isTower ? obj.target : obj.target.parent; // Find tower type from its config var myType = null; if (clickedTower.config) { for (var key in towerTypes) { if (towerTypes[key].asset === clickedTower.config.asset) { myType = key; break; } } } if (myType) { startPlacingTower(myType); if (placingTowerConfig) { game.move(x, y, obj); } } return; // Stop further processing (like map dragging) } if (!placingTowerConfig) { isDraggingMap = true; dragStart.x = x; dragStart.y = y; mapStart.x = mapContainer.x; mapStart.y = mapContainer.y; } }; game.move = function (x, y, obj) { if (placingTowerConfig) { var mapPos = mapContainer.toLocal({ x: x, y: y }); // Position ghost tower directly at cursor position without anchor offset ghostTower.x = mapPos.x; ghostTower.y = mapPos.y; var gridX = Math.floor(mapPos.x / CELL_SIZE); var gridY = Math.floor(mapPos.y / CELL_SIZE); if (gridX >= 0 && gridX < GRID_WIDTH && gridY >= 0 && gridY < GRID_HEIGHT && grid[gridX][gridY] === 2) { ghostTower.tint = 0x00ff00; // Green for valid } else { ghostTower.tint = 0xff0000; // Red for invalid } } else if (isDraggingMap) { var dx = x - dragStart.x; var dy = y - dragStart.y; // Clamp map position var newX = mapStart.x + dx; var newY = mapStart.y + dy; var gameWidth = 2048; var gameHeight = 2732; if (newX > 0) { newX = 0; } if (newY > 0) { newY = 0; } if (newX < gameWidth - MAP_WIDTH) { newX = gameWidth - MAP_WIDTH; } if (newY < gameHeight - MAP_HEIGHT) { newY = gameHeight - MAP_HEIGHT; } mapContainer.x = newX; mapContainer.y = newY; } }; game.up = function (x, y, obj) { if (placingTowerConfig) { var mapPos = mapContainer.toLocal({ x: x, y: y }); var gridX = Math.floor(mapPos.x / CELL_SIZE); var gridY = Math.floor(mapPos.y / CELL_SIZE); if (gridX >= 0 && gridX < GRID_WIDTH && gridY >= 0 && gridY < GRID_HEIGHT && grid[gridX][gridY] === 2) { if (LK.getScore() >= placingTowerConfig.cost) { var newTower = new Tower(placingTowerConfig); newTower.x = gridX * CELL_SIZE + CELL_SIZE / 2; newTower.y = gridY * CELL_SIZE + CELL_SIZE / 2; mapContainer.addChild(newTower); towers.push(newTower); grid[gridX][gridY] = 3; // Mark as occupied LK.setScore(LK.getScore() - placingTowerConfig.cost); scoreTxt.setText('SCORE: ' + LK.getScore()); LK.getSound('place_tower').play(); } } ghostTower.destroy(); ghostTower = null; placingTowerConfig = null; // Reset drag states towerIcon1.isDragging = false; towerIcon2.isDragging = false; towerIcon3.isDragging = false; } isDraggingMap = false; }; // --- Game Logic Functions --- function findClosestEnemy(x, y, range) { var closestEnemy = null; var minDistanceSq = range * range; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - x; var dy = enemy.y - y; var distanceSq = dx * dx + dy * dy; if (distanceSq < minDistanceSq) { minDistanceSq = distanceSq; closestEnemy = enemy; } } return closestEnemy; } function fireProjectile(tower, target) { var projectileTypes = tower.config.projectileTypes; for (var i = 0; i < projectileTypes.length; i++) { var projectile = new Projectile({ x: tower.x, y: tower.y }, target, tower.damage, projectileTypes[i]); // Flip arrow if enemy is to the left of tower_2 and projectile is arrow if (tower.config.asset === 'tower_2' && projectileTypes[i] === 'arrow' && target.x < tower.x) { projectile.scaleX = -1; } // Add rotation animation to star projectiles if (projectileTypes[i] === 'star') { tween(projectile, { rotation: Math.PI * 4 }, { duration: 2000 }); } projectiles.push(projectile); mapContainer.addChild(projectile); } LK.getSound('shoot').play(); } function startWave() { enemiesSpawnedInWave = 0; waveBossKilled = false; waveSpawnTimer = LK.setInterval(function () { if (enemiesSpawnedInWave >= 20) { LK.clearInterval(waveSpawnTimer); waveSpawnTimer = null; // Check for next wave after all enemies are defeated return; } enemiesSpawnedInWave++; var enemyType; // Determine enemy type based on position in wave if (currentWave === 3) { // Wave 3: Mix of serpent1 and serpent2 if (enemiesSpawnedInWave === 19) { // First boss - serpent1 boss enemyType = 'boss1'; } else if (enemiesSpawnedInWave === 20) { // Second boss - serpent2 boss enemyType = 'boss2'; } else if (enemiesSpawnedInWave === 15 || enemiesSpawnedInWave === 17) { // Big serpent1 enemies enemyType = 'serpent1_big'; } else if (enemiesSpawnedInWave === 16 || enemiesSpawnedInWave === 18) { // Big serpent2 enemies enemyType = 'serpent2_big'; } else { // Regular enemies - alternate between serpent1 and serpent2 enemyType = enemiesSpawnedInWave % 2 === 1 ? 'serpent1' : 'serpent2'; } } else if (currentWave === 6) { // Wave 6: Mix of all serpent types if (enemiesSpawnedInWave === 19) { // First boss - serpent3 boss enemyType = 'boss3'; } else if (enemiesSpawnedInWave === 20) { // Second boss - serpent4 boss enemyType = 'boss4'; } else if (enemiesSpawnedInWave === 15) { // Big serpent1 enemy enemyType = 'serpent1_big'; } else if (enemiesSpawnedInWave === 16) { // Big serpent2 enemy enemyType = 'serpent2_big'; } else if (enemiesSpawnedInWave === 17) { // Big serpent3 enemy enemyType = 'serpent3_big'; } else if (enemiesSpawnedInWave === 18) { // Big serpent4 enemy enemyType = 'serpent4_big'; } else { // Regular enemies - cycle through all serpent types var serpentTypes = ['serpent1', 'serpent2', 'serpent3', 'serpent4']; enemyType = serpentTypes[(enemiesSpawnedInWave - 1) % 4]; } } else if (enemiesSpawnedInWave === 20) { // Boss - use wave-specific boss type if (currentWave === 1) { enemyType = 'boss1'; } else if (currentWave === 2) { enemyType = 'boss2'; } else if (currentWave === 4) { enemyType = 'boss3'; } else if (currentWave === 5) { enemyType = 'boss4'; } } else if (enemiesSpawnedInWave === 18 || enemiesSpawnedInWave === 19) { // Big enemies - use wave-specific serpent type if (currentWave === 1) { enemyType = 'serpent1_big'; } else if (currentWave === 2) { enemyType = 'serpent2_big'; } else if (currentWave === 4) { enemyType = 'serpent3_big'; } else if (currentWave === 5) { enemyType = 'serpent4_big'; } } else { // Regular enemy based on wave if (currentWave === 1) { enemyType = 'serpent1'; } else if (currentWave === 2) { enemyType = 'serpent2'; } else if (currentWave === 4) { enemyType = 'serpent3'; } else if (currentWave === 5) { enemyType = 'serpent4'; } } var enemy = new Enemy(pathWaypoints, enemyType); enemy.x = pathWaypoints[0].x; enemy.y = pathWaypoints[0].y; enemies.push(enemy); mapContainer.addChild(enemy); }, 800); } // Wave text will be created dynamically when needed function showWaveText(waveNumber) { // Set flag to indicate wave text is showing isShowingWaveText = true; // Create wave text dynamically var waveText = new Text2('WAVE ' + waveNumber, { size: 120, fill: 0xFFA500 // Orange color }); waveText.anchor.set(0.5, 0.5); waveText.x = 2048 / 2; waveText.y = 2732 / 2; game.addChild(waveText); // Create blinking animation function blink() { tween(waveText, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { tween(waveText, { alpha: 1 }, { duration: 500, onFinish: blink }); } }); } blink(); // Hide wave text after 3 seconds and start spawning enemies LK.setTimeout(function () { tween.stop(waveText); tween(waveText, { alpha: 0 }, { duration: 500, onFinish: function onFinish() { waveText.destroy(); // Clear flag when wave text is destroyed isShowingWaveText = false; // Start spawning enemies after wave text disappears startWave(); } }); }, 3000); } // Show initial wave text (startWave will be called after text animation) showWaveText(4); game.update = function () { for (var i = enemies.length - 1; i >= 0; i--) { enemies[i].update(); } for (var i = towers.length - 1; i >= 0; i--) { towers[i].update(); } for (var i = projectiles.length - 1; i >= 0; i--) { projectiles[i].update(); } // Check if wave is complete and start next wave if (enemiesSpawnedInWave >= 20 && waveBossKilled && !waveSpawnTimer && !isShowingWaveText && enemies.length === 0) { currentWave++; if (currentWave <= 6) { // Reset wave state for next wave enemiesSpawnedInWave = 0; waveBossKilled = false; // Show wave text for new wave (startWave will be called after text animation) showWaveText(currentWave); } else { // All waves completed, show you win screen LK.showYouWin(); } } };
===================================================================
--- original.js
+++ change.js
@@ -190,9 +190,9 @@
var GRID_HEIGHT = MAP_HEIGHT / CELL_SIZE;
// Grid states: 0=empty, 1=path, 2=buildable, 3=occupied
var grid = [];
// Wave system
-var currentWave = 1;
+var currentWave = 4;
var enemiesSpawnedInWave = 0;
var waveSpawnTimer = null;
var waveBossKilled = false;
var isShowingWaveText = false;
@@ -904,9 +904,9 @@
});
}, 3000);
}
// Show initial wave text (startWave will be called after text animation)
-showWaveText(1);
+showWaveText(4);
game.update = function () {
for (var i = enemies.length - 1; i >= 0; i--) {
enemies[i].update();
}