/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, currentLevel: 1, weaponPower: 1 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.damage = 1; self.range = 2000; self.distanceTraveled = 0; self.setDamage = function (value) { self.damage = value; // Increase bullet size with damage bulletGraphics.scale.set(1 + value * 0.2, 1 + value * 0.2); }; self.update = function () { self.y -= self.speed; self.distanceTraveled += self.speed; // Remove bullet if it traveled beyond its range if (self.distanceTraveled > self.range) { self.shouldRemove = true; } }; return self; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.health = 3; self.maxHealth = 3; self.speed = 2; self.pointValue = 10; self.attackCooldown = 0; self.attackRate = 120; // Frames between attacks self.setType = function (type) { switch (type) { case 'basic': enemyGraphics.tint = 0xe74c3c; // Red self.health = 3; self.maxHealth = 3; self.speed = 2; self.pointValue = 10; break; case 'fast': enemyGraphics.tint = 0xf39c12; // Orange self.health = 2; self.maxHealth = 2; self.speed = 4; self.pointValue = 15; break; case 'tank': enemyGraphics.tint = 0x8e44ad; // Purple enemyGraphics.scale.set(1.3, 1.3); self.health = 8; self.maxHealth = 8; self.speed = 1; self.pointValue = 25; break; } }; self.takeDamage = function (amount) { self.health -= amount; // Flash effect when taking damage LK.effects.flashObject(enemyGraphics, 0xffffff, 200); if (self.health <= 0) { return true; // Enemy died } return false; }; self.update = function () { // Move toward player with some randomness var targetX = playerX + (Math.random() * 100 - 50); var dx = targetX - self.x; self.x += dx * 0.02; self.y += self.speed; // Attacking logic if (self.attackCooldown <= 0) { // Check if in attack range if (self.y > 2000) { self.attack(); self.attackCooldown = self.attackRate; } } else { self.attackCooldown--; } }; self.attack = function () { // Deal damage to player when in range if (player && player.health > 0) { var isDead = player.takeDamage(1); playerHealth = player.health; // Update global variable LK.getSound('playerHit').play(); LK.effects.flashScreen(0xff0000, 200); if (isDead) { isGameOver = true; LK.showGameOver(); } } }; return self; }); var GroundTile = Container.expand(function () { var self = Container.call(this); var tileGraphics = self.attachAsset('groundTile', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.update = function () { self.y += self.speed; // Reset position when off screen if (self.y > 2732 + tileGraphics.height) { self.y = -tileGraphics.height; } }; return self; }); var Pickup = Container.expand(function () { var self = Container.call(this); var pickupGraphics = self.attachAsset('upgradePickup', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'weapon'; self.speed = 3; self.setType = function (type) { self.type = type; switch (type) { case 'weapon': pickupGraphics.tint = 0x9b59b6; // Purple break; case 'health': pickupGraphics.tint = 0x2ecc71; // Green break; case 'ammo': pickupGraphics.tint = 0xf1c40f; // Yellow break; } }; self.update = function () { self.y += self.speed; // Add a floating effect pickupGraphics.y = Math.sin(LK.ticks * 0.05) * 10; // Spin effect pickupGraphics.rotation += 0.02; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.health = 10; self.maxHealth = 10; self.ammo = 30; self.maxAmmo = 30; self.move = function (targetX) { // Smooth movement var dx = targetX - self.x; self.x += dx * 0.1; // Clamp player to screen self.x = Math.max(100, Math.min(2048 - 100, self.x)); }; self.takeDamage = function (amount) { self.health -= amount; LK.effects.flashObject(playerGraphics, 0xff0000, 200); // Check if player is dead if (self.health <= 0) { return true; // Player died } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x34495e }); /**** * Game Code ****/ // Player state variables var playerX = 2048 / 2; var playerHealth = 10; var playerMaxHealth = 10; var playerAmmo = 30; var playerMaxAmmo = 30; var weaponLevel = storage.weaponPower || 1; var currentLevel = storage.currentLevel || 1; var score = 0; var highScore = storage.highScore || 0; var isGameOver = false; // Game state variables var bullets = []; var enemies = []; var pickups = []; var groundTiles = []; var enemySpawnTimer = 0; var enemySpawnRate = 60; // Frames between enemy spawns var pickupSpawnTimer = 0; var pickupSpawnRate = 300; // Frames between pickups var wavesCompleted = 0; var enemiesInWave = 10; var enemiesSpawned = 0; var fireRate = 15; // Frames between shots var fireCooldown = 0; // Create player var player = new Player(); player.x = playerX; player.y = 2300; player.health = playerHealth; player.maxHealth = playerMaxHealth; player.ammo = playerAmmo; player.maxAmmo = playerMaxAmmo; // Set player z-index higher to ensure visibility player.scale.set(1.2, 1.2); // Slightly enlarge player for better visibility // Ensure player is added to the game's display list game.addChild(player); // Create moving ground tiles for parallax effect function setupGround() { var tileSize = 256; var tilesNeeded = Math.ceil(2048 / tileSize) + 1; // Create a container for all ground tiles to ensure proper rendering order var groundContainer = new Container(); game.addChild(groundContainer); for (var x = 0; x < tilesNeeded; x++) { for (var y = 0; y < 12; y++) { var tile = new GroundTile(); tile.x = x * tileSize; tile.y = y * tileSize - tileSize; // Alternate colors for grid effect if ((x + y) % 2 === 0) { tile.getChildAt(0).tint = 0x95a5a6; // Light grey } else { tile.getChildAt(0).tint = 0x7f8c8d; // Darker grey } groundContainer.addChild(tile); groundTiles.push(tile); } } } // Setup UI elements function setupUI() { // Score Text var scoreText = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -250; scoreText.y = 30; // Level Text var levelText = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); LK.gui.topRight.addChild(levelText); levelText.x = -250; levelText.y = 100; // Weapon Level Text var weaponText = new Text2('Weapon: 1', { size: 50, fill: 0xFFFFFF }); weaponText.anchor.set(0, 0); LK.gui.topRight.addChild(weaponText); weaponText.x = -250; weaponText.y = 170; // Health Bar Background var healthBarBg = LK.getAsset('healthBarBackground', { anchorX: 0, anchorY: 0, x: 30, y: 30 }); LK.gui.topLeft.addChild(healthBarBg); healthBarBg.x = 100; // Move away from top left corner // Health Bar var healthBarFg = LK.getAsset('healthBar', { anchorX: 0, anchorY: 0, x: 30, y: 30 }); LK.gui.topLeft.addChild(healthBarFg); healthBarFg.x = 100; // Move away from top left corner // Ammo Bar Background var ammoBarBg = LK.getAsset('ammoBarBackground', { anchorX: 0, anchorY: 0, x: 30, y: 80 }); LK.gui.topLeft.addChild(ammoBarBg); ammoBarBg.x = 100; // Move away from top left corner // Ammo Bar var ammoBarFg = LK.getAsset('ammoBar', { anchorX: 0, anchorY: 0, x: 30, y: 80 }); LK.gui.topLeft.addChild(ammoBarFg); ammoBarFg.x = 100; // Move away from top left corner // Update UI function function updateUI() { scoreText.setText('Score: ' + score); levelText.setText('Level: ' + currentLevel); weaponText.setText('Weapon: ' + weaponLevel); // Update health bar var healthPercent = Math.max(0, playerHealth / playerMaxHealth); healthBarFg.scale.x = healthPercent; // Update ammo bar var ammoPercent = Math.max(0, playerAmmo / playerMaxAmmo); ammoBarFg.scale.x = ammoPercent; // Change health bar color based on health if (healthPercent < 0.3) { healthBarFg.tint = 0xe74c3c; // Red } else if (healthPercent < 0.6) { healthBarFg.tint = 0xf39c12; // Orange } else { healthBarFg.tint = 0x2ecc71; // Green } } return updateUI; } // Function to fire a bullet function fireBullet() { if (player.ammo <= 0 || fireCooldown > 0) return; var bullet = new Bullet(); bullet.x = player.x; bullet.y = player.y - 100; bullet.setDamage(weaponLevel); game.addChild(bullet); bullets.push(bullet); // Play sound LK.getSound('shoot').play(); // Reduce ammo player.ammo--; playerAmmo = player.ammo; // Update global variable // Set cooldown fireCooldown = fireRate; } // Function to spawn an enemy function spawnEnemy() { if (enemiesSpawned >= enemiesInWave) return; var enemy = new Enemy(); // Random X position enemy.x = Math.random() * (2048 - 200) + 100; enemy.y = -200; // Determine enemy type based on level and randomness var typeRoll = Math.random(); if (currentLevel >= 3 && typeRoll < 0.2) { enemy.setType('tank'); } else if (currentLevel >= 2 && typeRoll < 0.4) { enemy.setType('fast'); } else { enemy.setType('basic'); } // Scale difficulty with level enemy.health += Math.floor(currentLevel / 2); enemy.maxHealth += Math.floor(currentLevel / 2); game.addChild(enemy); enemies.push(enemy); enemiesSpawned++; } // Function to spawn a pickup function spawnPickup() { var pickup = new Pickup(); pickup.x = Math.random() * (2048 - 200) + 100; pickup.y = -100; // Determine pickup type var typeRoll = Math.random(); if (typeRoll < 0.3) { pickup.setType('weapon'); } else if (typeRoll < 0.7) { pickup.setType('health'); } else { pickup.setType('ammo'); } game.addChild(pickup); pickups.push(pickup); } // Function to start next level function startNextLevel() { currentLevel++; // Update difficulty enemiesInWave = 10 + currentLevel * 5; enemiesSpawned = 0; enemySpawnRate = Math.max(20, 60 - currentLevel * 5); // Store progress storage.currentLevel = currentLevel; // Reset pickups for (var i = pickups.length - 1; i >= 0; i--) { pickups[i].destroy(); } pickups = []; // Play level complete sound LK.getSound('levelComplete').play(); } // Function to handle collisions function checkCollisions() { // Check bullet-enemy collisions for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (bullet.intersects(enemy)) { // Enemy takes damage var isDead = enemy.takeDamage(bullet.damage); if (isDead) { // Add score score += enemy.pointValue; // Check for high score if (score > highScore) { highScore = score; storage.highScore = highScore; } // Remove enemy enemy.destroy(); enemies.splice(j, 1); // Small chance to spawn pickup when enemy dies if (Math.random() < 0.2) { var pickup = new Pickup(); pickup.x = enemy.x; pickup.y = enemy.y; var typeRoll = Math.random(); if (typeRoll < 0.3) { pickup.setType('weapon'); } else if (typeRoll < 0.7) { pickup.setType('health'); } else { pickup.setType('ammo'); } game.addChild(pickup); pickups.push(pickup); } // Check if wave is completed if (enemies.length === 0 && enemiesSpawned >= enemiesInWave) { startNextLevel(); } } // Play hit sound LK.getSound('enemyHit').play(); // Remove bullet bullet.destroy(); bullets.splice(i, 1); break; } } } // Check player-pickup collisions for (var k = pickups.length - 1; k >= 0; k--) { var pickup = pickups[k]; // Simple distance check (approximation of player pickup range) var dx = pickup.x - playerX; var dy = pickup.y - 2300; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 150) { // Process pickup switch (pickup.type) { case 'weapon': weaponLevel = Math.min(5, weaponLevel + 1); storage.weaponPower = weaponLevel; break; case 'health': playerHealth = Math.min(playerMaxHealth, playerHealth + 3); break; case 'ammo': playerAmmo = playerMaxAmmo; break; } // Play pickup sound LK.getSound('pickup').play(); // Remove pickup pickup.destroy(); pickups.splice(k, 1); } } } // Initialize game - first setup ground, then player is added, then UI setupGround(); // Ensure player is visible by bringing it to the front after ground setup game.removeChild(player); game.addChild(player); var updateUI = setupUI(); // Play background music LK.playMusic('gameMusic', { loop: true }); // Touch controls for player movement var touching = false; var touchTarget = playerX; game.down = function (x, y) { touching = true; touchTarget = x; // Fire bullet on tap fireBullet(); }; game.move = function (x, y) { touchTarget = x; // Always update target position when mouse moves player.move(x); // Make player directly follow mouse position playerX = player.x; // Keep playerX updated for other game systems }; game.up = function (x, y) { touching = false; }; // Main game update loop game.update = function () { // Skip updates if game is over if (isGameOver) return; // Update player position player.move(touchTarget); playerX = player.x; // Keep playerX updated for other game systems // Update ground tiles for (var i = 0; i < groundTiles.length; i++) { groundTiles[i].update(); } // Update bullets for (var j = bullets.length - 1; j >= 0; j--) { bullets[j].update(); // Remove bullets that have traveled their full range if (bullets[j].shouldRemove) { bullets[j].destroy(); bullets.splice(j, 1); } } // Update enemies for (var k = 0; k < enemies.length; k++) { enemies[k].update(); // Remove enemies that are offscreen if (enemies[k].y > 2732 + 200) { enemies[k].destroy(); enemies.splice(k, 1); k--; } } // Update pickups for (var l = pickups.length - 1; l >= 0; l--) { pickups[l].update(); // Remove pickups that are offscreen if (pickups[l].y > 2732 + 100) { pickups[l].destroy(); pickups.splice(l, 1); } } // Spawn enemies if (enemySpawnTimer <= 0 && enemiesSpawned < enemiesInWave) { spawnEnemy(); enemySpawnTimer = enemySpawnRate; } else { enemySpawnTimer--; } // Spawn pickups if (pickupSpawnTimer <= 0) { if (Math.random() < 0.3) { // 30% chance to spawn a pickup spawnPickup(); } pickupSpawnTimer = pickupSpawnRate; } else { pickupSpawnTimer--; } // Regenerate ammo over time if (LK.ticks % 60 === 0 && playerAmmo < playerMaxAmmo) { playerAmmo++; } // Handle collisions checkCollisions(); // Update weapon cooldown if (fireCooldown > 0) { fireCooldown--; } // Auto-fire if holding touch if (touching && fireCooldown <= 0) { fireBullet(); } // Update UI updateUI(); // Check game over condition if (player.health <= 0 && !isGameOver) { isGameOver = true; LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
currentLevel: 1,
weaponPower: 1
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.damage = 1;
self.range = 2000;
self.distanceTraveled = 0;
self.setDamage = function (value) {
self.damage = value;
// Increase bullet size with damage
bulletGraphics.scale.set(1 + value * 0.2, 1 + value * 0.2);
};
self.update = function () {
self.y -= self.speed;
self.distanceTraveled += self.speed;
// Remove bullet if it traveled beyond its range
if (self.distanceTraveled > self.range) {
self.shouldRemove = true;
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3;
self.maxHealth = 3;
self.speed = 2;
self.pointValue = 10;
self.attackCooldown = 0;
self.attackRate = 120; // Frames between attacks
self.setType = function (type) {
switch (type) {
case 'basic':
enemyGraphics.tint = 0xe74c3c; // Red
self.health = 3;
self.maxHealth = 3;
self.speed = 2;
self.pointValue = 10;
break;
case 'fast':
enemyGraphics.tint = 0xf39c12; // Orange
self.health = 2;
self.maxHealth = 2;
self.speed = 4;
self.pointValue = 15;
break;
case 'tank':
enemyGraphics.tint = 0x8e44ad; // Purple
enemyGraphics.scale.set(1.3, 1.3);
self.health = 8;
self.maxHealth = 8;
self.speed = 1;
self.pointValue = 25;
break;
}
};
self.takeDamage = function (amount) {
self.health -= amount;
// Flash effect when taking damage
LK.effects.flashObject(enemyGraphics, 0xffffff, 200);
if (self.health <= 0) {
return true; // Enemy died
}
return false;
};
self.update = function () {
// Move toward player with some randomness
var targetX = playerX + (Math.random() * 100 - 50);
var dx = targetX - self.x;
self.x += dx * 0.02;
self.y += self.speed;
// Attacking logic
if (self.attackCooldown <= 0) {
// Check if in attack range
if (self.y > 2000) {
self.attack();
self.attackCooldown = self.attackRate;
}
} else {
self.attackCooldown--;
}
};
self.attack = function () {
// Deal damage to player when in range
if (player && player.health > 0) {
var isDead = player.takeDamage(1);
playerHealth = player.health; // Update global variable
LK.getSound('playerHit').play();
LK.effects.flashScreen(0xff0000, 200);
if (isDead) {
isGameOver = true;
LK.showGameOver();
}
}
};
return self;
});
var GroundTile = Container.expand(function () {
var self = Container.call(this);
var tileGraphics = self.attachAsset('groundTile', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.update = function () {
self.y += self.speed;
// Reset position when off screen
if (self.y > 2732 + tileGraphics.height) {
self.y = -tileGraphics.height;
}
};
return self;
});
var Pickup = Container.expand(function () {
var self = Container.call(this);
var pickupGraphics = self.attachAsset('upgradePickup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'weapon';
self.speed = 3;
self.setType = function (type) {
self.type = type;
switch (type) {
case 'weapon':
pickupGraphics.tint = 0x9b59b6; // Purple
break;
case 'health':
pickupGraphics.tint = 0x2ecc71; // Green
break;
case 'ammo':
pickupGraphics.tint = 0xf1c40f; // Yellow
break;
}
};
self.update = function () {
self.y += self.speed;
// Add a floating effect
pickupGraphics.y = Math.sin(LK.ticks * 0.05) * 10;
// Spin effect
pickupGraphics.rotation += 0.02;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 10;
self.maxHealth = 10;
self.ammo = 30;
self.maxAmmo = 30;
self.move = function (targetX) {
// Smooth movement
var dx = targetX - self.x;
self.x += dx * 0.1;
// Clamp player to screen
self.x = Math.max(100, Math.min(2048 - 100, self.x));
};
self.takeDamage = function (amount) {
self.health -= amount;
LK.effects.flashObject(playerGraphics, 0xff0000, 200);
// Check if player is dead
if (self.health <= 0) {
return true; // Player died
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x34495e
});
/****
* Game Code
****/
// Player state variables
var playerX = 2048 / 2;
var playerHealth = 10;
var playerMaxHealth = 10;
var playerAmmo = 30;
var playerMaxAmmo = 30;
var weaponLevel = storage.weaponPower || 1;
var currentLevel = storage.currentLevel || 1;
var score = 0;
var highScore = storage.highScore || 0;
var isGameOver = false;
// Game state variables
var bullets = [];
var enemies = [];
var pickups = [];
var groundTiles = [];
var enemySpawnTimer = 0;
var enemySpawnRate = 60; // Frames between enemy spawns
var pickupSpawnTimer = 0;
var pickupSpawnRate = 300; // Frames between pickups
var wavesCompleted = 0;
var enemiesInWave = 10;
var enemiesSpawned = 0;
var fireRate = 15; // Frames between shots
var fireCooldown = 0;
// Create player
var player = new Player();
player.x = playerX;
player.y = 2300;
player.health = playerHealth;
player.maxHealth = playerMaxHealth;
player.ammo = playerAmmo;
player.maxAmmo = playerMaxAmmo;
// Set player z-index higher to ensure visibility
player.scale.set(1.2, 1.2); // Slightly enlarge player for better visibility
// Ensure player is added to the game's display list
game.addChild(player);
// Create moving ground tiles for parallax effect
function setupGround() {
var tileSize = 256;
var tilesNeeded = Math.ceil(2048 / tileSize) + 1;
// Create a container for all ground tiles to ensure proper rendering order
var groundContainer = new Container();
game.addChild(groundContainer);
for (var x = 0; x < tilesNeeded; x++) {
for (var y = 0; y < 12; y++) {
var tile = new GroundTile();
tile.x = x * tileSize;
tile.y = y * tileSize - tileSize;
// Alternate colors for grid effect
if ((x + y) % 2 === 0) {
tile.getChildAt(0).tint = 0x95a5a6; // Light grey
} else {
tile.getChildAt(0).tint = 0x7f8c8d; // Darker grey
}
groundContainer.addChild(tile);
groundTiles.push(tile);
}
}
}
// Setup UI elements
function setupUI() {
// Score Text
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -250;
scoreText.y = 30;
// Level Text
var levelText = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0, 0);
LK.gui.topRight.addChild(levelText);
levelText.x = -250;
levelText.y = 100;
// Weapon Level Text
var weaponText = new Text2('Weapon: 1', {
size: 50,
fill: 0xFFFFFF
});
weaponText.anchor.set(0, 0);
LK.gui.topRight.addChild(weaponText);
weaponText.x = -250;
weaponText.y = 170;
// Health Bar Background
var healthBarBg = LK.getAsset('healthBarBackground', {
anchorX: 0,
anchorY: 0,
x: 30,
y: 30
});
LK.gui.topLeft.addChild(healthBarBg);
healthBarBg.x = 100; // Move away from top left corner
// Health Bar
var healthBarFg = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0,
x: 30,
y: 30
});
LK.gui.topLeft.addChild(healthBarFg);
healthBarFg.x = 100; // Move away from top left corner
// Ammo Bar Background
var ammoBarBg = LK.getAsset('ammoBarBackground', {
anchorX: 0,
anchorY: 0,
x: 30,
y: 80
});
LK.gui.topLeft.addChild(ammoBarBg);
ammoBarBg.x = 100; // Move away from top left corner
// Ammo Bar
var ammoBarFg = LK.getAsset('ammoBar', {
anchorX: 0,
anchorY: 0,
x: 30,
y: 80
});
LK.gui.topLeft.addChild(ammoBarFg);
ammoBarFg.x = 100; // Move away from top left corner
// Update UI function
function updateUI() {
scoreText.setText('Score: ' + score);
levelText.setText('Level: ' + currentLevel);
weaponText.setText('Weapon: ' + weaponLevel);
// Update health bar
var healthPercent = Math.max(0, playerHealth / playerMaxHealth);
healthBarFg.scale.x = healthPercent;
// Update ammo bar
var ammoPercent = Math.max(0, playerAmmo / playerMaxAmmo);
ammoBarFg.scale.x = ammoPercent;
// Change health bar color based on health
if (healthPercent < 0.3) {
healthBarFg.tint = 0xe74c3c; // Red
} else if (healthPercent < 0.6) {
healthBarFg.tint = 0xf39c12; // Orange
} else {
healthBarFg.tint = 0x2ecc71; // Green
}
}
return updateUI;
}
// Function to fire a bullet
function fireBullet() {
if (player.ammo <= 0 || fireCooldown > 0) return;
var bullet = new Bullet();
bullet.x = player.x;
bullet.y = player.y - 100;
bullet.setDamage(weaponLevel);
game.addChild(bullet);
bullets.push(bullet);
// Play sound
LK.getSound('shoot').play();
// Reduce ammo
player.ammo--;
playerAmmo = player.ammo; // Update global variable
// Set cooldown
fireCooldown = fireRate;
}
// Function to spawn an enemy
function spawnEnemy() {
if (enemiesSpawned >= enemiesInWave) return;
var enemy = new Enemy();
// Random X position
enemy.x = Math.random() * (2048 - 200) + 100;
enemy.y = -200;
// Determine enemy type based on level and randomness
var typeRoll = Math.random();
if (currentLevel >= 3 && typeRoll < 0.2) {
enemy.setType('tank');
} else if (currentLevel >= 2 && typeRoll < 0.4) {
enemy.setType('fast');
} else {
enemy.setType('basic');
}
// Scale difficulty with level
enemy.health += Math.floor(currentLevel / 2);
enemy.maxHealth += Math.floor(currentLevel / 2);
game.addChild(enemy);
enemies.push(enemy);
enemiesSpawned++;
}
// Function to spawn a pickup
function spawnPickup() {
var pickup = new Pickup();
pickup.x = Math.random() * (2048 - 200) + 100;
pickup.y = -100;
// Determine pickup type
var typeRoll = Math.random();
if (typeRoll < 0.3) {
pickup.setType('weapon');
} else if (typeRoll < 0.7) {
pickup.setType('health');
} else {
pickup.setType('ammo');
}
game.addChild(pickup);
pickups.push(pickup);
}
// Function to start next level
function startNextLevel() {
currentLevel++;
// Update difficulty
enemiesInWave = 10 + currentLevel * 5;
enemiesSpawned = 0;
enemySpawnRate = Math.max(20, 60 - currentLevel * 5);
// Store progress
storage.currentLevel = currentLevel;
// Reset pickups
for (var i = pickups.length - 1; i >= 0; i--) {
pickups[i].destroy();
}
pickups = [];
// Play level complete sound
LK.getSound('levelComplete').play();
}
// Function to handle collisions
function checkCollisions() {
// Check bullet-enemy collisions
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
// Enemy takes damage
var isDead = enemy.takeDamage(bullet.damage);
if (isDead) {
// Add score
score += enemy.pointValue;
// Check for high score
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
}
// Remove enemy
enemy.destroy();
enemies.splice(j, 1);
// Small chance to spawn pickup when enemy dies
if (Math.random() < 0.2) {
var pickup = new Pickup();
pickup.x = enemy.x;
pickup.y = enemy.y;
var typeRoll = Math.random();
if (typeRoll < 0.3) {
pickup.setType('weapon');
} else if (typeRoll < 0.7) {
pickup.setType('health');
} else {
pickup.setType('ammo');
}
game.addChild(pickup);
pickups.push(pickup);
}
// Check if wave is completed
if (enemies.length === 0 && enemiesSpawned >= enemiesInWave) {
startNextLevel();
}
}
// Play hit sound
LK.getSound('enemyHit').play();
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
}
// Check player-pickup collisions
for (var k = pickups.length - 1; k >= 0; k--) {
var pickup = pickups[k];
// Simple distance check (approximation of player pickup range)
var dx = pickup.x - playerX;
var dy = pickup.y - 2300;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 150) {
// Process pickup
switch (pickup.type) {
case 'weapon':
weaponLevel = Math.min(5, weaponLevel + 1);
storage.weaponPower = weaponLevel;
break;
case 'health':
playerHealth = Math.min(playerMaxHealth, playerHealth + 3);
break;
case 'ammo':
playerAmmo = playerMaxAmmo;
break;
}
// Play pickup sound
LK.getSound('pickup').play();
// Remove pickup
pickup.destroy();
pickups.splice(k, 1);
}
}
}
// Initialize game - first setup ground, then player is added, then UI
setupGround();
// Ensure player is visible by bringing it to the front after ground setup
game.removeChild(player);
game.addChild(player);
var updateUI = setupUI();
// Play background music
LK.playMusic('gameMusic', {
loop: true
});
// Touch controls for player movement
var touching = false;
var touchTarget = playerX;
game.down = function (x, y) {
touching = true;
touchTarget = x;
// Fire bullet on tap
fireBullet();
};
game.move = function (x, y) {
touchTarget = x; // Always update target position when mouse moves
player.move(x); // Make player directly follow mouse position
playerX = player.x; // Keep playerX updated for other game systems
};
game.up = function (x, y) {
touching = false;
};
// Main game update loop
game.update = function () {
// Skip updates if game is over
if (isGameOver) return;
// Update player position
player.move(touchTarget);
playerX = player.x; // Keep playerX updated for other game systems
// Update ground tiles
for (var i = 0; i < groundTiles.length; i++) {
groundTiles[i].update();
}
// Update bullets
for (var j = bullets.length - 1; j >= 0; j--) {
bullets[j].update();
// Remove bullets that have traveled their full range
if (bullets[j].shouldRemove) {
bullets[j].destroy();
bullets.splice(j, 1);
}
}
// Update enemies
for (var k = 0; k < enemies.length; k++) {
enemies[k].update();
// Remove enemies that are offscreen
if (enemies[k].y > 2732 + 200) {
enemies[k].destroy();
enemies.splice(k, 1);
k--;
}
}
// Update pickups
for (var l = pickups.length - 1; l >= 0; l--) {
pickups[l].update();
// Remove pickups that are offscreen
if (pickups[l].y > 2732 + 100) {
pickups[l].destroy();
pickups.splice(l, 1);
}
}
// Spawn enemies
if (enemySpawnTimer <= 0 && enemiesSpawned < enemiesInWave) {
spawnEnemy();
enemySpawnTimer = enemySpawnRate;
} else {
enemySpawnTimer--;
}
// Spawn pickups
if (pickupSpawnTimer <= 0) {
if (Math.random() < 0.3) {
// 30% chance to spawn a pickup
spawnPickup();
}
pickupSpawnTimer = pickupSpawnRate;
} else {
pickupSpawnTimer--;
}
// Regenerate ammo over time
if (LK.ticks % 60 === 0 && playerAmmo < playerMaxAmmo) {
playerAmmo++;
}
// Handle collisions
checkCollisions();
// Update weapon cooldown
if (fireCooldown > 0) {
fireCooldown--;
}
// Auto-fire if holding touch
if (touching && fireCooldown <= 0) {
fireBullet();
}
// Update UI
updateUI();
// Check game over condition
if (player.health <= 0 && !isGameOver) {
isGameOver = true;
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
}
};
Bullet . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Bullet Ammo. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
bullet with bar ammo . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a health Bar. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a bad guy . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a good guy with weapons
Grass