User prompt
tıklayınca ışınlanmayı da sil
User prompt
hareket mekaniği sil
User prompt
hareket etmek için tıklama gerekmez hep haraket eder
User prompt
mouse mapte neredeyse karakter de oraya haraket eder
User prompt
karakterimiz tıklamadan da mouse a ışınlanabiliyor
User prompt
mouse a ışınlanarak kaçsın
Code edit (1 edits merged)
Please save this source code
User prompt
Spectral Dodge: Ghost vs Bullets
Initial prompt
biz bir hayaletiz ve bize mermiler geliyor wave sistemi var
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = 0; self.speedY = 0; self.rotation = 0; self.rotationSpeed = 0; self.update = function () { self.x += self.speedX; self.y += self.speedY; // Rotate bullet if it has rotation speed if (self.rotationSpeed !== 0) { bulletGraphics.rotation += self.rotationSpeed; } // Check if bullet is off-screen with padding if (self.x < -50 || self.x > 2048 + 50 || self.y < -50 || self.y > 2732 + 50) { return true; // Return true to indicate it should be removed } return false; }; return self; }); var Ghost = Container.expand(function () { var self = Container.call(this); var ghostGraphics = self.attachAsset('ghost', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); // Trail effect using small ghost shapes self.trail = []; self.trailMax = 5; self.trailInterval = 3; self.trailCounter = 0; self.invulnerable = false; self.invulnerableTime = 0; self.blinkInterval = 5; self.update = function () { // Handle trail effect self.trailCounter++; if (self.trailCounter >= self.trailInterval) { self.trailCounter = 0; // Add new trail element if (self.trail.length >= self.trailMax) { var oldest = self.trail.shift(); oldest.destroy(); } var trail = LK.getAsset('ghost', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: 0.7, scaleY: 0.7, x: self.x, y: self.y }); game.addChildAt(trail, 0); self.trail.push(trail); // Fade out trail elements for (var i = 0; i < self.trail.length; i++) { var trailElement = self.trail[i]; tween(trailElement, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { // Cleanup happens in the shift above } }); } } // Handle invulnerability blinking if (self.invulnerable) { self.invulnerableTime--; if (self.invulnerableTime <= 0) { self.invulnerable = false; ghostGraphics.alpha = 0.8; } else { // Set transparency only during invulnerability ghostGraphics.alpha = 0.3; // Blink effect if (self.invulnerableTime % self.blinkInterval === 0) { ghostGraphics.alpha = ghostGraphics.alpha < 0.4 ? 0.8 : 0.3; } } } }; self.makeInvulnerable = function (time) { self.invulnerable = true; self.invulnerableTime = time; }; return self; }); var WaveIndicator = Container.expand(function () { var self = Container.call(this); var indicatorGraphic = self.attachAsset('wave_indicator', { anchorX: 0.5, anchorY: 0.5 }); self.active = false; self.setActive = function (isActive) { self.active = isActive; if (isActive) { tween(indicatorGraphic, { alpha: 1, scaleX: 1.2, scaleY: 1.2 }, { duration: 300, onFinish: function onFinish() { tween(indicatorGraphic, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } }); } else { indicatorGraphic.alpha = 0.4; indicatorGraphic.scaleX = 1; indicatorGraphic.scaleY = 1; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000033 }); /**** * Game Code ****/ // Background var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(background); // Game state var state = { score: 0, wave: 1, waveTimer: 0, difficulty: 1, isGameOver: false, isPaused: false, highScore: storage.highScore || 0 }; // Player var ghost = new Ghost(); ghost.x = 2048 / 2; ghost.y = 2732 / 2; game.addChild(ghost); // Add wave indicators var waveIndicators = []; var indicatorSpacing = 30; var totalIndicators = 5; var indicatorStartX = (2048 - (totalIndicators - 1) * indicatorSpacing) / 2; for (var i = 0; i < totalIndicators; i++) { var indicator = new WaveIndicator(); indicator.x = indicatorStartX + i * indicatorSpacing; indicator.y = 50; indicator.setActive(i === 0); // Set first one active waveIndicators.push(indicator); LK.gui.top.addChild(indicator); } // Bullet management var bullets = []; var patterns = { // Wave patterns circle: function circle(centerX, centerY, count, speed, size) { var angleStep = Math.PI * 2 / count; for (var i = 0; i < count; i++) { var angle = i * angleStep; createBullet(centerX, centerY, Math.cos(angle) * speed, Math.sin(angle) * speed, size); } }, spiral: function spiral(centerX, centerY, count, speed, size) { var timeout = 0; var angleStep = Math.PI * 2 / count; for (var i = 0; i < count; i++) { (function (index) { LK.setTimeout(function () { var angle = index * angleStep; createBullet(centerX, centerY, Math.cos(angle) * speed, Math.sin(angle) * speed, size); }, timeout); timeout += 100; })(i); } }, random: function random(count, speed, size) { for (var i = 0; i < count; i++) { var side = Math.floor(Math.random() * 4); // 0:top, 1:right, 2:bottom, 3:left var startX, startY; var targetX = ghost.x + (Math.random() * 100 - 50); var targetY = ghost.y + (Math.random() * 100 - 50); switch (side) { case 0: // Top startX = Math.random() * 2048; startY = -50; break; case 1: // Right startX = 2048 + 50; startY = Math.random() * 2732; break; case 2: // Bottom startX = Math.random() * 2048; startY = 2732 + 50; break; case 3: // Left startX = -50; startY = Math.random() * 2732; break; } var angle = Math.atan2(targetY - startY, targetX - startX); createBullet(startX, startY, Math.cos(angle) * speed, Math.sin(angle) * speed, size, 0.05); } }, aimed: function aimed(count, speed, size) { var angleSpread = Math.PI / 4; // 45 degree spread for (var i = 0; i < count; i++) { var side = Math.floor(Math.random() * 4); var startX, startY; switch (side) { case 0: // Top startX = Math.random() * 2048; startY = -50; break; case 1: // Right startX = 2048 + 50; startY = Math.random() * 2732; break; case 2: // Bottom startX = Math.random() * 2048; startY = 2732 + 50; break; case 3: // Left startX = -50; startY = Math.random() * 2732; break; } var baseAngle = Math.atan2(ghost.y - startY, ghost.x - startX); var angleOffset = angleSpread * (Math.random() - 0.5); var angle = baseAngle + angleOffset; createBullet(startX, startY, Math.cos(angle) * speed, Math.sin(angle) * speed, size); } } }; function createBullet(x, y, speedX, speedY, scale, rotationSpeed) { var bullet = new Bullet(); bullet.x = x; bullet.y = y; bullet.speedX = speedX; bullet.speedY = speedY; bullet.rotationSpeed = rotationSpeed || 0; if (scale) { bullet.scale.set(scale); } bullets.push(bullet); game.addChild(bullet); return bullet; } function spawnWave() { var baseCount = 10; var baseSpeed = 3; // Update wave indicators var currentWaveIndex = (state.wave - 1) % totalIndicators; for (var i = 0; i < waveIndicators.length; i++) { waveIndicators[i].setActive(i === currentWaveIndex); } // Increase difficulty with each wave var count = Math.floor(baseCount * Math.sqrt(state.difficulty)); var speed = baseSpeed * (1 + (state.difficulty - 1) * 0.1); // Play wave complete sound if not the first wave if (state.wave > 1) { LK.getSound('wave_complete').play(); } // Choose pattern based on wave switch ((state.wave - 1) % 4) { case 0: patterns.circle(2048 / 2, 2732 / 2, count, speed, 1); break; case 1: patterns.spiral(2048 / 2, 2732 / 2, count, speed, 1); break; case 2: patterns.random(count, speed, 1); break; case 3: patterns.aimed(count, speed, 1); break; } // Make player briefly invulnerable after a new wave ghost.makeInvulnerable(60); // Increment difficulty state.difficulty += 0.2; // Set timer for next wave state.waveTimer = Math.max(180, 300 - state.wave * 10); // Decrease time between waves } // Initialize scoreboard var scoreTxt = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); // Anchor to top-right LK.gui.topRight.addChild(scoreTxt); // Wave indicator text var waveTxt = new Text2('Wave: 1', { size: 50, fill: 0xFFFFFF }); waveTxt.anchor.set(0, 0); // Anchor to top-left LK.gui.top.addChild(waveTxt); // Allow dragging of the ghost var isDragging = false; // Handle input game.down = function (x, y) { if (!state.isPaused && !state.isGameOver) { // Teleport ghost to mouse position ghost.x = x; ghost.y = y; // Make ghost invulnerable and semi-transparent for 1 second ghost.makeInvulnerable(60); } }; game.move = function (x, y) { if (!state.isPaused && !state.isGameOver) { // Continuously update ghost position to follow the mouse ghost.x = x; ghost.y = y; } }; game.up = function () { // Removed dragging state reset }; // Main game update function game.update = function () { if (state.isGameOver) { return; } // Increment score state.score++; scoreTxt.setText('Score: ' + state.score); waveTxt.setText('Wave: ' + state.wave); // Wave timer logic if (state.waveTimer > 0) { state.waveTimer--; if (state.waveTimer === 0 || bullets.length === 0) { state.wave++; spawnWave(); } } // Update bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (bullet.update()) { // Bullet is off-screen, remove it bullet.destroy(); bullets.splice(i, 1); continue; } // Check collision with ghost if (!ghost.invulnerable && bullet.intersects(ghost)) { // Handle collision LK.getSound('hit').play(); // Flash screen LK.effects.flashScreen(0xff0000, 500); // Game over state.isGameOver = true; // Update high score if (state.score > state.highScore) { state.highScore = state.score; storage.highScore = state.score; } // Play game over sound LK.getSound('game_over').play(); // Show game over screen after a short delay LK.setTimeout(function () { LK.showGameOver(); }, 1000); break; } } }; // Start first wave spawnWave(); // Play background music LK.playMusic('game_music', { fade: { start: 0, end: 0.4, duration: 1000 } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedX = 0;
self.speedY = 0;
self.rotation = 0;
self.rotationSpeed = 0;
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
// Rotate bullet if it has rotation speed
if (self.rotationSpeed !== 0) {
bulletGraphics.rotation += self.rotationSpeed;
}
// Check if bullet is off-screen with padding
if (self.x < -50 || self.x > 2048 + 50 || self.y < -50 || self.y > 2732 + 50) {
return true; // Return true to indicate it should be removed
}
return false;
};
return self;
});
var Ghost = Container.expand(function () {
var self = Container.call(this);
var ghostGraphics = self.attachAsset('ghost', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
// Trail effect using small ghost shapes
self.trail = [];
self.trailMax = 5;
self.trailInterval = 3;
self.trailCounter = 0;
self.invulnerable = false;
self.invulnerableTime = 0;
self.blinkInterval = 5;
self.update = function () {
// Handle trail effect
self.trailCounter++;
if (self.trailCounter >= self.trailInterval) {
self.trailCounter = 0;
// Add new trail element
if (self.trail.length >= self.trailMax) {
var oldest = self.trail.shift();
oldest.destroy();
}
var trail = LK.getAsset('ghost', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3,
scaleX: 0.7,
scaleY: 0.7,
x: self.x,
y: self.y
});
game.addChildAt(trail, 0);
self.trail.push(trail);
// Fade out trail elements
for (var i = 0; i < self.trail.length; i++) {
var trailElement = self.trail[i];
tween(trailElement, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
// Cleanup happens in the shift above
}
});
}
}
// Handle invulnerability blinking
if (self.invulnerable) {
self.invulnerableTime--;
if (self.invulnerableTime <= 0) {
self.invulnerable = false;
ghostGraphics.alpha = 0.8;
} else {
// Set transparency only during invulnerability
ghostGraphics.alpha = 0.3;
// Blink effect
if (self.invulnerableTime % self.blinkInterval === 0) {
ghostGraphics.alpha = ghostGraphics.alpha < 0.4 ? 0.8 : 0.3;
}
}
}
};
self.makeInvulnerable = function (time) {
self.invulnerable = true;
self.invulnerableTime = time;
};
return self;
});
var WaveIndicator = Container.expand(function () {
var self = Container.call(this);
var indicatorGraphic = self.attachAsset('wave_indicator', {
anchorX: 0.5,
anchorY: 0.5
});
self.active = false;
self.setActive = function (isActive) {
self.active = isActive;
if (isActive) {
tween(indicatorGraphic, {
alpha: 1,
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300,
onFinish: function onFinish() {
tween(indicatorGraphic, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
} else {
indicatorGraphic.alpha = 0.4;
indicatorGraphic.scaleX = 1;
indicatorGraphic.scaleY = 1;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
// Game state
var state = {
score: 0,
wave: 1,
waveTimer: 0,
difficulty: 1,
isGameOver: false,
isPaused: false,
highScore: storage.highScore || 0
};
// Player
var ghost = new Ghost();
ghost.x = 2048 / 2;
ghost.y = 2732 / 2;
game.addChild(ghost);
// Add wave indicators
var waveIndicators = [];
var indicatorSpacing = 30;
var totalIndicators = 5;
var indicatorStartX = (2048 - (totalIndicators - 1) * indicatorSpacing) / 2;
for (var i = 0; i < totalIndicators; i++) {
var indicator = new WaveIndicator();
indicator.x = indicatorStartX + i * indicatorSpacing;
indicator.y = 50;
indicator.setActive(i === 0); // Set first one active
waveIndicators.push(indicator);
LK.gui.top.addChild(indicator);
}
// Bullet management
var bullets = [];
var patterns = {
// Wave patterns
circle: function circle(centerX, centerY, count, speed, size) {
var angleStep = Math.PI * 2 / count;
for (var i = 0; i < count; i++) {
var angle = i * angleStep;
createBullet(centerX, centerY, Math.cos(angle) * speed, Math.sin(angle) * speed, size);
}
},
spiral: function spiral(centerX, centerY, count, speed, size) {
var timeout = 0;
var angleStep = Math.PI * 2 / count;
for (var i = 0; i < count; i++) {
(function (index) {
LK.setTimeout(function () {
var angle = index * angleStep;
createBullet(centerX, centerY, Math.cos(angle) * speed, Math.sin(angle) * speed, size);
}, timeout);
timeout += 100;
})(i);
}
},
random: function random(count, speed, size) {
for (var i = 0; i < count; i++) {
var side = Math.floor(Math.random() * 4); // 0:top, 1:right, 2:bottom, 3:left
var startX, startY;
var targetX = ghost.x + (Math.random() * 100 - 50);
var targetY = ghost.y + (Math.random() * 100 - 50);
switch (side) {
case 0:
// Top
startX = Math.random() * 2048;
startY = -50;
break;
case 1:
// Right
startX = 2048 + 50;
startY = Math.random() * 2732;
break;
case 2:
// Bottom
startX = Math.random() * 2048;
startY = 2732 + 50;
break;
case 3:
// Left
startX = -50;
startY = Math.random() * 2732;
break;
}
var angle = Math.atan2(targetY - startY, targetX - startX);
createBullet(startX, startY, Math.cos(angle) * speed, Math.sin(angle) * speed, size, 0.05);
}
},
aimed: function aimed(count, speed, size) {
var angleSpread = Math.PI / 4; // 45 degree spread
for (var i = 0; i < count; i++) {
var side = Math.floor(Math.random() * 4);
var startX, startY;
switch (side) {
case 0:
// Top
startX = Math.random() * 2048;
startY = -50;
break;
case 1:
// Right
startX = 2048 + 50;
startY = Math.random() * 2732;
break;
case 2:
// Bottom
startX = Math.random() * 2048;
startY = 2732 + 50;
break;
case 3:
// Left
startX = -50;
startY = Math.random() * 2732;
break;
}
var baseAngle = Math.atan2(ghost.y - startY, ghost.x - startX);
var angleOffset = angleSpread * (Math.random() - 0.5);
var angle = baseAngle + angleOffset;
createBullet(startX, startY, Math.cos(angle) * speed, Math.sin(angle) * speed, size);
}
}
};
function createBullet(x, y, speedX, speedY, scale, rotationSpeed) {
var bullet = new Bullet();
bullet.x = x;
bullet.y = y;
bullet.speedX = speedX;
bullet.speedY = speedY;
bullet.rotationSpeed = rotationSpeed || 0;
if (scale) {
bullet.scale.set(scale);
}
bullets.push(bullet);
game.addChild(bullet);
return bullet;
}
function spawnWave() {
var baseCount = 10;
var baseSpeed = 3;
// Update wave indicators
var currentWaveIndex = (state.wave - 1) % totalIndicators;
for (var i = 0; i < waveIndicators.length; i++) {
waveIndicators[i].setActive(i === currentWaveIndex);
}
// Increase difficulty with each wave
var count = Math.floor(baseCount * Math.sqrt(state.difficulty));
var speed = baseSpeed * (1 + (state.difficulty - 1) * 0.1);
// Play wave complete sound if not the first wave
if (state.wave > 1) {
LK.getSound('wave_complete').play();
}
// Choose pattern based on wave
switch ((state.wave - 1) % 4) {
case 0:
patterns.circle(2048 / 2, 2732 / 2, count, speed, 1);
break;
case 1:
patterns.spiral(2048 / 2, 2732 / 2, count, speed, 1);
break;
case 2:
patterns.random(count, speed, 1);
break;
case 3:
patterns.aimed(count, speed, 1);
break;
}
// Make player briefly invulnerable after a new wave
ghost.makeInvulnerable(60);
// Increment difficulty
state.difficulty += 0.2;
// Set timer for next wave
state.waveTimer = Math.max(180, 300 - state.wave * 10); // Decrease time between waves
}
// Initialize scoreboard
var scoreTxt = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(1, 0); // Anchor to top-right
LK.gui.topRight.addChild(scoreTxt);
// Wave indicator text
var waveTxt = new Text2('Wave: 1', {
size: 50,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0, 0); // Anchor to top-left
LK.gui.top.addChild(waveTxt);
// Allow dragging of the ghost
var isDragging = false;
// Handle input
game.down = function (x, y) {
if (!state.isPaused && !state.isGameOver) {
// Teleport ghost to mouse position
ghost.x = x;
ghost.y = y;
// Make ghost invulnerable and semi-transparent for 1 second
ghost.makeInvulnerable(60);
}
};
game.move = function (x, y) {
if (!state.isPaused && !state.isGameOver) {
// Continuously update ghost position to follow the mouse
ghost.x = x;
ghost.y = y;
}
};
game.up = function () {
// Removed dragging state reset
};
// Main game update function
game.update = function () {
if (state.isGameOver) {
return;
}
// Increment score
state.score++;
scoreTxt.setText('Score: ' + state.score);
waveTxt.setText('Wave: ' + state.wave);
// Wave timer logic
if (state.waveTimer > 0) {
state.waveTimer--;
if (state.waveTimer === 0 || bullets.length === 0) {
state.wave++;
spawnWave();
}
}
// Update bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet.update()) {
// Bullet is off-screen, remove it
bullet.destroy();
bullets.splice(i, 1);
continue;
}
// Check collision with ghost
if (!ghost.invulnerable && bullet.intersects(ghost)) {
// Handle collision
LK.getSound('hit').play();
// Flash screen
LK.effects.flashScreen(0xff0000, 500);
// Game over
state.isGameOver = true;
// Update high score
if (state.score > state.highScore) {
state.highScore = state.score;
storage.highScore = state.score;
}
// Play game over sound
LK.getSound('game_over').play();
// Show game over screen after a short delay
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
break;
}
}
};
// Start first wave
spawnWave();
// Play background music
LK.playMusic('game_music', {
fade: {
start: 0,
end: 0.4,
duration: 1000
}
});