User prompt
tamam bunları ekle oyuna
User prompt
kontroller de kullanıcı dostu olsun
User prompt
Please fix the bug: 'tween.to is not a function' in or related to this line: 'tween.to(instructionTxt, {' Line Number: 470 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
daha profesyonel bir oyun yap kullanıcı dostu olsun
Code edit (1 edits merged)
Please save this source code
User prompt
Endless Sky Shooter
Initial prompt
Make a professional endless shooting game with all the features that the game should have.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Enemy var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGfx = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0.5 }); self.radius = enemyGfx.width * 0.5; self.speed = 8 + Math.random() * 8; self.moveType = Math.random() < 0.5 ? 'straight' : 'sine'; self.sinePhase = Math.random() * Math.PI * 2; self.sineAmp = 120 + Math.random() * 120; self.shootCooldown = 60 + Math.floor(Math.random() * 60); // Health system for enemy self.maxHealth = 3; self.health = self.maxHealth; self.update = function () { if (self.moveType === 'straight') { self.y += self.speed; } else { self.y += self.speed * 0.85; self.x += Math.sin(self.y / 120 + self.sinePhase) * 6; } self.shootCooldown--; }; self.takeDamage = function (dmg) { self.health -= dmg; LK.effects.flashObject(self, 0xffffff, 80); if (self.health <= 0) { self.health = 0; // Death handled in game loop } }; return self; }); // Enemy Bullet var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGfx = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 20; self.dirX = 0; self.dirY = 1; self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; }; return self; }); // Player Bullet var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGfx = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -32; self.update = function () { self.y += self.speed; }; return self; }); // Powerup var Powerup = Container.expand(function () { var self = Container.call(this); var types = ['rapid', 'shield', 'heal']; var r = Math.random(); if (r < 0.4) self.type = 'rapid';else if (r < 0.8) self.type = 'shield';else self.type = 'heal'; var powerupGfx = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); if (self.type === 'rapid') powerupGfx.tint = 0xffe100;else if (self.type === 'shield') powerupGfx.tint = 0x00ffff;else powerupGfx.tint = 0x44ff44; self.speed = 10; self.update = function () { self.y += self.speed; }; return self; }); // Player Ship var Ship = Container.expand(function () { var self = Container.call(this); var shipGfx = self.attachAsset('ship', { anchorX: 0.5, anchorY: 0.5 }); self.radius = shipGfx.width * 0.5; self.shootCooldown = 0; self.rapidFire = false; self.rapidFireTimer = 0; self.shield = false; self.shieldTimer = 0; // Health system for player self.maxHealth = 5; self.health = self.maxHealth; // Health bar var healthBarBg = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 0.25, tint: 0x222222, y: shipGfx.height * 0.7 }); var healthBar = self.attachAsset('playerBullet', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 0.18, tint: 0xff4444, y: shipGfx.height * 0.7 }); // Visual shield indicator var shieldGfx = self.attachAsset('ship', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.3, scaleY: 1.3, tint: 0x00ffff }); shieldGfx.alpha = 0.25; shieldGfx.visible = false; self.update = function () { // Handle powerup timers if (self.rapidFire) { self.rapidFireTimer--; // Visual feedback for rapid fire: pulse ship color shipGfx.tint = LK.ticks % 10 < 5 ? 0xffe100 : 0x33c1ff; if (self.rapidFireTimer <= 0) { self.rapidFire = false; shipGfx.tint = 0x33c1ff; } } else { shipGfx.tint = 0x33c1ff; } if (self.shield) { self.shieldTimer--; shieldGfx.visible = true; if (self.shieldTimer <= 0) { self.shield = false; shieldGfx.visible = false; } } else { shieldGfx.visible = false; } // Update health bar healthBar.scaleX = 2 * (self.health / self.maxHealth); if (self.health < 1) healthBar.scaleX = 0; }; self.activateRapidFire = function (duration) { self.rapidFire = true; self.rapidFireTimer = duration; }; self.activateShield = function (duration) { self.shield = true; self.shieldTimer = duration; shieldGfx.visible = true; }; self.takeDamage = function (dmg) { if (self.shield) return; self.health -= dmg; LK.effects.flashObject(self, 0xff0000, 200); if (self.health < 0) self.health = 0; }; self.heal = function (amount) { self.health += amount; if (self.health > self.maxHealth) self.health = self.maxHealth; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ // No title, no description // Always backgroundColor is black backgroundColor: 0x000000 }); /**** * Game Code ****/ // Music // Sound effects // Powerup // Enemy bullet // Enemy // Player bullet // Spaceship (player) // Game area var GAME_W = 2048, GAME_H = 2732; // Score var score = 0; var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Player ship var ship = new Ship(); game.addChild(ship); ship.x = GAME_W / 2; ship.y = GAME_H - 350; // Arrays for game objects var playerBullets = []; var enemies = []; var enemyBullets = []; var powerups = []; // Dragging var dragNode = null; // Difficulty var enemySpawnTimer = 0; var enemySpawnInterval = 60; var minEnemyInterval = 18; var enemySpeedInc = 0; // Powerup spawn var powerupTimer = 0; var powerupInterval = 600; // Last intersect states var lastShipEnemyIntersect = false; var lastShipEnemyBulletIntersect = false; var lastShipPowerupIntersect = false; // Music LK.playMusic('bgmusic'); // Move handler (drag ship) function handleMove(x, y, obj) { if (dragNode === ship) { // Clamp ship inside game area (with margin) var margin = 80; var nx = Math.max(margin, Math.min(GAME_W - margin, x)); var ny = Math.max(margin, Math.min(GAME_H - margin, y)); ship.x = nx; ship.y = ny; // Touch feedback: scale ship up slightly while dragging, then back ship.scale.set(1.15, 1.15); tween(ship.scale, { x: 1, y: 1 }, { duration: 120 }); } } game.move = handleMove; var dragAnywhereHintShown = false; game.down = function (x, y, obj) { // User-friendly: allow drag to start if touch is on ship OR anywhere in lower half of screen var dx = x - ship.x, dy = y - ship.y; var onShip = dx * dx + dy * dy < ship.radius * ship.radius * 1.2; var inLowerHalf = y > GAME_H / 2; if (onShip || inLowerHalf) { dragNode = ship; handleMove(x, y, obj); // Visual feedback: flash ship blue for 120ms on drag start LK.effects.flashObject(ship, 0x33c1ff, 120); // Show floating helper text only the first time user drags from lower half (not on ship) if (!onShip && inLowerHalf && !dragAnywhereHintShown) { showFloatingText("Tip: Drag anywhere below to move!", ship.x, ship.y - 180, 0x33c1ff); dragAnywhereHintShown = true; } } }; game.up = function (x, y, obj) { dragNode = null; }; // Main update loop game.update = function () { // Update ship ship.update(); // --- Player shooting --- ship.shootCooldown--; var shootRate = ship.rapidFire ? 6 : 18; if (ship.shootCooldown <= 0) { // Auto-fire var pb = new PlayerBullet(); pb.x = ship.x; pb.y = ship.y - ship.radius - 30; playerBullets.push(pb); game.addChild(pb); ship.shootCooldown = shootRate; LK.getSound('shoot').play(); } // --- Update player bullets --- for (var i = playerBullets.length - 1; i >= 0; i--) { var b = playerBullets[i]; b.update(); // Remove if off screen if (b.y < -80) { b.destroy(); playerBullets.splice(i, 1); } } // --- Update enemies --- for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; // --- Enemy AI: dodge if player is close horizontally --- if (Math.abs(ship.x - e.x) < 180 && Math.abs(ship.y - e.y) < 600) { // Try to dodge left or right if (ship.x < e.x) e.x += 10 + Math.random() * 6;else e.x -= 10 + Math.random() * 6; } e.update(); // Remove if off screen if (e.y > GAME_H + 120) { e.destroy(); enemies.splice(i, 1); continue; } // Enemy shooting if (e.shootCooldown <= 0) { var eb = new EnemyBullet(); eb.x = e.x; eb.y = e.y + e.radius + 10; // Aim at ship var dx = ship.x - e.x, dy = ship.y - e.y; var len = Math.sqrt(dx * dx + dy * dy); if (len > 0) { eb.dirX = dx / len; eb.dirY = dy / len; } enemyBullets.push(eb); game.addChild(eb); e.shootCooldown = 90 + Math.floor(Math.random() * 60); } } // --- Update enemy bullets --- for (var i = enemyBullets.length - 1; i >= 0; i--) { var eb = enemyBullets[i]; eb.update(); if (eb.x < -100 || eb.x > GAME_W + 100 || eb.y < -100 || eb.y > GAME_H + 100) { eb.destroy(); enemyBullets.splice(i, 1); } } // --- Update powerups --- for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; p.update(); if (p.y > GAME_H + 100) { p.destroy(); powerups.splice(i, 1); } } // --- Collision: Player bullets vs Enemies --- for (var i = playerBullets.length - 1; i >= 0; i--) { var b = playerBullets[i]; for (var j = enemies.length - 1; j >= 0; j--) { var e = enemies[j]; if (b.intersects(e)) { // Hit enemy e.takeDamage(1); // Recoil effect for enemy tween(e, { y: e.y - 30 }, { duration: 60, yoyo: true, repeat: 1 }); // Camera shake on hit LK.effects.shakeScreen(8, 80); LK.getSound('enemyDown').play(); // Score only if enemy dies if (e.health <= 0) { score += 10; // Animate score text for feedback scoreTxt.setText(score); scoreTxt.scale.set(1.25, 1.25); tween(scoreTxt.scale, { x: 1, y: 1 }, { duration: 200 }); e.destroy(); enemies.splice(j, 1); } b.destroy(); playerBullets.splice(i, 1); break; } } } // --- Collision: Ship vs Enemies --- var shipEnemyIntersect = false; for (var i = 0; i < enemies.length; i++) { var e = enemies[i]; if (ship.intersects(e)) { shipEnemyIntersect = true; break; } } if (!lastShipEnemyIntersect && shipEnemyIntersect) { if (ship.shield) { // Absorb hit, destroy enemy LK.effects.flashObject(ship, 0x00ffff, 400); for (var i = 0; i < enemies.length; i++) { if (ship.intersects(enemies[i])) { enemies[i].destroy(); enemies.splice(i, 1); break; } } ship.shield = false; ship.shieldTimer = 0; ship.children[1].visible = false; } else { // Take damage ship.takeDamage(2); // Camera shake LK.effects.shakeScreen(18, 300); LK.getSound('hit').play(); if (ship.health <= 0) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } } lastShipEnemyIntersect = shipEnemyIntersect; // --- Collision: Ship vs Enemy Bullets --- var shipEnemyBulletIntersect = false; for (var i = 0; i < enemyBullets.length; i++) { var eb = enemyBullets[i]; if (ship.intersects(eb)) { shipEnemyBulletIntersect = true; break; } } if (!lastShipEnemyBulletIntersect && shipEnemyBulletIntersect) { if (ship.shield) { LK.effects.flashObject(ship, 0x00ffff, 400); // Remove bullet for (var i = 0; i < enemyBullets.length; i++) { if (ship.intersects(enemyBullets[i])) { enemyBullets[i].destroy(); enemyBullets.splice(i, 1); break; } } ship.shield = false; ship.shieldTimer = 0; ship.children[1].visible = false; } else { // Take damage ship.takeDamage(1); // Camera shake LK.effects.shakeScreen(10, 180); LK.getSound('hit').play(); if (ship.health <= 0) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } } lastShipEnemyBulletIntersect = shipEnemyBulletIntersect; // --- Collision: Ship vs Powerups --- var shipPowerupIntersect = false; for (var i = powerups.length - 1; i >= 0; i--) { var p = powerups[i]; if (ship.intersects(p)) { shipPowerupIntersect = true; // Apply powerup LK.getSound('powerup').play(); if (p.type === 'rapid') { ship.activateRapidFire(360); showFloatingText("Rapid Fire!", ship.x, ship.y - 120, 0xffe100); } else if (p.type === 'shield') { ship.activateShield(480); showFloatingText("Shield!", ship.x, ship.y - 120, 0x00ffff); } else if (p.type === 'heal') { ship.heal(2); showFloatingText("+2 Health", ship.x, ship.y - 120, 0x44ff44); } p.destroy(); powerups.splice(i, 1); } } lastShipPowerupIntersect = shipPowerupIntersect; // --- Mission system: show floating text for milestones --- if (score > 0 && score % 100 === 0 && !game['milestone_' + score]) { showFloatingText("Milestone: " + score + "!", GAME_W / 2, 320, 0xffe100); game['milestone_' + score] = true; } // --- Enemy spawn --- enemySpawnTimer--; if (enemySpawnTimer <= 0) { // Spawn enemy at random x var e = new Enemy(); e.x = 180 + Math.random() * (GAME_W - 360); e.y = -100; // Increase speed as score increases e.speed += Math.floor(score / 200) * 2; enemies.push(e); game.addChild(e); // Decrease interval as score increases enemySpawnInterval = Math.max(minEnemyInterval, 60 - Math.floor(score / 100) * 4); enemySpawnTimer = enemySpawnInterval; } // --- Powerup spawn --- powerupTimer--; if (powerupTimer <= 0) { var p = new Powerup(); p.x = 180 + Math.random() * (GAME_W - 360); p.y = -80; powerups.push(p); game.addChild(p); powerupInterval = 600 + Math.floor(Math.random() * 600); powerupTimer = powerupInterval; } }; // Floating text helper for feedback function showFloatingText(txt, x, y, color) { var t = new Text2(txt, { size: 90, fill: color || 0xffffff, stroke: 0x000000, strokeThickness: 8 }); t.anchor.set(0.5, 1); t.x = x; t.y = y; game.addChild(t); tween(t, { y: y - 120, alpha: 0 }, { duration: 700, onFinish: function onFinish() { t.destroy(); } }); } // Show instructions at game start var instructionTxt = new Text2("Drag the ship to move\nAuto-fire enabled\nCollect powerups!", { size: 90, fill: 0xffffff, stroke: 0x000000, strokeThickness: 8, align: "center" }); instructionTxt.anchor.set(0.5, 0.5); instructionTxt.x = GAME_W / 2; instructionTxt.y = GAME_H / 2 - 200; game.addChild(instructionTxt); tween(instructionTxt, { alpha: 0 }, { duration: 1800, onFinish: function onFinish() { instructionTxt.destroy(); } });
===================================================================
--- original.js
+++ change.js
@@ -18,8 +18,11 @@
self.moveType = Math.random() < 0.5 ? 'straight' : 'sine';
self.sinePhase = Math.random() * Math.PI * 2;
self.sineAmp = 120 + Math.random() * 120;
self.shootCooldown = 60 + Math.floor(Math.random() * 60);
+ // Health system for enemy
+ self.maxHealth = 3;
+ self.health = self.maxHealth;
self.update = function () {
if (self.moveType === 'straight') {
self.y += self.speed;
} else {
@@ -27,8 +30,16 @@
self.x += Math.sin(self.y / 120 + self.sinePhase) * 6;
}
self.shootCooldown--;
};
+ self.takeDamage = function (dmg) {
+ self.health -= dmg;
+ LK.effects.flashObject(self, 0xffffff, 80);
+ if (self.health <= 0) {
+ self.health = 0;
+ // Death handled in game loop
+ }
+ };
return self;
});
// Enemy Bullet
var EnemyBullet = Container.expand(function () {
@@ -61,14 +72,16 @@
});
// Powerup
var Powerup = Container.expand(function () {
var self = Container.call(this);
+ var types = ['rapid', 'shield', 'heal'];
+ var r = Math.random();
+ if (r < 0.4) self.type = 'rapid';else if (r < 0.8) self.type = 'shield';else self.type = 'heal';
var powerupGfx = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
- self.type = Math.random() < 0.5 ? 'rapid' : 'shield';
- powerupGfx.tint = self.type === 'rapid' ? 0xffe100 : 0x00ffff;
+ if (self.type === 'rapid') powerupGfx.tint = 0xffe100;else if (self.type === 'shield') powerupGfx.tint = 0x00ffff;else powerupGfx.tint = 0x44ff44;
self.speed = 10;
self.update = function () {
self.y += self.speed;
};
@@ -86,8 +99,28 @@
self.rapidFire = false;
self.rapidFireTimer = 0;
self.shield = false;
self.shieldTimer = 0;
+ // Health system for player
+ self.maxHealth = 5;
+ self.health = self.maxHealth;
+ // Health bar
+ var healthBarBg = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2.2,
+ scaleY: 0.25,
+ tint: 0x222222,
+ y: shipGfx.height * 0.7
+ });
+ var healthBar = self.attachAsset('playerBullet', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 2,
+ scaleY: 0.18,
+ tint: 0xff4444,
+ y: shipGfx.height * 0.7
+ });
// Visual shield indicator
var shieldGfx = self.attachAsset('ship', {
anchorX: 0.5,
anchorY: 0.5,
@@ -119,8 +152,11 @@
}
} else {
shieldGfx.visible = false;
}
+ // Update health bar
+ healthBar.scaleX = 2 * (self.health / self.maxHealth);
+ if (self.health < 1) healthBar.scaleX = 0;
};
self.activateRapidFire = function (duration) {
self.rapidFire = true;
self.rapidFireTimer = duration;
@@ -129,8 +165,18 @@
self.shield = true;
self.shieldTimer = duration;
shieldGfx.visible = true;
};
+ self.takeDamage = function (dmg) {
+ if (self.shield) return;
+ self.health -= dmg;
+ LK.effects.flashObject(self, 0xff0000, 200);
+ if (self.health < 0) self.health = 0;
+ };
+ self.heal = function (amount) {
+ self.health += amount;
+ if (self.health > self.maxHealth) self.health = self.maxHealth;
+ };
return self;
});
/****
@@ -260,8 +306,13 @@
}
// --- Update enemies ---
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
+ // --- Enemy AI: dodge if player is close horizontally ---
+ if (Math.abs(ship.x - e.x) < 180 && Math.abs(ship.y - e.y) < 600) {
+ // Try to dodge left or right
+ if (ship.x < e.x) e.x += 10 + Math.random() * 6;else e.x -= 10 + Math.random() * 6;
+ }
e.update();
// Remove if off screen
if (e.y > GAME_H + 120) {
e.destroy();
@@ -309,22 +360,36 @@
var b = playerBullets[i];
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (b.intersects(e)) {
- // Enemy down
- LK.getSound('enemyDown').play();
- score += 10;
- // Animate score text for feedback
- scoreTxt.setText(score);
- scoreTxt.scale.set(1.25, 1.25);
- tween(scoreTxt.scale, {
- x: 1,
- y: 1
+ // Hit enemy
+ e.takeDamage(1);
+ // Recoil effect for enemy
+ tween(e, {
+ y: e.y - 30
}, {
- duration: 200
+ duration: 60,
+ yoyo: true,
+ repeat: 1
});
- e.destroy();
- enemies.splice(j, 1);
+ // Camera shake on hit
+ LK.effects.shakeScreen(8, 80);
+ LK.getSound('enemyDown').play();
+ // Score only if enemy dies
+ if (e.health <= 0) {
+ score += 10;
+ // Animate score text for feedback
+ scoreTxt.setText(score);
+ scoreTxt.scale.set(1.25, 1.25);
+ tween(scoreTxt.scale, {
+ x: 1,
+ y: 1
+ }, {
+ duration: 200
+ });
+ e.destroy();
+ enemies.splice(j, 1);
+ }
b.destroy();
playerBullets.splice(i, 1);
break;
}
@@ -353,13 +418,18 @@
ship.shield = false;
ship.shieldTimer = 0;
ship.children[1].visible = false;
} else {
- // Game over
- LK.effects.flashScreen(0xff0000, 1000);
+ // Take damage
+ ship.takeDamage(2);
+ // Camera shake
+ LK.effects.shakeScreen(18, 300);
LK.getSound('hit').play();
- LK.showGameOver();
- return;
+ if (ship.health <= 0) {
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.showGameOver();
+ return;
+ }
}
}
lastShipEnemyIntersect = shipEnemyIntersect;
// --- Collision: Ship vs Enemy Bullets ---
@@ -385,12 +455,18 @@
ship.shield = false;
ship.shieldTimer = 0;
ship.children[1].visible = false;
} else {
- LK.effects.flashScreen(0xff0000, 1000);
+ // Take damage
+ ship.takeDamage(1);
+ // Camera shake
+ LK.effects.shakeScreen(10, 180);
LK.getSound('hit').play();
- LK.showGameOver();
- return;
+ if (ship.health <= 0) {
+ LK.effects.flashScreen(0xff0000, 1000);
+ LK.showGameOver();
+ return;
+ }
}
}
lastShipEnemyBulletIntersect = shipEnemyBulletIntersect;
// --- Collision: Ship vs Powerups ---
@@ -406,14 +482,22 @@
showFloatingText("Rapid Fire!", ship.x, ship.y - 120, 0xffe100);
} else if (p.type === 'shield') {
ship.activateShield(480);
showFloatingText("Shield!", ship.x, ship.y - 120, 0x00ffff);
+ } else if (p.type === 'heal') {
+ ship.heal(2);
+ showFloatingText("+2 Health", ship.x, ship.y - 120, 0x44ff44);
}
p.destroy();
powerups.splice(i, 1);
}
}
lastShipPowerupIntersect = shipPowerupIntersect;
+ // --- Mission system: show floating text for milestones ---
+ if (score > 0 && score % 100 === 0 && !game['milestone_' + score]) {
+ showFloatingText("Milestone: " + score + "!", GAME_W / 2, 320, 0xffe100);
+ game['milestone_' + score] = true;
+ }
// --- Enemy spawn ---
enemySpawnTimer--;
if (enemySpawnTimer <= 0) {
// Spawn enemy at random x