User prompt
tekrar dene hala hata veriyorsa değiştir
User prompt
tekrar dene
User prompt
topladığımız puanları kullanabileceğimiz bir format ayarla
User prompt
oyunu geliştir
User prompt
speed boost yerine gölgeleri yavaşlatan gücü ekle
User prompt
özel güçler ekle
User prompt
özel güçler ekle
User prompt
ekrandan topladığımız bir kaç saniye süren özel güçler ekle hız gibi
Code edit (1 edits merged)
Please save this source code
User prompt
Shadow Swap: Işık ve Karanlık
Initial prompt
bana kendine özgü bir oyun yap
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // LightOrb (Player) class var LightOrb = Container.expand(function () { var self = Container.call(this); var orb = self.attachAsset('lightOrb', { anchorX: 0.5, anchorY: 0.5 }); // For touch feedback self.flash = function () { tween(orb, { alpha: 0.6 }, { duration: 80, onFinish: function onFinish() { tween(orb, { alpha: 1 }, { duration: 120 }); } }); }; // No update needed; position is set by player return self; }); // PowerUp (Special Ability) class var PowerUp = Container.expand(function () { var self = Container.call(this); // Types: 'slow', 'shield', 'score' self.type = 'slow'; // Visuals: color by type var color = 0x00eaff; if (self.type === 'shield') color = 0x7fff00; if (self.type === 'score') color = 0xffd700; var asset = self.attachAsset('lightOrb', { anchorX: 0.5, anchorY: 0.5 }); asset.width = 90; asset.height = 90; asset.tint = color; // For state tracking self.lastIntersecting = false; // No update needed; position is static return self; }); // Shadow (Enemy) class var Shadow = Container.expand(function () { var self = Container.call(this); var shadow = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5 }); // Movement properties self.vx = 0; self.vy = 0; self.speed = 2; // Will be set on spawn // Shadow type: 'normal' or 'splitter' self.shadowType = 'normal'; // default // For state tracking self.lastIntersecting = false; // Called every tick self.update = function () { self.x += self.vx * self.speed; self.y += self.vy * self.speed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c24 }); /**** * Game Code ****/ // Game area // Light orb (player) // Shadow (enemy) // Score text will use Text2, no asset needed var GAME_W = 2048; var GAME_H = 2732; // Player (light orb) var lightOrb = new LightOrb(); lightOrb.x = GAME_W / 2; lightOrb.y = GAME_H * 0.75; game.addChild(lightOrb); // Shadows (enemies) var shadows = []; // PowerUps (special abilities) var powerUps = []; // PowerUp state var powerUpActive = false; var powerUpType = null; var powerUpTimer = 0; // Score var score = 0; var highScore = storage.highScore || 0; var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFBE0 }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // High score text var highScoreTxt = new Text2('En Yüksek Skor: 0', { size: 54, fill: 0xFFFFFF }); // Place at bottom right, anchor to right edge highScoreTxt.anchor.set(1, 1); highScoreTxt.x = -40; // 40px from right edge highScoreTxt.y = -40; // 40px from bottom edge LK.gui.bottomRight.addChild(highScoreTxt); // Level system var level = 1; var levelTxt = new Text2('Seviye 1', { size: 80, fill: 0x7fff00 }); levelTxt.anchor.set(0.5, 0); levelTxt.y = 120; LK.gui.top.addChild(levelTxt); // Survival time var survivalTime = 0; // in seconds var survivalTick = 0; // for counting frames var timeTxt = new Text2('Süre: 0', { size: 80, fill: 0x00eaff }); timeTxt.anchor.set(0.5, 0); timeTxt.y = 220; LK.gui.top.addChild(timeTxt); // High survival time (persistent) var highSurvivalTime = storage.highSurvivalTime || 0; var highTimeTxt = new Text2('En Yüksek Süre: 0', { size: 54, fill: 0x00eaff }); highTimeTxt.anchor.set(1, 1); highTimeTxt.x = -40; highTimeTxt.y = -140; // stack above highScoreTxt LK.gui.bottomRight.addChild(highTimeTxt); // Level up logic var nextLevelScore = 15; // First level up at 15, then increases function checkLevelUp() { if (score >= nextLevelScore) { level++; levelTxt.setText('Seviye ' + level); // Animate level text: scale up and back for feedback tween(levelTxt, { scaleX: 1.4, scaleY: 1.4 }, { duration: 180, onFinish: function onFinish() { tween(levelTxt, { scaleX: 1, scaleY: 1 }, { duration: 180 }); } }); // Increase next level threshold (progressively harder) nextLevelScore += 18 + Math.floor(level * 2.5); // Require more points for next level // Level up feedback LK.effects.flashScreen(0x7fff00, 600); // Optionally: boost difficulty a bit more on level up increaseDifficulty(); } } // Difficulty var shadowSpeed = 1.3; // Lower base speed var shadowSpawnInterval = 180; // Slower spawn rate var minShadowSpawnInterval = 60; // Don't get too fast var shadowCount = 1; // Fewer shadows at start var maxShadowCount = 5; // Lower max shadow count // Dragging var dragging = false; // Helper: clamp position inside game area function clamp(val, min, max) { return Math.max(min, Math.min(max, val)); } // Helper: spawn a shadow at a random edge, moving in a random direction function spawnShadow() { var s = new Shadow(); // Random edge: 0=top, 1=bottom, 2=left, 3=right var edge = Math.floor(Math.random() * 4); var margin = 120; var x, y, angle; if (edge === 0) { // top x = margin + Math.random() * (GAME_W - 2 * margin); y = -90; angle = Math.PI / 4 + Math.random() * (Math.PI / 2); // 45-135 deg } else if (edge === 1) { // bottom x = margin + Math.random() * (GAME_W - 2 * margin); y = GAME_H + 90; angle = -Math.PI / 4 - Math.random() * (Math.PI / 2); // -45 to -135 deg } else if (edge === 2) { // left x = -90; y = margin + Math.random() * (GAME_H - 2 * margin); angle = -Math.PI / 4 + Math.random() * (Math.PI / 2); // -45 to 45 deg } else { // right x = GAME_W + 90; y = margin + Math.random() * (GAME_H - 2 * margin); angle = Math.PI * (1.25 + Math.random() * 0.5); // 225-315 deg } s.x = x; s.y = y; s.speed = shadowSpeed + Math.random() * 0.7; s.vx = Math.cos(angle); s.vy = Math.sin(angle); // Randomly assign splitter type (10% chance, but not if too many shadows) if (Math.random() < 0.10 && shadows.length < 6 && level > 1) { s.shadowType = 'splitter'; // Tint splitter shadow for visibility if (s.children && s.children[0]) { s.children[0].tint = 0x4e7fff; } } // Add to game and array game.addChild(s); shadows.push(s); } // Score update function updateScore(val) { score = val; scoreTxt.setText(score); if (score > highScore) { highScore = score; highScoreTxt.setText('En Yüksek Skor: ' + highScore); storage.highScore = highScore; } } // Difficulty ramp function increaseDifficulty() { if (shadowSpawnInterval > minShadowSpawnInterval) { shadowSpawnInterval -= 3; // Decrease spawn interval more slowly } if (shadowCount < maxShadowCount) { shadowCount += 1; } shadowSpeed += 0.09; // Increase speed more slowly } // Move handler (drag orb) function handleMove(x, y, obj) { if (dragging) { // Clamp to game area, avoid top left 100x100 var nx = clamp(x, 100 + lightOrb.width / 2, GAME_W - lightOrb.width / 2); var ny = clamp(y, lightOrb.height / 2, GAME_H - lightOrb.height / 2); lightOrb.x = nx; lightOrb.y = ny; } } game.move = handleMove; // Down handler (start drag) game.down = function (x, y, obj) { // Only start drag if touch is on orb var dx = x - lightOrb.x; var dy = y - lightOrb.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < lightOrb.width / 2 + 30) { dragging = true; lightOrb.flash(); handleMove(x, y, obj); } }; // Up handler (stop drag) game.up = function (x, y, obj) { dragging = false; }; // Shadow spawn timer var shadowTick = 0; // Main update loop game.update = function () { // Update survival time survivalTick++; if (survivalTick >= 60) { // update every 1s (60fps) survivalTime += 1; timeTxt.setText('Süre: ' + survivalTime); survivalTick = 0; // Pulse background color every 10 seconds survived if (survivalTime > 0 && survivalTime % 10 === 0) { var baseColor = 0x181c24; var pulseColor = 0x232a3a; game.setBackgroundColor(pulseColor); LK.setTimeout(function () { game.setBackgroundColor(baseColor); }, 400); } } // Spawn shadows shadowTick++; if (shadowTick >= shadowSpawnInterval) { shadowTick = 0; for (var i = 0; i < shadowCount; i++) { spawnShadow(); } } // PowerUp spawn: every 6-10 seconds, if none active or on field if (!powerUpActive && powerUps.length === 0 && Math.random() < 0.012) { var p = new PowerUp(); // Random type, now includes 'shrink' and 'repel' var types = ['slow', 'shield', 'score', 'shrink', 'repel']; p.type = types[Math.floor(Math.random() * types.length)]; // Color by type var color = 0x00eaff; if (p.type === 'shield') color = 0x7fff00; if (p.type === 'score') color = 0xffd700; if (p.type === 'shrink') color = 0xff66cc; if (p.type === 'repel') color = 0xff4400; p.children[0].tint = color; // Place randomly, not too close to edges or player var safe = false, px, py, tries = 0; while (!safe && tries < 20) { px = 200 + Math.random() * (GAME_W - 400); py = 200 + Math.random() * (GAME_H - 400); var dx = px - lightOrb.x, dy = py - lightOrb.y; if (Math.sqrt(dx * dx + dy * dy) > 300) safe = true; tries++; } p.x = px; p.y = py; game.addChild(p); powerUps.push(p); } // Update shadows for (var i = shadows.length - 1; i >= 0; i--) { var s = shadows[i]; s.update(); // Out of bounds: if shadow is far outside, remove and score if (s.x < -300 || s.x > GAME_W + 300 || s.y < -300 || s.y > GAME_H + 300) { // If this is a splitter shadow, split it before removing if (s.shadowType === 'splitter' && !s._hasSplit) { // Split into two smaller shadows for (var splitIdx = 0; splitIdx < 2; splitIdx++) { var newS = new Shadow(); newS.x = s.x; newS.y = s.y; // Give a random direction var angle = Math.random() * Math.PI * 2; newS.vx = Math.cos(angle); newS.vy = Math.sin(angle); newS.speed = shadowSpeed + 1.2 + Math.random() * 0.7; newS.width = s.width * 0.7; newS.height = s.height * 0.7; newS.shadowType = 'normal'; game.addChild(newS); shadows.push(newS); } s._hasSplit = true; } s.destroy(); shadows.splice(i, 1); // Score for successful dodge updateScore(score + 2); // Give 2 points per dodge checkLevelUp(); // Every 5 points, ramp up difficulty if (score > 0 && score % 5 === 0) { increaseDifficulty(); } continue; } // Collision with player var intersecting = s.intersects(lightOrb); // If invincible, flash orb and skip collision if (lightOrb._invincible && lightOrb._invincible > 0) { if (lightOrb._invincible % 8 === 0) { LK.effects.flashObject(lightOrb, 0xffffff, 120); } lightOrb._invincible--; s.lastIntersecting = intersecting; continue; } if (!s.lastIntersecting && intersecting) { // If shield powerup is active, destroy shadow and continue if (powerUpActive && powerUpType === 'shield') { // If this is a splitter shadow, split it before removing if (s.shadowType === 'splitter' && !s._hasSplit) { for (var splitIdx = 0; splitIdx < 2; splitIdx++) { var newS = new Shadow(); newS.x = s.x; newS.y = s.y; var angle = Math.random() * Math.PI * 2; newS.vx = Math.cos(angle); newS.vy = Math.sin(angle); newS.speed = shadowSpeed + 1.2 + Math.random() * 0.7; newS.width = s.width * 0.7; newS.height = s.height * 0.7; newS.shadowType = 'normal'; game.addChild(newS); shadows.push(newS); } s._hasSplit = true; } s.destroy(); shadows.splice(i, 1); continue; } // Flash screen, game over LK.effects.flashScreen(0xff2222, 900); // Update high survival time if needed if (survivalTime > highSurvivalTime) { highSurvivalTime = survivalTime; highTimeTxt.setText('En Yüksek Süre: ' + highSurvivalTime); storage.highSurvivalTime = highSurvivalTime; } LK.showGameOver(); return; } s.lastIntersecting = intersecting; } // PowerUp collection and effect for (var i = powerUps.length - 1; i >= 0; i--) { var p = powerUps[i]; var intersecting = p.intersects(lightOrb); if (!p.lastIntersecting && intersecting) { // Activate effect powerUpActive = true; powerUpType = p.type; powerUpTimer = 0; // Add invincibility for 0.7s after collecting any powerup lightOrb._invincible = 42; // 0.7s at 60fps // Visual feedback LK.effects.flashObject(lightOrb, p.children[0].tint, 600); // Repel: extra visual feedback if (p.type === 'repel') { LK.effects.flashScreen(0xff4400, 400); } // Score boost: instant if (p.type === 'score') { updateScore(score + 10); checkLevelUp(); powerUpActive = false; powerUpType = null; } // Shrink: shrink orb for 4 seconds if (p.type === 'shrink') { // Store original size if (!lightOrb._origW) { lightOrb._origW = lightOrb.width; lightOrb._origH = lightOrb.height; } lightOrb.width = lightOrb._origW * 0.55; lightOrb.height = lightOrb._origH * 0.55; } // Repel: instantly push all shadows away from player if (p.type === 'repel') { for (var j = 0; j < shadows.length; j++) { var s = shadows[j]; var dx = s.x - lightOrb.x; var dy = s.y - lightOrb.y; var dist = Math.sqrt(dx * dx + dy * dy) || 1; // Set direction away from orb, keep speed s.vx = dx / dist; s.vy = dy / dist; // Give a burst of speed s.speed = Math.max(shadowSpeed + 2.5, 4.5); } powerUpActive = false; powerUpType = null; } // Remove powerup from field p.destroy(); powerUps.splice(i, 1); continue; } p.lastIntersecting = intersecting; } // PowerUp timer/effect duration if (powerUpActive) { powerUpTimer++; // Shadow slow: 4 seconds if (powerUpType === 'slow') { // Visual feedback: pulse effect while slow is active if (powerUpTimer % 30 === 0) { LK.effects.flashObject(lightOrb, 0x00eaff, 200); } // Slow down all shadows for (var j = 0; j < shadows.length; j++) { shadows[j].speed = 0.7; } shadowSpeed = 0.7; if (powerUpTimer > 240) { powerUpActive = false; powerUpType = null; shadowSpeed = 2.2 + Math.floor(score / 5) * 0.18; // Restore all shadows to normal speed for (var j = 0; j < shadows.length; j++) { shadows[j].speed = shadowSpeed + Math.random() * 0.7; } } } // Shield: 4 seconds if (powerUpType === 'shield') { // Visual feedback: pulse effect while shield is active if (powerUpTimer % 30 === 0) { LK.effects.flashObject(lightOrb, 0x7fff00, 200); } if (powerUpTimer > 240) { powerUpActive = false; powerUpType = null; } } // Shrink: 4 seconds if (powerUpType === 'shrink') { // Visual feedback: pulse effect while shrink is active if (powerUpTimer % 30 === 0) { LK.effects.flashObject(lightOrb, 0xff66cc, 200); } if (powerUpTimer > 240) { powerUpActive = false; powerUpType = null; // Restore orb size if (lightOrb._origW) { lightOrb.width = lightOrb._origW; lightOrb.height = lightOrb._origH; } } } } else { // Reset shadowSpeed if not under slow powerup shadowSpeed = 2.2 + Math.floor(score / 5) * 0.18; for (var j = 0; j < shadows.length; j++) { shadows[j].speed = shadowSpeed + Math.random() * 0.7; } } }; // Initial score updateScore(0); level = 1; levelTxt.setText('Seviye 1'); nextLevelScore = 15; // Do not reset high score display or value on game start highScoreTxt.setText('En Yüksek Skor: ' + highScore); // Reset survival time survivalTime = 0; survivalTick = 0; timeTxt.setText('Süre: 0'); // Show high survival time at game start highTimeTxt.setText('En Yüksek Süre: ' + highSurvivalTime); ; ;
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// LightOrb (Player) class
var LightOrb = Container.expand(function () {
var self = Container.call(this);
var orb = self.attachAsset('lightOrb', {
anchorX: 0.5,
anchorY: 0.5
});
// For touch feedback
self.flash = function () {
tween(orb, {
alpha: 0.6
}, {
duration: 80,
onFinish: function onFinish() {
tween(orb, {
alpha: 1
}, {
duration: 120
});
}
});
};
// No update needed; position is set by player
return self;
});
// PowerUp (Special Ability) class
var PowerUp = Container.expand(function () {
var self = Container.call(this);
// Types: 'slow', 'shield', 'score'
self.type = 'slow';
// Visuals: color by type
var color = 0x00eaff;
if (self.type === 'shield') color = 0x7fff00;
if (self.type === 'score') color = 0xffd700;
var asset = self.attachAsset('lightOrb', {
anchorX: 0.5,
anchorY: 0.5
});
asset.width = 90;
asset.height = 90;
asset.tint = color;
// For state tracking
self.lastIntersecting = false;
// No update needed; position is static
return self;
});
// Shadow (Enemy) class
var Shadow = Container.expand(function () {
var self = Container.call(this);
var shadow = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5
});
// Movement properties
self.vx = 0;
self.vy = 0;
self.speed = 2; // Will be set on spawn
// Shadow type: 'normal' or 'splitter'
self.shadowType = 'normal'; // default
// For state tracking
self.lastIntersecting = false;
// Called every tick
self.update = function () {
self.x += self.vx * self.speed;
self.y += self.vy * self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181c24
});
/****
* Game Code
****/
// Game area
// Light orb (player)
// Shadow (enemy)
// Score text will use Text2, no asset needed
var GAME_W = 2048;
var GAME_H = 2732;
// Player (light orb)
var lightOrb = new LightOrb();
lightOrb.x = GAME_W / 2;
lightOrb.y = GAME_H * 0.75;
game.addChild(lightOrb);
// Shadows (enemies)
var shadows = [];
// PowerUps (special abilities)
var powerUps = [];
// PowerUp state
var powerUpActive = false;
var powerUpType = null;
var powerUpTimer = 0;
// Score
var score = 0;
var highScore = storage.highScore || 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFBE0
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// High score text
var highScoreTxt = new Text2('En Yüksek Skor: 0', {
size: 54,
fill: 0xFFFFFF
});
// Place at bottom right, anchor to right edge
highScoreTxt.anchor.set(1, 1);
highScoreTxt.x = -40; // 40px from right edge
highScoreTxt.y = -40; // 40px from bottom edge
LK.gui.bottomRight.addChild(highScoreTxt);
// Level system
var level = 1;
var levelTxt = new Text2('Seviye 1', {
size: 80,
fill: 0x7fff00
});
levelTxt.anchor.set(0.5, 0);
levelTxt.y = 120;
LK.gui.top.addChild(levelTxt);
// Survival time
var survivalTime = 0; // in seconds
var survivalTick = 0; // for counting frames
var timeTxt = new Text2('Süre: 0', {
size: 80,
fill: 0x00eaff
});
timeTxt.anchor.set(0.5, 0);
timeTxt.y = 220;
LK.gui.top.addChild(timeTxt);
// High survival time (persistent)
var highSurvivalTime = storage.highSurvivalTime || 0;
var highTimeTxt = new Text2('En Yüksek Süre: 0', {
size: 54,
fill: 0x00eaff
});
highTimeTxt.anchor.set(1, 1);
highTimeTxt.x = -40;
highTimeTxt.y = -140; // stack above highScoreTxt
LK.gui.bottomRight.addChild(highTimeTxt);
// Level up logic
var nextLevelScore = 15; // First level up at 15, then increases
function checkLevelUp() {
if (score >= nextLevelScore) {
level++;
levelTxt.setText('Seviye ' + level);
// Animate level text: scale up and back for feedback
tween(levelTxt, {
scaleX: 1.4,
scaleY: 1.4
}, {
duration: 180,
onFinish: function onFinish() {
tween(levelTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 180
});
}
});
// Increase next level threshold (progressively harder)
nextLevelScore += 18 + Math.floor(level * 2.5); // Require more points for next level
// Level up feedback
LK.effects.flashScreen(0x7fff00, 600);
// Optionally: boost difficulty a bit more on level up
increaseDifficulty();
}
}
// Difficulty
var shadowSpeed = 1.3; // Lower base speed
var shadowSpawnInterval = 180; // Slower spawn rate
var minShadowSpawnInterval = 60; // Don't get too fast
var shadowCount = 1; // Fewer shadows at start
var maxShadowCount = 5; // Lower max shadow count
// Dragging
var dragging = false;
// Helper: clamp position inside game area
function clamp(val, min, max) {
return Math.max(min, Math.min(max, val));
}
// Helper: spawn a shadow at a random edge, moving in a random direction
function spawnShadow() {
var s = new Shadow();
// Random edge: 0=top, 1=bottom, 2=left, 3=right
var edge = Math.floor(Math.random() * 4);
var margin = 120;
var x, y, angle;
if (edge === 0) {
// top
x = margin + Math.random() * (GAME_W - 2 * margin);
y = -90;
angle = Math.PI / 4 + Math.random() * (Math.PI / 2); // 45-135 deg
} else if (edge === 1) {
// bottom
x = margin + Math.random() * (GAME_W - 2 * margin);
y = GAME_H + 90;
angle = -Math.PI / 4 - Math.random() * (Math.PI / 2); // -45 to -135 deg
} else if (edge === 2) {
// left
x = -90;
y = margin + Math.random() * (GAME_H - 2 * margin);
angle = -Math.PI / 4 + Math.random() * (Math.PI / 2); // -45 to 45 deg
} else {
// right
x = GAME_W + 90;
y = margin + Math.random() * (GAME_H - 2 * margin);
angle = Math.PI * (1.25 + Math.random() * 0.5); // 225-315 deg
}
s.x = x;
s.y = y;
s.speed = shadowSpeed + Math.random() * 0.7;
s.vx = Math.cos(angle);
s.vy = Math.sin(angle);
// Randomly assign splitter type (10% chance, but not if too many shadows)
if (Math.random() < 0.10 && shadows.length < 6 && level > 1) {
s.shadowType = 'splitter';
// Tint splitter shadow for visibility
if (s.children && s.children[0]) {
s.children[0].tint = 0x4e7fff;
}
}
// Add to game and array
game.addChild(s);
shadows.push(s);
}
// Score update
function updateScore(val) {
score = val;
scoreTxt.setText(score);
if (score > highScore) {
highScore = score;
highScoreTxt.setText('En Yüksek Skor: ' + highScore);
storage.highScore = highScore;
}
}
// Difficulty ramp
function increaseDifficulty() {
if (shadowSpawnInterval > minShadowSpawnInterval) {
shadowSpawnInterval -= 3; // Decrease spawn interval more slowly
}
if (shadowCount < maxShadowCount) {
shadowCount += 1;
}
shadowSpeed += 0.09; // Increase speed more slowly
}
// Move handler (drag orb)
function handleMove(x, y, obj) {
if (dragging) {
// Clamp to game area, avoid top left 100x100
var nx = clamp(x, 100 + lightOrb.width / 2, GAME_W - lightOrb.width / 2);
var ny = clamp(y, lightOrb.height / 2, GAME_H - lightOrb.height / 2);
lightOrb.x = nx;
lightOrb.y = ny;
}
}
game.move = handleMove;
// Down handler (start drag)
game.down = function (x, y, obj) {
// Only start drag if touch is on orb
var dx = x - lightOrb.x;
var dy = y - lightOrb.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < lightOrb.width / 2 + 30) {
dragging = true;
lightOrb.flash();
handleMove(x, y, obj);
}
};
// Up handler (stop drag)
game.up = function (x, y, obj) {
dragging = false;
};
// Shadow spawn timer
var shadowTick = 0;
// Main update loop
game.update = function () {
// Update survival time
survivalTick++;
if (survivalTick >= 60) {
// update every 1s (60fps)
survivalTime += 1;
timeTxt.setText('Süre: ' + survivalTime);
survivalTick = 0;
// Pulse background color every 10 seconds survived
if (survivalTime > 0 && survivalTime % 10 === 0) {
var baseColor = 0x181c24;
var pulseColor = 0x232a3a;
game.setBackgroundColor(pulseColor);
LK.setTimeout(function () {
game.setBackgroundColor(baseColor);
}, 400);
}
}
// Spawn shadows
shadowTick++;
if (shadowTick >= shadowSpawnInterval) {
shadowTick = 0;
for (var i = 0; i < shadowCount; i++) {
spawnShadow();
}
}
// PowerUp spawn: every 6-10 seconds, if none active or on field
if (!powerUpActive && powerUps.length === 0 && Math.random() < 0.012) {
var p = new PowerUp();
// Random type, now includes 'shrink' and 'repel'
var types = ['slow', 'shield', 'score', 'shrink', 'repel'];
p.type = types[Math.floor(Math.random() * types.length)];
// Color by type
var color = 0x00eaff;
if (p.type === 'shield') color = 0x7fff00;
if (p.type === 'score') color = 0xffd700;
if (p.type === 'shrink') color = 0xff66cc;
if (p.type === 'repel') color = 0xff4400;
p.children[0].tint = color;
// Place randomly, not too close to edges or player
var safe = false,
px,
py,
tries = 0;
while (!safe && tries < 20) {
px = 200 + Math.random() * (GAME_W - 400);
py = 200 + Math.random() * (GAME_H - 400);
var dx = px - lightOrb.x,
dy = py - lightOrb.y;
if (Math.sqrt(dx * dx + dy * dy) > 300) safe = true;
tries++;
}
p.x = px;
p.y = py;
game.addChild(p);
powerUps.push(p);
}
// Update shadows
for (var i = shadows.length - 1; i >= 0; i--) {
var s = shadows[i];
s.update();
// Out of bounds: if shadow is far outside, remove and score
if (s.x < -300 || s.x > GAME_W + 300 || s.y < -300 || s.y > GAME_H + 300) {
// If this is a splitter shadow, split it before removing
if (s.shadowType === 'splitter' && !s._hasSplit) {
// Split into two smaller shadows
for (var splitIdx = 0; splitIdx < 2; splitIdx++) {
var newS = new Shadow();
newS.x = s.x;
newS.y = s.y;
// Give a random direction
var angle = Math.random() * Math.PI * 2;
newS.vx = Math.cos(angle);
newS.vy = Math.sin(angle);
newS.speed = shadowSpeed + 1.2 + Math.random() * 0.7;
newS.width = s.width * 0.7;
newS.height = s.height * 0.7;
newS.shadowType = 'normal';
game.addChild(newS);
shadows.push(newS);
}
s._hasSplit = true;
}
s.destroy();
shadows.splice(i, 1);
// Score for successful dodge
updateScore(score + 2); // Give 2 points per dodge
checkLevelUp();
// Every 5 points, ramp up difficulty
if (score > 0 && score % 5 === 0) {
increaseDifficulty();
}
continue;
}
// Collision with player
var intersecting = s.intersects(lightOrb);
// If invincible, flash orb and skip collision
if (lightOrb._invincible && lightOrb._invincible > 0) {
if (lightOrb._invincible % 8 === 0) {
LK.effects.flashObject(lightOrb, 0xffffff, 120);
}
lightOrb._invincible--;
s.lastIntersecting = intersecting;
continue;
}
if (!s.lastIntersecting && intersecting) {
// If shield powerup is active, destroy shadow and continue
if (powerUpActive && powerUpType === 'shield') {
// If this is a splitter shadow, split it before removing
if (s.shadowType === 'splitter' && !s._hasSplit) {
for (var splitIdx = 0; splitIdx < 2; splitIdx++) {
var newS = new Shadow();
newS.x = s.x;
newS.y = s.y;
var angle = Math.random() * Math.PI * 2;
newS.vx = Math.cos(angle);
newS.vy = Math.sin(angle);
newS.speed = shadowSpeed + 1.2 + Math.random() * 0.7;
newS.width = s.width * 0.7;
newS.height = s.height * 0.7;
newS.shadowType = 'normal';
game.addChild(newS);
shadows.push(newS);
}
s._hasSplit = true;
}
s.destroy();
shadows.splice(i, 1);
continue;
}
// Flash screen, game over
LK.effects.flashScreen(0xff2222, 900);
// Update high survival time if needed
if (survivalTime > highSurvivalTime) {
highSurvivalTime = survivalTime;
highTimeTxt.setText('En Yüksek Süre: ' + highSurvivalTime);
storage.highSurvivalTime = highSurvivalTime;
}
LK.showGameOver();
return;
}
s.lastIntersecting = intersecting;
}
// PowerUp collection and effect
for (var i = powerUps.length - 1; i >= 0; i--) {
var p = powerUps[i];
var intersecting = p.intersects(lightOrb);
if (!p.lastIntersecting && intersecting) {
// Activate effect
powerUpActive = true;
powerUpType = p.type;
powerUpTimer = 0;
// Add invincibility for 0.7s after collecting any powerup
lightOrb._invincible = 42; // 0.7s at 60fps
// Visual feedback
LK.effects.flashObject(lightOrb, p.children[0].tint, 600);
// Repel: extra visual feedback
if (p.type === 'repel') {
LK.effects.flashScreen(0xff4400, 400);
}
// Score boost: instant
if (p.type === 'score') {
updateScore(score + 10);
checkLevelUp();
powerUpActive = false;
powerUpType = null;
}
// Shrink: shrink orb for 4 seconds
if (p.type === 'shrink') {
// Store original size
if (!lightOrb._origW) {
lightOrb._origW = lightOrb.width;
lightOrb._origH = lightOrb.height;
}
lightOrb.width = lightOrb._origW * 0.55;
lightOrb.height = lightOrb._origH * 0.55;
}
// Repel: instantly push all shadows away from player
if (p.type === 'repel') {
for (var j = 0; j < shadows.length; j++) {
var s = shadows[j];
var dx = s.x - lightOrb.x;
var dy = s.y - lightOrb.y;
var dist = Math.sqrt(dx * dx + dy * dy) || 1;
// Set direction away from orb, keep speed
s.vx = dx / dist;
s.vy = dy / dist;
// Give a burst of speed
s.speed = Math.max(shadowSpeed + 2.5, 4.5);
}
powerUpActive = false;
powerUpType = null;
}
// Remove powerup from field
p.destroy();
powerUps.splice(i, 1);
continue;
}
p.lastIntersecting = intersecting;
}
// PowerUp timer/effect duration
if (powerUpActive) {
powerUpTimer++;
// Shadow slow: 4 seconds
if (powerUpType === 'slow') {
// Visual feedback: pulse effect while slow is active
if (powerUpTimer % 30 === 0) {
LK.effects.flashObject(lightOrb, 0x00eaff, 200);
}
// Slow down all shadows
for (var j = 0; j < shadows.length; j++) {
shadows[j].speed = 0.7;
}
shadowSpeed = 0.7;
if (powerUpTimer > 240) {
powerUpActive = false;
powerUpType = null;
shadowSpeed = 2.2 + Math.floor(score / 5) * 0.18;
// Restore all shadows to normal speed
for (var j = 0; j < shadows.length; j++) {
shadows[j].speed = shadowSpeed + Math.random() * 0.7;
}
}
}
// Shield: 4 seconds
if (powerUpType === 'shield') {
// Visual feedback: pulse effect while shield is active
if (powerUpTimer % 30 === 0) {
LK.effects.flashObject(lightOrb, 0x7fff00, 200);
}
if (powerUpTimer > 240) {
powerUpActive = false;
powerUpType = null;
}
}
// Shrink: 4 seconds
if (powerUpType === 'shrink') {
// Visual feedback: pulse effect while shrink is active
if (powerUpTimer % 30 === 0) {
LK.effects.flashObject(lightOrb, 0xff66cc, 200);
}
if (powerUpTimer > 240) {
powerUpActive = false;
powerUpType = null;
// Restore orb size
if (lightOrb._origW) {
lightOrb.width = lightOrb._origW;
lightOrb.height = lightOrb._origH;
}
}
}
} else {
// Reset shadowSpeed if not under slow powerup
shadowSpeed = 2.2 + Math.floor(score / 5) * 0.18;
for (var j = 0; j < shadows.length; j++) {
shadows[j].speed = shadowSpeed + Math.random() * 0.7;
}
}
};
// Initial score
updateScore(0);
level = 1;
levelTxt.setText('Seviye 1');
nextLevelScore = 15;
// Do not reset high score display or value on game start
highScoreTxt.setText('En Yüksek Skor: ' + highScore);
// Reset survival time
survivalTime = 0;
survivalTick = 0;
timeTxt.setText('Süre: 0');
// Show high survival time at game start
highTimeTxt.setText('En Yüksek Süre: ' + highSurvivalTime);
;
;