User prompt
uzaylılar ateş etmiyor
User prompt
aynı hizadaki bütün uzaylılar sürekli ateş etsin
User prompt
roketle aynı hizaya gelen uzaylılar ateş etmeye başlasınlar
User prompt
roketi takip etmesinler
User prompt
uzaylılar bize sadece ateş etsin saldırmalarına gerek yok
User prompt
uzaylılar bize saldırsınlar ve bizim canımız azalsın
User prompt
uzaylılar bize ateş etsin
User prompt
uzaylılar ateş etsinler
User prompt
As the level increases in the game, the health of the enemies increases and they start shooting at us.
User prompt
seviye arttıkça düşmanların canı da artsın
User prompt
oyunda bir level bar olsun
User prompt
skor sayacı ekranda görünsün
User prompt
Keep the score counter aligned with the rocket
User prompt
skor sayacı roketin olduğu hizada yukarda olsun
User prompt
skor sayacı koy
User prompt
skor sayacı ekranın orta üstünde olsun
User prompt
yıldızlar daha belirgin olsun
User prompt
Arka planda yıldızlar olsun
User prompt
her level atlandıgında mermiler güçlensin
User prompt
düşmanların sayısı level geçişlerinde artsın
User prompt
daha güçlü düşmanlar olsun
User prompt
skor sayacı daha solda olsun
User prompt
skor biraz daha solda olsun
User prompt
Please fix the bug: 'Cannot read properties of null (reading 'y')' in or related to this line: 'levelBarContainer.y = rocket.y - rocket.height / 2 - 80; // 80px above the rocket' Line Number: 222
User prompt
seviye çubugu roketin üzerine gelsin ama hareket etmesin
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Alien class
var Alien = Container.expand(function () {
var self = Container.call(this);
var alienAsset = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = alienAsset.width;
self.height = alienAsset.height;
self.hp = 2; // Each alien takes 2 hits
self.isHit = false;
self.hitTween = null;
// For hit flash
self.flash = function () {
if (self.hitTween) {
tween.stop(alienAsset, {
tint: true
});
}
alienAsset.tint = 0xff5252;
self.hitTween = tween(alienAsset, {
tint: 0x8d3abf
}, {
duration: 200,
easing: tween.linear,
onFinish: function onFinish() {
self.hitTween = null;
}
});
};
// For movement
self.speed = 8 + Math.random() * 4; // Slightly random speed
self.update = function () {
// Only move downwards, do not follow rocket's x position
self.y += self.speed;
};
return self;
});
// Boss Alien class (for level 7)
var BossAlien = Container.expand(function () {
var self = Container.call(this);
var bossAsset = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.7,
scaleY: 1.7
});
self.width = bossAsset.width * 1.7;
self.height = bossAsset.height * 1.7;
self.hp = 6; // Boss takes 6 hits
self.isHit = false;
self.hitTween = null;
self.flash = function () {
if (self.hitTween) {
tween.stop(bossAsset, {
tint: true
});
}
bossAsset.tint = 0xff5252;
self.hitTween = tween(bossAsset, {
tint: 0x8d3abf
}, {
duration: 200,
easing: tween.linear,
onFinish: function onFinish() {
self.hitTween = null;
}
});
};
self.speed = 10; // Boss is faster
self.update = function () {
// Only move downwards, do not follow rocket's x position
self.y += self.speed;
};
return self;
});
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletAsset = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -32; // Upwards
self.power = bulletPower; // Set bullet power at creation
self.update = function () {
self.y += self.speed;
};
return self;
});
// Enemy bullet class (alien shoots at player)
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletAsset = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletAsset.tint = 0xff5252; // Red tint for enemy bullets
self.speed = 18; // Downwards, slower than player bullet
self.update = function () {
self.y += self.speed;
};
return self;
});
// Rocket (player) class
var Rocket = Container.expand(function () {
var self = Container.call(this);
var rocketAsset = self.attachAsset('rocket', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = rocketAsset.width;
self.height = rocketAsset.height;
// For hit flash
self.flashTween = null;
// Show hit flash
self.flash = function () {
if (self.flashTween) {
tween.stop(rocketAsset, {
tint: true
});
}
rocketAsset.tint = 0xff5252;
self.flashTween = tween(rocketAsset, {
tint: 0x4fc3f7
}, {
duration: 400,
easing: tween.linear,
onFinish: function onFinish() {
self.flashTween = null;
}
});
};
return self;
});
// Star class for animated background stars
var Star = Container.expand(function () {
var self = Container.call(this);
// Use a larger ellipse for the star to make it more visible
var size = 6 + Math.random() * 8; // Increased min and max size
var starAsset = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size / 160,
scaleY: size / 160
});
// Brighter color choices for more visibility
var colorChoices = [0xffffff, 0xe3f2fd, 0xfffde7, 0xb3e5fc, 0xfff9c4];
starAsset.tint = colorChoices[Math.floor(Math.random() * colorChoices.length)];
self.width = size;
self.height = size;
self.speed = 2.5 + Math.random() * 4.5;
// Higher minimum alpha for more visible stars
self.alpha = 0.7 + Math.random() * 0.3;
self.update = function () {
self.y += self.speed;
if (self.y > GAME_HEIGHT + 10) {
// Respawn at top
self.y = -10;
self.x = 10 + Math.random() * (GAME_WIDTH - 20);
self.speed = 2.5 + Math.random() * 4.5;
self.alpha = 0.7 + Math.random() * 0.3;
}
};
return self;
});
// Strong Alien class (tougher, faster)
var StrongAlien = Container.expand(function () {
var self = Container.call(this);
var alienAsset = self.attachAsset('alien', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.2
});
self.width = alienAsset.width * 1.2;
self.height = alienAsset.height * 1.2;
self.hp = 4; // Strong alien takes 4 hits
self.isHit = false;
self.hitTween = null;
self.flash = function () {
if (self.hitTween) {
tween.stop(alienAsset, {
tint: true
});
}
alienAsset.tint = 0xff5252;
self.hitTween = tween(alienAsset, {
tint: 0x8d3abf
}, {
duration: 200,
easing: tween.linear,
onFinish: function onFinish() {
self.hitTween = null;
}
});
};
// For movement
self.speed = 12 + Math.random() * 3; // Stronger and faster
self.update = function () {
// Only move downwards, do not follow rocket's x position
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Life bar background
// Life bar
// Alien hit flash
// Bullet
// Alien (enemy)
// Rocket (player)
// Game constants
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
// --- Starfield background ---
var stars = [];
var STAR_COUNT = 60;
for (var i = 0; i < STAR_COUNT; ++i) {
var star = new Star();
star.x = 10 + Math.random() * (GAME_WIDTH - 20);
star.y = Math.random() * GAME_HEIGHT;
stars.push(star);
game.addChildAt(star, 0); // Add behind all other objects
}
var ROCKET_START_LIFE = 3;
var LEVEL_TO_BOSS = 7;
// Game state
var rocket = null;
var bullets = [];
var aliens = [];
var level = 1;
var rocketLife = ROCKET_START_LIFE;
var bulletPower = 1; // Bullet power, increases every level
var canShoot = true;
var shootCooldown = 0;
var dragNode = null;
var lastMoveX = 0;
var lastMoveY = 0;
var score = 0;
var bossSpawned = false;
var enemyBullets = []; // Track enemy bullets
// GUI elements
var scoreTxt = new Text2('0', {
size: 90,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 1);
// Ensure score is always visible
scoreTxt.alpha = 1;
scoreTxt.visible = true;
// Position the score text horizontally aligned with the rocket, above it
scoreTxt.x = GAME_WIDTH / 2;
scoreTxt.y = GAME_HEIGHT - 400 - (rocket ? rocket.height / 2 : 110) - 40; // 40px above rocket top, fallback if rocket not yet created
LK.gui.top.addChild(scoreTxt);
if (LK.gui.top.children && LK.gui.top.children.length > 1) {
LK.gui.top.setChildIndex(scoreTxt, LK.gui.top.children.length - 1);
}
var lifeBarBg = LK.getAsset('lifeBarBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
var lifeBar = LK.getAsset('lifeBar', {
anchorX: 0,
anchorY: 0.5,
x: -200,
y: 0
});
var lifeBarContainer = new Container();
lifeBarContainer.addChild(lifeBarBg);
lifeBarContainer.addChild(lifeBar);
lifeBarContainer.x = GAME_WIDTH / 2;
lifeBarContainer.y = 180;
LK.gui.top.addChild(lifeBarContainer);
// Level bar background and bar
// Centered level bar (not full width)
var LEVEL_BAR_WIDTH = 900;
var levelBarBg = LK.getAsset('lifeBarBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0,
width: LEVEL_BAR_WIDTH
});
var levelBar = LK.getAsset('lifeBar', {
anchorX: 0,
anchorY: 0.5,
x: -LEVEL_BAR_WIDTH / 2,
y: 0,
width: 0 // Start empty, will be set by updateLevelBar
});
levelBar.tint = 0x1976d2; // blue for level bar
var levelBarContainer = new Container();
levelBarContainer.addChild(levelBarBg);
levelBarContainer.addChild(levelBar);
// Place the level bar container above the rocket, centered horizontally
levelBarContainer.x = GAME_WIDTH / 2;
// Delay setting y until after rocket is initialized
// LK.gui.top.addChild(levelBarContainer); // Move this after rocket is created
// Helper to update life bar
function updateLifeBar() {
var percent = rocketLife / ROCKET_START_LIFE;
if (percent < 0) percent = 0;
lifeBar.width = 400 * percent;
if (percent > 0.5) {
lifeBar.tint = 0x43a047;
} else if (percent > 0.2) {
lifeBar.tint = 0xffc107;
} else {
lifeBar.tint = 0xd32f2f;
}
}
// Helper to update level bar
function updateLevelBar() {
// Level progress: 0 to 1, based on kills in this level
var killsThisLevel = score % 10;
var percent = killsThisLevel / 10;
if (percent < 0) percent = 0;
if (percent > 1) percent = 1;
levelBar.width = LEVEL_BAR_WIDTH * percent;
// Color: blue if not full, green if full
if (percent >= 1) {
levelBar.tint = 0x43a047;
} else {
levelBar.tint = 0x1976d2;
}
}
// Helper to update level text (removed levelTxt, now only bar)
function updateLevelText() {
// No text, only bar
}
// Helper to update score text
function updateScoreText() {
scoreTxt.setText(score);
updateLevelBar();
}
// Spawn a new alien
function spawnAlien() {
var alien;
if (level === LEVEL_TO_BOSS && !bossSpawned) {
alien = new BossAlien();
// Boss hp scales with level (optional, can be made harder)
alien.hp = 6 + Math.floor((level - 1) * 1.5);
bossSpawned = true;
} else {
// 30% chance to spawn a StrongAlien, 70% normal Alien
if (Math.random() < 0.3 && level > 2) {
alien = new StrongAlien();
// StrongAlien hp increases with level
alien.hp = 4 + Math.floor((level - 1) * 0.7);
} else {
alien = new Alien();
// Alien hp increases with level
alien.hp = 2 + Math.floor((level - 1) * 0.5);
}
}
// Random x, but keep inside screen
var margin = 120;
alien.x = margin + Math.random() * (GAME_WIDTH - margin * 2);
alien.y = -alien.height / 2;
aliens.push(alien);
game.addChild(alien);
}
// Reset game state
function resetGame() {
// Remove all bullets and aliens
for (var i = 0; i < bullets.length; ++i) {
bullets[i].destroy();
}
for (var j = 0; j < aliens.length; ++j) {
aliens[j].destroy();
}
for (var k = 0; k < enemyBullets.length; ++k) {
enemyBullets[k].destroy();
}
bullets = [];
aliens = [];
enemyBullets = [];
level = 1;
rocketLife = ROCKET_START_LIFE;
canShoot = true;
shootCooldown = 0;
dragNode = null;
lastMoveX = 0;
lastMoveY = 0;
score = 0;
bossSpawned = false;
updateLevelText();
updateScoreText();
updateLifeBar();
updateLevelBar();
}
// Initialize rocket
rocket = new Rocket();
rocket.x = GAME_WIDTH / 2;
rocket.y = GAME_HEIGHT - 400;
game.addChild(rocket);
// Now that rocket is initialized, set levelBarContainer.y and add to GUI
levelBarContainer.y = rocket.y - rocket.height / 2 - 80; // 80px above the rocket
LK.gui.top.addChild(levelBarContainer);
// Move scoreTxt to be above the rocket, horizontally aligned
scoreTxt.x = rocket.x;
scoreTxt.y = rocket.y - rocket.height / 2 - 40; // 40px above rocket top
// Initial GUI
updateLevelText();
updateScoreText();
updateLifeBar();
updateLevelBar();
// Touch/move controls
game.down = function (x, y, obj) {
// Only start drag if touch is on rocket
var local = rocket.toLocal(game.toGlobal({
x: x,
y: y
}));
if (local.x > -rocket.width / 2 && local.x < rocket.width / 2 && local.y > -rocket.height / 2 && local.y < rocket.height / 2) {
dragNode = rocket;
lastMoveX = x;
lastMoveY = y;
}
};
game.move = function (x, y, obj) {
// Always move the rocket to the mouse/touch position, clamped to screen
var newX = x;
var halfW = rocket.width / 2;
if (newX < halfW) newX = halfW;
if (newX > GAME_WIDTH - halfW) newX = GAME_WIDTH - halfW;
rocket.x = newX;
// Y position stays fixed at the starting Y
rocket.y = GAME_HEIGHT - 400;
lastMoveX = x;
lastMoveY = y;
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Tap to shoot (left mouse button or tap)
game.down = function (x, y, obj) {
// Only start drag if touch is on rocket
var local = rocket.toLocal(game.toGlobal({
x: x,
y: y
}));
if (local.x > -rocket.width / 2 && local.x < rocket.width / 2 && local.y > -rocket.height / 2 && local.y < rocket.height / 2) {
dragNode = rocket;
lastMoveX = x;
lastMoveY = y;
}
// Always allow shooting with left mouse button/tap, regardless of drag state
if (canShoot) {
shootBullet();
}
};
// Shoot bullet
function shootBullet() {
if (!canShoot) return;
var bullet = new Bullet();
bullet.x = rocket.x;
bullet.y = rocket.y - rocket.height / 2 - 20;
bullets.push(bullet);
game.addChild(bullet);
canShoot = false;
shootCooldown = 10; // 10 ticks cooldown
}
// Main update loop
game.update = function () {
// Shooting cooldown
if (!canShoot) {
shootCooldown--;
if (shootCooldown <= 0) {
canShoot = true;
}
}
// Update stars
for (var si = 0; si < stars.length; ++si) {
stars[si].update();
}
// Keep score counter aligned with rocket
scoreTxt.x = rocket.x;
scoreTxt.y = rocket.y - rocket.height / 2 - 40; // 40px above rocket top
// Level bar container stays fixed next to the stop button, do not move it
// Update bullets
for (var i = bullets.length - 1; i >= 0; --i) {
var b = bullets[i];
b.update();
// Remove if off screen
if (b.y < -100) {
b.destroy();
bullets.splice(i, 1);
continue;
}
}
// Update aliens
for (var j = aliens.length - 1; j >= 0; --j) {
var a = aliens[j];
a.update();
// Remove if off screen
if (a.y > GAME_HEIGHT + 200) {
a.destroy();
aliens.splice(j, 1);
continue;
}
// Alien shooting logic: aliens shoot only when horizontally aligned with rocket
if (level > 1 && LK.ticks % Math.max(60 - level * 4, 18) === 0) {
// Only shoot if alien is on screen
if (a.y > 0 && a.y < GAME_HEIGHT - 400) {
// Check if alien is horizontally aligned with rocket (within 30px)
if (Math.abs(a.x - rocket.x) <= 30) {
// 30% chance to shoot per eligible tick, increases with level
var shootChance = 0.18 + level * 0.03;
if (Math.random() < shootChance) {
var enemyBullet = new EnemyBullet();
enemyBullet.x = a.x;
enemyBullet.y = a.y + a.height / 2 + 10;
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
}
}
}
}
// No alien-rocket collision: aliens do not damage rocket by contact
}
// Update enemy bullets
for (var eb = enemyBullets.length - 1; eb >= 0; --eb) {
var ebull = enemyBullets[eb];
ebull.update();
// Remove if off screen
if (ebull.y > GAME_HEIGHT + 100) {
ebull.destroy();
enemyBullets.splice(eb, 1);
continue;
}
// Check collision with rocket
if (ebull.intersects(rocket)) {
if (rocketLife > 0) {
rocketLife--;
updateLifeBar();
rocket.flash();
}
ebull.destroy();
enemyBullets.splice(eb, 1);
// Check for game over
if (rocketLife <= 0) {
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
}
// Bullet-alien collisions
for (var i2 = bullets.length - 1; i2 >= 0; --i2) {
var b2 = bullets[i2];
for (var j2 = aliens.length - 1; j2 >= 0; --j2) {
var a2 = aliens[j2];
if (b2.intersects(a2)) {
a2.hp -= b2.power !== undefined ? b2.power : 1; // Use bullet power, fallback to 1
a2.flash();
b2.destroy();
bullets.splice(i2, 1);
if (a2.hp <= 0) {
a2.destroy();
aliens.splice(j2, 1);
score++;
updateScoreText();
// Increase level every 10 kills
if (level < LEVEL_TO_BOSS && score % 10 === 0) {
level++;
bulletPower++; // Increase bullet power each level
updateLevelText();
}
// If boss defeated, win
if (level === LEVEL_TO_BOSS && bossSpawned && aliens.length === 0) {
LK.effects.flashScreen(0x00e676, 1000);
LK.showYouWin();
return;
}
}
break;
}
}
}
// Alien spawn logic
if (level < LEVEL_TO_BOSS) {
// Increase max aliens on screen as level increases
var maxAliens = 2 + Math.floor((level - 1) / 2); // +1 every 2 levels (2,3,4,5...)
if (aliens.length < maxAliens && LK.ticks % (60 - level * 4) === 0) {
spawnAlien();
}
} else if (level === LEVEL_TO_BOSS && !bossSpawned) {
// Spawn boss
spawnAlien();
}
};
// Initial spawn
spawnAlien(); ===================================================================
--- original.js
+++ change.js
@@ -519,20 +519,23 @@
a.destroy();
aliens.splice(j, 1);
continue;
}
- // Alien shooting logic: as level increases, aliens shoot more often
+ // Alien shooting logic: aliens shoot only when horizontally aligned with rocket
if (level > 1 && LK.ticks % Math.max(60 - level * 4, 18) === 0) {
// Only shoot if alien is on screen
if (a.y > 0 && a.y < GAME_HEIGHT - 400) {
- // 30% chance to shoot per eligible tick, increases with level
- var shootChance = 0.18 + level * 0.03;
- if (Math.random() < shootChance) {
- var enemyBullet = new EnemyBullet();
- enemyBullet.x = a.x;
- enemyBullet.y = a.y + a.height / 2 + 10;
- enemyBullets.push(enemyBullet);
- game.addChild(enemyBullet);
+ // Check if alien is horizontally aligned with rocket (within 30px)
+ if (Math.abs(a.x - rocket.x) <= 30) {
+ // 30% chance to shoot per eligible tick, increases with level
+ var shootChance = 0.18 + level * 0.03;
+ if (Math.random() < shootChance) {
+ var enemyBullet = new EnemyBullet();
+ enemyBullet.x = a.x;
+ enemyBullet.y = a.y + a.height / 2 + 10;
+ enemyBullets.push(enemyBullet);
+ game.addChild(enemyBullet);
+ }
}
}
}
// No alien-rocket collision: aliens do not damage rocket by contact