/****
* 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