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);
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--;
};
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 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;
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;
// 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;
}
};
self.activateRapidFire = function (duration) {
self.rapidFire = true;
self.rapidFireTimer = duration;
};
self.activateShield = function (duration) {
self.shield = true;
self.shieldTimer = duration;
shieldGfx.visible = true;
};
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: flash ship slightly blue for 100ms on drag
LK.effects.flashObject(ship, 0x33c1ff, 100);
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Only drag if touch is on ship
var dx = x - ship.x,
dy = y - ship.y;
if (dx * dx + dy * dy < ship.radius * ship.radius * 1.2) {
dragNode = ship;
handleMove(x, y, obj);
}
};
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];
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)) {
// Enemy down
LK.getSound('enemyDown').play();
score += 10;
// Animate score text for feedback
scoreTxt.setText(score);
scoreTxt.scale.set(1.25, 1.25);
tween.to(scoreTxt.scale, {
x: 1,
y: 1
}, 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 {
// Game over
LK.effects.flashScreen(0xff0000, 1000);
LK.getSound('hit').play();
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 {
LK.effects.flashScreen(0xff0000, 1000);
LK.getSound('hit').play();
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);
}
p.destroy();
powerups.splice(i, 1);
}
}
lastShipPowerupIntersect = shipPowerupIntersect;
// --- 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.to(t, {
y: y - 120,
alpha: 0
}, 700).on('end', function () {
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.to(instructionTxt, {
alpha: 0
}, 1800).on('end', function () {
instructionTxt.destroy();
}); ===================================================================
--- original.js
+++ change.js
@@ -100,18 +100,26 @@
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;
}
};
self.activateRapidFire = function (duration) {
self.rapidFire = true;
@@ -128,9 +136,11 @@
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0x000010
+ // No title, no description
+ // Always backgroundColor is black
+ backgroundColor: 0x000000
});
/****
* Game Code
@@ -187,8 +197,10 @@
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: flash ship slightly blue for 100ms on drag
+ LK.effects.flashObject(ship, 0x33c1ff, 100);
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
@@ -284,9 +296,15 @@
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.to(scoreTxt.scale, {
+ x: 1,
+ y: 1
+ }, 200);
e.destroy();
enemies.splice(j, 1);
b.destroy();
playerBullets.splice(i, 1);
@@ -366,10 +384,12 @@
// 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);
}
p.destroy();
powerups.splice(i, 1);
}
@@ -400,5 +420,41 @@
game.addChild(p);
powerupInterval = 600 + Math.floor(Math.random() * 600);
powerupTimer = powerupInterval;
}
-};
\ No newline at end of file
+};
+// 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.to(t, {
+ y: y - 120,
+ alpha: 0
+ }, 700).on('end', function () {
+ 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.to(instructionTxt, {
+ alpha: 0
+}, 1800).on('end', function () {
+ instructionTxt.destroy();
+});
\ No newline at end of file