User prompt
add player voice when lose health
User prompt
add zombies voice
User prompt
fix bugs
User prompt
zombie3 less health
User prompt
add zombie4 1.5x health
User prompt
add zombie4 health
User prompt
add zombie4 little health
User prompt
add zombie2 more health
User prompt
add zombie2 2x health
User prompt
Play a sound when firing the pistol.
User prompt
add pistol voice
User prompt
add background music
User prompt
true bullet count
User prompt
remove bullet count color rainbow
User prompt
bullet count is rainbow
User prompt
add bullet count right bottom visible
User prompt
bullets count remove
User prompt
reverse
User prompt
Written on a stop plate. bullets count visible
User prompt
bullets count text Written on a plate.
User prompt
Please fix the bug: 'tween.to is not a function' in or related to this line: 'tween.to(scoreTxt, {' Line Number: 226 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
score color is rainbow
User prompt
bullet count colour is yellow
User prompt
bullet count colour is green
User prompt
bullets count at the right bottom side
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
// Attach bullet asset (yellow box)
var bulletSprite = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 32;
self.damage = 1;
self.update = function () {
self.x += self.speed;
};
return self;
});
// LootBox class
var LootBox = Container.expand(function () {
var self = Container.call(this);
// Attach lootbox asset (orange ellipse)
var lootSprite = self.attachAsset('lootbox', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'ammo'; // 'ammo', 'medkit', 'money'
self.value = 1;
self.speed = 2.5;
self.update = function () {
self.x -= self.speed;
};
return self;
});
// Player class (stationary)
var Player = Container.expand(function () {
var self = Container.call(this);
// Attach player asset (red box)
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Gun barrel position (relative to player)
self.getGunPos = function () {
// Gun at right edge, center vertically
return {
x: self.x + playerSprite.width / 2,
y: self.y
};
};
return self;
});
// Zombie class
var Zombie = Container.expand(function (style) {
var self = Container.call(this);
// Default to style 1 if not provided
if (typeof style !== "number" || style < 1 || style > 4) style = 1;
var zombieAssetId = "zombie" + style;
// Attach zombie asset (varied style)
var zombieSprite = self.attachAsset(zombieAssetId, {
anchorX: 0.5,
anchorY: 1
});
// Set up stats
self.maxHealth = 1;
self.health = 1;
self.speed = 2;
self.reward = 10; // money for killing
// Health bar
var healthBar = self.addChild(LK.getAsset('zombieHealthBar', {
anchorX: 0.5,
anchorY: 0.5,
width: 60,
height: 10,
color: 0xff0000
}));
healthBar.y = -zombieSprite.height + 10;
// Update health bar
self.updateHealthBar = function () {
healthBar.width = 60 * (self.health / self.maxHealth);
};
// Called every tick
self.update = function () {
self.x -= self.speed;
// Health bar follows
self.updateHealthBar();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// --- Asset Initialization ---
// Add background image (centered, covers full game area)
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
width: 2048,
height: 2732
});
game.addChild(background);
// --- Game State ---
var player = null;
var bullets = [];
var zombies = [];
var lootboxes = [];
var ammo = 10;
var maxAmmo = 10;
var health = 5;
var maxHealth = 5;
var level = 1;
var zombiesToSpawn = 0;
var zombiesSpawned = 0;
var zombiesKilled = 0;
var spawnTimer = 0;
var reloadTimer = 0;
var isReloading = false;
var weaponIndex = 0;
// --- Zombie Speed Scaling ---
var zombieBaseSpeedMin = 2.0;
var zombieBaseSpeedMax = 2.5;
var zombieSpeedIncreasePerMinute = 0.5; // total increase per minute
var zombieMaxSpeed = 4.0; // maximum allowed zombie speed
var gameStartTick = null; // will be set at game start
var weapons = [{
name: "Pistol",
damage: 1,
ammo: 20,
// doubled from 10
reload: 60,
bulletSpeed: 18,
color: 0xf7e12b
}, {
name: "SMG",
damage: 1,
ammo: 40,
// doubled from 20
reload: 40,
bulletSpeed: 20,
color: 0x00bfff
}, {
name: "Shotgun",
damage: 3,
ammo: 10,
// doubled from 5
reload: 90,
bulletSpeed: 14,
color: 0xffffff
}];
var unlockedWeapons = 1; // Start with 1 weapon
// --- UI Elements ---
// Weapon name text (top center, above score)
var weaponNameTxt = new Text2('', {
size: 70,
fill: "#fff"
});
weaponNameTxt.anchor.set(0.5, 1);
weaponNameTxt.x = LK.gui.top.width / 2;
weaponNameTxt.y = 0;
LK.gui.top.addChild(weaponNameTxt);
var scoreTxt = new Text2('Score: 0', {
size: 100,
fill: "#fff"
});
// Place score at true top center
scoreTxt.anchor.set(0.5, 0);
// Position: top center
scoreTxt.x = LK.gui.top.width / 2;
scoreTxt.y = 0;
LK.gui.top.addChild(scoreTxt);
// Animate score color as rainbow using tween plugin
var rainbowColors = [0xFF0000,
// red
0xFF7F00,
// orange
0xFFFF00,
// yellow
0x00FF00,
// green
0x0000FF,
// blue
0x4B0082,
// indigo
0x9400D3 // violet
];
var rainbowIndex = 0;
function animateScoreColor() {
var nextIndex = (rainbowIndex + 1) % rainbowColors.length;
var fromColor = rainbowColors[rainbowIndex];
var toColor = rainbowColors[nextIndex];
// Animate over 400ms for smooth transition
tween.to(scoreTxt, {
tint: toColor
}, 400, {
onStart: function onStart() {
scoreTxt.tint = fromColor;
},
onUpdate: function onUpdate(obj) {
// tween plugin will update .tint property
},
onComplete: function onComplete() {
rainbowIndex = nextIndex;
animateScoreColor();
}
});
}
animateScoreColor();
// Money UI removed
var ammoTxt = new Text2('Ammo: 10 / 10', {
size: 60,
fill: "#fff"
});
ammoTxt.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(ammoTxt);
// Bullet count text (numbers)
var bulletCountTxt = new Text2('Bullets: 10', {
size: 60,
fill: 0xFFFF00
});
// Anchor bottom right
bulletCountTxt.anchor.set(1, 1);
// Place at right bottom of the screen (HUD)
bulletCountTxt.x = LK.gui.bottomRight.width;
bulletCountTxt.y = LK.gui.bottomRight.height;
LK.gui.bottomRight.addChild(bulletCountTxt);
var healthTxt = new Text2('♥♥♥♥♥', {
size: 100,
fill: 0xFF4D4D
});
healthTxt.anchor.set(0, 1);
healthTxt.x = 20;
healthTxt.y = -10;
LK.gui.bottomLeft.addChild(healthTxt);
// --- Helper Functions ---
function updateUI() {
scoreTxt.setText('Score: ' + zombiesKilled);
ammoTxt.setText('Ammo: ' + ammo + ' / ' + maxAmmo);
bulletCountTxt.setText('Bullets: ' + ammo);
var hearts = '';
for (var i = 0; i < health; i++) hearts += '♥';
for (var i = health; i < maxHealth; i++) hearts += '♡';
healthTxt.setText(hearts);
// Show weapon name
if (weapons && weapons[weaponIndex]) {
weaponNameTxt.setText(weapons[weaponIndex].name);
} else {
weaponNameTxt.setText('');
}
}
function startLevel(lvl) {
// No level or wave logic needed
zombiesKilled = 0;
spawnTimer = 0;
}
function spawnZombie() {
// Pick a random zombie style (1-4)
var zombieStyle = 1 + Math.floor(Math.random() * 4);
var z = new Zombie(zombieStyle);
// Position at right edge, random y
z.x = 2048 + 80;
z.y = 400 + Math.floor(Math.random() * (2732 - 800));
// Set fixed health and slow speed for zombies (health halved)
z.maxHealth = 1.5;
z.health = z.maxHealth;
// --- Calculate elapsed minutes since game start ---
var elapsedTicks = gameStartTick !== null ? LK.ticks - gameStartTick : 0;
var elapsedMinutes = elapsedTicks / (60 * 60); // 60 ticks per second * 60 seconds
// --- Calculate speed increase ---
var speedIncrease = zombieSpeedIncreasePerMinute * elapsedMinutes;
var minSpeed = zombieBaseSpeedMin + speedIncrease;
var maxSpeed = zombieBaseSpeedMax + speedIncrease;
// --- Clamp to max speed ---
if (minSpeed > zombieMaxSpeed) minSpeed = zombieMaxSpeed;
if (maxSpeed > zombieMaxSpeed) maxSpeed = zombieMaxSpeed;
// --- Assign speed within range ---
z.speed = minSpeed + Math.random() * (maxSpeed - minSpeed);
zombies.push(z);
game.addChild(z);
}
function spawnLootBox(x, y) {
var loot = new LootBox();
loot.x = x;
loot.y = y;
// Randomize type
var r = Math.random();
if (r < 0.5) {
loot.type = 'ammo';
loot.value = 5 + Math.floor(Math.random() * 5);
} else {
loot.type = 'medkit';
loot.value = 1;
}
lootboxes.push(loot);
game.addChild(loot);
}
// --- Game Setup ---
player = new Player();
player.x = 180;
player.y = 2732 / 2;
game.addChild(player);
// --- Input Handling ---
var lastShotTick = 0;
var dragNode = null;
// Mouse/touch move: aim gun
game.move = function (x, y, obj) {
// No drag, just aiming
// Optionally, could rotate gun sprite, but for now, just use for shooting
};
// Mouse/touch down: shoot
game.down = function (x, y, obj) {
// Only shoot if not reloading
if (isReloading) return;
if (ammo <= 0) {
// Start reload
isReloading = true;
reloadTimer = 0;
return;
}
// Fire bullet
var gunPos = player.getGunPos();
var b = new Bullet();
b.x = gunPos.x;
b.y = gunPos.y;
// Aim: calculate angle to (x, y)
var dx = x - gunPos.x;
var dy = y - gunPos.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) dist = 1;
b.speed = weapons[weaponIndex].bulletSpeed;
b.damage = weapons[weaponIndex].damage;
// Set bullet direction
b.vx = b.speed * (dx / dist);
b.vy = b.speed * (dy / dist);
// Overwrite update to use vx/vy
b.update = function () {
b.x += b.vx;
b.y += b.vy;
};
bullets.push(b);
game.addChild(b);
ammo--;
updateUI();
};
// Mouse/touch up: nothing
game.up = function (x, y, obj) {};
// --- Weapon Switching removed (no weapon name or tap to switch) ---
// --- Main Game Loop ---
game.update = function () {
// --- Spawning zombies continuously ---
spawnTimer++;
if (spawnTimer > 55) {
spawnZombie();
spawnTimer = 0;
}
// --- Bullets update ---
for (var i = bullets.length - 1; i >= 0; i--) {
var b = bullets[i];
b.update();
// Remove if off screen
if (b.x > 2048 + 100 || b.y < -100 || b.y > 2732 + 100) {
b.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with zombies
var bulletDestroyed = false;
for (var j = zombies.length - 1; j >= 0; j--) {
var z = zombies[j];
if (b.intersects(z)) {
z.health -= b.damage;
if (z.health <= 0) {
// Zombie dies
zombiesKilled++;
// Only spawn a lootbox 30% of the time
if (Math.random() < 0.3) {
spawnLootBox(z.x, z.y - 40);
}
z.destroy();
zombies.splice(j, 1);
}
b.destroy();
bullets.splice(i, 1);
bulletDestroyed = true;
break;
}
}
if (bulletDestroyed) continue;
// Check collision with lootboxes (shoot to open)
for (var k = lootboxes.length - 1; k >= 0; k--) {
var l = lootboxes[k];
if (b.intersects(l)) {
// Open lootbox and grant reward
if (l.type === 'ammo') {
ammo += l.value;
if (ammo > maxAmmo) ammo = maxAmmo;
} else if (l.type === 'medkit') {
health += l.value;
if (health > maxHealth) health = maxHealth;
}
// Increase score when shooting and opening a lootbox
zombiesKilled++;
l.destroy();
lootboxes.splice(k, 1);
b.destroy();
bullets.splice(i, 1);
bulletDestroyed = true;
break;
}
}
if (bulletDestroyed) continue;
}
// --- Zombies update ---
for (var i = zombies.length - 1; i >= 0; i--) {
var z = zombies[i];
z.update();
// If zombie reaches player
if (z.x < player.x + 60) {
// Damage player (reduced by half)
health -= 0.5;
LK.effects.flashObject(player, 0xff0000, 400);
z.destroy();
zombies.splice(i, 1);
if (health <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
}
// --- Lootboxes update ---
for (var i = lootboxes.length - 1; i >= 0; i--) {
var l = lootboxes[i];
l.update();
// If off screen
if (l.x < -100) {
l.destroy();
lootboxes.splice(i, 1);
continue;
}
// No automatic pickup; lootboxes must be shot to open
}
// --- Reloading ---
if (isReloading) {
reloadTimer++;
if (reloadTimer > weapons[weaponIndex].reload) {
isReloading = false;
ammo = maxAmmo;
updateUI();
}
}
// No level progression or waves
updateUI();
};
// --- Start Game ---
ammo = weapons[weaponIndex].ammo;
maxAmmo = weapons[weaponIndex].ammo;
health = maxHealth;
zombiesKilled = 0;
unlockedWeapons = 1;
weaponIndex = 0;
gameStartTick = LK.ticks; // Track when the game started for zombie speed scaling
startLevel(1);
updateUI(); ===================================================================
--- original.js
+++ change.js
@@ -182,8 +182,45 @@
// Position: top center
scoreTxt.x = LK.gui.top.width / 2;
scoreTxt.y = 0;
LK.gui.top.addChild(scoreTxt);
+// Animate score color as rainbow using tween plugin
+var rainbowColors = [0xFF0000,
+// red
+0xFF7F00,
+// orange
+0xFFFF00,
+// yellow
+0x00FF00,
+// green
+0x0000FF,
+// blue
+0x4B0082,
+// indigo
+0x9400D3 // violet
+];
+var rainbowIndex = 0;
+function animateScoreColor() {
+ var nextIndex = (rainbowIndex + 1) % rainbowColors.length;
+ var fromColor = rainbowColors[rainbowIndex];
+ var toColor = rainbowColors[nextIndex];
+ // Animate over 400ms for smooth transition
+ tween.to(scoreTxt, {
+ tint: toColor
+ }, 400, {
+ onStart: function onStart() {
+ scoreTxt.tint = fromColor;
+ },
+ onUpdate: function onUpdate(obj) {
+ // tween plugin will update .tint property
+ },
+ onComplete: function onComplete() {
+ rainbowIndex = nextIndex;
+ animateScoreColor();
+ }
+ });
+}
+animateScoreColor();
// Money UI removed
var ammoTxt = new Text2('Ammo: 10 / 10', {
size: 60,
fill: "#fff"