Code edit (1 edits merged)
Please save this source code
User prompt
Show an option popup at the start of the game before gameplay begins
User prompt
give additional option pop up screen start of the game
Code edit (1 edits merged)
Please save this source code
User prompt
make all options inside the big popup background
User prompt
give an additional pop up screen at the start of the game
User prompt
edit the pop up screen some text is not on the pop up screen
User prompt
prevent bullets disappear after hit an enemy
User prompt
avoid bullets follow the same enemy after hitting first one
User prompt
while bullets following enemies, if ther is more than 1 bullet make them spread first and then follow enemies
User prompt
alse freeze bullets when in option screen
User prompt
Reduce the experience range curve required to level up
User prompt
add new option "bullets can follow up enemies"
User prompt
change furhter upgrades text as "Richochat +1 bounce"
User prompt
after first richochet upgrade other upgrades will be +1 bounce can u make it like that
User prompt
make richochet bullet options bounce 1 time instead of 5
User prompt
now remove the attack speed,pierce and number of bullet upgrades for automatic upgrade and make them pop up options
User prompt
now remove the attack speed,pierce and number of bullet upgrades when level up
User prompt
but power up assets can be attracted by heros collection area can u make it
User prompt
Prevent all powerup assets from being attracted by magnet effect
User prompt
make the same thing for all powerups
User prompt
bring back dragged effect for powerups while collecting
User prompt
magnet effect shouldnt attract powerups
User prompt
prevent collecting powerups with magnet effect
User prompt
enemies still moving
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// BossEnemy class (big zombie boss)
var BossEnemy = Container.expand(function () {
var self = Container.call(this);
// Preload both right and left sprites, only one visible at a time
var bossSpriteRight = self.attachAsset('boss_enemy', {
anchorX: 0.5,
anchorY: 0.5
});
bossSpriteRight.assetId = 'boss_enemy';
var bossSpriteLeft = self.attachAsset('boss_enemy_left', {
anchorX: 0.5,
anchorY: 0.5
});
bossSpriteLeft.assetId = 'boss_enemy_left';
bossSpriteLeft.visible = false;
self.radius = 120;
self.speed = 0.7;
self.hp = 30;
self._lastFacingRight = true; // Track last facing direction
self.update = function () {
if (typeof game !== "undefined" && game._levelUpFrozen) {
return;
}
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
// Face boss left/right depending on hero position, by toggling visibility
var shouldFaceRight = hero.x > self.x;
if (shouldFaceRight !== self._lastFacingRight) {
bossSpriteRight.visible = shouldFaceRight;
bossSpriteLeft.visible = !shouldFaceRight;
self._lastFacingRight = shouldFaceRight;
}
};
return self;
});
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 18;
self.speed = 9.5;
self.dirX = 1;
self.dirY = 0;
self.pierce = 1;
// Track enemies already hit by this bullet
self._hitEnemies = [];
self.update = function () {
if (typeof game !== "undefined" && game._levelUpFrozen) {
return;
}
// Homing logic: if enabled, adjust direction toward nearest enemy
if (Bullet.prototype.homing && typeof enemies !== "undefined" && enemies.length > 0) {
// Spread phase: if more than 1 bullet, spread out for a short time before homing
if (typeof bullets !== "undefined" && bullets.length > 1) {
if (typeof self._spreadTimer === "undefined") {
// Each bullet gets a unique spread angle based on its index in bullets array
var idx = 0;
for (var bidx = 0; bidx < bullets.length; bidx++) {
if (bullets[bidx] === self) {
idx = bidx;
break;
}
}
var spreadTotal = bullets.length;
var spreadAngle = Math.PI / 6; // 30 degrees total spread
var baseAngle = Math.atan2(self.dirY, self.dirX);
var angleOffset = -spreadAngle / 2 + (spreadTotal === 1 ? 0 : spreadAngle * idx / (spreadTotal - 1));
self._spreadTargetAngle = baseAngle + angleOffset;
self._spreadTimer = 12; // frames to spread before homing
}
if (self._spreadTimer > 0) {
// Lerp direction toward spread angle
var currentAngle = Math.atan2(self.dirY, self.dirX);
var targetAngle = self._spreadTargetAngle;
// Shortest angle difference
var da = targetAngle - currentAngle;
while (da > Math.PI) {
da -= Math.PI * 2;
}
while (da < -Math.PI) {
da += Math.PI * 2;
}
var lerp = 0.25;
var newAngle = currentAngle + da * lerp;
self.dirX = Math.cos(newAngle);
self.dirY = Math.sin(newAngle);
self.rotation = newAngle;
self._spreadTimer--;
} else {
// After spread, start homing
var minDist = 99999;
var nearest = null;
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
// Exclude enemies already hit by this bullet
if (self._hitEnemies.indexOf(e) !== -1) {
continue;
}
var dx = e.x - self.x;
var dy = e.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
nearest = e;
}
}
if (nearest) {
var dx = nearest.x - self.x;
var dy = nearest.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
var homingStrength = 0.18;
var targetDirX = dx / dist;
var targetDirY = dy / dist;
self.dirX = self.dirX * (1 - homingStrength) + targetDirX * homingStrength;
self.dirY = self.dirY * (1 - homingStrength) + targetDirY * homingStrength;
var norm = Math.sqrt(self.dirX * self.dirX + self.dirY * self.dirY);
if (norm > 0) {
self.dirX /= norm;
self.dirY /= norm;
}
self.rotation = Math.atan2(self.dirY, self.dirX);
}
}
}
} else {
// Only one bullet, home immediately
var minDist = 99999;
var nearest = null;
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
// Exclude enemies already hit by this bullet
if (self._hitEnemies.indexOf(e) !== -1) {
continue;
}
var dx = e.x - self.x;
var dy = e.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
nearest = e;
}
}
if (nearest) {
var dx = nearest.x - self.x;
var dy = nearest.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
var homingStrength = 0.18;
var targetDirX = dx / dist;
var targetDirY = dy / dist;
self.dirX = self.dirX * (1 - homingStrength) + targetDirX * homingStrength;
self.dirY = self.dirY * (1 - homingStrength) + targetDirY * homingStrength;
var norm = Math.sqrt(self.dirX * self.dirX + self.dirY * self.dirY);
if (norm > 0) {
self.dirX /= norm;
self.dirY /= norm;
}
self.rotation = Math.atan2(self.dirY, self.dirX);
}
}
}
}
self.x += self.dirX * self.speed;
self.y += self.dirY * self.speed;
// Ricochet logic: if enabled, on hit, bounce to nearest enemy up to N times
if (typeof self.ricochetLeft === "undefined" && Bullet.prototype.ricochet) {
self.ricochetLeft = Bullet.prototype.ricochet;
}
if (typeof self.ricochetLeft !== "undefined" && self.ricochetLeft > 0 && typeof enemies !== "undefined") {
// Ricochet handled in collision, see main game.update
}
};
return self;
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Preload both right and left sprites, only one visible at a time
var enemySpriteRight = self.attachAsset('enemy_right', {
anchorX: 0.5,
anchorY: 0.5
});
enemySpriteRight.assetId = 'enemy_right';
var enemySpriteLeft = self.attachAsset('enemy_left', {
anchorX: 0.5,
anchorY: 0.5
});
enemySpriteLeft.assetId = 'enemy_left';
enemySpriteLeft.visible = false;
self.radius = 50;
self.speed = 1.5 + Math.random();
self._lastFacingRight = true; // Track last facing direction
self.update = function () {
if (typeof game !== "undefined" && game._levelUpFrozen) {
return;
}
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
// Face enemy left/right depending on hero position, by toggling visibility
var shouldFaceRight = hero.x > self.x;
if (shouldFaceRight !== self._lastFacingRight) {
enemySpriteRight.visible = shouldFaceRight;
enemySpriteLeft.visible = !shouldFaceRight;
self._lastFacingRight = shouldFaceRight;
}
};
return self;
});
// Experience Gem class (handles both normal and big XP gems)
var Gem = Container.expand(function (opts) {
var self = Container.call(this);
// Default to normal gem
self.type = opts && opts.type || 'xp';
if (self.type === 'big') {
var gemSprite = self.attachAsset('big_xp_gem', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 30;
} else {
var gemSprite = self.attachAsset('xp_gem', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 20;
}
self.update = function () {};
return self;
});
// HeartPowerup class (can artıran kalp)
var HeartPowerup = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('heart_powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.radius = 30;
self.update = function () {};
return self;
});
// Hero class
var Hero = Container.expand(function () {
var self = Container.call(this);
// Preload both right and left hero sprites, only one visible at a time
var heroSpriteRight = self.attachAsset('hero_right', {
anchorX: 0.5,
anchorY: 0.5
});
heroSpriteRight.assetId = 'hero_right';
var heroSpriteLeft = self.attachAsset('hero_left', {
anchorX: 0.5,
anchorY: 0.5
});
heroSpriteLeft.assetId = 'hero_left';
heroSpriteLeft.visible = false;
self.radius = 60;
self.speed = 100;
self.targetX = 1024;
self.targetY = 1366;
self.magnetActive = false;
self.magnetDuration = 0;
self.magnetRange = 300;
self.magnetRangeBoosted = 800;
self._lastFacingRight = true; // Track last facing direction
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
var move = Math.min(self.speed, dist);
var prevX = self.x;
self.x += dx / dist * move;
self.y += dy / dist * move;
// Face hero left/right depending on movement direction, by toggling visibility
var shouldFaceRight = self.x > prevX;
if (shouldFaceRight !== self._lastFacingRight) {
heroSpriteRight.visible = shouldFaceRight;
heroSpriteLeft.visible = !shouldFaceRight;
self._lastFacingRight = shouldFaceRight;
}
}
if (self.magnetActive) {
// Make hero glow blue while magnet is active
if (!self._magnetGlowActive) {
LK.effects.flashObject(self, 0x00ffff, 60000); // long duration, will be reset when deactivated
self._magnetGlowActive = true;
}
// Magnet duration is now synchronized with game time (ticksSurvived)
if (typeof self.magnetEndTick === "number") {
if (typeof ticksSurvived === "number" && ticksSurvived >= self.magnetEndTick) {
self.magnetActive = false;
self.magnetDuration = 0;
self.magnetEndTick = undefined;
} else {
// Update magnetDuration for UI display
if (typeof ticksSurvived === "number") {
self.magnetDuration = self.magnetEndTick - ticksSurvived;
}
}
}
} else {
self._magnetGlowActive = false;
}
};
return self;
});
// Powerup class (now only for magnet)
var Powerup = Container.expand(function (opts) {
var self = Container.call(this);
self.isMagnet = opts && opts.isMagnet || false;
if (self.isMagnet) {
self.attachAsset('magnet_powerup', {
anchorX: 0.5,
anchorY: 0.5
});
}
self.radius = 30;
self.update = function () {};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x444444
});
/****
* Game Code
****/
// <-- Kırmızı kalp powerup shape
var hero;
var heroLives = 5;
var enemies = [];
var bullets = [];
var gems = [];
var powerups = [];
var spawnTimer = 0;
var spawnInterval = 90;
var wave = 1;
var xp = 0;
var xpToLevel = 10;
var level = 1;
var dragging = false;
var lastGameOver = false;
var scoreTxt, xpTxt, levelTxt;
var centerX = 2048 / 2;
var centerY = 2732 / 2;
// --- Option popup at game start ---
var startOptionPopup;
function showStartOptionPopup() {
// Freeze all game logic and input
game._levelUpFrozen = true;
// Remove any previous popup if present
if (typeof startOptionPopup !== "undefined" && startOptionPopup && startOptionPopup.parent) {
startOptionPopup.parent.removeChild(startOptionPopup);
startOptionPopup = null;
}
startOptionPopup = new Container();
// Dim background
var bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
bg.width = 900;
bg.height = 1500;
bg.alpha = 0.92;
bg.x = centerX;
bg.y = centerY;
startOptionPopup.addChild(bg);
// Title
var titleTxt = new Text2('Choose Your Power!', {
size: 90,
fill: "#fff"
});
titleTxt.anchor.set(0.5, 0);
titleTxt.x = centerX;
titleTxt.y = centerY - 520;
startOptionPopup.addChild(titleTxt);
// Option vertical layout
var optionStartY = centerY - 320;
var optionSpacing = 220;
// Option 1: Attack Speed Up
var opt1 = new Container();
var opt1Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt1Bg.width = 700;
opt1Bg.height = 160;
opt1Bg.alpha = 0.98;
opt1Bg.x = centerX;
opt1Bg.y = optionStartY;
opt1.addChild(opt1Bg);
var opt1Txt = new Text2('Attack Speed Up', {
size: 54,
fill: 0xF7E967
});
opt1Txt.anchor.set(0.5, 0.5);
opt1Txt.x = centerX;
opt1Txt.y = optionStartY - 25;
opt1.addChild(opt1Txt);
var opt1Desc = new Text2('Fire faster from the start!', {
size: 32,
fill: "#fff"
});
opt1Desc.anchor.set(0.5, 0.5);
opt1Desc.x = centerX;
opt1Desc.y = optionStartY + 35;
opt1.addChild(opt1Desc);
opt1.interactive = true;
opt1.down = function (x, y, obj) {
// Apply attack speed boost
autoAttackInterval = Math.max(6, autoAttackInterval - 18);
// Resume game and remove popup
if (startOptionPopup && startOptionPopup.parent) {
startOptionPopup.parent.removeChild(startOptionPopup);
startOptionPopup = null;
}
game._levelUpFrozen = false;
};
startOptionPopup.addChild(opt1);
// Option 2: Ricochet Bullet
var opt2 = new Container();
var opt2Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt2Bg.width = 700;
opt2Bg.height = 160;
opt2Bg.alpha = 0.98;
opt2Bg.x = centerX;
opt2Bg.y = optionStartY + optionSpacing;
opt2.addChild(opt2Bg);
var opt2Txt = new Text2('Ricochet Bullet', {
size: 54,
fill: 0x7BE495
});
opt2Txt.anchor.set(0.5, 0.5);
opt2Txt.x = centerX;
opt2Txt.y = optionStartY + optionSpacing - 25;
opt2.addChild(opt2Txt);
var opt2Desc = new Text2('Bullets bounce to another enemy', {
size: 40,
fill: "#fff"
});
opt2Desc.anchor.set(0.5, 0.5);
opt2Desc.x = centerX;
opt2Desc.y = optionStartY + optionSpacing + 35;
opt2.addChild(opt2Desc);
opt2.interactive = true;
opt2.down = function (x, y, obj) {
Bullet.prototype.ricochet = 1;
if (startOptionPopup && startOptionPopup.parent) {
startOptionPopup.parent.removeChild(startOptionPopup);
startOptionPopup = null;
}
game._levelUpFrozen = false;
};
startOptionPopup.addChild(opt2);
// Option 3: +1 Bullet (spread shot)
var opt3 = new Container();
var opt3Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt3Bg.width = 700;
opt3Bg.height = 160;
opt3Bg.alpha = 0.98;
opt3Bg.x = centerX;
opt3Bg.y = optionStartY + optionSpacing * 2;
opt3.addChild(opt3Bg);
var opt3Txt = new Text2('+1 Bullet (spread shot)', {
size: 54,
fill: 0xFFB347
});
opt3Txt.anchor.set(0.5, 0.5);
opt3Txt.x = centerX;
opt3Txt.y = optionStartY + optionSpacing * 2 - 25;
opt3.addChild(opt3Txt);
var opt3Desc = new Text2('Shoot more bullets at once', {
size: 32,
fill: "#fff"
});
opt3Desc.anchor.set(0.5, 0.5);
opt3Desc.x = centerX;
opt3Desc.y = optionStartY + optionSpacing * 2 + 35;
opt3.addChild(opt3Desc);
opt3.interactive = true;
opt3.down = function (x, y, obj) {
Bullet.prototype.extraBullets = 1;
if (startOptionPopup && startOptionPopup.parent) {
startOptionPopup.parent.removeChild(startOptionPopup);
startOptionPopup = null;
}
game._levelUpFrozen = false;
};
startOptionPopup.addChild(opt3);
// Option 4: Pierce +1
var opt4 = new Container();
var opt4Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt4Bg.width = 700;
opt4Bg.height = 160;
opt4Bg.alpha = 0.98;
opt4Bg.x = centerX;
opt4Bg.y = optionStartY + optionSpacing * 3;
opt4.addChild(opt4Bg);
var opt4Txt = new Text2('Pierce +1 (bullets go through more enemies)', {
size: 44,
fill: 0x7BE4FF
});
opt4Txt.anchor.set(0.5, 0.5);
opt4Txt.x = centerX;
opt4Txt.y = optionStartY + optionSpacing * 3 - 25;
opt4.addChild(opt4Txt);
var opt4Desc = new Text2('Bullets pass through more enemies', {
size: 32,
fill: "#fff"
});
opt4Desc.anchor.set(0.5, 0.5);
opt4Desc.x = centerX;
opt4Desc.y = optionStartY + optionSpacing * 3 + 35;
opt4.addChild(opt4Desc);
opt4.interactive = true;
opt4.down = function (x, y, obj) {
Bullet.prototype.pierce = 2;
if (startOptionPopup && startOptionPopup.parent) {
startOptionPopup.parent.removeChild(startOptionPopup);
startOptionPopup = null;
}
game._levelUpFrozen = false;
};
startOptionPopup.addChild(opt4);
// Option 5: Bullets can follow up enemies
var opt5 = new Container();
var opt5Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt5Bg.width = 700;
opt5Bg.height = 160;
opt5Bg.alpha = 0.98;
opt5Bg.x = centerX;
opt5Bg.y = optionStartY + optionSpacing * 4;
opt5.addChild(opt5Bg);
var opt5Txt = new Text2('Bullets can follow up enemies', {
size: 44,
fill: 0xFF77FF
});
opt5Txt.anchor.set(0.5, 0.5);
opt5Txt.x = centerX;
opt5Txt.y = optionStartY + optionSpacing * 4 - 25;
opt5.addChild(opt5Txt);
var opt5Desc = new Text2('Bullets home in on enemies', {
size: 32,
fill: "#fff"
});
opt5Desc.anchor.set(0.5, 0.5);
opt5Desc.x = centerX;
opt5Desc.y = optionStartY + optionSpacing * 4 + 35;
opt5.addChild(opt5Desc);
opt5.interactive = true;
opt5.down = function (x, y, obj) {
Bullet.prototype.homing = true;
if (startOptionPopup && startOptionPopup.parent) {
startOptionPopup.parent.removeChild(startOptionPopup);
startOptionPopup = null;
}
game._levelUpFrozen = false;
};
startOptionPopup.addChild(opt5);
// Add popup to game
game.addChild(startOptionPopup);
}
// Show the popup at game start
showStartOptionPopup();
hero = new Hero();
hero.x = centerX;
hero.y = centerY;
game.addChild(hero);
scoreTxt = new Text2('Score: 0', {
size: 54,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var livesTxt = new Text2('Lives: ' + heroLives, {
size: 36,
fill: 0xFF5555
});
livesTxt.anchor.set(0.5, 0);
livesTxt.y = 60;
LK.gui.top.addChild(livesTxt);
var timerTxt = new Text2('00:00', {
size: 54,
fill: "#fff"
});
timerTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(timerTxt);
var magnetTimerTxt = new Text2('', {
size: 44,
fill: 0x00FFFF
});
magnetTimerTxt.anchor.set(1, 0);
magnetTimerTxt.y = 60;
LK.gui.topRight.addChild(magnetTimerTxt);
xpTxt = new Text2('XP: 0/10', {
size: 36,
fill: 0x7BE495
});
xpTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(xpTxt);
xpTxt.y = 110;
levelTxt = new Text2('Level: 1', {
size: 36,
fill: 0xF7E967
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 180;
function spawnEnemy() {
var edge = Math.floor(Math.random() * 4);
var x, y;
var useRight = false;
if (edge === 0) {
x = Math.random() * 2048;
y = -100;
if (x > 1024) {
useRight = true;
}
} else if (edge === 1) {
x = 2048 + 100;
y = Math.random() * 2732;
useRight = true;
} else if (edge === 2) {
x = Math.random() * 2048;
y = 2732 + 100;
if (x > 1024) {
useRight = true;
}
} else {
x = -100;
y = Math.random() * 2732;
}
var enemy = new Enemy();
// Set initial facing direction based on spawn side
if (useRight) {
// Face right: right sprite visible, left sprite hidden
if (enemy.children && enemy.children.length > 0) {
for (var i = 0; i < enemy.children.length; i++) {
var child = enemy.children[i];
if (child.assetId === 'enemy_right') {
child.visible = true;
}
if (child.assetId === 'enemy_left') {
child.visible = false;
}
}
}
enemy._lastFacingRight = true;
} else {
// Face left: left sprite visible, right sprite hidden
if (enemy.children && enemy.children.length > 0) {
for (var i = 0; i < enemy.children.length; i++) {
var child = enemy.children[i];
if (child.assetId === 'enemy_right') {
child.visible = false;
}
if (child.assetId === 'enemy_left') {
child.visible = true;
}
}
}
enemy._lastFacingRight = false;
}
enemy.x = x;
enemy.y = y;
enemies.push(enemy);
game.addChild(enemy);
}
function spawnGem(x, y, opts) {
var gem = new Gem(opts);
gem.x = x;
gem.y = y;
gems.push(gem);
game.addChild(gem);
}
function spawnMagnetPowerup(x, y) {
var powerup = new Powerup({
isMagnet: true
}); // isMagnet parametresiyle oluştur
powerup.x = x;
powerup.y = y;
powerups.push(powerup);
game.addChild(powerup);
}
function spawnPowerup(x, y) {
var powerup = new Powerup({
isMagnet: false
}); // Diğer poweruplar
powerup.x = x;
powerup.y = y;
powerups.push(powerup);
// Remove and re-add to ensure it's above any background (if present)
if (game.children && game.children.length > 0) {
game.removeChild(powerup);
game.addChild(powerup);
} else {
game.addChild(powerup);
}
}
// Yeni: kalp powerup spawn fonksiyonu
function spawnHeartPowerup(x, y) {
var heart = new HeartPowerup();
heart.x = x;
heart.y = y;
powerups.push(heart);
game.addChild(heart);
}
function fireBullet(dx, dy) {
var bullet = new Bullet();
bullet.x = hero.x;
bullet.y = hero.y;
if (typeof Bullet.prototype.pierce === "undefined") {
Bullet.prototype.pierce = 1;
}
bullet.pierce = Bullet.prototype.pierce;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist === 0) {
bullet.dirX = 1;
bullet.dirY = 0;
} else {
bullet.dirX = dx / dist;
bullet.dirY = dy / dist;
}
bullet.rotation = Math.atan2(bullet.dirY, bullet.dirX);
bullets.push(bullet);
game.addChild(bullet);
}
function randomDir() {
var angle = Math.random() * Math.PI * 2;
return {
x: Math.cos(angle),
y: Math.sin(angle)
};
}
function dist2(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
game.down = function (x, y, obj) {
if (game._levelUpFrozen) {
return;
}
if (x < 100 && y < 100) {
return;
}
hero.targetX = x;
hero.targetY = y;
dragging = true;
};
game.move = function (x, y, obj) {
if (game._levelUpFrozen) {
return;
}
hero.targetX = x;
hero.targetY = y;
};
game.up = function (x, y, obj) {
if (game._levelUpFrozen) {
return;
}
dragging = false;
};
var ticksSurvived = 0;
var autoAttackTimer = 0;
var autoAttackInterval = 96;
game.update = function () {
if (game._levelUpFrozen) {
// Freeze all game logic and input while level up popup is active
return;
}
hero.update();
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
// Track lastWasTouchingHero for exact frame detection
if (typeof e.lastWasTouchingHero === "undefined") {
e.lastWasTouchingHero = false;
}
var isTouchingHero = dist2(e, hero) < e.radius + hero.radius;
if (!e.lastWasTouchingHero && isTouchingHero) {
LK.effects.flashScreen(0xff0000, 1000);
heroLives--;
livesTxt.setText('Lives: ' + heroLives);
if (heroLives <= 0) {
LK.showGameOver();
lastGameOver = true;
}
}
e.lastWasTouchingHero = isTouchingHero;
}
for (var i = bullets.length - 1; i >= 0; i--) {
var b = bullets[i];
b.update();
if (b.x < -100 || b.x > 2148 || b.y < -100 || b.y > 2832) {
b.destroy();
bullets.splice(i, 1);
continue;
}
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (dist2(b, e) < b.radius + e.radius) {
// Mark this enemy as hit by this bullet
if (b._hitEnemies && b._hitEnemies.indexOf(e) === -1) {
b._hitEnemies.push(e);
}
// Boss enemy logic
if (typeof e.hp === "number" && e.hp > 0) {
e.hp -= 1;
LK.effects.flashObject(e, 0xffffff, 120);
if (e.hp <= 0) {
// Boss defeated: drop multiple big gems and normal gems
for (var drop = 0; drop < 3; drop++) {
var angle = Math.random() * Math.PI * 2;
var dist = 60 + Math.random() * 40;
var gemX = e.x + Math.cos(angle) * dist;
var gemY = e.y + Math.sin(angle) * dist;
spawnGem(gemX, gemY, {
type: 'big'
});
}
for (var drop = 0; drop < 5; drop++) {
var angle = Math.random() * Math.PI * 2;
var dist = 80 + Math.random() * 60;
var gemX = e.x + Math.cos(angle) * dist;
var gemY = e.y + Math.sin(angle) * dist;
spawnGem(gemX, gemY);
}
// Always drop a magnet powerup
spawnMagnetPowerup(e.x, e.y);
// Yeni: boss öldüğünde kalp powerup düşürme (10% şans)
if (Math.random() < 0.1) {
spawnHeartPowerup(e.x, e.y);
}
e.destroy();
enemies.splice(j, 1);
}
} else {
var bigGemSpawned = false;
if (Math.random() < 0.10) {
// Drop big xp gem at 10% rate
spawnGem(e.x, e.y, {
type: 'big'
});
bigGemSpawned = true;
}
// Offset the normal gem if big gem was spawned to avoid overlap
if (bigGemSpawned) {
var offsetAngle = Math.random() * Math.PI * 2;
var offsetDist = 40;
var gemX = e.x + Math.cos(offsetAngle) * offsetDist;
var gemY = e.y + Math.sin(offsetAngle) * offsetDist;
spawnGem(gemX, gemY);
} else {
spawnGem(e.x, e.y);
}
// Set magnet drop rate to 5% (1 in 20 chance)
if (Math.random() < 0.05) {
spawnMagnetPowerup(e.x, e.y);
}
// Yeni: normal düşman öldüğünde kalp powerup düşürme (10% şans)
if (Math.random() < 0.1) {
spawnHeartPowerup(e.x, e.y);
}
e.destroy();
enemies.splice(j, 1);
}
b.pierce -= 1;
// Ricochet logic: if bullet has ricochetLeft, bounce to nearest enemy
if (typeof b.ricochetLeft !== "undefined" && b.ricochetLeft > 0 && enemies.length > 1) {
// Find nearest enemy that is not the one just hit
var minDist = 99999;
var nearest = null;
for (var ricI = 0; ricI < enemies.length; ricI++) {
var ricE = enemies[ricI];
// Exclude the just-hit enemy and any already-hit enemies
if (ricE === e) {
continue;
}
if (b._hitEnemies && b._hitEnemies.indexOf(ricE) !== -1) {
continue;
}
var d = dist2(b, ricE);
if (d < minDist) {
minDist = d;
nearest = ricE;
}
}
if (nearest) {
// Ricochet: set bullet position to current, aim at nearest enemy
var dx = nearest.x - b.x;
var dy = nearest.y - b.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
b.dirX = dx / dist;
b.dirY = dy / dist;
b.rotation = Math.atan2(b.dirY, b.dirX);
b.ricochetLeft--;
// Don't destroy or remove bullet, let it continue
// Restore pierce for next hit
b.pierce = Math.max(1, Bullet.prototype.pierce || 1);
// Move bullet slightly toward new direction to avoid instant re-collision
b.x += b.dirX * 10;
b.y += b.dirY * 10;
continue;
}
}
}
// If no ricochet, destroy as normal
if (b.pierce <= 0) {
b.destroy();
bullets.splice(i, 1);
}
break;
}
}
}
for (var i = gems.length - 1; i >= 0; i--) {
var g = gems[i];
// Set XP gem attraction area to 800 pixels when magnet is active, otherwise 150
var xpAttractRange = hero.magnetActive ? 800 : 150;
var d = dist2(g, hero);
if (d < xpAttractRange) {
var dx = hero.x - g.x;
var dy = hero.y - g.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
g.x += dx / dist * 18;
g.y += dy / dist * 18;
}
}
if (dist2(g, hero) < g.radius + hero.radius) {
// Big XP gem gives 5 XP, normal gives 1
if (g.type === 'big') {
xp += 5;
} else {
xp += 1;
}
g.destroy();
gems.splice(i, 1);
if (xp >= xpToLevel) {
level += 1;
xp = 0;
// Easier XP curve: gentler growth for faster level up
xpToLevel = 8 + level * 5 + Math.floor(level * level * 0.7);
LK.effects.flashObject(hero, 0xf7e967, 600);
// On level up, spawn a big XP gem near hero
spawnGem(hero.x + (Math.random() - 0.5) * 200, hero.y + (Math.random() - 0.5) * 200, {
type: 'big'
});
// Pause game and show level up popup with two options
// Remove any previous popup if present
if (typeof levelUpPopup !== "undefined" && levelUpPopup && levelUpPopup.parent) {
levelUpPopup.parent.removeChild(levelUpPopup);
levelUpPopup = null;
}
// Freeze all game logic and input
game._levelUpFrozen = true;
// Create popup container
var levelUpPopup = new Container();
// Dim background
var bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
// Make the popup background taller to fit all options
bg.width = 900;
bg.height = 1200;
bg.alpha = 0.92;
bg.x = centerX;
bg.y = centerY;
levelUpPopup.addChild(bg);
// Title
var titleTxt = new Text2('Level Up!', {
size: 90,
fill: "#fff"
});
titleTxt.anchor.set(0.5, 0);
titleTxt.x = centerX;
titleTxt.y = centerY - 520;
levelUpPopup.addChild(titleTxt);
// Option vertical layout: start higher, increase spacing, keep all inside popup
var optionStartY = centerY - 320;
var optionSpacing = 220;
// Option 1: Permanent Attack Speed Boost
var opt1 = new Container();
var opt1Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt1Bg.width = 700;
opt1Bg.height = 160;
opt1Bg.alpha = 0.98;
opt1Bg.x = centerX;
opt1Bg.y = optionStartY;
opt1.addChild(opt1Bg);
var opt1Txt = new Text2('Attack Speed Up', {
size: 54,
fill: 0xF7E967
});
opt1Txt.anchor.set(0.5, 0.5);
opt1Txt.x = centerX;
opt1Txt.y = optionStartY - 25;
opt1.addChild(opt1Txt);
// Description for option 1
var opt1Desc = new Text2('Fire faster every level!', {
size: 32,
fill: "#fff"
});
opt1Desc.anchor.set(0.5, 0.5);
opt1Desc.x = centerX;
opt1Desc.y = optionStartY + 35;
opt1.addChild(opt1Desc);
opt1.interactive = true;
opt1.down = function (x, y, obj) {
// Apply attack speed boost
autoAttackInterval = Math.max(6, autoAttackInterval - 12);
// Resume game and remove popup
if (levelUpPopup && levelUpPopup.parent) {
levelUpPopup.parent.removeChild(levelUpPopup);
levelUpPopup = null;
}
// Unfreeze game logic and input
game._levelUpFrozen = false;
};
levelUpPopup.addChild(opt1);
// Option 2: Ricochet bullet between 5 zombies
var opt2 = new Container();
var opt2Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt2Bg.width = 700;
opt2Bg.height = 160;
opt2Bg.alpha = 0.98;
opt2Bg.x = centerX;
opt2Bg.y = optionStartY + optionSpacing;
opt2.addChild(opt2Bg);
var ricochetText = 'Ricochet Bullet (bounces 1x)';
if (typeof Bullet.prototype.ricochet !== "undefined" && Bullet.prototype.ricochet >= 1) {
ricochetText = 'Ricochet +1 bounce';
}
var opt2Txt = new Text2(ricochetText, {
size: 54,
fill: 0x7BE495
});
opt2Txt.anchor.set(0.5, 0.5);
opt2Txt.x = centerX;
opt2Txt.y = optionStartY + optionSpacing - 25;
opt2.addChild(opt2Txt);
// Description for option 2
var opt2Desc = new Text2('Bullets bounce to another enemy', {
size: 40,
fill: "#fff"
});
opt2Desc.anchor.set(0.5, 0.5);
opt2Desc.x = centerX;
opt2Desc.y = optionStartY + optionSpacing + 35;
opt2.addChild(opt2Desc);
opt2.interactive = true;
opt2.down = function (x, y, obj) {
// If first time, set ricochet to 1, else increment by 1
if (typeof Bullet.prototype.ricochet === "undefined" || Bullet.prototype.ricochet < 1) {
Bullet.prototype.ricochet = 1;
} else {
Bullet.prototype.ricochet += 1;
}
// Resume game and remove popup
if (levelUpPopup && levelUpPopup.parent) {
levelUpPopup.parent.removeChild(levelUpPopup);
levelUpPopup = null;
}
// Unfreeze game logic and input
game._levelUpFrozen = false;
};
levelUpPopup.addChild(opt2);
// Option 3: +1 Bullet (spread shot)
var opt3 = new Container();
var opt3Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt3Bg.width = 700;
opt3Bg.height = 160;
opt3Bg.alpha = 0.98;
opt3Bg.x = centerX;
opt3Bg.y = optionStartY + optionSpacing * 2;
opt3.addChild(opt3Bg);
var opt3Txt = new Text2('+1 Bullet (spread shot)', {
size: 54,
fill: 0xFFB347
});
opt3Txt.anchor.set(0.5, 0.5);
opt3Txt.x = centerX;
opt3Txt.y = optionStartY + optionSpacing * 2 - 25;
opt3.addChild(opt3Txt);
// Description for option 3
var opt3Desc = new Text2('Shoot more bullets at once', {
size: 32,
fill: "#fff"
});
opt3Desc.anchor.set(0.5, 0.5);
opt3Desc.x = centerX;
opt3Desc.y = optionStartY + optionSpacing * 2 + 35;
opt3.addChild(opt3Desc);
opt3.interactive = true;
opt3.down = function (x, y, obj) {
// Increase number of bullets fired
if (typeof Bullet.prototype.extraBullets === "undefined") {
Bullet.prototype.extraBullets = 1;
} else {
Bullet.prototype.extraBullets += 1;
}
// Resume game and remove popup
if (levelUpPopup && levelUpPopup.parent) {
levelUpPopup.parent.removeChild(levelUpPopup);
levelUpPopup = null;
}
// Unfreeze game logic and input
game._levelUpFrozen = false;
};
levelUpPopup.addChild(opt3);
// Option 4: Pierce +1
var opt4 = new Container();
var opt4Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt4Bg.width = 700;
opt4Bg.height = 160;
opt4Bg.alpha = 0.98;
opt4Bg.x = centerX;
opt4Bg.y = optionStartY + optionSpacing * 3;
opt4.addChild(opt4Bg);
var opt4Txt = new Text2('Pierce +1 (bullets go through more enemies)', {
size: 44,
fill: 0x7BE4FF
});
opt4Txt.anchor.set(0.5, 0.5);
opt4Txt.x = centerX;
opt4Txt.y = optionStartY + optionSpacing * 3 - 25;
opt4.addChild(opt4Txt);
// Description for option 4
var opt4Desc = new Text2('Bullets pass through more enemies', {
size: 32,
fill: "#fff"
});
opt4Desc.anchor.set(0.5, 0.5);
opt4Desc.x = centerX;
opt4Desc.y = optionStartY + optionSpacing * 3 + 35;
opt4.addChild(opt4Desc);
opt4.interactive = true;
opt4.down = function (x, y, obj) {
// Increase bullet pierce
if (typeof Bullet.prototype.pierce === "undefined") {
Bullet.prototype.pierce = 2;
} else {
Bullet.prototype.pierce += 1;
}
// Resume game and remove popup
if (levelUpPopup && levelUpPopup.parent) {
levelUpPopup.parent.removeChild(levelUpPopup);
levelUpPopup = null;
}
// Unfreeze game logic and input
game._levelUpFrozen = false;
};
levelUpPopup.addChild(opt4);
// Option 5: Bullets can follow up enemies
var opt5 = new Container();
var opt5Bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
opt5Bg.width = 700;
opt5Bg.height = 160;
opt5Bg.alpha = 0.98;
opt5Bg.x = centerX;
opt5Bg.y = optionStartY + optionSpacing * 4;
opt5.addChild(opt5Bg);
var opt5Txt = new Text2('Bullets can follow up enemies', {
size: 44,
fill: 0xFF77FF
});
opt5Txt.anchor.set(0.5, 0.5);
opt5Txt.x = centerX;
opt5Txt.y = optionStartY + optionSpacing * 4 - 25;
opt5.addChild(opt5Txt);
// Description for option 5
var opt5Desc = new Text2('Bullets home in on enemies', {
size: 32,
fill: "#fff"
});
opt5Desc.anchor.set(0.5, 0.5);
opt5Desc.x = centerX;
opt5Desc.y = optionStartY + optionSpacing * 4 + 35;
opt5.addChild(opt5Desc);
opt5.interactive = true;
opt5.down = function (x, y, obj) {
Bullet.prototype.homing = true;
// Resume game and remove popup
if (levelUpPopup && levelUpPopup.parent) {
levelUpPopup.parent.removeChild(levelUpPopup);
levelUpPopup = null;
}
// Unfreeze game logic and input
game._levelUpFrozen = false;
};
levelUpPopup.addChild(opt5);
// Add popup to game
game.addChild(levelUpPopup);
}
}
}
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
// Powerup collection area: always 150px (not affected by magnet)
var powerupAttractRange = 150;
var d = dist2(p, hero);
// Attract powerups (magnet, heart, and others) if within hero's collection area (150px), but NOT by magnet effect
if (d < powerupAttractRange && d > p.radius + hero.radius) {
// Move powerup toward hero (gentle attraction)
var dx = hero.x - p.x;
var dy = hero.y - p.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
p.x += dx / dist * 10;
p.y += dy / dist * 10;
}
}
// Magnet powerup pickup radius (same as attract range)
if (p.isMagnet && d < p.radius + hero.radius) {
hero.magnetActive = true;
// Set magnetEndTick to 10 seconds (600 frames) from now, synchronized with game time
if (typeof ticksSurvived === "number") {
hero.magnetEndTick = ticksSurvived + 600;
hero.magnetDuration = 600;
} else {
hero.magnetEndTick = undefined;
hero.magnetDuration = 600;
}
hero._magnetGlowActive = false; // force re-apply blue glow in Hero.update
LK.effects.flashObject(hero, 0x00ffff, 800);
p.destroy();
powerups.splice(i, 1);
}
// Yeni: Kalp powerup toplama
else if (p.constructor === HeartPowerup && d < p.radius + hero.radius) {
heroLives++;
if (heroLives > 5) {
heroLives = 5;
}
livesTxt.setText('Lives: ' + heroLives);
p.destroy();
powerups.splice(i, 1);
}
// Diğer poweruplar için (şu an sadece magnet ve heart var)
else if (!p.isMagnet && !(p.constructor === HeartPowerup) && d < p.radius + hero.radius) {
// Pick up other powerups if needed (future-proof)
p.destroy();
powerups.splice(i, 1);
}
}
autoAttackTimer++;
if (autoAttackTimer >= autoAttackInterval) {
autoAttackTimer = 0;
var nearest = null,
minDist = 99999;
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
var d = dist2(hero, e);
if (d < minDist) {
minDist = d;
nearest = e;
}
}
if (nearest) {
var dx = nearest.x - hero.x;
var dy = nearest.y - hero.y;
// Remove automatic extra bullets from level; now controlled by upgrade
if (typeof Bullet.prototype.extraBullets === "undefined") {
Bullet.prototype.extraBullets = 0;
}
var extraBullets = Bullet.prototype.extraBullets;
var totalBullets = 1 + extraBullets;
var spread;
var baseAngle = Math.atan2(dy, dx);
if (totalBullets % 2 === 0 && totalBullets > 1) {
// Even number of bullets: 2 center bullets go straight and parallel, others scatter
var centerIdx1 = totalBullets / 2 - 1;
var centerIdx2 = totalBullets / 2;
var offsetDist = 30;
var perpAngle = baseAngle + Math.PI / 2;
// Fire center two bullets parallel
for (var b = 0; b < totalBullets; b++) {
if (b === centerIdx1 || b === centerIdx2) {
// Parallel bullets
var offset = (b === centerIdx1 ? -1 : 1) * offsetDist / 2;
var bulletX = hero.x + Math.cos(perpAngle) * offset;
var bulletY = hero.y + Math.sin(perpAngle) * offset;
var dirX = Math.cos(baseAngle);
var dirY = Math.sin(baseAngle);
var bullet = new Bullet();
bullet.x = bulletX;
bullet.y = bulletY;
bullet.pierce = Bullet.prototype.pierce || 1;
bullet.dirX = dirX;
bullet.dirY = dirY;
bullet.rotation = baseAngle;
bullets.push(bullet);
game.addChild(bullet);
} else {
// Scattered bullets
// Calculate scatter index for non-center bullets
var scatterCount = totalBullets - 2;
var scatterIdx = b < centerIdx1 ? b : b - 2;
var scatterSpread = Math.PI / 32 + (level - 2) * Math.PI / 48;
if (scatterSpread > Math.PI / 4) {
scatterSpread = Math.PI / 4;
}
var angle = baseAngle;
if (scatterCount > 1) {
angle = baseAngle - scatterSpread / 2 + scatterSpread * scatterIdx / (scatterCount - 1);
}
var dirX = Math.cos(angle);
var dirY = Math.sin(angle);
fireBullet(dirX, dirY);
}
}
} else if (level > 2) {
spread = Math.PI / 32 + (level - 2) * Math.PI / 48;
if (spread > Math.PI / 4) {
spread = Math.PI / 4;
}
for (var b = 0; b < totalBullets; b++) {
var angle = baseAngle;
if (totalBullets > 1) {
angle = baseAngle - spread / 2 + spread * b / (totalBullets - 1);
}
var dirX = Math.cos(angle);
var dirY = Math.sin(angle);
fireBullet(dirX, dirY);
}
} else {
spread = Math.PI / 16;
for (var b = 0; b < totalBullets; b++) {
var angle = baseAngle;
if (totalBullets > 1) {
angle = baseAngle - spread / 2 + spread * b / (totalBullets - 1);
}
var dirX = Math.cos(angle);
var dirY = Math.sin(angle);
fireBullet(dirX, dirY);
}
}
} else {
var extraBullets = Math.max(0, level - 1);
var totalBullets = 1 + extraBullets;
var spread;
if (level === 2) {
spread = Math.PI / 32;
} else if (level > 2) {
spread = Math.PI / 32 + (level - 2) * Math.PI / 48;
if (spread > Math.PI / 4) {
spread = Math.PI / 4;
}
} else {
spread = Math.PI / 16;
}
var baseAngle = Math.random() * Math.PI * 2;
for (var b = 0; b < totalBullets; b++) {
var angle = baseAngle;
if (totalBullets > 1) {
angle = baseAngle - spread / 2 + spread * b / (totalBullets - 1);
}
var dirX = Math.cos(angle);
var dirY = Math.sin(angle);
fireBullet(dirX, dirY);
}
}
}
spawnTimer++;
if (spawnTimer >= spawnInterval) {
spawnTimer = 0;
var toSpawn = Math.max(1, Math.floor((1 + Math.floor(wave / 3)) / 4));
for (var i = 0; i < toSpawn; i++) {
spawnEnemy();
}
// Boss spawn logic: spawn boss every 30 waves
if (typeof bossSpawnedWaves === "undefined") {
bossSpawnedWaves = {};
}
if (wave % 30 === 0 && !bossSpawnedWaves[wave]) {
var boss = new BossEnemy();
// Spawn boss at a random edge
var edge = Math.floor(Math.random() * 4);
if (edge === 0) {
boss.x = Math.random() * 2048;
boss.y = -200;
} else if (edge === 1) {
boss.x = 2048 + 200;
boss.y = Math.random() * 2732;
} else if (edge === 2) {
boss.x = Math.random() * 2048;
boss.y = 2732 + 200;
} else {
boss.x = -200;
boss.y = Math.random() * 2732;
}
enemies.push(boss);
game.addChild(boss);
bossSpawnedWaves[wave] = true;
}
wave++;
spawnInterval = Math.max(24, 90 - Math.floor(wave / 2));
}
ticksSurvived++;
scoreTxt.setText('Score: ' + Math.floor(ticksSurvived / 60));
xpTxt.setText('XP: ' + xp + '/' + xpToLevel);
levelTxt.setText('Level: ' + level);
var totalSeconds = Math.floor(ticksSurvived / 60);
var minutes = Math.floor(totalSeconds / 60);
var seconds = totalSeconds % 60;
var minStr = minutes < 10 ? '0' + minutes : '' + minutes;
var secStr = seconds < 10 ? '0' + seconds : '' + seconds;
timerTxt.setText(minStr + ':' + secStr);
// Only reset heroLives and livesTxt on game restart, not every frame
if (lastGameOver && hero && hero.parent) {
lastGameOver = false;
heroLives = 5;
if (heroLives > 5) {
heroLives = 5;
}
if (livesTxt) {
livesTxt.setText('Lives: ' + heroLives);
}
}
// Magnet timer display
if (hero.magnetActive && hero.magnetDuration > 0) {
var magnetSeconds = Math.ceil(hero.magnetDuration / 60);
magnetTimerTxt.setText('Magnet: ' + magnetSeconds + 's');
} else {
magnetTimerTxt.setText('');
}
}; ===================================================================
--- original.js
+++ change.js
@@ -385,9 +385,9 @@
anchorX: 0.5,
anchorY: 0.5
});
bg.width = 900;
- bg.height = 1200;
+ bg.height = 1500;
bg.alpha = 0.92;
bg.x = centerX;
bg.y = centerY;
startOptionPopup.addChild(bg);
16x16 pixel wounded guy holding pistol. In-Game asset. 2d. High contrast. No shadows. pixel art. retro arcade game
3x3 pixel green coin. In-Game asset. 2d. High contrast. No shadows. retro arcade. Pixel art
3x3 pixel blue coin. In-Game asset. 2d. High contrast. No shadows. Pixel art. retro arcade
4x4 pixel art heart. In-Game asset. 2d. High contrast. No shadows. retro arcade. Pixel art. 8 bit
fill the circle with yellow colour
remove cars and buildings
Create an 8-bit style effect representing a magnetic power-up area. The effect should be a circular, glowing field with a soft, pulsing light. The colors should be green and blue, with a slight gradient effect to indicate the area where objects (such as coins or experience points) are attracted towards the character. The circle should have a subtle flicker to show the magnetic pull, and it should be designed to fit within the retro, pixel-art aesthetic of an 8-bit game. In-Game asset. 2d. High contrast. No shadows
Vertical windowed filled rectangle HUD for the 2d zombie theme game. Use green colours. Do not make it too much pixelated. In-Game asset. 2d. High contrast. No shadows. No text. No icon. No background Transparent.Retro arcade theme.
windowed filled rectangle HUD button for the 2d pixel art zombie theme game. Use dark green colours. In-Game asset. 2d. High contrast. No shadows. No text. No icon. No background Transparent.Retro arcade theme.
pixelart magnet In-Game asset. 2d. High contrast. No shadows. Pixel art
pixelart red circular enemy projectile to dodge In-Game asset. 2d. High contrast. No shadows. Pixel art
pixelart yellow circular bullet to shoot enemies In-Game asset. 2d. High contrast. No shadows. Pixel art
pixelart blue circular enemy projectile to dodge In-Game asset. 2d. High contrast. No shadows. Pixel art
4x4pixel bow and arrow. In-Game asset. 2d. High contrast. No shadows. Black outline
8x8 pixel movement speed powerup icon. boot with wings. In-Game asset. 2d. High contrast. No shadows. Black outline